On 05 August 2000, Amos Latteier said:
Right. However I was looking for something I could do from Python, not the command line. I'd like to import the distribution's setup module and then interrogate it from Python to find out meta-data.
I know, how about os.popen("%s setup.py --name --version" % sys.executable).read() ?
Right now, I can't think of a good way to do this. As you suspected, you'd have to write your own setup() function and stick it into distutils.core before importing setup, then just "import setup". setup.py would then call your craftily constructed 'setup()' function instead of the standard one.
Obviously, your setup() would probably look an awful lot like the one in distutils.core; you should really read through the source to see what it does. Here's a summary:
* figure out the distribution class to use (default distutils.dist.Distribution) * instantiate the distribution class, using (most of) the keyword args to 'setup()' as constructor args. (IOW, setup(name="Distutils, version="1.0") is nearly equivalent to Distribution(name="Distutils, version="1.0") .) * parse config files * parse the command line * run all commands mentioned on the command line, using the per-command options that were found by parsing config files and the command line
You might think that this:
from distutils.dist import Distribution from distutils import core core.setup = Distribution import setup
would work, but there are two problems: * there's at least one keyword arg to 'setup()' that is not passed to the Distribution constructor: 'distclass', which specifies the distribution class to use (this is one of the "backdoors" for extending the Distutils, but (AFAIK) it has never been used in practice) * no way to get at the Distribution object slyly created for you
Next option: write your own version of 'setup()' that just does the first two steps and stores the created object somewhere you can get your hands on it (eg. a global in distutils.core), and then replace distutils.core.setup with your version.
Best option: change the Distutils so that it (optionally) does this for you. Eg. where a normal setup script does this:
from distutils.core import setup setup(name = "Distutils, version = "1.0")
and nothing more, your tool would do something like this:
from distutils import core
core.do_nothing_mode() # better name? import setup dist = core.get_distribution() dist.get_name(), dist.get_version(), ...
I think you could get away with execfile()'ing "setup.py" instead of importing it; it's not really a module to be imported, after all. It would have the same effect: call the official Distutils 'setup()' function, which -- since we're in "do nothing" mode -- just does the first two steps and saves the distribution object somewhere. 'get_distribution()' would then retrieve that distribution object so you can query its meta-data.
A bit of a hack, sure, I think it'll work. Let me know if you cook up a patch to core.py, or if you'd rather I did it. Shouldn't be too hard.
To install a distribution obviously you must trust it. I'm imaging a system that does stuff like crawl the web looking for Python distributions, downloads them and parses them for meta-data. In this case I don't trust the distribution enough to install it, but I do want to find out what it has to say for itself.
Yeah, I can definitely see that as useful in (say) a Distutils-aware Vaults of Parnassus. You still have to import or execfile() untrusted code, of course. Ahh well...