Hello community,
here is the log from the commit of package python3-setuptools for
openSUSE:Factory checked in at 2015-01-21 21:54:36
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python3-setuptools (Old)
and /work/SRC/openSUSE:Factory/.python3-setuptools.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python3-setuptools"
Changes:
--------
--- /work/SRC/openSUSE:Factory/python3-setuptools/python3-setuptools.changes
2015-01-08 23:05:30.000000000 +0100
+++
/work/SRC/openSUSE:Factory/.python3-setuptools.new/python3-setuptools.changes
2015-01-21 21:54:40.000000000 +0100
@@ -1,0 +2,36 @@
+Tue Jan 20 19:45:50 UTC 2015 - [email protected]
+
+- update to version 12.0.3:
+ * Fixed incorrect class attribute in ``install_scripts``. Tests
+ would be nice.
+
+- changes to version 12.0.2:
+ * Issue #331: Fixed ``install_scripts`` command on Windows systems
+ corrupting the header.
+
+-------------------------------------------------------------------
+Sat Jan 17 18:59:40 UTC 2015 - [email protected]
+
+- update to version 12.0.1:
+ * Restore "setuptools.command.easy_install.sys_executable" for pbr
+ compatibility. For the future, tools should construct a
+ CommandSpec explicitly.
+
+- changes from version 12.0:
+ * Issue #188: Setuptools now support multiple entities in the value
+ for "build.executable", such that an executable of "/usr/bin/env
+ my-python" may be specified. This means that systems with a
+ specified executable whose name has spaces in the path must be
+ updated to escape or quote that value.
+ * Deprecated "easy_install.ScriptWriter.get_writer", replaced by
+ ".best()" with slightly different semantics (no force_windows
+ flag).
+
+-------------------------------------------------------------------
+Sun Jan 10 00:51:53 UTC 2015 - [email protected]
+
+- specfile:
+ * update copyright year
+ * remove ifs for opensuse version <=1220
+
+-------------------------------------------------------------------
Old:
----
setuptools-11.3.1.tar.gz
New:
----
setuptools-12.0.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python3-setuptools.spec ++++++
--- /var/tmp/diff_new_pack.CB3j1B/_old 2015-01-21 21:54:41.000000000 +0100
+++ /var/tmp/diff_new_pack.CB3j1B/_new 2015-01-21 21:54:41.000000000 +0100
@@ -17,7 +17,7 @@
Name: python3-setuptools
-Version: 11.3.1
+Version: 12.0.3
Release: 0
Url: http://pypi.python.org/pypi/setuptools
Summary: Easily download, build, install, upgrade, and uninstall Python
packages
@@ -32,10 +32,6 @@
#NOTE(saschpe): Need 'python3' for the 'xml' module:
BuildRequires: python3
Requires: python3
-%if 0%{?suse_version} == 1220
-BuildRequires: python3-2to3
-BuildRequires: python3-xml
-%endif
BuildRequires: python3-devel
Requires(post): update-alternatives
Requires(postun): update-alternatives
++++++ setuptools-11.3.1.tar.gz -> setuptools-12.0.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/CHANGES.txt
new/setuptools-12.0.3/CHANGES.txt
--- old/setuptools-11.3.1/CHANGES.txt 2015-01-06 15:47:44.000000000 +0100
+++ new/setuptools-12.0.3/CHANGES.txt 2015-01-19 02:48:13.000000000 +0100
@@ -3,6 +3,38 @@
=======
------
+12.0.3
+------
+
+* Fixed incorrect class attribute in ``install_scripts``. Tests would be nice.
+
+------
+12.0.2
+------
+
+* Issue #331: Fixed ``install_scripts`` command on Windows systems corrupting
+ the header.
+
+------
+12.0.1
+------
+
+* Restore ``setuptools.command.easy_install.sys_executable`` for pbr
+ compatibility. For the future, tools should construct a CommandSpec
+ explicitly.
+
+----
+12.0
+----
+
+* Issue #188: Setuptools now support multiple entities in the value for
+ ``build.executable``, such that an executable of "/usr/bin/env my-python" may
+ be specified. This means that systems with a specified executable whose name
+ has spaces in the path must be updated to escape or quote that value.
+* Deprecated ``easy_install.ScriptWriter.get_writer``, replaced by ``.best()``
+ with slightly different semantics (no force_windows flag).
+
+------
11.3.1
------
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/MANIFEST.in
new/setuptools-12.0.3/MANIFEST.in
--- old/setuptools-11.3.1/MANIFEST.in 2015-01-05 18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/MANIFEST.in 2015-01-19 00:48:57.000000000 +0100
@@ -1,5 +1,5 @@
recursive-include setuptools *.py *.exe *.xml
-recursive-include tests *.py *.c *.pyx
+recursive-include tests *.py
recursive-include setuptools/tests *.html
recursive-include docs *.py *.txt *.conf *.css *.css_t Makefile
indexsidebar.html
recursive-include _markerlib *.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/PKG-INFO
new/setuptools-12.0.3/PKG-INFO
--- old/setuptools-11.3.1/PKG-INFO 2015-01-06 16:11:58.000000000 +0100
+++ new/setuptools-12.0.3/PKG-INFO 2015-01-19 02:48:36.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: setuptools
-Version: 11.3.1
+Version: 12.0.3
Summary: Easily download, build, install, upgrade, and uninstall Python
packages
Home-page: https://bitbucket.org/pypa/setuptools
Author: Python Packaging Authority
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/ez_setup.py
new/setuptools-12.0.3/ez_setup.py
--- old/setuptools-11.3.1/ez_setup.py 2015-01-06 16:11:49.000000000 +0100
+++ new/setuptools-12.0.3/ez_setup.py 2015-01-19 02:43:32.000000000 +0100
@@ -36,7 +36,7 @@
except ImportError:
USER_SITE = None
-DEFAULT_VERSION = "11.3.1"
+DEFAULT_VERSION = "12.0.3"
DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/"
def _python_cmd(*args):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setup.py
new/setuptools-12.0.3/setup.py
--- old/setuptools-11.3.1/setup.py 2015-01-04 17:22:03.000000000 +0100
+++ new/setuptools-12.0.3/setup.py 2015-01-19 00:48:57.000000000 +0100
@@ -170,8 +170,7 @@
tests_require=[
'setuptools[ssl]',
'pytest',
- 'mock',
- ],
+ ] + (['mock'] if sys.version_info[:2] < (3, 3) else []),
setup_requires=[
] + pytest_runner,
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setuptools/command/easy_install.py
new/setuptools-12.0.3/setuptools/command/easy_install.py
--- old/setuptools-11.3.1/setuptools/command/easy_install.py 2015-01-05
18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/command/easy_install.py 2015-01-19
02:21:47.000000000 +0100
@@ -35,6 +35,8 @@
import site
import struct
import contextlib
+import subprocess
+import shlex
from setuptools import Command
from setuptools.sandbox import run_setup
@@ -54,15 +56,10 @@
)
import pkg_resources
-
# Turn on PEP440Warnings
warnings.filterwarnings("default", category=pkg_resources.PEP440Warning)
-sys_executable = os.environ.get('__PYVENV_LAUNCHER__',
- os.path.normpath(sys.executable))
-
-
__all__ = [
'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg',
'main', 'get_exe_prefixes',
@@ -448,43 +445,49 @@
self.pth_file = None # and don't create a .pth file
self.install_dir = instdir
- def cant_write_to_target(self):
- template = """can't create or remove files in install directory
+ __cant_write_msg = textwrap.dedent("""
+ can't create or remove files in install directory
-The following error occurred while trying to add or remove files in the
-installation directory:
+ The following error occurred while trying to add or remove files in the
+ installation directory:
- %s
+ %s
-The installation directory you specified (via --install-dir, --prefix, or
-the distutils default setting) was:
+ The installation directory you specified (via --install-dir, --prefix,
or
+ the distutils default setting) was:
- %s
-"""
- msg = template % (sys.exc_info()[1], self.install_dir,)
+ %s
+ """).lstrip()
- if not os.path.exists(self.install_dir):
- msg += """
-This directory does not currently exist. Please create it and try again, or
-choose a different installation directory (using the -d or --install-dir
-option).
-"""
- else:
- msg += """
-Perhaps your account does not have write access to this directory? If the
-installation directory is a system-owned directory, you may need to sign in
-as the administrator or "root" account. If you do not have administrative
-access to this machine, you may wish to choose a different installation
-directory, preferably one that is listed in your PYTHONPATH environment
-variable.
+ __not_exists_id = textwrap.dedent("""
+ This directory does not currently exist. Please create it and try
again, or
+ choose a different installation directory (using the -d or
--install-dir
+ option).
+ """).lstrip()
+
+ __access_msg = textwrap.dedent("""
+ Perhaps your account does not have write access to this directory? If
the
+ installation directory is a system-owned directory, you may need to
sign in
+ as the administrator or "root" account. If you do not have
administrative
+ access to this machine, you may wish to choose a different installation
+ directory, preferably one that is listed in your PYTHONPATH environment
+ variable.
+
+ For information on other options, you may wish to consult the
+ documentation at:
-For information on other options, you may wish to consult the
-documentation at:
+ https://pythonhosted.org/setuptools/easy_install.html
- https://pythonhosted.org/setuptools/easy_install.html
+ Please make the appropriate changes for your system and try again.
+ """).lstrip()
+
+ def cant_write_to_target(self):
+ msg = self._cant_write_msg % (sys.exc_info()[1], self.install_dir,)
-Please make the appropriate changes for your system and try again.
-"""
+ if not os.path.exists(self.install_dir):
+ msg += '\n' + self.__not_exists_id
+ else:
+ msg += '\n' + self.__access_msg
raise DistutilsError(msg)
def check_pth_processing(self):
@@ -744,7 +747,7 @@
def install_wrapper_scripts(self, dist):
if not self.exclude_scripts:
- for args in get_script_args(dist):
+ for args in ScriptWriter.best().get_args(dist):
self.write_script(*args)
def install_script(self, dist, script_name, script_text, dev_path=None):
@@ -753,7 +756,7 @@
is_script = is_python_script(script_text, script_name)
if is_script:
- script_text = (get_script_header(script_text) +
+ script_text = (ScriptWriter.get_header(script_text) +
self._load_template(dev_path) % locals())
self.write_script(script_name, _to_ascii(script_text), 'b')
@@ -917,9 +920,10 @@
f.write('%s: %s\n' % (k.replace('_', '-').title(), v))
f.close()
script_dir = os.path.join(_egg_info, 'scripts')
- self.delete_blockers( # delete entry-point scripts to avoid duping
+ # delete entry-point scripts to avoid duping
+ self.delete_blockers(
[os.path.join(script_dir, args[0]) for args in
- get_script_args(dist)]
+ ScriptWriter.get_args(dist)]
)
# Build .egg file from tmpdir
bdist_egg.make_zipfile(
@@ -981,46 +985,52 @@
f.write('\n'.join(locals()[name]) + '\n')
f.close()
+ __mv_warning = textwrap.dedent("""
+ Because this distribution was installed --multi-version, before you can
+ import modules from this package in an application, you will need to
+ 'import pkg_resources' and then use a 'require()' call similar to one
of
+ these examples, in order to select the desired version:
+
+ pkg_resources.require("%(name)s") # latest installed version
+ pkg_resources.require("%(name)s==%(version)s") # this exact
version
+ pkg_resources.require("%(name)s>=%(version)s") # this version or
higher
+ """).lstrip()
+
+ __id_warning = textwrap.dedent("""
+ Note also that the installation directory must be on sys.path at
runtime for
+ this to work. (e.g. by being the application's script directory, by
being on
+ PYTHONPATH, or by being added to sys.path by your code.)
+ """)
+
def installation_report(self, req, dist, what="Installed"):
"""Helpful installation message for display to package users"""
msg = "\n%(what)s %(eggloc)s%(extras)s"
if self.multi_version and not self.no_report:
- msg += """
-
-Because this distribution was installed --multi-version, before you can
-import modules from this package in an application, you will need to
-'import pkg_resources' and then use a 'require()' call similar to one of
-these examples, in order to select the desired version:
-
- pkg_resources.require("%(name)s") # latest installed version
- pkg_resources.require("%(name)s==%(version)s") # this exact version
- pkg_resources.require("%(name)s>=%(version)s") # this version or higher
-"""
+ msg += '\n' + self.__mv_warning
if self.install_dir not in map(normalize_path, sys.path):
- msg += """
+ msg += '\n' + self.__id_warning
-Note also that the installation directory must be on sys.path at runtime for
-this to work. (e.g. by being the application's script directory, by being on
-PYTHONPATH, or by being added to sys.path by your code.)
-"""
eggloc = dist.location
name = dist.project_name
version = dist.version
extras = '' # TODO: self.report_extras(req, dist)
return msg % locals()
- def report_editable(self, spec, setup_script):
- dirname = os.path.dirname(setup_script)
- python = sys.executable
- return """\nExtracted editable version of %(spec)s to %(dirname)s
+ __editable_msg = textwrap.dedent("""
+ Extracted editable version of %(spec)s to %(dirname)s
-If it uses setuptools in its setup script, you can activate it in
-"development" mode by going to that directory and running::
+ If it uses setuptools in its setup script, you can activate it in
+ "development" mode by going to that directory and running::
- %(python)s setup.py develop
+ %(python)s setup.py develop
-See the setuptools documentation for the "develop" command for more info.
-""" % locals()
+ See the setuptools documentation for the "develop" command for more
info.
+ """).lstrip()
+
+ def report_editable(self, spec, setup_script):
+ dirname = os.path.dirname(setup_script)
+ python = sys.executable
+ return '\n' + self.__editable_msg % locals()
def run_setup(self, setup_script, setup_base, args):
sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg)
@@ -1171,35 +1181,38 @@
finally:
log.set_verbosity(self.verbose) # restore original verbosity
- def no_default_version_msg(self):
- template = """bad install directory or PYTHONPATH
+ __no_default_msg = textwrap.dedent("""
+ bad install directory or PYTHONPATH
-You are attempting to install a package to a directory that is not
-on PYTHONPATH and which Python does not read ".pth" files from. The
-installation directory you specified (via --install-dir, --prefix, or
-the distutils default setting) was:
+ You are attempting to install a package to a directory that is not
+ on PYTHONPATH and which Python does not read ".pth" files from. The
+ installation directory you specified (via --install-dir, --prefix, or
+ the distutils default setting) was:
- %s
+ %s
-and your PYTHONPATH environment variable currently contains:
+ and your PYTHONPATH environment variable currently contains:
- %r
+ %r
-Here are some of your options for correcting the problem:
+ Here are some of your options for correcting the problem:
-* You can choose a different installation directory, i.e., one that is
- on PYTHONPATH or supports .pth files
+ * You can choose a different installation directory, i.e., one that is
+ on PYTHONPATH or supports .pth files
-* You can add the installation directory to the PYTHONPATH environment
- variable. (It must then also be on PYTHONPATH whenever you run
- Python and want to use the package(s) you are installing.)
+ * You can add the installation directory to the PYTHONPATH environment
+ variable. (It must then also be on PYTHONPATH whenever you run
+ Python and want to use the package(s) you are installing.)
-* You can set up the installation directory to support ".pth" files by
- using one of the approaches described here:
+ * You can set up the installation directory to support ".pth" files by
+ using one of the approaches described here:
-
https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations
+
https://pythonhosted.org/setuptools/easy_install.html#custom-installation-locations
-Please make the appropriate changes for your system and try again."""
+ Please make the appropriate changes for your system and try
again.""").lstrip()
+
+ def no_default_version_msg(self):
+ template = self.__no_default_msg
return template % (self.install_dir, os.environ.get('PYTHONPATH', ''))
def install_site_py(self):
@@ -1590,33 +1603,6 @@
return re.compile(first_line_re.pattern.decode())
-def get_script_header(script_text, executable=sys_executable, wininst=False):
- """Create a #! line, getting options (if any) from script_text"""
- first = (script_text + '\n').splitlines()[0]
- match = _first_line_re().match(first)
- options = ''
- if match:
- options = match.group(1) or ''
- if options:
- options = ' ' + options
- if wininst:
- executable = "python.exe"
- else:
- executable = nt_quote_arg(executable)
- hdr = "#!%(executable)s%(options)s\n" % locals()
- if not isascii(hdr):
- # Non-ascii path to sys.executable, use -x to prevent warnings
- if options:
- if options.strip().startswith('-'):
- options = ' -x' + options.strip()[1:]
- # else: punt, we can't do it, let the warning happen anyway
- else:
- options = ' -x'
- executable = fix_jython_executable(executable, options)
- hdr = "#!%(executable)s%(options)s\n" % locals()
- return hdr
-
-
def auto_chmod(func, arg, exc):
if func is os.remove and os.name == 'nt':
chmod(arg, stat.S_IWRITE)
@@ -1825,36 +1811,7 @@
def nt_quote_arg(arg):
"""Quote a command line argument according to Windows parsing rules"""
-
- result = []
- needquote = False
- nb = 0
-
- needquote = (" " in arg) or ("\t" in arg)
- if needquote:
- result.append('"')
-
- for c in arg:
- if c == '\\':
- nb += 1
- elif c == '"':
- # double preceding backslashes, then add a \"
- result.append('\\' * (nb * 2) + '\\"')
- nb = 0
- else:
- if nb:
- result.append('\\' * nb)
- nb = 0
- result.append(c)
-
- if nb:
- result.append('\\' * nb)
-
- if needquote:
- result.append('\\' * nb) # double the trailing backslashes
- result.append('"')
-
- return ''.join(result)
+ return subprocess.list2cmdline([arg])
def is_python_script(script_text, filename):
@@ -1909,6 +1866,115 @@
return executable
+class CommandSpec(list):
+ """
+ A command spec for a #! header, specified as a list of arguments akin to
+ those passed to Popen.
+ """
+
+ options = []
+ split_args = dict()
+
+ @classmethod
+ def _sys_executable(cls):
+ _default = os.path.normpath(sys.executable)
+ return os.environ.get('__PYVENV_LAUNCHER__', _default)
+
+ @classmethod
+ def from_param(cls, param):
+ """
+ Construct a CommandSpec from a parameter to build_scripts, which may
+ be None.
+ """
+ if isinstance(param, cls):
+ return param
+ if isinstance(param, list):
+ return cls(param)
+ if param is None:
+ return cls.from_environment()
+ # otherwise, assume it's a string.
+ return cls.from_string(param)
+
+ @classmethod
+ def from_environment(cls):
+ return cls.from_string('"' + cls._sys_executable() + '"')
+
+ @classmethod
+ def from_string(cls, string):
+ """
+ Construct a command spec from a simple string representing a command
+ line parseable by shlex.split.
+ """
+ items = shlex.split(string, **cls.split_args)
+ return JythonCommandSpec.from_string(string) or cls(items)
+
+ def install_options(self, script_text):
+ self.options = shlex.split(self._extract_options(script_text))
+ cmdline = subprocess.list2cmdline(self)
+ if not isascii(cmdline):
+ self.options[:0] = ['-x']
+
+ @staticmethod
+ def _extract_options(orig_script):
+ """
+ Extract any options from the first line of the script.
+ """
+ first = (orig_script + '\n').splitlines()[0]
+ match = _first_line_re().match(first)
+ options = match.group(1) or '' if match else ''
+ return options.strip()
+
+ def as_header(self):
+ return self._render(self + list(self.options))
+
+ @staticmethod
+ def _render(items):
+ cmdline = subprocess.list2cmdline(items)
+ return '#!' + cmdline + '\n'
+
+# For pbr compat; will be removed in a future version.
+sys_executable = CommandSpec._sys_executable()
+
+
+class WindowsCommandSpec(CommandSpec):
+ split_args = dict(posix=False)
+
+
+class JythonCommandSpec(CommandSpec):
+ @classmethod
+ def from_string(cls, string):
+ """
+ On Jython, construct an instance of this class.
+ On platforms other than Jython, return None.
+ """
+ needs_jython_spec = (
+ sys.platform.startswith('java')
+ and
+ __import__('java').lang.System.getProperty('os.name') != 'Linux'
+ )
+ return cls([string]) if needs_jython_spec else None
+
+ def as_header(self):
+ """
+ Workaround Jython's sys.executable being a .sh (an invalid
+ shebang line interpreter)
+ """
+ if not is_sh(self[0]):
+ return super(JythonCommandSpec, self).as_header()
+
+ if self.options:
+ # Can't apply the workaround, leave it broken
+ log.warn(
+ "WARNING: Unable to adapt shebang line for Jython,"
+ " the following script is NOT executable\n"
+ " see http://bugs.jython.org/issue1112 for"
+ " more information.")
+ return super(JythonCommandSpec, self).as_header()
+
+ items = ['/usr/bin/env'] + self + list(self.options)
+ return self._render(items)
+
+
class ScriptWriter(object):
"""
Encapsulates behavior around writing entry point scripts for console and
@@ -1927,39 +1993,81 @@
)
""").lstrip()
+ command_spec_class = CommandSpec
+
+ @classmethod
+ def get_script_args(cls, dist, executable=None, wininst=False):
+ # for backward compatibility
+ warnings.warn("Use get_args", DeprecationWarning)
+ writer = (WindowsScriptWriter if wininst else ScriptWriter).best()
+ header = cls.get_script_header("", executable, wininst)
+ return writer.get_args(dist, header)
+
@classmethod
- def get_script_args(cls, dist, executable=sys_executable, wininst=False):
+ def get_script_header(cls, script_text, executable=None, wininst=False):
+ # for backward compatibility
+ warnings.warn("Use get_header", DeprecationWarning)
+ if wininst:
+ executable = "python.exe"
+ cmd = cls.command_spec_class.from_param(executable)
+ cmd.install_options(script_text)
+ return cmd.as_header()
+
+ @classmethod
+ def get_args(cls, dist, header=None):
"""
Yield write_script() argument tuples for a distribution's entrypoints
"""
- gen_class = cls.get_writer(wininst)
+ if header is None:
+ header = cls.get_header()
spec = str(dist.as_requirement())
- header = get_script_header("", executable, wininst)
for type_ in 'console', 'gui':
group = type_ + '_scripts'
for name, ep in dist.get_entry_map(group).items():
- script_text = gen_class.template % locals()
- for res in gen_class._get_script_args(type_, name, header,
- script_text):
+ script_text = cls.template % locals()
+ for res in cls._get_script_args(type_, name, header,
+ script_text):
yield res
@classmethod
def get_writer(cls, force_windows):
- if force_windows or sys.platform == 'win32':
- return WindowsScriptWriter.get_writer()
- return cls
+ # for backward compatibility
+ warnings.warn("Use best", DeprecationWarning)
+ return WindowsScriptWriter.best() if force_windows else cls.best()
+
+ @classmethod
+ def best(cls):
+ """
+ Select the best ScriptWriter for this environment.
+ """
+ return WindowsScriptWriter.best() if sys.platform == 'win32' else cls
@classmethod
def _get_script_args(cls, type_, name, header, script_text):
# Simply write the stub with no extension.
yield (name, header + script_text)
+ @classmethod
+ def get_header(cls, script_text="", executable=None):
+ """Create a #! line, getting options (if any) from script_text"""
+ cmd = cls.command_spec_class.from_param(executable)
+ cmd.install_options(script_text)
+ return cmd.as_header()
+
class WindowsScriptWriter(ScriptWriter):
+ command_spec_class = WindowsCommandSpec
+
@classmethod
def get_writer(cls):
+ # for backward compatibility
+ warnings.warn("Use best", DeprecationWarning)
+ return cls.best()
+
+ @classmethod
+ def best(cls):
"""
- Get a script writer suitable for Windows
+ Select the best ScriptWriter suitable for Windows
"""
writer_lookup = dict(
executable=WindowsExecutableLauncherWriter,
@@ -2034,6 +2142,7 @@
# for backward-compatibility
get_script_args = ScriptWriter.get_script_args
+get_script_header = ScriptWriter.get_script_header
def get_win_launcher(type):
@@ -2155,4 +2264,3 @@
yield
finally:
distutils.core.gen_usage = saved
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/setuptools-11.3.1/setuptools/command/install_scripts.py
new/setuptools-12.0.3/setuptools/command/install_scripts.py
--- old/setuptools-11.3.1/setuptools/command/install_scripts.py 2015-01-05
18:51:43.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/command/install_scripts.py 2015-01-19
02:45:22.000000000 +0100
@@ -13,8 +13,7 @@
self.no_ep = False
def run(self):
- from setuptools.command.easy_install import get_script_args
- from setuptools.command.easy_install import sys_executable
+ import setuptools.command.easy_install as ei
self.run_command("egg_info")
if self.distribution.scripts:
@@ -31,11 +30,17 @@
ei_cmd.egg_name, ei_cmd.egg_version,
)
bs_cmd = self.get_finalized_command('build_scripts')
- executable = getattr(bs_cmd, 'executable', sys_executable)
- is_wininst = getattr(
- self.get_finalized_command("bdist_wininst"), '_is_running', False
- )
- for args in get_script_args(dist, executable, is_wininst):
+ exec_param = getattr(bs_cmd, 'executable', None)
+ bw_cmd = self.get_finalized_command("bdist_wininst")
+ is_wininst = getattr(bw_cmd, '_is_running', False)
+ writer = ei.ScriptWriter
+ if is_wininst:
+ exec_param = "python.exe"
+ writer = ei.WindowsScriptWriter
+ # resolve the writer to the environment
+ writer = writer.best()
+ cmd = writer.command_spec_class.from_param(exec_param)
+ for args in writer.get_args(dist, cmd.as_header()):
self.write_script(*args)
def write_script(self, script_name, contents, mode="t", *ignored):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setuptools/msvc9_support.py
new/setuptools-12.0.3/setuptools/msvc9_support.py
--- old/setuptools-11.3.1/setuptools/msvc9_support.py 2015-01-05
18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/msvc9_support.py 2015-01-19
00:48:58.000000000 +0100
@@ -1,5 +1,3 @@
-import sys
-
try:
import distutils.msvc9compiler
except ImportError:
@@ -29,13 +27,15 @@
def find_vcvarsall(version):
Reg = distutils.msvc9compiler.Reg
VC_BASE = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f'
+ key = VC_BASE % ('', version)
try:
# Per-user installs register the compiler path here
- productdir = Reg.get_value(VC_BASE % ('', version), "installdir")
+ productdir = Reg.get_value(key, "installdir")
except KeyError:
try:
# All-user installs on a 64-bit system register here
- productdir = Reg.get_value(VC_BASE % ('Wow6432Node\\', version),
"installdir")
+ key = VC_BASE % ('Wow6432Node\\', version)
+ productdir = Reg.get_value(key, "installdir")
except KeyError:
productdir = None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setuptools/sandbox.py
new/setuptools-12.0.3/setuptools/sandbox.py
--- old/setuptools-11.3.1/setuptools/sandbox.py 2015-01-05 18:59:01.000000000
+0100
+++ new/setuptools-12.0.3/setuptools/sandbox.py 2015-01-19 00:48:58.000000000
+0100
@@ -92,6 +92,51 @@
os.chdir(saved)
+class UnpickleableException(Exception):
+ """
+ An exception representing another Exception that could not be pickled.
+ """
+ @classmethod
+ def dump(cls, type, exc):
+ """
+ Always return a dumped (pickled) type and exc. If exc can't be pickled,
+ wrap it in UnpickleableException first.
+ """
+ try:
+ return pickle.dumps(type), pickle.dumps(exc)
+ except Exception:
+ return cls.dump(cls, cls(repr(exc)))
+
+
+class ExceptionSaver:
+ """
+ A Context Manager that will save an exception, serialized, and restore it
+ later.
+ """
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, exc, tb):
+ if not exc:
+ return
+
+ # dump the exception
+ self._saved = UnpickleableException.dump(type, exc)
+ self._tb = tb
+
+ # suppress the exception
+ return True
+
+ def resume(self):
+ "restore and re-raise any exception"
+
+ if '_saved' not in vars(self):
+ return
+
+ type, exc = map(pickle.loads, self._saved)
+ compat.reraise(type, exc, self._tb)
+
+
@contextlib.contextmanager
def save_modules():
"""
@@ -101,31 +146,20 @@
outside the context.
"""
saved = sys.modules.copy()
- try:
- try:
- yield saved
- except:
- # dump any exception
- class_, exc, tb = sys.exc_info()
- saved_cls = pickle.dumps(class_)
- saved_exc = pickle.dumps(exc)
- raise
- finally:
- sys.modules.update(saved)
- # remove any modules imported since
- del_modules = (
- mod_name for mod_name in sys.modules
- if mod_name not in saved
- # exclude any encodings modules. See #285
- and not mod_name.startswith('encodings.')
- )
- _clear_modules(del_modules)
- except:
- # reload and re-raise any exception, using restored modules
- class_, exc, tb = sys.exc_info()
- new_cls = pickle.loads(saved_cls)
- new_exc = pickle.loads(saved_exc)
- compat.reraise(new_cls, new_exc, tb)
+ with ExceptionSaver() as saved_exc:
+ yield saved
+
+ sys.modules.update(saved)
+ # remove any modules imported since
+ del_modules = (
+ mod_name for mod_name in sys.modules
+ if mod_name not in saved
+ # exclude any encodings modules. See #285
+ and not mod_name.startswith('encodings.')
+ )
+ _clear_modules(del_modules)
+
+ saved_exc.resume()
def _clear_modules(module_names):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setuptools/tests/contexts.py
new/setuptools-12.0.3/setuptools/tests/contexts.py
--- old/setuptools-11.3.1/setuptools/tests/contexts.py 2015-01-05
18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/tests/contexts.py 2015-01-19
00:48:58.000000000 +0100
@@ -27,7 +27,7 @@
to clear the values.
"""
saved = dict(
- (key, os.environ['key'])
+ (key, os.environ[key])
for key in replacements
if key in os.environ
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setuptools/tests/fixtures.py
new/setuptools-12.0.3/setuptools/tests/fixtures.py
--- old/setuptools-11.3.1/setuptools/tests/fixtures.py 2015-01-05
18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/tests/fixtures.py 2015-01-19
00:48:58.000000000 +0100
@@ -1,4 +1,7 @@
-import mock
+try:
+ from unittest import mock
+except ImportError:
+ import mock
import pytest
from . import contexts
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setuptools/tests/py26compat.py
new/setuptools-12.0.3/setuptools/tests/py26compat.py
--- old/setuptools-11.3.1/setuptools/tests/py26compat.py 2015-01-05
18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/tests/py26compat.py 2015-01-19
01:21:40.000000000 +0100
@@ -8,4 +8,7 @@
"""
return contextlib.closing(tarfile.open(*args, **kwargs))
-tarfile_open = _tarfile_open_ex if sys.version_info < (2,7) else tarfile.open
+if sys.version_info[:2] < (2, 7) or (3, 0) <= sys.version_info[:2] < (3, 2):
+ tarfile_open = _tarfile_open_ex
+else:
+ tarfile_open = tarfile.open
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/setuptools-11.3.1/setuptools/tests/test_easy_install.py
new/setuptools-12.0.3/setuptools/tests/test_easy_install.py
--- old/setuptools-11.3.1/setuptools/tests/test_easy_install.py 2015-01-05
18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/tests/test_easy_install.py 2015-01-19
02:14:42.000000000 +0100
@@ -1,4 +1,4 @@
-#! -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""Easy install Tests
"""
@@ -15,20 +15,23 @@
import itertools
import pytest
-import mock
+try:
+ from unittest import mock
+except ImportError:
+ import mock
from setuptools import sandbox
from setuptools import compat
from setuptools.compat import StringIO, BytesIO, urlparse
-from setuptools.sandbox import run_setup, SandboxViolation
+from setuptools.sandbox import run_setup
from setuptools.command.easy_install import (
- easy_install, fix_jython_executable, get_script_args, nt_quote_arg,
- get_script_header, is_sh,
+ easy_install, fix_jython_executable, nt_quote_arg,
+ is_sh, ScriptWriter, CommandSpec,
)
from setuptools.command.easy_install import PthDistributions
from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
-from pkg_resources import working_set, VersionConflict
+from pkg_resources import working_set
from pkg_resources import Distribution as PRDistribution
import setuptools.tests.server
import pkg_resources
@@ -83,7 +86,7 @@
def test_get_script_args(self):
dist = FakeDist()
- args = next(get_script_args(dist))
+ args = next(ScriptWriter.get_args(dist))
name, script = itertools.islice(args, 2)
assert script == WANTED
@@ -425,15 +428,22 @@
)
def test_get_script_header(self):
expected = '#!%s\n' % nt_quote_arg(os.path.normpath(sys.executable))
- assert get_script_header('#!/usr/local/bin/python') == expected
- expected = '#!%s -x\n' %
nt_quote_arg(os.path.normpath(sys.executable))
- assert get_script_header('#!/usr/bin/python -x') == expected
- candidate = get_script_header('#!/usr/bin/python',
+ actual = ScriptWriter.get_script_header('#!/usr/local/bin/python')
+ assert actual == expected
+
+ expected = '#!%s -x\n' % nt_quote_arg(os.path.normpath(sys.executable))
+ actual = ScriptWriter.get_script_header('#!/usr/bin/python -x')
+ assert actual == expected
+
+ actual = ScriptWriter.get_script_header('#!/usr/bin/python',
executable=self.non_ascii_exe)
- assert candidate == '#!%s -x\n' % self.non_ascii_exe
- candidate = get_script_header('#!/usr/bin/python',
- executable=self.exe_with_spaces)
- assert candidate == '#!"%s"\n' % self.exe_with_spaces
+ expected = '#!%s -x\n' % self.non_ascii_exe
+ assert actual == expected
+
+ actual = ScriptWriter.get_script_header('#!/usr/bin/python',
+ executable='"'+self.exe_with_spaces+'"')
+ expected = '#!"%s"\n' % self.exe_with_spaces
+ assert actual == expected
@pytest.mark.xfail(
compat.PY3 and os.environ.get("LC_CTYPE") in ("C", "POSIX"),
@@ -453,7 +463,8 @@
f.write(header)
exe = str(exe)
- header = get_script_header('#!/usr/local/bin/python', executable=exe)
+ header = ScriptWriter.get_script_header('#!/usr/local/bin/python',
+ executable=exe)
assert header == '#!/usr/bin/env %s\n' % exe
expect_out = 'stdout' if sys.version_info < (2,7) else 'stderr'
@@ -461,15 +472,57 @@
with contexts.quiet() as (stdout, stderr):
# When options are included, generate a broken shebang line
# with a warning emitted
- candidate = get_script_header('#!/usr/bin/python -x',
+ candidate = ScriptWriter.get_script_header('#!/usr/bin/python -x',
executable=exe)
- assert candidate == '#!%s -x\n' % exe
+ assert candidate == '#!%s -x\n' % exe
output = locals()[expect_out]
assert 'Unable to adapt shebang line' in output.getvalue()
with contexts.quiet() as (stdout, stderr):
- candidate = get_script_header('#!/usr/bin/python',
+ candidate = ScriptWriter.get_script_header('#!/usr/bin/python',
executable=self.non_ascii_exe)
assert candidate == '#!%s -x\n' % self.non_ascii_exe
output = locals()[expect_out]
assert 'Unable to adapt shebang line' in output.getvalue()
+
+
+class TestCommandSpec:
+ def test_custom_launch_command(self):
+ """
+ Show how a custom CommandSpec could be used to specify a #! executable
+ which takes parameters.
+ """
+ cmd = CommandSpec(['/usr/bin/env', 'python3'])
+ assert cmd.as_header() == '#!/usr/bin/env python3\n'
+
+ def test_from_param_for_CommandSpec_is_passthrough(self):
+ """
+ from_param should return an instance of a CommandSpec
+ """
+ cmd = CommandSpec(['python'])
+ cmd_new = CommandSpec.from_param(cmd)
+ assert cmd is cmd_new
+
+ def test_from_environment_with_spaces_in_executable(self):
+ with mock.patch('sys.executable', TestScriptHeader.exe_with_spaces):
+ cmd = CommandSpec.from_environment()
+ assert len(cmd) == 1
+ assert cmd.as_header().startswith('#!"')
+
+ def test_from_simple_string_uses_shlex(self):
+ """
+ In order to support `executable = /usr/bin/env my-python`, make sure
+ from_param invokes shlex on that input.
+ """
+ cmd = CommandSpec.from_param('/usr/bin/env my-python')
+ assert len(cmd) == 2
+ assert '"' not in cmd.as_header()
+
+ def test_sys_executable(self):
+ """
+ CommandSpec.from_string(sys.executable) should contain just that param.
+ """
+ writer = ScriptWriter.best()
+ cmd = writer.command_spec_class.from_string(sys.executable)
+ assert len(cmd) == 1
+ assert cmd[0] == sys.executable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/setuptools-11.3.1/setuptools/tests/test_integration.py
new/setuptools-12.0.3/setuptools/tests/test_integration.py
--- old/setuptools-11.3.1/setuptools/tests/test_integration.py 2015-01-05
18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/tests/test_integration.py 2015-01-19
00:48:58.000000000 +0100
@@ -12,6 +12,7 @@
from setuptools.command.easy_install import easy_install
from setuptools.command import easy_install as easy_install_pkg
from setuptools.dist import Distribution
+from setuptools.compat import urlopen
def setup_module(module):
@@ -24,6 +25,11 @@
except ImportError:
pass
+ try:
+ urlopen('https://pypi.python.org/pypi')
+ except Exception as exc:
+ pytest.skip(reason=str(exc))
+
@pytest.fixture
def install_context(request, tmpdir, monkeypatch):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/setuptools-11.3.1/setuptools/tests/test_msvc9compiler.py
new/setuptools-12.0.3/setuptools/tests/test_msvc9compiler.py
--- old/setuptools-11.3.1/setuptools/tests/test_msvc9compiler.py
2015-01-05 18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/tests/test_msvc9compiler.py
2015-01-19 00:48:58.000000000 +0100
@@ -7,7 +7,10 @@
import distutils.errors
import pytest
-import mock
+try:
+ from unittest import mock
+except ImportError:
+ import mock
from . import contexts
@@ -110,7 +113,8 @@
Ensure user's settings are preferred.
"""
result = distutils.msvc9compiler.find_vcvarsall(9.0)
- assert user_preferred_setting == result
+ expected = os.path.join(user_preferred_setting, 'vcvarsall.bat')
+ assert expected == result
@pytest.yield_fixture
def local_machine_setting(self):
@@ -131,13 +135,14 @@
Ensure machine setting is honored if user settings are not present.
"""
result = distutils.msvc9compiler.find_vcvarsall(9.0)
- assert local_machine_setting == result
+ expected = os.path.join(local_machine_setting, 'vcvarsall.bat')
+ assert expected == result
@pytest.yield_fixture
def x64_preferred_setting(self):
"""
Set up environment with 64-bit and 32-bit system settings configured
- and yield the 64-bit location.
+ and yield the canonical location.
"""
with self.mock_install_dir() as x32_dir:
with self.mock_install_dir() as x64_dir:
@@ -150,14 +155,15 @@
},
)
with reg:
- yield x64_dir
+ yield x32_dir
def test_ensure_64_bit_preferred(self, x64_preferred_setting):
"""
Ensure 64-bit system key is preferred.
"""
result = distutils.msvc9compiler.find_vcvarsall(9.0)
- assert x64_preferred_setting == result
+ expected = os.path.join(x64_preferred_setting, 'vcvarsall.bat')
+ assert expected == result
@staticmethod
@contextlib.contextmanager
@@ -170,4 +176,4 @@
vcvarsall = os.path.join(result, 'vcvarsall.bat')
with open(vcvarsall, 'w'):
pass
- yield
+ yield result
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setuptools/tests/test_sandbox.py
new/setuptools-12.0.3/setuptools/tests/test_sandbox.py
--- old/setuptools-11.3.1/setuptools/tests/test_sandbox.py 2015-01-05
18:59:01.000000000 +0100
+++ new/setuptools-12.0.3/setuptools/tests/test_sandbox.py 2015-01-19
00:48:58.000000000 +0100
@@ -7,7 +7,7 @@
import pkg_resources
import setuptools.sandbox
-from setuptools.sandbox import DirectorySandbox, SandboxViolation
+from setuptools.sandbox import DirectorySandbox
class TestSandbox:
@@ -54,3 +54,49 @@
with setup_py.open('wb') as stream:
stream.write(b'"degenerate script"\r\n')
setuptools.sandbox._execfile(str(setup_py), globals())
+
+
+class TestExceptionSaver:
+ def test_exception_trapped(self):
+ with setuptools.sandbox.ExceptionSaver():
+ raise ValueError("details")
+
+ def test_exception_resumed(self):
+ with setuptools.sandbox.ExceptionSaver() as saved_exc:
+ raise ValueError("details")
+
+ with pytest.raises(ValueError) as caught:
+ saved_exc.resume()
+
+ assert isinstance(caught.value, ValueError)
+ assert str(caught.value) == 'details'
+
+ def test_exception_reconstructed(self):
+ orig_exc = ValueError("details")
+
+ with setuptools.sandbox.ExceptionSaver() as saved_exc:
+ raise orig_exc
+
+ with pytest.raises(ValueError) as caught:
+ saved_exc.resume()
+
+ assert isinstance(caught.value, ValueError)
+ assert caught.value is not orig_exc
+
+ def test_no_exception_passes_quietly(self):
+ with setuptools.sandbox.ExceptionSaver() as saved_exc:
+ pass
+
+ saved_exc.resume()
+
+ def test_unpickleable_exception(self):
+ class CantPickleThis(Exception):
+ "This Exception is unpickleable because it's not in globals"
+
+ with setuptools.sandbox.ExceptionSaver() as saved_exc:
+ raise CantPickleThis('detail')
+
+ with pytest.raises(setuptools.sandbox.UnpickleableException) as caught:
+ saved_exc.resume()
+
+ assert str(caught.value) == "CantPickleThis('detail',)"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setuptools/version.py
new/setuptools-12.0.3/setuptools/version.py
--- old/setuptools-11.3.1/setuptools/version.py 2015-01-06 16:11:49.000000000
+0100
+++ new/setuptools-12.0.3/setuptools/version.py 2015-01-19 02:43:32.000000000
+0100
@@ -1 +1 @@
-__version__ = '11.3.1'
+__version__ = '12.0.3'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/setuptools-11.3.1/setuptools.egg-info/PKG-INFO
new/setuptools-12.0.3/setuptools.egg-info/PKG-INFO
--- old/setuptools-11.3.1/setuptools.egg-info/PKG-INFO 2015-01-06
16:11:56.000000000 +0100
+++ new/setuptools-12.0.3/setuptools.egg-info/PKG-INFO 2015-01-19
02:48:34.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: setuptools
-Version: 11.3.1
+Version: 12.0.3
Summary: Easily download, build, install, upgrade, and uninstall Python
packages
Home-page: https://bitbucket.org/pypa/setuptools
Author: Python Packaging Authority
--
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]