[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