views:

223

answers:

3

I'm writing a Python package. The package needs to know its version number internally, while also including this version in the setup.py script for distutils.

What's the best way of doing this, so that the version number doesn't need to be maintained in two separate places? I don't want to import the setup.py script from the rest of my library (that seems rather silly) and I don't want to import my library from the setup.py script (likewise). Ideally, I'd just set a keyword in svn and have that automatically substituted into the files, but that doesn't seem to be possible in svn. I could read a common text file containing the version number in both places--is this the best solution?

To clarify: I want to maintain the version number in one place. Yes, I could put a variable in the package, and again in the setup.py file. But then they'd inevitably get out of sync.

+5  A: 

Inside of your main package, you probably have an __init__.py, right?

Directory structure:

> ./packageTest
>   ./packageTest/__init__.py
>   ./packageTest/setup.py

Inside the __init__.py file, add the following line:

# package directory __init__.py
__version__ = 1.0

setup.py file:

# setup.py
from packageTest import __version__
...

Now in any module that imports from the package directory (I'll call packageTest), you can do this:

from packageTest import setup
print 'Setup.py version:', setup.__version__  
# prints Setup.py version: 1.0
jcoon
That doesn't tell me the version in setup.py, does it?
Chris B.
You can add a __version__ to setup.py as well. Using the __init__.py is a version for the whole package.
jcoon
I think he wants to write it once, in this way he needs to update 2 places every time there is an update...
Andrea Ambu
Are you suggesting I import my package from within the setup.py script? That won't work, will it?
Chris B.
OK I understand what you are looking for I think. Define the version in your package, then have setup.py use the same version. I updated the code above
jcoon
You suggest an unusual layout. Usually the setup script would be in the directory that also contains the package directory (named packageTest in your case IIUC).
theller
Is that an unusual structure? The distutils documentation doesn't mention there's an expected way to arrange things.
Chris B.
A: 

Importing the setup script inside your package is silly (especially since it may no longer be present after your library is installed), but importing your library inside setup.py should be fine. A separate text file would work too, but has the problem that you must install the text file with your package if you want to access the version number at runtime.

theller
Isn't it the same setup.py that gets executed before the package gets installed, as gets executed to create the installer? Or does distutils write out a different setup.py?
Chris B.
It's the setup.py script that *does* install your package (if you run 'setup.py install'), or that does create the installer for your package (if you run 'setup.py bdist_wininst', for example). The setup script itself is NOT installed.
theller
A: 

I have a similar problem with my project. I have written a top-level, test/build/package/deploy script called build.py (not distutils-based, mind you). It reads a properties file, which contains the centralized version number. Instead of maintaining a setup.py file directly, I instead keep a template file, and my build.py script reads it in, substitutes the version variable with the value from the props file, and then writes out a setup.py script. Then my script file will execute it, to generate a package or upload to pypi.

gregturn