Mostrando entradas con la etiqueta python. Mostrar todas las entradas
Mostrando entradas con la etiqueta python. Mostrar todas las entradas

viernes, 9 de diciembre de 2011

GIT Rev number on Python Package with SetupTool

Is very common to see on python projects a VERSION.py file or a VERSION string on setup.py. Every time the project has a new version, the you have to modify and push it. Personally, I don't like hardcoded version on the code, that responsibility should be share by the repository and the packager script. So after google it and not find something useful, I coded something, not so elegant, but works for me. Well first, setup your git repo and add tag in it. The way to get a cool revision number is:
git describe --abbrev=4 HEAD 
you will get something like :
0.0.1-29-gad35
Thats means, from the tag 0.0.1 there are 29 commits and the last one is gad35. In setup.py there is a field "version" so you can put a DEFAULT version mean while like '0.0.1' OR we can create a function that actually call the git command:
def get_version():
    git_call = subprocess.Popen(['git','describe','--abbrev=4','HEAD'], stdout=subprocess.PIPE)
    return git_call.stdout.read().strip()
and call it from the setup
setup( name='test'
    ,version=get_version()
    ,description=("Test blabla babla ........
That works, if the setup.py is called from the GIT repo. But what happen if it is called from the production environment, well will fail, because there is no GIT repo. So the change is kind of tricky.
def get_version(argv):
    if "install" in argv or "egg_info" in argv:
        #means setup.py is called from deployment process
        return "0.0.0"
    else:
        try:
            git_call = subprocess.Popen(['git','describe','--abbrev=4','HEAD'],
                                        stdout=subprocess.PIPE)
            return git_call.stdout.read().strip()
        except OSError:
            return "0.0.0"

The arg is added to the function, so the setup must provide them:
setup( name='test'
    ,version=get_version(sys.arg)
    ,description=("Test blabla babla ........
Now we need to create a packager script and get the revision number (from GIT or from the package created by setuptools). Then replace that REVISION number in the setup.py generated in the package. Repackage again and voila.
FILENAME=`python setup.py build sdist 2>/dev/null| grep Writing | cut -d' ' -f2 | cut -d/ -f1`

VERSION=${FILENAME#*lbsc-};
VERSION=${VERSION%/*}

pushd dist; tar xzf $FILENAME.tar.gz; rm $FILENAME.tar.gz;
pushd $FILENAME;
sed -i "s/return .0.0.0./return '$VERSION'/g" setup.py;
popd; tar czf $FILENAME.tar.gz $FILENAME;rm $FILENAME -rf;popd
Also we can create a get_version function on __init__.py and replace the VERSION on the code for the current one:
sed -i "s/^VERSION =.*$/VERSION = '$VERSION'/g" lbsc/__init__.py;
Now after install you can do:
import test; test.get_version()
Hope this was helpful.

miércoles, 13 de julio de 2011

Remove repeated elements from a list in Python

Say we have the python list:

>>> x = [5,6,5]

to remove the duplications, use the following code snippet:


>>> x_nodups = dict(map(lambda i: (i,1),x)).keys()


Taken from the desk of stinkpot

viernes, 17 de julio de 2009

UnicodeEncodeError: 'ascii' codec can't encode character XXX

 Yet another text-format error in python (personal error, of course)...  while I was trying to store in file a joined list (through list comprehension), one or more of the characters of one the fields that are being joined generate the following 'friendly message':

Traceback (most recent call last):
  File "stations.py", line 62, in
  exit(main())
  File "stations.py", line 16, in main
  record.append(str(element.text))
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf1' in position 7: ordinal not in range(128)

 to avoid it, instead of trying to cast into a string the variable, you could use the repr() function... 

repr(object)
  Return a string containing a printable representation of an object.
  (http://docs.python.org/library/functions.html)

Example:

>>> caca = u'\u2603'
>>> print caca
☃
>>> str(caca)
Traceback (most recent call last):
  File "", line 1, in
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2603' in position 0: ordinal not in range(128)
>>> repr(caca)
"u'\\u2603'"

solution from:
http://blog.codekills.net/archives/45-str...-yer-probably-doin-it-wrong..html

viernes, 10 de julio de 2009

Python broken pipe

This could be little weird but I have seen this, more than once. When you work in python , parsing the standard input, and for some reason you use a pipe at the end of you process to see the head or tail like:
python foo.py| head
and you get a Broken Pipe Error then the next code snippet could be useful.


import sys
for line in sys.stdin:
print line.strip()


Then run your program and you will get

$ yes | python pipe.py |head
y
y
y
y
y
Traceback (most recent call last):
File "pipe.py", line 5, in ?
print line
IOError: [Errno 32] Broken pipe


To avoid this error just use signal package:

import signal
import sys

signal.signal(signal.SIGPIPE, signal.SIG_DFL)

for line in sys.stdin:
print line.strip()



Enjoy