24

After reading the python documentation (http://www.python.org/dev/peps/pep-0396/) I was more confused than before about how to set the __version__ attribute for packages appropriately. It is mentioned to put them into the setup.py file, which kind of confuses me: it would not be available as my_package.__version__, would it?

I ended up to import the version attribute from a separate file.

So my "version" file usually is

my_package/
    __init__.py
    my_module1/
        ...
    my_module2/
        ...
    my_module3/
        ...
    info/
        __init__.py
        version.py
            __version__ = '0.1.0'

and in the uppermost __init__.py I import the __version__ attribute from info.version :

import __version__

so that one can get version number via

my_package.__version__

I am just wondering if this is a "okay" approach, and if something speaks against doing it like this? I am looking forward to your opinions and suggestions!

  • 6
    Closely related: [What is the correct way to share package version with setup.py and the package?](http://stackoverflow.com/q/17583443), which requires you use `setuptools` instead of `distutils`. No, setting the version in `setup.py` will not make it available as `my_package.__version__`. – Martijn Pieters Jul 22 '13 at 15:33
  • I will check out the other thread, thank you! –  Jul 22 '13 at 15:58

2 Answers2

11

One solution is to define the __version__ in your __init__.py file and read that from within the setup.py. This means you only have to change the version in one location. I wrote a small function that will do this:

from setuptools import setup
import re

def get_property(prop, project):
    result = re.search(r'{}\s*=\s*[\'"]([^\'"]*)[\'"]'.format(prop), open(project + '/__init__.py').read())
    return result.group(1)

project_name = 'YOUR PROJECT'
setup(
    ...,
    version = get_property('__version__', project_name),
    ...,
)

you can also use this to fetch things like __author__ or anything else defined in the __init__.py file

Eric Blum
  • 744
  • 12
  • 29
0

You haven't said how you get the version number into setup.py, but don't try to import it with the usual import my_package approach. You package hasn't been installed when you run setup.py!

My usual approach is to define the version number in setup.py and have setup.py (re)generate the package's top level __init__.py file when the version number changes. This is easy to do if the __init__.py file contains no other code.

  • 1
    Yes, that sounds like a hack that would work! Right now, I have basically a version number defined in the `setup.py` and one in `__init__.py` -- this works fine until you forget to change either of those when you update the package ... :P –  Jan 08 '15 at 01:04