Folks:

I have a recurring problem with distutils/setuptools/Distribute, which is that I don't know how to extend the functionality of setup.py and make the new functionality be testable and modular.

Here's one specific example that I currently have a lot of experience with: I'd like to generate a version number from revision control history. Don't get hung up on the desired functionality though -- if you think that generating version numbers is best done a different way, or if you don't care about generating version numbers, then please just mentally insert some other extension of your build functionality that you do care about.

I'm familiar with three different ways to implement an extension like this.

The first is what Nevow does [1], which is to write in setup.py "from nevow import __version__". Well, this works in the case that setup.py is being executed as the command-line script in a fresh, empty Python interpreter, but it fails in the case that the Python interpreter has already been running for a while, has already imported nevow (a *different* nevow from a different location on the local filesystem), and is now importing *this* nevow's setup module in order to build this nevow. This happens with setuptools and py2exe. Distribute v0.6 includes a patch [2] to fix this, but I'm not sure the patch is right (it involves 'for m in various_modules: del sys.modules[m]' and it doesn't seem to fix all cases). PJE says "Thou shalt not import yourself when trying to build yourself" [3]. Glyph says "Then how do I test this code?" [4]. I say "Ugh, I don't know. Let's look at the other two ways to do it."

The second is what I do in some of my packages such as pycryptopp [5]. Just take that functionality that you want to add to all of your packages and cut and paste the code into each of your setup.py's, then edit it a little to reflect the correct name of the current package. This sucks because you're cutting and pasting code, because your setup.py gets bigger and hairier the more functionality your build system has, and because, again, you can't test it.

The third is what I do in Tahoe-LAFS [6]. I moved the functionality in question into a separate Python package, in this case named "darcsver" [7], and used setuptools's plugin system to add a command named "darcsver" which initializes the distribution.metadata.version attribute correctly. Then I had to add a bunch of aliases to my setup.cfg [8] saying "If you're going to build, first darcsver, and if you're going to install, first darcsver, and ...". This sort of works, except that yesterday my programming partner Brian Warner informed me [9] that he expected the "python ./setup.py --version" command-line to output the version number. Argh! There is no way to configure in my setup.cfg "If you're going to --version, first darcsver.".

So it appears to me that none of these techniques are both modular/ testable and compatible with distutils/setuptools/Distribute. What are we to do?

Regards,

Zooko

[1] http://www.divmod.org/trac/browser/trunk/Nevow/setup.py?rev=17531
[2] http://bugs.python.org/setuptools/issue20
[3] http://bugs.python.org/setuptools/msg139
[4] http://www.divmod.org/trac/ticket/2699#comment:20
[5] http://allmydata.org/trac/pycryptopp/browser/setup.py?rev=661#L181
[6] http://allmydata.org/trac/tahoe/browser/setup.py?rev=4036#L97
[7] http://allmydata.org/trac/darcsver
[8] http://allmydata.org/trac/tahoe/browser/setup.cfg?rev=3996#L46
[9] http://allmydata.org/trac/darcsver/ticket/6
_______________________________________________
Distutils-SIG maillist  -  [email protected]
http://mail.python.org/mailman/listinfo/distutils-sig

Reply via email to