Question on using distutils.core.run_setup
[Apologies if this is in the mailing list archives. I looked but didn't see anything, based on a search for run_setup] I'm trying to programmatically install something built using distutils. I found distutils.core.run_setup and can use it via
dist = run_setup('setup.py', ['-q', 'install'])
Is that the recommended way to do an install from inside Python (as opposed to doing it on the command line)? If so, how can I find where the thing(s) I installed now resides? I saw dist.packages but that just has top-level package names. I could __import__ these (and then use module.__file__), but that's not a good solution as it may run code I don't want run. On my machine, I can see the packages have been installed under the system's python2.5/site-packages directory. But how can I determine that programmatically? I don't see anything useful on the distutils.dist.Distribution instance I'm getting back from run_setup. Thanks! Terry
On Tue, Mar 18, 2008 at 6:27 AM, Terry Jones
[Apologies if this is in the mailing list archives. I looked but didn't see anything, based on a search for run_setup]
I'm trying to programmatically install something built using distutils. I found distutils.core.run_setup and can use it via
dist = run_setup('setup.py', ['-q', 'install'])
Is that the recommended way to do an install from inside Python (as opposed to doing it on the command line)?
I don't use this command because it does an execfile, which will lead to errors if the setup script uses some globals like __file__, iirc You can import the module that contains the setup() call from you code as long as you set the sys.argv values as you would do through the command line *before* the import statement. I would do something like this:: import sys import os def run_setup(script='setup.py', args=('install',)): base_name = os.path.basename(script) module_name = script.split('.')[0] folder_name = os.path.realpath(os.path.dirname(script)) old = sys.argv old_location = os.curdir try: os.chdir(folder_name) sys.argv = [base_name] + list(args) __import__(module_name) finally: os.chdir(old_location) sys.argv = old if __name__ == '__main__': if len(sys.argv) > 1: setup_py = sys.argv[1] run_setup(setup_py, sys.argv[2:]) else: run_setup()
If so, how can I find where the thing(s) I installed now resides? I saw dist.packages but that just has top-level package names. I could __import__ these (and then use module.__file__), but that's not a good solution as it may run code I don't want run. On my machine, I can see the packages have been installed under the system's python2.5/site-packages directory. But how can I determine that programmatically? I don't see anything useful on the distutils.dist.Distribution instance I'm getting back from run_setup.
I don't know about run_setup but you can use get_python_lib when you are using default locations on your setup() call. It will give you the default location:
from distutils.sysconfig import get_python_lib get_python_lib() '/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages'
Thanks!
Terry _______________________________________________ Distutils-SIG maillist - Distutils-SIG@python.org http://mail.python.org/mailman/listinfo/distutils-sig
-- Tarek Ziadé | Association AfPy | www.afpy.org Blog FR | http://programmation-python.org Blog EN | http://tarekziade.wordpress.com/
At 06:27 AM 3/18/2008 +0100, Terry Jones wrote:
[Apologies if this is in the mailing list archives. I looked but didn't see anything, based on a search for run_setup]
I'm trying to programmatically install something built using distutils. I found distutils.core.run_setup and can use it via
dist = run_setup('setup.py', ['-q', 'install'])
Is that the recommended way to do an install from inside Python (as opposed to doing it on the command line)?
I never could get run_setup() to work robustly. Here's how setuptools does it, and it works well with quite a lot of packages: os.chdir(setup_dir) try: sys.argv[:] = [setup_script]+list(args) sys.path.insert(0, setup_dir) DirectorySandbox(setup_dir).run( lambda: execfile( "setup.py", {'__file__':setup_script, '__name__':'__main__'} ) ) except SystemExit, v: if v.args and v.args[0]: raise # Normal exit, just return This is actually wrapped in a try-finally that saves and restores sys.argv, sys.path, os.chdir(), etc. Have a look at setuptools.sandbox.run_setup() for the full source. Of course, this won't get you access to the distribution object; setuptools uses this mainly to run "bdist_egg" on the setup script, rather than having it do the installation directly. (Note, by the way, that distutils setup scripts can get very confused if you don't os.chdir() to their directory before running them.)
If so, how can I find where the thing(s) I installed now resides?
The simplest way would be to use the --record option to "install", to write a file listing all the installed files.
I saw dist.packages but that just has top-level package names. I could __import__ these (and then use module.__file__), but that's not a good solution as it may run code I don't want run. On my machine, I can see the packages have been installed under the system's python2.5/site-packages directory. But how can I determine that programmatically? I don't see anything useful on the distutils.dist.Distribution instance I'm getting back from run_setup.
It'd be on the 'install_lib' command instance, not the distribution. Try dist.get_finalized_command('install_lib').install_dir instead.
On Tue, Mar 18, 2008 at 5:34 PM, Phillip J. Eby
[cut]
I never could get run_setup() to work robustly.
Here's how setuptools does it, and it works well with quite a lot of packages:
os.chdir(setup_dir) try: sys.argv[:] = [setup_script]+list(args) sys.path.insert(0, setup_dir) DirectorySandbox(setup_dir).run( lambda: execfile( "setup.py", {'__file__':setup_script, '__name__':'__main__'} ) ) except SystemExit, v: if v.args and v.args[0]: raise # Normal exit, just return
This is actually wrapped in a try-finally that saves and restores sys.argv, sys.path, os.chdir(), etc. Have a look at setuptools.sandbox.run_setup() for the full source.
Cool ! Maybe this could be pushed into distutils ? It looks more like a fix to me Tarek
participants (3)
-
Phillip J. Eby
-
Tarek Ziadé
-
Terry Jones