[Checkins] SVN: zc.buildout/branches/gary-8/ set up PYTHONPATH for scripts too, so subprocesses are good to go by default.
Gary Poster
gary.poster at canonical.com
Wed Mar 10 21:59:49 EST 2010
Log message for revision 109905:
set up PYTHONPATH for scripts too, so subprocesses are good to go by default.
Changed:
A zc.buildout/branches/gary-8/
U zc.buildout/branches/gary-8/src/zc/buildout/buildout.py
U zc.buildout/branches/gary-8/src/zc/buildout/easy_install.py
U zc.buildout/branches/gary-8/src/zc/buildout/easy_install.txt
U zc.buildout/branches/gary-8/src/zc/buildout/tests.py
-=-
Modified: zc.buildout/branches/gary-8/src/zc/buildout/buildout.py
===================================================================
--- zc.buildout/branches/gary-7/src/zc/buildout/buildout.py 2010-02-24 23:25:20 UTC (rev 109427)
+++ zc.buildout/branches/gary-8/src/zc/buildout/buildout.py 2010-03-11 02:59:48 UTC (rev 109905)
@@ -355,7 +355,9 @@
if options.get('offline') == 'true':
ws = zc.buildout.easy_install.working_set(
distributions, options['executable'],
- [options['develop-eggs-directory'], options['eggs-directory']]
+ [options['develop-eggs-directory'],
+ options['eggs-directory']],
+ include_site_packages=False,
)
else:
ws = zc.buildout.easy_install.install(
@@ -365,7 +367,8 @@
executable=options['executable'],
path=[options['develop-eggs-directory']],
newest=self.newest,
- allow_hosts=self._allow_hosts
+ allow_hosts=self._allow_hosts,
+ include_site_packages=False,
)
# Now copy buildout and setuptools eggs, and record destination eggs:
@@ -1034,7 +1037,8 @@
path=path,
working_set=pkg_resources.working_set,
newest=buildout.newest,
- allow_hosts=buildout._allow_hosts
+ allow_hosts=buildout._allow_hosts,
+ include_site_packages=False,
)
__doing__ = 'Loading %s recipe entry %s:%s.', group, spec, entry
Modified: zc.buildout/branches/gary-8/src/zc/buildout/easy_install.py
===================================================================
--- zc.buildout/branches/gary-7/src/zc/buildout/easy_install.py 2010-02-24 23:25:20 UTC (rev 109427)
+++ zc.buildout/branches/gary-8/src/zc/buildout/easy_install.py 2010-03-11 02:59:48 UTC (rev 109905)
@@ -99,6 +99,7 @@
"print repr([os.path.normpath(p) for p in sys.path if p])"])
# Windows needs some (as yet to be determined) part of the real env.
env = os.environ.copy()
+ env.pop('PYTHONPATH', None)
env.update(kwargs)
_proc = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
@@ -337,9 +338,6 @@
self._site_packages))
if self._include_site_packages:
path.extend(self._site_packages)
- # else we could try to still include the buildout_and_setuptools_path
- # if the elements are not in site_packages, but we're not bothering
- # with this optimization for now, in the name of code simplicity.
if dest is not None and dest not in path:
path.insert(0, dest)
self._path = path
@@ -1184,9 +1182,9 @@
generated.append(_generate_site(
site_py_dest, working_set, executable, extra_paths,
include_site_packages, relative_paths))
- script_initialization = (
- '\nimport site # imports custom buildout-generated site.py\n%s' % (
- script_initialization,))
+ script_initialization = _script_initialization_template % dict(
+ site_py_dest=site_py_dest,
+ script_initialization=script_initialization)
if not script_initialization.endswith('\n'):
script_initialization += '\n'
generated.extend(_generate_scripts(
@@ -1197,6 +1195,15 @@
interpreter, dest, executable, site_py_dest, relative_paths))
return generated
+_script_initialization_template = '''
+import site # imports custom buildout-generated site.py
+import os
+path = %(site_py_dest)r
+if os.environ.get('PYTHONPATH'):
+ path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+os.environ['PYTHONPATH'] = path
+%(script_initialization)s'''
+
# Utilities for the script generation functions.
# These are shared by both ``scripts`` and ``sitepackage_safe_scripts``
Modified: zc.buildout/branches/gary-8/src/zc/buildout/easy_install.txt
===================================================================
--- zc.buildout/branches/gary-7/src/zc/buildout/easy_install.txt 2010-02-24 23:25:20 UTC (rev 109427)
+++ zc.buildout/branches/gary-8/src/zc/buildout/easy_install.txt 2010-03-11 02:59:48 UTC (rev 109905)
@@ -1499,6 +1499,11 @@
<BLANKLINE>
<BLANKLINE>
import site # imports custom buildout-generated site.py
+ import os
+ path = '/interpreter/parts/interpreter'
+ if os.environ.get('PYTHONPATH'):
+ path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+ os.environ['PYTHONPATH'] = path
<BLANKLINE>
import eggrecipedemo
<BLANKLINE>
@@ -1528,7 +1533,7 @@
>>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... reqs=['demo'], script_arguments='1, 2',
- ... script_initialization='import os\nos.chdir("foo")')
+ ... script_initialization='import os\nos.chdir("foo")')
>>> cat(demo_path) # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.4 -S
@@ -1539,6 +1544,11 @@
<BLANKLINE>
import site # imports custom buildout-generated site.py
import os
+ path = '/interpreter/parts/interpreter'
+ if os.environ.get('PYTHONPATH'):
+ path = os.pathsep.join([path, os.environ['PYTHONPATH']])
+ os.environ['PYTHONPATH'] = path
+ import os
os.chdir("foo")
<BLANKLINE>
import eggrecipedemo
Modified: zc.buildout/branches/gary-8/src/zc/buildout/tests.py
===================================================================
--- zc.buildout/branches/gary-7/src/zc/buildout/tests.py 2010-02-24 23:25:20 UTC (rev 109427)
+++ zc.buildout/branches/gary-8/src/zc/buildout/tests.py 2010-03-11 02:59:48 UTC (rev 109905)
@@ -2254,8 +2254,50 @@
"""
+def subprocesses_have_same_environment_by_default():
+ """
+The scripts generated by sitepackage_safe_scripts set the PYTHONPATH so that,
+if the environment is maintained (the default behavior), subprocesses get
+the same Python packages.
+
+First, we set up a script and an interpreter.
+
+ >>> interpreter_dir = tmpdir('interpreter')
+ >>> interpreter_parts_dir = os.path.join(
+ ... interpreter_dir, 'parts', 'interpreter')
+ >>> interpreter_bin_dir = os.path.join(interpreter_dir, 'bin')
+ >>> mkdir(interpreter_bin_dir)
+ >>> mkdir(interpreter_dir, 'eggs')
+ >>> mkdir(interpreter_dir, 'parts')
+ >>> mkdir(interpreter_parts_dir)
+ >>> ws = zc.buildout.easy_install.install(
+ ... ['demo'], join(interpreter_dir, 'eggs'), links=[link_server],
+ ... index=link_server+'index/')
+ >>> test = (
+ ... "import subprocess, sys; subprocess.call("
+ ... "[sys.executable, '-c', "
+ ... "'import eggrecipedemo; print eggrecipedemo.x'])")
+ >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
+ ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
+ ... reqs=['demo'], interpreter='py',
+ ... script_initialization=test + '; sys.exit(0)')
+
+This works for the script.
+
+ >>> print system(join(interpreter_bin_dir, 'demo'))
+ 3
+ <BLANKLINE>
+
+This also works for the generated interpreter.
+
+ >>> print call_py(join(interpreter_bin_dir, 'py'), test)
+ 3
+ <BLANKLINE>
+
+ """
+
def bootstrap_makes_buildout_that_works_with_system_python():
- """
+ r"""
In order to work smoothly with a system Python, bootstrapping creates
the buildout script with
zc.buildout.easy_install.sitepackage_safe_scripts. If it did not, a
@@ -2274,15 +2316,11 @@
>>> write(sample_buildout, 'recipes', 'dummy.py',
... '''
... import logging, os, zc.buildout
- ...
... class Dummy:
- ...
... def __init__(self, buildout, name, options):
... pass
- ...
... def install(self):
... return ()
- ...
... def update(self):
... pass
... ''')
@@ -2340,6 +2378,67 @@
Installing dummy.
<BLANKLINE>
+Here's the same story with a namespace package, which has some additional
+complications behind the scenes. First, a recipe, in the "tellmy" namespace.
+
+ >>> mkdir(sample_buildout, 'ns')
+ >>> mkdir(sample_buildout, 'ns', 'tellmy')
+ >>> write(sample_buildout, 'ns', 'tellmy', '__init__.py',
+ ... "__import__('pkg_resources').declare_namespace(__name__)\n")
+ >>> mkdir(sample_buildout, 'ns', 'tellmy', 'recipes')
+ >>> write(sample_buildout, 'ns', 'tellmy', 'recipes', '__init__.py', ' ')
+ >>> write(sample_buildout, 'ns', 'tellmy', 'recipes', 'dummy.py',
+ ... '''
+ ... import logging, os, zc.buildout
+ ... class Dummy:
+ ... def __init__(self, buildout, name, options):
+ ... pass
+ ... def install(self):
+ ... return ()
+ ... def update(self):
+ ... pass
+ ... ''')
+ >>> write(sample_buildout, 'ns', 'setup.py',
+ ... '''
+ ... from setuptools import setup
+ ... setup(
+ ... name="tellmy.recipes",
+ ... packages=['tellmy', 'tellmy.recipes'],
+ ... install_requires=['setuptools'],
+ ... namespace_packages=['tellmy'],
+ ... entry_points = {'zc.buildout':
+ ... ['dummy = tellmy.recipes.dummy:Dummy']},
+ ... )
+ ... ''')
+
+Now, a buildout that uses it.
+
+ >>> create_sample_namespace_eggs(sample_eggs, site_packages_path)
+ >>> rmdir('develop-eggs')
+ >>> from zc.buildout.testing import make_buildout
+ >>> make_buildout(executable=py_path)
+ >>> write(sample_buildout, 'buildout.cfg',
+ ... '''
+ ... [buildout]
+ ... develop = ns
+ ... recipes
+ ... parts = dummy
+ ... find-links = %(link_server)s
+ ... executable = %(py_path)s
+ ...
+ ... [dummy]
+ ... recipe = tellmy.recipes:dummy
+ ... ''' % globals())
+
+Now we actually run the buildout.
+
+ >>> print system(buildout)
+ Develop: '/sample-buildout/ns'
+ Develop: '/sample-buildout/recipes'
+ Uninstalling dummy.
+ Installing dummy.
+ <BLANKLINE>
+
"""
if sys.version_info > (2, 4):
More information about the checkins
mailing list