views:

2732

answers:

6

Hey everyone,

Is there a standard way to associate version string with a python package in such way that I could do the following?

import foo
print foo.version

I would imagine there's some way to retrieve that data without any extra hardcoding, since minor/major strings are specified in setup.py already. Alternative solution that I found was to have import __version__ in my foo/__init__.py and then have __version__.py generated by setup.py

Thanks,

A: 

For what it's worth, if you're using NumPy distutils, numpy.distutils.misc_util.Configuration has a make_svn_version_py() method that embeds the revision number inside package.__svn_version__ in the variable version .

Matt
+1  A: 

There doesn't seem to be a standard way to embed a version string in a python package. Most packages I've seen use some variant of your solution, i.e. eitner

  1. Embed the version in setup.py and have setup.py generate a module (e.g. version.py) containing only version info, that's imported by your package, or

  2. The reverse: put the version info in your package itself, and import that to set the version in setup.py

dF
+22  A: 

Not directly an answer to your question, but you should consider naming it __version__, not version.

This is almost a quasi-standard. Many modules in the standard library use __version__, and this is also used in lots of 3rd-party modules, so it's the quasi-standard. It's also mentioned in PEP 3001

Usually, __version__ is a string, but sometimes it's also a float or tuple.

Edit: as mentioned by S.Lott (Thank you!), PEP 8 says it explicitly:

Version Bookkeeping

If you have to have Subversion, CVS, or RCS crud in your source file, do it as follows.

    __version__ = "$Revision: 63990 $"
    # $Source$

These lines should be included after the module's docstring, before any other code, separated by a blank line above and below.

oefe
+1: __version__. PEP 8 specifically names this module global for version bookkeeping.
S.Lott
It should be a string, and have a __version_info__ for the tuple version.
James Antill
James: Why `__version_info__` specifically? (Which "invents" your own double-underscore-word.) [When James commented, underscores did nothing in comments, now they indicate emphasis, so James really wrote `__version_info__` too. ---ed.]
Roger Pate
You can see something about what __version__ should say at http://packages.python.org/distribute/setuptools.html#specifying-your-project-s-versionThat page is about distribute, but the meaning of the version number is becoming a de-facto standard.
sienkiew
+1  A: 

Also worth noting is that as well as __version__ being a semi-std. in python so is __version_info__ which is a tuple, in the simple cases you can just do something like:

__version__ = '1.2.3'
__version_info__ = tuple([ int(num) for num in __version__.split('.')])

...and you can get the __version__ string from a file, or whatever.

James Antill
Do you have any references/links regarding the origin of this usage of `__version_info__`?
Craig McQueen
Well it's the same mapping as sys.version to sys.version_info. So: http://docs.python.org/library/sys.html#sys.version_info
James Antill
+5  A: 

Though this is probably far too late, there is a slightly simpler alternative to the previous answer:

__version_info__ = ('1', '2', '3')
__version__ = '.'.join(__version_info__)

(And it would be fairly simple to convert auto-incrementing portions of version numbers to a string using str().)

Of course, from what I've seen, people tend to use something like the previously-mentioned version when using __version_info__, and as such store it as a tuple of ints; however, I don't quite see the point in doing so, as I doubt there are situations where you would perform mathematical operations such as addition and subtraction on portions of version numbers for any purpose besides curiosity or auto-incrementation (and even then, int() and str() can be used fairly easily), and comparison operations can be performed just as easily on string numerals as on integers. (On the other hand, there is the possibility of someone else's code expecting a numerical tuple rather than a string tuple and thus failing.)

This is, of course, my own view, and I would gladly like others' input on using a numerical tuple.

JAB
nice (+1), but wouldn't you prefer numbers instead of strings? e.g. `__version_info__ = (1,2,3)`
orip
+2  A: 

I also saw another style:

>>> django.VERSION
(1, 1, 0, 'final', 0)
L1ker