![](https://secure.gravatar.com/avatar/09641288a077f37031fc8520d5d1d01a.jpg?s=120&d=mm&r=g)
I've been thinking about how to query distutils packages. One thing I'd like to do is download archives from the net and programmatically find meta-data about the archive
$ ./setup.py --name --version --author-email --url Distutils 0.9.1pre gward@python.net http://www.python.org/sigs/distutils-sig/
Clear enough?
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.
* It seems that I must execute potentially untrusted code to get the meta-data. Is there anyway around this? I guess RExec is the answer...
Curses. I knew someone would get paranoid about writing dist-bots at some point. I have no answers to this... however, the above "informational" command shouldn't be doing any filesystem access apart from importing stuff, so it's probably "securable". Obviously, general Distutils usage makes extensive use of the filesystem, so writing general dist-bots securely will probably be tricky. Sigh.
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. Thanks for you help! I'll let you know if I come up with solutions to these problems that I like better. -Amos
![](https://secure.gravatar.com/avatar/3d5a540f00cbb2cc4e09ae5913fa781a.jpg?s=120&d=mm&r=g)
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() ? Just kidding! 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... Greg -- Greg Ward - geek-at-large gward@python.net http://starship.python.net/~gward/ All the world's a stage and most of us are desperately unrehearsed.
participants (2)
-
Amos Latteier
-
Greg Ward