bundled zetuptoolz: if __main__.__requires__ exists then do not add packages to the working set if they provide an incompatible version of a package. Also put a complete __requires__ listing the transitive closure of dependencies at the beginning of generated scripts, rather than a shallow __requires__ specifying only the application version. refs #1190

This commit is contained in:
david-sarah 2010-10-29 15:31:11 -07:00
parent fd02946074
commit 647aa74d68
2 changed files with 24 additions and 8 deletions

View File

@ -524,6 +524,16 @@ class WorkingSet(object):
if dist.key in self.by_key: if dist.key in self.by_key:
return # ignore hidden distros return # ignore hidden distros
# If we have a __requires__ then we can already tell if this
# dist is unsatisfactory, in which case we won't add it.
if __requires__ is not None:
for thisreqstr in __requires__:
for thisreq in parse_requirements(thisreqstr):
if thisreq.key == dist.key:
if dist not in thisreq:
return
self.by_key[dist.key] = dist self.by_key[dist.key] = dist
if dist.key not in keys: if dist.key not in keys:
keys.append(dist.key) keys.append(dist.key)
@ -2591,6 +2601,7 @@ def _initialize(g):
_initialize(globals()) _initialize(globals())
# Prepare the master working set and make the ``require()`` API available # Prepare the master working set and make the ``require()`` API available
__requires__ = None
_declare_state('object', working_set = WorkingSet()) _declare_state('object', working_set = WorkingSet())
try: try:
# Does the main program list any requirements? # Does the main program list any requirements?
@ -2601,12 +2612,15 @@ else:
# Yes: ensure the requirements are met, by prefixing sys.path if necessary # Yes: ensure the requirements are met, by prefixing sys.path if necessary
try: try:
working_set.require(__requires__) working_set.require(__requires__)
except VersionConflict: # try it without defaults already on sys.path except (VersionConflict, DistributionNotFound): # try it without defaults already on sys.path
working_set = WorkingSet([]) # by starting with an empty path working_set = WorkingSet([]) # by starting with an empty path
for dist in working_set.resolve( try:
parse_requirements(__requires__), Environment() for dist in working_set.resolve(
): parse_requirements(__requires__), Environment()
working_set.add(dist) ):
working_set.add(dist)
except DistributionNotFound:
pass
for entry in sys.path: # add any missing entries from sys.path for entry in sys.path: # add any missing entries from sys.path
if entry not in working_set.entries: if entry not in working_set.entries:
working_set.add_entry(entry) working_set.add_entry(entry)

View File

@ -584,10 +584,11 @@ Please make the appropriate changes for your system and try again.
spec = str(dist.as_requirement()) spec = str(dist.as_requirement())
is_script = is_python_script(script_text, script_name) is_script = is_python_script(script_text, script_name)
requires = [spec] + [str(r) for r in dist.requires()]
if is_script and dev_path: if is_script and dev_path:
script_text = get_script_header(script_text) + ( script_text = get_script_header(script_text) + (
"# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r\n" "# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r\n"
"__requires__ = %(spec)r\n" "__requires__ = %(requires)r\n"
"from pkg_resources import require; require(%(spec)r)\n" "from pkg_resources import require; require(%(spec)r)\n"
"del require\n" "del require\n"
"__file__ = %(dev_path)r\n" "__file__ = %(dev_path)r\n"
@ -596,7 +597,7 @@ Please make the appropriate changes for your system and try again.
elif is_script: elif is_script:
script_text = get_script_header(script_text) + ( script_text = get_script_header(script_text) + (
"# EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r\n" "# EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r\n"
"__requires__ = %(spec)r\n" "__requires__ = %(requires)r\n"
"import pkg_resources\n" "import pkg_resources\n"
"pkg_resources.run_script(%(spec)r, %(script_name)r)\n" "pkg_resources.run_script(%(spec)r, %(script_name)r)\n"
) % locals() ) % locals()
@ -1575,6 +1576,7 @@ def fix_jython_executable(executable, options):
def get_script_args(dist, executable=sys_executable, wininst=False, script_dir=None): def get_script_args(dist, executable=sys_executable, wininst=False, script_dir=None):
"""Yield write_script() argument tuples for a distribution's entrypoints""" """Yield write_script() argument tuples for a distribution's entrypoints"""
spec = str(dist.as_requirement()) spec = str(dist.as_requirement())
requires = [spec] + [str(r) for r in dist.requires()]
header = get_script_header("", executable, wininst) header = get_script_header("", executable, wininst)
generated_by = "# generated by zetuptoolz %s" % (setuptools_version,) generated_by = "# generated by zetuptoolz %s" % (setuptools_version,)
@ -1583,7 +1585,7 @@ def get_script_args(dist, executable=sys_executable, wininst=False, script_dir=N
script_head, script_tail = (( script_head, script_tail = ((
"# EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r\n" "# EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r\n"
"%(generated_by)s\n" "%(generated_by)s\n"
"__requires__ = %(spec)r\n" "__requires__ = %(requires)r\n"
"import sys\n" "import sys\n"
"from pkg_resources import load_entry_point\n" "from pkg_resources import load_entry_point\n"
"\n" "\n"