Commit d708760c authored by Gary Poster's avatar Gary Poster

switch ``generate_scripts`` to ``sitepackage_safe_scripts`` per review

parent 8e65ae9f
...@@ -19,8 +19,8 @@ New Features: ...@@ -19,8 +19,8 @@ New Features:
exact version as specified in your buildout configuration, buildout exact version as specified in your buildout configuration, buildout
will still use its own copy. will still use its own copy.
- Added new function, ``zc.buildout.easy_install.generate_scripts``, to - Added new function, ``zc.buildout.easy_install.sitepackage_safe_scripts``,
generate scripts and interpreter. It produces a full-featured to generate scripts and interpreter. It produces a full-featured
interpreter (all command-line options supported) and the ability to interpreter (all command-line options supported) and the ability to
safely let scripts include site packages. The ``z3c.recipe.scripts`` safely let scripts include site packages. The ``z3c.recipe.scripts``
recipe uses this new function. recipe uses this new function.
......
...@@ -959,8 +959,9 @@ def scripts(reqs, working_set, executable, dest, ...@@ -959,8 +959,9 @@ def scripts(reqs, working_set, executable, dest,
): ):
"""Generate scripts and/or an interpreter. """Generate scripts and/or an interpreter.
See generate_scripts for a newer version with more options and a See sitepackage_safe_scripts for a version that can be used with a Python
different approach. that can be used with a Python that has code installed in site-packages.
It has more options and a different approach.
""" """
path = _get_path(working_set, extra_paths) path = _get_path(working_set, extra_paths)
if initialization: if initialization:
...@@ -975,12 +976,12 @@ def scripts(reqs, working_set, executable, dest, ...@@ -975,12 +976,12 @@ def scripts(reqs, working_set, executable, dest,
_pyscript(spath, sname, executable, rpsetup)) _pyscript(spath, sname, executable, rpsetup))
return generated return generated
def generate_scripts( def sitepackage_safe_scripts(
dest, working_set, executable, site_py_dest, dest, working_set, executable, site_py_dest,
reqs=(), scripts=None, interpreter=None, extra_paths=(), reqs=(), scripts=None, interpreter=None, extra_paths=(),
initialization='', add_site_packages=False, exec_sitecustomize=False, initialization='', add_site_packages=False, exec_sitecustomize=False,
relative_paths=False, script_arguments='', script_initialization=''): relative_paths=False, script_arguments='', script_initialization=''):
"""Generate scripts and/or an interpreter. """Generate scripts and/or an interpreter from a system Python.
This accomplishes the same job as the ``scripts`` function, above, This accomplishes the same job as the ``scripts`` function, above,
but it does so in an alternative way that allows safely including but it does so in an alternative way that allows safely including
...@@ -1008,7 +1009,7 @@ def generate_scripts( ...@@ -1008,7 +1009,7 @@ def generate_scripts(
# Utilities for the script generation functions. # Utilities for the script generation functions.
# These are shared by both ``scripts`` and ``generate_scripts`` # These are shared by both ``scripts`` and ``sitepackage_safe_scripts``
def _get_path(working_set, extra_paths=()): def _get_path(working_set, extra_paths=()):
"""Given working set and extra paths, return a normalized path list.""" """Given working set and extra paths, return a normalized path list."""
...@@ -1275,7 +1276,7 @@ if _interactive: ...@@ -1275,7 +1276,7 @@ if _interactive:
__import__("code").interact(banner="", local=globals()) __import__("code").interact(banner="", local=globals())
''' '''
# These are used only by the newer ``generate_scripts`` function. # These are used only by the newer ``sitepackage_safe_scripts`` function.
def _get_system_paths(executable): def _get_system_paths(executable):
"""return lists of standard lib and site paths for executable. """return lists of standard lib and site paths for executable.
......
...@@ -525,7 +525,7 @@ The easy_install module provides support for creating scripts from eggs. ...@@ -525,7 +525,7 @@ The easy_install module provides support for creating scripts from eggs.
It provides two competing functions. One, ``scripts``, is a It provides two competing functions. One, ``scripts``, is a
well-established approach to generating reliable scripts with a "clean" well-established approach to generating reliable scripts with a "clean"
Python--e.g., one that does not have any packages in its site-packages. Python--e.g., one that does not have any packages in its site-packages.
The other, ``generate_scripts``, is newer, a bit trickier, and is The other, ``sitepackage_safe_scripts``, is newer, a bit trickier, and is
designed to work with a Python that has code in its site-packages, such designed to work with a Python that has code in its site-packages, such
as a system Python. as a system Python.
...@@ -537,10 +537,10 @@ baking a script's path into the script. This has two advantages: ...@@ -537,10 +537,10 @@ baking a script's path into the script. This has two advantages:
- The script doesn't have to import pkg_resources because the logic that - The script doesn't have to import pkg_resources because the logic that
pkg_resources would execute at run time is executed at script-creation pkg_resources would execute at run time is executed at script-creation
time. (There is an exception in ``generate_scripts`` if you want to time. (There is an exception in ``sitepackage_safe_scripts`` if you
have your Python's site packages available, as discussed below, but want to have your Python's site packages available, as discussed
even in that case pkg_resources is only partially activated, which can below, but even in that case pkg_resources is only partially
be a significant time savings.) activated, which can be a significant time savings.)
The ``scripts`` function The ``scripts`` function
...@@ -924,22 +924,23 @@ We specified an interpreter and its paths are adjusted too: ...@@ -924,22 +924,23 @@ We specified an interpreter and its paths are adjusted too:
del _interactive del _interactive
__import__("code").interact(banner="", local=globals()) __import__("code").interact(banner="", local=globals())
The ``generate_scripts`` function The ``sitepackage_safe_scripts`` function
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The newer function for creating scripts is ``generate_scripts``. It has the The newer function for creating scripts is ``sitepackage_safe_scripts``.
same basic functionality as the ``scripts`` function: it can create scripts It has the same basic functionality as the ``scripts`` function: it can
to run arbitrary entry points, and to run a Python interpreter. The create scripts to run arbitrary entry points, and to run a Python
following are the differences from a user's perspective. interpreter. The following are the differences from a user's
perspective.
- It can be used safely with a Python that has packages installed itself, - It can be used safely with a Python that has packages installed itself,
such as a system-installed Python. such as a system-installed Python.
- In contrast to the interpreter generated by the ``scripts`` method, which - In contrast to the interpreter generated by the ``scripts`` method, which
supports only a small subset of the usual Python executable's options, supports only a small subset of the usual Python executable's options,
the interpreter generated by ``generate_scripts`` supports all of them. the interpreter generated by ``sitepackage_safe_scripts`` supports all
This makes it possible to use as full Python replacement for scripts that of them. This makes it possible to use as full Python replacement for
need the distributions specified in your buildout. scripts that need the distributions specified in your buildout.
- Both the interpreter and the entry point scripts allow you to include the - Both the interpreter and the entry point scripts allow you to include the
site packages, and/or the sitecustomize, of the Python executable, if site packages, and/or the sitecustomize, of the Python executable, if
...@@ -963,7 +964,7 @@ Here's the simplest example, building an interpreter script. ...@@ -963,7 +964,7 @@ Here's the simplest example, building an interpreter script.
>>> ws = zc.buildout.easy_install.install( >>> ws = zc.buildout.easy_install.install(
... ['demo'], join(interpreter_dir, 'eggs'), links=[link_server], ... ['demo'], join(interpreter_dir, 'eggs'), links=[link_server],
... index=link_server+'index/') ... index=link_server+'index/')
>>> generated = zc.buildout.easy_install.generate_scripts( >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... interpreter='py') ... interpreter='py')
...@@ -1065,7 +1066,7 @@ If you provide initialization, it goes in sitecustomize.py. ...@@ -1065,7 +1066,7 @@ If you provide initialization, it goes in sitecustomize.py.
>>> initialization_string = """\ >>> initialization_string = """\
... import os ... import os
... os.environ['FOO'] = 'bar baz bing shazam'""" ... os.environ['FOO'] = 'bar baz bing shazam'"""
>>> generated = zc.buildout.easy_install.generate_scripts( >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... interpreter='py', initialization=initialization_string) ... interpreter='py', initialization=initialization_string)
>>> cat(sitecustomize_path) >>> cat(sitecustomize_path)
...@@ -1080,7 +1081,7 @@ again the UNIX version; the Windows version uses subprocess instead of ...@@ -1080,7 +1081,7 @@ again the UNIX version; the Windows version uses subprocess instead of
os.execve.) os.execve.)
>>> reset_interpreter() >>> reset_interpreter()
>>> generated = zc.buildout.easy_install.generate_scripts( >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... interpreter='py', relative_paths=interpreter_dir) ... interpreter='py', relative_paths=interpreter_dir)
>>> cat(py_path) >>> cat(py_path)
...@@ -1136,7 +1137,7 @@ The ``extra_paths`` argument affects the path in site.py. Notice that ...@@ -1136,7 +1137,7 @@ The ``extra_paths`` argument affects the path in site.py. Notice that
>>> reset_interpreter() >>> reset_interpreter()
>>> mkdir(interpreter_dir, 'other') >>> mkdir(interpreter_dir, 'other')
>>> generated = zc.buildout.easy_install.generate_scripts( >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... interpreter='py', extra_paths=[join(interpreter_dir, 'other')]) ... interpreter='py', extra_paths=[join(interpreter_dir, 'other')])
>>> sys.stdout.write('#\n'); cat(site_path) # doctest: +ELLIPSIS >>> sys.stdout.write('#\n'); cat(site_path) # doctest: +ELLIPSIS
...@@ -1162,11 +1163,11 @@ The ``extra_paths`` argument affects the path in site.py. Notice that ...@@ -1162,11 +1163,11 @@ The ``extra_paths`` argument affects the path in site.py. Notice that
'/interpreter/other'] '/interpreter/other']
<BLANKLINE> <BLANKLINE>
The ``generate_scripts`` function: using site-packages The ``sitepackage_safe_scripts`` function: using site-packages
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``generate_scripts`` function supports including site packages. This has The ``sitepackage_safe_scripts`` function supports including site
some advantages and some serious dangers. packages. This has some advantages and some serious dangers.
A typical reason to include site-packages is that it is easier to A typical reason to include site-packages is that it is easier to
install one or more dependencies in your Python than it is with install one or more dependencies in your Python than it is with
...@@ -1194,7 +1195,7 @@ That explained, let's see how it works. If you don't use namespace packages, ...@@ -1194,7 +1195,7 @@ That explained, let's see how it works. If you don't use namespace packages,
this is very straightforward. this is very straightforward.
>>> reset_interpreter() >>> reset_interpreter()
>>> generated = zc.buildout.easy_install.generate_scripts( >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... interpreter='py', add_site_packages=True) ... interpreter='py', add_site_packages=True)
>>> sys.stdout.write('#\n'); cat(site_path) >>> sys.stdout.write('#\n'); cat(site_path)
...@@ -1262,7 +1263,7 @@ call to another text fixture to create. ...@@ -1262,7 +1263,7 @@ call to another text fixture to create.
>>> ws = zc.buildout.easy_install.install( >>> ws = zc.buildout.easy_install.install(
... ['demo', 'tellmy.fortune'], join(interpreter_dir, 'eggs'), ... ['demo', 'tellmy.fortune'], join(interpreter_dir, 'eggs'),
... links=[link_server, namespace_eggs], index=link_server+'index/') ... links=[link_server, namespace_eggs], index=link_server+'index/')
>>> generated = zc.buildout.easy_install.generate_scripts( >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... interpreter='py', add_site_packages=True) ... interpreter='py', add_site_packages=True)
>>> sys.stdout.write('#\n'); cat(site_path) >>> sys.stdout.write('#\n'); cat(site_path)
...@@ -1319,7 +1320,7 @@ The most complex that this function gets is if you use namespace packages, ...@@ -1319,7 +1320,7 @@ The most complex that this function gets is if you use namespace packages,
include site-packages, and use relative paths. For completeness, we'll look include site-packages, and use relative paths. For completeness, we'll look
at that result. at that result.
>>> generated = zc.buildout.easy_install.generate_scripts( >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... interpreter='py', add_site_packages=True, ... interpreter='py', add_site_packages=True,
... relative_paths=interpreter_dir) ... relative_paths=interpreter_dir)
...@@ -1376,8 +1377,8 @@ sitecustomize module in the underlying Python if you set the argument to ...@@ -1376,8 +1377,8 @@ sitecustomize module in the underlying Python if you set the argument to
True. The z3c.recipe.scripts package sets up the full environment necessary True. The z3c.recipe.scripts package sets up the full environment necessary
to demonstrate this piece. to demonstrate this piece.
The ``generate_scripts`` function: writing scripts for entry points The ``sitepackage_safe_scripts`` function: writing scripts for entry points
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
All of the examples so far for this function have been creating All of the examples so far for this function have been creating
interpreters. The function can also write scripts for entry interpreters. The function can also write scripts for entry
...@@ -1391,7 +1392,7 @@ see a simple example. ...@@ -1391,7 +1392,7 @@ see a simple example.
>>> ws = zc.buildout.easy_install.install( >>> ws = zc.buildout.easy_install.install(
... ['demo'], join(interpreter_dir, 'eggs'), links=[link_server], ... ['demo'], join(interpreter_dir, 'eggs'), links=[link_server],
... index=link_server+'index/') ... index=link_server+'index/')
>>> generated = zc.buildout.easy_install.generate_scripts( >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... reqs=['demo']) ... reqs=['demo'])
...@@ -1452,7 +1453,7 @@ pertinent to the entry point scripts, you can use the ...@@ -1452,7 +1453,7 @@ pertinent to the entry point scripts, you can use the
Let's see ``script_arguments`` and ``script_initialization`` in action. Let's see ``script_arguments`` and ``script_initialization`` in action.
>>> reset_interpreter() >>> reset_interpreter()
>>> generated = zc.buildout.easy_install.generate_scripts( >>> generated = zc.buildout.easy_install.sitepackage_safe_scripts(
... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir, ... interpreter_bin_dir, ws, sys.executable, interpreter_parts_dir,
... reqs=['demo'], script_arguments='1, 2', ... reqs=['demo'], script_arguments='1, 2',
... script_initialization='import os\nos.chdir("foo")') ... script_initialization='import os\nos.chdir("foo")')
......
...@@ -1823,8 +1823,9 @@ def handle_namespace_package_in_both_site_packages_and_buildout_eggs(): ...@@ -1823,8 +1823,9 @@ def handle_namespace_package_in_both_site_packages_and_buildout_eggs():
r""" r"""
If you have the same namespace package in both site-packages and in If you have the same namespace package in both site-packages and in
buildout, we need to be very careful that faux-Python-executables and buildout, we need to be very careful that faux-Python-executables and
scripts generated by easy_install.generate_scripts correctly combine the two. scripts generated by easy_install.sitepackage_safe_scripts correctly
We show this with the local recipe that uses the function, z3c.recipe.scripts. combine the two. We show this with the local recipe that uses the
function, z3c.recipe.scripts.
To demonstrate this, we will create three packages: tellmy.version 1.0, To demonstrate this, we will create three packages: tellmy.version 1.0,
tellmy.version 1.1, and tellmy.fortune 1.0. tellmy.version 1.1 is installed. tellmy.version 1.1, and tellmy.fortune 1.0. tellmy.version 1.1 is installed.
......
...@@ -61,7 +61,7 @@ def multi_python(test): ...@@ -61,7 +61,7 @@ def multi_python(test):
['setuptools'], executable_dir, ['setuptools'], executable_dir,
index='http://www.python.org/pypi/', index='http://www.python.org/pypi/',
always_unzip=True, executable=other_executable) always_unzip=True, executable=other_executable)
zc.buildout.easy_install.generate_scripts( zc.buildout.easy_install.sitepackage_safe_scripts(
executable_dir, ws, other_executable, executable_parts, executable_dir, ws, other_executable, executable_parts,
reqs=['setuptools'], interpreter='py') reqs=['setuptools'], interpreter='py')
original_executable = other_executable original_executable = other_executable
......
...@@ -63,7 +63,7 @@ class Interpreter(Base): ...@@ -63,7 +63,7 @@ class Interpreter(Base):
if not os.path.exists(options['parts-directory']): if not os.path.exists(options['parts-directory']):
os.mkdir(options['parts-directory']) os.mkdir(options['parts-directory'])
generated.append(options['parts-directory']) generated.append(options['parts-directory'])
generated.extend(zc.buildout.easy_install.generate_scripts( generated.extend(zc.buildout.easy_install.sitepackage_safe_scripts(
options['bin-directory'], ws, options['executable'], options['bin-directory'], ws, options['executable'],
options['parts-directory'], options['parts-directory'],
interpreter=options['name'], interpreter=options['name'],
...@@ -86,7 +86,7 @@ class Scripts(Base): ...@@ -86,7 +86,7 @@ class Scripts(Base):
if not os.path.exists(options['parts-directory']): if not os.path.exists(options['parts-directory']):
os.mkdir(options['parts-directory']) os.mkdir(options['parts-directory'])
generated.append(options['parts-directory']) generated.append(options['parts-directory'])
generated.extend(zc.buildout.easy_install.generate_scripts( generated.extend(zc.buildout.easy_install.sitepackage_safe_scripts(
options['bin-directory'], ws, options['executable'], options['bin-directory'], ws, options['executable'],
options['parts-directory'], reqs=reqs, scripts=scripts, options['parts-directory'], reqs=reqs, scripts=scripts,
interpreter=options.get('interpreter'), interpreter=options.get('interpreter'),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment