4

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.

Chris B.
  • 85,731
  • 25
  • 98
  • 139

4 Answers4

5

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
Jason Coon
  • 17,601
  • 10
  • 42
  • 50
  • That doesn't tell me the version in setup.py, does it? – Chris B. Mar 10 '09 at 19:56
  • You can add a __version__ to setup.py as well. Using the __init__.py is a version for the whole package. – Jason Coon Mar 10 '09 at 20:00
  • 1
    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 Mar 10 '09 at 20:02
  • Are you suggesting I import my package from within the setup.py script? That won't work, will it? – Chris B. Mar 10 '09 at 20:05
  • 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 – Jason Coon Mar 10 '09 at 20:08
  • 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 Mar 10 '09 at 21:19
  • Is that an unusual structure? The distutils documentation doesn't mention there's an expected way to arrange things. – Chris B. Mar 10 '09 at 23:57
0

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
  • 2,809
  • 19
  • 19
  • 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. Mar 10 '09 at 20:12
  • 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 Mar 10 '09 at 21:17
0

I had 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.

Brock Adams
  • 90,639
  • 22
  • 233
  • 295
gregturn
  • 2,625
  • 3
  • 25
  • 40
0

See also Standard way to embed version into python package? which is about how to propagate the version information from the one location (a file named _version.py) to the places where other code looks for it (e.g. an attribute named __version__ and PEP 0345 metadata).

Then see Brian Warner's new "versioneer" tool, which produces the _version.py file from revision control history.

Also, please check out my answer to Standard way to embed version into python package?, the more people that realize there is a way to do it which avoids the problems of importing your module from your setup script, the better.

Community
  • 1
  • 1
Zooko
  • 2,342
  • 1
  • 18
  • 12