[pypy-commit] pypy vendor/stdlib: update the Python 3 stdlib to v3.2.5
pjenvey
noreply at buildbot.pypy.org
Thu Mar 13 00:21:06 CET 2014
Author: Philip Jenvey <pjenvey at underboss.org>
Branch: vendor/stdlib
Changeset: r69915:bd484963d7ae
Date: 2014-03-12 15:34 -0700
http://bitbucket.org/pypy/pypy/changeset/bd484963d7ae/
Log: update the Python 3 stdlib to v3.2.5
diff too long, truncating to 2000 out of 27236 lines
diff --git a/lib-python/3/__future__.py b/lib-python/3/__future__.py
--- a/lib-python/3/__future__.py
+++ b/lib-python/3/__future__.py
@@ -114,7 +114,7 @@
CO_FUTURE_DIVISION)
absolute_import = _Feature((2, 5, 0, "alpha", 1),
- (2, 7, 0, "alpha", 0),
+ (3, 0, 0, "alpha", 0),
CO_FUTURE_ABSOLUTE_IMPORT)
with_statement = _Feature((2, 5, 0, "alpha", 1),
diff --git a/lib-python/3/_abcoll.py b/lib-python/3/_abcoll.py
--- a/lib-python/3/_abcoll.py
+++ b/lib-python/3/_abcoll.py
@@ -184,12 +184,12 @@
def __gt__(self, other):
if not isinstance(other, Set):
return NotImplemented
- return other < self
+ return other.__lt__(self)
def __ge__(self, other):
if not isinstance(other, Set):
return NotImplemented
- return other <= self
+ return other.__le__(self)
def __eq__(self, other):
if not isinstance(other, Set):
diff --git a/lib-python/3/_osx_support.py b/lib-python/3/_osx_support.py
new file mode 100644
--- /dev/null
+++ b/lib-python/3/_osx_support.py
@@ -0,0 +1,488 @@
+"""Shared OS X support functions."""
+
+import os
+import re
+import sys
+
+__all__ = [
+ 'compiler_fixup',
+ 'customize_config_vars',
+ 'customize_compiler',
+ 'get_platform_osx',
+]
+
+# configuration variables that may contain universal build flags,
+# like "-arch" or "-isdkroot", that may need customization for
+# the user environment
+_UNIVERSAL_CONFIG_VARS = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS',
+ 'BLDSHARED', 'LDSHARED', 'CC', 'CXX',
+ 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS',
+ 'PY_CORE_CFLAGS')
+
+# configuration variables that may contain compiler calls
+_COMPILER_CONFIG_VARS = ('BLDSHARED', 'LDSHARED', 'CC', 'CXX')
+
+# prefix added to original configuration variable names
+_INITPRE = '_OSX_SUPPORT_INITIAL_'
+
+
+def _find_executable(executable, path=None):
+ """Tries to find 'executable' in the directories listed in 'path'.
+
+ A string listing directories separated by 'os.pathsep'; defaults to
+ os.environ['PATH']. Returns the complete filename or None if not found.
+ """
+ if path is None:
+ path = os.environ['PATH']
+
+ paths = path.split(os.pathsep)
+ base, ext = os.path.splitext(executable)
+
+ if (sys.platform == 'win32' or os.name == 'os2') and (ext != '.exe'):
+ executable = executable + '.exe'
+
+ if not os.path.isfile(executable):
+ for p in paths:
+ f = os.path.join(p, executable)
+ if os.path.isfile(f):
+ # the file exists, we have a shot at spawn working
+ return f
+ return None
+ else:
+ return executable
+
+
+def _read_output(commandstring):
+ """Output from succesful command execution or None"""
+ # Similar to os.popen(commandstring, "r").read(),
+ # but without actually using os.popen because that
+ # function is not usable during python bootstrap.
+ # tempfile is also not available then.
+ import contextlib
+ try:
+ import tempfile
+ fp = tempfile.NamedTemporaryFile()
+ except ImportError:
+ fp = open("/tmp/_osx_support.%s"%(
+ os.getpid(),), "w+b")
+
+ with contextlib.closing(fp) as fp:
+ cmd = "%s 2>/dev/null >'%s'" % (commandstring, fp.name)
+ return fp.read().decode('utf-8').strip() if not os.system(cmd) else None
+
+
+def _find_build_tool(toolname):
+ """Find a build tool on current path or using xcrun"""
+ return (_find_executable(toolname)
+ or _read_output("/usr/bin/xcrun -find %s" % (toolname,))
+ or ''
+ )
+
+_SYSTEM_VERSION = None
+
+def _get_system_version():
+ """Return the OS X system version as a string"""
+ # Reading this plist is a documented way to get the system
+ # version (see the documentation for the Gestalt Manager)
+ # We avoid using platform.mac_ver to avoid possible bootstrap issues during
+ # the build of Python itself (distutils is used to build standard library
+ # extensions).
+
+ global _SYSTEM_VERSION
+
+ if _SYSTEM_VERSION is None:
+ _SYSTEM_VERSION = ''
+ try:
+ f = open('/System/Library/CoreServices/SystemVersion.plist')
+ except IOError:
+ # We're on a plain darwin box, fall back to the default
+ # behaviour.
+ pass
+ else:
+ try:
+ m = re.search(r'<key>ProductUserVisibleVersion</key>\s*'
+ r'<string>(.*?)</string>', f.read())
+ finally:
+ f.close()
+ if m is not None:
+ _SYSTEM_VERSION = '.'.join(m.group(1).split('.')[:2])
+ # else: fall back to the default behaviour
+
+ return _SYSTEM_VERSION
+
+def _remove_original_values(_config_vars):
+ """Remove original unmodified values for testing"""
+ # This is needed for higher-level cross-platform tests of get_platform.
+ for k in list(_config_vars):
+ if k.startswith(_INITPRE):
+ del _config_vars[k]
+
+def _save_modified_value(_config_vars, cv, newvalue):
+ """Save modified and original unmodified value of configuration var"""
+
+ oldvalue = _config_vars.get(cv, '')
+ if (oldvalue != newvalue) and (_INITPRE + cv not in _config_vars):
+ _config_vars[_INITPRE + cv] = oldvalue
+ _config_vars[cv] = newvalue
+
+def _supports_universal_builds():
+ """Returns True if universal builds are supported on this system"""
+ # As an approximation, we assume that if we are running on 10.4 or above,
+ # then we are running with an Xcode environment that supports universal
+ # builds, in particular -isysroot and -arch arguments to the compiler. This
+ # is in support of allowing 10.4 universal builds to run on 10.3.x systems.
+
+ osx_version = _get_system_version()
+ if osx_version:
+ try:
+ osx_version = tuple(int(i) for i in osx_version.split('.'))
+ except ValueError:
+ osx_version = ''
+ return bool(osx_version >= (10, 4)) if osx_version else False
+
+
+def _find_appropriate_compiler(_config_vars):
+ """Find appropriate C compiler for extension module builds"""
+
+ # Issue #13590:
+ # The OSX location for the compiler varies between OSX
+ # (or rather Xcode) releases. With older releases (up-to 10.5)
+ # the compiler is in /usr/bin, with newer releases the compiler
+ # can only be found inside Xcode.app if the "Command Line Tools"
+ # are not installed.
+ #
+ # Futhermore, the compiler that can be used varies between
+ # Xcode releases. Upto Xcode 4 it was possible to use 'gcc-4.2'
+ # as the compiler, after that 'clang' should be used because
+ # gcc-4.2 is either not present, or a copy of 'llvm-gcc' that
+ # miscompiles Python.
+
+ # skip checks if the compiler was overriden with a CC env variable
+ if 'CC' in os.environ:
+ return _config_vars
+
+ # The CC config var might contain additional arguments.
+ # Ignore them while searching.
+ cc = oldcc = _config_vars['CC'].split()[0]
+ if not _find_executable(cc):
+ # Compiler is not found on the shell search PATH.
+ # Now search for clang, first on PATH (if the Command LIne
+ # Tools have been installed in / or if the user has provided
+ # another location via CC). If not found, try using xcrun
+ # to find an uninstalled clang (within a selected Xcode).
+
+ # NOTE: Cannot use subprocess here because of bootstrap
+ # issues when building Python itself (and os.popen is
+ # implemented on top of subprocess and is therefore not
+ # usable as well)
+
+ cc = _find_build_tool('clang')
+
+ elif os.path.basename(cc).startswith('gcc'):
+ # Compiler is GCC, check if it is LLVM-GCC
+ data = _read_output("'%s' --version"
+ % (cc.replace("'", "'\"'\"'"),))
+ if 'llvm-gcc' in data:
+ # Found LLVM-GCC, fall back to clang
+ cc = _find_build_tool('clang')
+
+ if not cc:
+ raise SystemError(
+ "Cannot locate working compiler")
+
+ if cc != oldcc:
+ # Found a replacement compiler.
+ # Modify config vars using new compiler, if not already explictly
+ # overriden by an env variable, preserving additional arguments.
+ for cv in _COMPILER_CONFIG_VARS:
+ if cv in _config_vars and cv not in os.environ:
+ cv_split = _config_vars[cv].split()
+ cv_split[0] = cc if cv != 'CXX' else cc + '++'
+ _save_modified_value(_config_vars, cv, ' '.join(cv_split))
+
+ return _config_vars
+
+
+def _remove_universal_flags(_config_vars):
+ """Remove all universal build arguments from config vars"""
+
+ for cv in _UNIVERSAL_CONFIG_VARS:
+ # Do not alter a config var explicitly overriden by env var
+ if cv in _config_vars and cv not in os.environ:
+ flags = _config_vars[cv]
+ flags = re.sub('-arch\s+\w+\s', ' ', flags, re.ASCII)
+ flags = re.sub('-isysroot [^ \t]*', ' ', flags)
+ _save_modified_value(_config_vars, cv, flags)
+
+ return _config_vars
+
+
+def _remove_unsupported_archs(_config_vars):
+ """Remove any unsupported archs from config vars"""
+ # Different Xcode releases support different sets for '-arch'
+ # flags. In particular, Xcode 4.x no longer supports the
+ # PPC architectures.
+ #
+ # This code automatically removes '-arch ppc' and '-arch ppc64'
+ # when these are not supported. That makes it possible to
+ # build extensions on OSX 10.7 and later with the prebuilt
+ # 32-bit installer on the python.org website.
+
+ # skip checks if the compiler was overriden with a CC env variable
+ if 'CC' in os.environ:
+ return _config_vars
+
+ if re.search('-arch\s+ppc', _config_vars['CFLAGS']) is not None:
+ # NOTE: Cannot use subprocess here because of bootstrap
+ # issues when building Python itself
+ status = os.system("'%s' -arch ppc -x c /dev/null 2>/dev/null"%(
+ _config_vars['CC'].replace("'", "'\"'\"'"),))
+ # The Apple compiler drivers return status 255 if no PPC
+ if (status >> 8) == 255:
+ # Compiler doesn't support PPC, remove the related
+ # '-arch' flags if not explicitly overridden by an
+ # environment variable
+ for cv in _UNIVERSAL_CONFIG_VARS:
+ if cv in _config_vars and cv not in os.environ:
+ flags = _config_vars[cv]
+ flags = re.sub('-arch\s+ppc\w*\s', ' ', flags)
+ _save_modified_value(_config_vars, cv, flags)
+
+ return _config_vars
+
+
+def _override_all_archs(_config_vars):
+ """Allow override of all archs with ARCHFLAGS env var"""
+ # NOTE: This name was introduced by Apple in OSX 10.5 and
+ # is used by several scripting languages distributed with
+ # that OS release.
+ if 'ARCHFLAGS' in os.environ:
+ arch = os.environ['ARCHFLAGS']
+ for cv in _UNIVERSAL_CONFIG_VARS:
+ if cv in _config_vars and '-arch' in _config_vars[cv]:
+ flags = _config_vars[cv]
+ flags = re.sub('-arch\s+\w+\s', ' ', flags)
+ flags = flags + ' ' + arch
+ _save_modified_value(_config_vars, cv, flags)
+
+ return _config_vars
+
+
+def _check_for_unavailable_sdk(_config_vars):
+ """Remove references to any SDKs not available"""
+ # If we're on OSX 10.5 or later and the user tries to
+ # compile an extension using an SDK that is not present
+ # on the current machine it is better to not use an SDK
+ # than to fail. This is particularly important with
+ # the standalong Command Line Tools alternative to a
+ # full-blown Xcode install since the CLT packages do not
+ # provide SDKs. If the SDK is not present, it is assumed
+ # that the header files and dev libs have been installed
+ # to /usr and /System/Library by either a standalone CLT
+ # package or the CLT component within Xcode.
+ cflags = _config_vars.get('CFLAGS', '')
+ m = re.search(r'-isysroot\s+(\S+)', cflags)
+ if m is not None:
+ sdk = m.group(1)
+ if not os.path.exists(sdk):
+ for cv in _UNIVERSAL_CONFIG_VARS:
+ # Do not alter a config var explicitly overriden by env var
+ if cv in _config_vars and cv not in os.environ:
+ flags = _config_vars[cv]
+ flags = re.sub(r'-isysroot\s+\S+(?:\s|$)', ' ', flags)
+ _save_modified_value(_config_vars, cv, flags)
+
+ return _config_vars
+
+
+def compiler_fixup(compiler_so, cc_args):
+ """
+ This function will strip '-isysroot PATH' and '-arch ARCH' from the
+ compile flags if the user has specified one them in extra_compile_flags.
+
+ This is needed because '-arch ARCH' adds another architecture to the
+ build, without a way to remove an architecture. Furthermore GCC will
+ barf if multiple '-isysroot' arguments are present.
+ """
+ stripArch = stripSysroot = False
+
+ compiler_so = list(compiler_so)
+
+ if not _supports_universal_builds():
+ # OSX before 10.4.0, these don't support -arch and -isysroot at
+ # all.
+ stripArch = stripSysroot = True
+ else:
+ stripArch = '-arch' in cc_args
+ stripSysroot = '-isysroot' in cc_args
+
+ if stripArch or 'ARCHFLAGS' in os.environ:
+ while True:
+ try:
+ index = compiler_so.index('-arch')
+ # Strip this argument and the next one:
+ del compiler_so[index:index+2]
+ except ValueError:
+ break
+
+ if 'ARCHFLAGS' in os.environ and not stripArch:
+ # User specified different -arch flags in the environ,
+ # see also distutils.sysconfig
+ compiler_so = compiler_so + os.environ['ARCHFLAGS'].split()
+
+ if stripSysroot:
+ while True:
+ try:
+ index = compiler_so.index('-isysroot')
+ # Strip this argument and the next one:
+ del compiler_so[index:index+2]
+ except ValueError:
+ break
+
+ # Check if the SDK that is used during compilation actually exists,
+ # the universal build requires the usage of a universal SDK and not all
+ # users have that installed by default.
+ sysroot = None
+ if '-isysroot' in cc_args:
+ idx = cc_args.index('-isysroot')
+ sysroot = cc_args[idx+1]
+ elif '-isysroot' in compiler_so:
+ idx = compiler_so.index('-isysroot')
+ sysroot = compiler_so[idx+1]
+
+ if sysroot and not os.path.isdir(sysroot):
+ from distutils import log
+ log.warn("Compiling with an SDK that doesn't seem to exist: %s",
+ sysroot)
+ log.warn("Please check your Xcode installation")
+
+ return compiler_so
+
+
+def customize_config_vars(_config_vars):
+ """Customize Python build configuration variables.
+
+ Called internally from sysconfig with a mutable mapping
+ containing name/value pairs parsed from the configured
+ makefile used to build this interpreter. Returns
+ the mapping updated as needed to reflect the environment
+ in which the interpreter is running; in the case of
+ a Python from a binary installer, the installed
+ environment may be very different from the build
+ environment, i.e. different OS levels, different
+ built tools, different available CPU architectures.
+
+ This customization is performed whenever
+ distutils.sysconfig.get_config_vars() is first
+ called. It may be used in environments where no
+ compilers are present, i.e. when installing pure
+ Python dists. Customization of compiler paths
+ and detection of unavailable archs is deferred
+ until the first extention module build is
+ requested (in distutils.sysconfig.customize_compiler).
+
+ Currently called from distutils.sysconfig
+ """
+
+ if not _supports_universal_builds():
+ # On Mac OS X before 10.4, check if -arch and -isysroot
+ # are in CFLAGS or LDFLAGS and remove them if they are.
+ # This is needed when building extensions on a 10.3 system
+ # using a universal build of python.
+ _remove_universal_flags(_config_vars)
+
+ # Allow user to override all archs with ARCHFLAGS env var
+ _override_all_archs(_config_vars)
+
+ # Remove references to sdks that are not found
+ _check_for_unavailable_sdk(_config_vars)
+
+ return _config_vars
+
+
+def customize_compiler(_config_vars):
+ """Customize compiler path and configuration variables.
+
+ This customization is performed when the first
+ extension module build is requested
+ in distutils.sysconfig.customize_compiler).
+ """
+
+ # Find a compiler to use for extension module builds
+ _find_appropriate_compiler(_config_vars)
+
+ # Remove ppc arch flags if not supported here
+ _remove_unsupported_archs(_config_vars)
+
+ # Allow user to override all archs with ARCHFLAGS env var
+ _override_all_archs(_config_vars)
+
+ return _config_vars
+
+
+def get_platform_osx(_config_vars, osname, release, machine):
+ """Filter values for get_platform()"""
+ # called from get_platform() in sysconfig and distutils.util
+ #
+ # For our purposes, we'll assume that the system version from
+ # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set
+ # to. This makes the compatibility story a bit more sane because the
+ # machine is going to compile and link as if it were
+ # MACOSX_DEPLOYMENT_TARGET.
+
+ macver = _config_vars.get('MACOSX_DEPLOYMENT_TARGET', '')
+ macrelease = _get_system_version() or macver
+ macver = macver or macrelease
+
+ if macver:
+ release = macver
+ osname = "macosx"
+
+ # Use the original CFLAGS value, if available, so that we
+ # return the same machine type for the platform string.
+ # Otherwise, distutils may consider this a cross-compiling
+ # case and disallow installs.
+ cflags = _config_vars.get(_INITPRE+'CFLAGS',
+ _config_vars.get('CFLAGS', ''))
+ if ((macrelease + '.') >= '10.4.' and
+ '-arch' in cflags.strip()):
+ # The universal build will build fat binaries, but not on
+ # systems before 10.4
+
+ machine = 'fat'
+
+ archs = re.findall('-arch\s+(\S+)', cflags)
+ archs = tuple(sorted(set(archs)))
+
+ if len(archs) == 1:
+ machine = archs[0]
+ elif archs == ('i386', 'ppc'):
+ machine = 'fat'
+ elif archs == ('i386', 'x86_64'):
+ machine = 'intel'
+ elif archs == ('i386', 'ppc', 'x86_64'):
+ machine = 'fat3'
+ elif archs == ('ppc64', 'x86_64'):
+ machine = 'fat64'
+ elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'):
+ machine = 'universal'
+ else:
+ raise ValueError(
+ "Don't know machine value for archs=%r" % (archs,))
+
+ elif machine == 'i386':
+ # On OSX the machine type returned by uname is always the
+ # 32-bit variant, even if the executable architecture is
+ # the 64-bit variant
+ if sys.maxsize >= 2**32:
+ machine = 'x86_64'
+
+ elif machine in ('PowerPC', 'Power_Macintosh'):
+ # Pick a sane name for the PPC architecture.
+ # See 'i386' case
+ if sys.maxsize >= 2**32:
+ machine = 'ppc64'
+ else:
+ machine = 'ppc'
+
+ return (osname, release, machine)
diff --git a/lib-python/3/_pyio.py b/lib-python/3/_pyio.py
--- a/lib-python/3/_pyio.py
+++ b/lib-python/3/_pyio.py
@@ -298,7 +298,7 @@
def seek(self, pos, whence=0):
"""Change stream position.
- Change the stream position to byte offset offset. offset is
+ Change the stream position to byte offset pos. Argument pos is
interpreted relative to the position indicated by whence. Values
for whence are ints:
@@ -889,12 +889,18 @@
return pos
def readable(self):
+ if self.closed:
+ raise ValueError("I/O operation on closed file.")
return True
def writable(self):
+ if self.closed:
+ raise ValueError("I/O operation on closed file.")
return True
def seekable(self):
+ if self.closed:
+ raise ValueError("I/O operation on closed file.")
return True
@@ -1567,6 +1573,8 @@
return self._buffer
def seekable(self):
+ if self.closed:
+ raise ValueError("I/O operation on closed file.")
return self._seekable
def readable(self):
diff --git a/lib-python/3/_strptime.py b/lib-python/3/_strptime.py
--- a/lib-python/3/_strptime.py
+++ b/lib-python/3/_strptime.py
@@ -339,7 +339,7 @@
raise ValueError("unconverted data remains: %s" %
data_string[found.end():])
- year = 1900
+ year = None
month = day = 1
hour = minute = second = fraction = 0
tz = -1
@@ -444,6 +444,12 @@
else:
tz = value
break
+ leap_year_fix = False
+ if year is None and month == 2 and day == 29:
+ year = 1904 # 1904 is first leap year of 20th century
+ leap_year_fix = True
+ elif year is None:
+ year = 1900
# If we know the week of the year and what day of that week, we can figure
# out the Julian day of the year.
if julian == -1 and week_of_year != -1 and weekday != -1:
@@ -472,6 +478,12 @@
else:
gmtoff = None
+ if leap_year_fix:
+ # the caller didn't supply a year but asked for Feb 29th. We couldn't
+ # use the default of 1900 for computations. We set it back to ensure
+ # that February 29th is smaller than March 1st.
+ year = 1900
+
return (year, month, day,
hour, minute, second,
weekday, julian, tz, gmtoff, tzname), fraction
diff --git a/lib-python/3/_weakrefset.py b/lib-python/3/_weakrefset.py
--- a/lib-python/3/_weakrefset.py
+++ b/lib-python/3/_weakrefset.py
@@ -63,7 +63,7 @@
yield item
def __len__(self):
- return sum(x() is not None for x in self.data)
+ return len(self.data) - len(self._pending_removals)
def __contains__(self, item):
try:
@@ -114,36 +114,21 @@
def update(self, other):
if self._pending_removals:
self._commit_removals()
- if isinstance(other, self.__class__):
- self.data.update(other.data)
- else:
- for element in other:
- self.add(element)
+ for element in other:
+ self.add(element)
def __ior__(self, other):
self.update(other)
return self
- # Helper functions for simple delegating methods.
- def _apply(self, other, method):
- if not isinstance(other, self.__class__):
- other = self.__class__(other)
- newdata = method(other.data)
- newset = self.__class__()
- newset.data = newdata
+ def difference(self, other):
+ newset = self.copy()
+ newset.difference_update(other)
return newset
-
- def difference(self, other):
- return self._apply(other, self.data.difference)
__sub__ = difference
def difference_update(self, other):
- if self._pending_removals:
- self._commit_removals()
- if self is other:
- self.data.clear()
- else:
- self.data.difference_update(ref(item) for item in other)
+ self.__isub__(other)
def __isub__(self, other):
if self._pending_removals:
self._commit_removals()
@@ -154,13 +139,11 @@
return self
def intersection(self, other):
- return self._apply(other, self.data.intersection)
+ return self.__class__(item for item in other if item in self)
__and__ = intersection
def intersection_update(self, other):
- if self._pending_removals:
- self._commit_removals()
- self.data.intersection_update(ref(item) for item in other)
+ self.__iand__(other)
def __iand__(self, other):
if self._pending_removals:
self._commit_removals()
@@ -169,17 +152,17 @@
def issubset(self, other):
return self.data.issubset(ref(item) for item in other)
- __lt__ = issubset
+ __le__ = issubset
- def __le__(self, other):
- return self.data <= set(ref(item) for item in other)
+ def __lt__(self, other):
+ return self.data < set(ref(item) for item in other)
def issuperset(self, other):
return self.data.issuperset(ref(item) for item in other)
- __gt__ = issuperset
+ __ge__ = issuperset
- def __ge__(self, other):
- return self.data >= set(ref(item) for item in other)
+ def __gt__(self, other):
+ return self.data > set(ref(item) for item in other)
def __eq__(self, other):
if not isinstance(other, self.__class__):
@@ -187,27 +170,24 @@
return self.data == set(ref(item) for item in other)
def symmetric_difference(self, other):
- return self._apply(other, self.data.symmetric_difference)
+ newset = self.copy()
+ newset.symmetric_difference_update(other)
+ return newset
__xor__ = symmetric_difference
def symmetric_difference_update(self, other):
- if self._pending_removals:
- self._commit_removals()
- if self is other:
- self.data.clear()
- else:
- self.data.symmetric_difference_update(ref(item) for item in other)
+ self.__ixor__(other)
def __ixor__(self, other):
if self._pending_removals:
self._commit_removals()
if self is other:
self.data.clear()
else:
- self.data.symmetric_difference_update(ref(item) for item in other)
+ self.data.symmetric_difference_update(ref(item, self._remove) for item in other)
return self
def union(self, other):
- return self._apply(other, self.data.union)
+ return self.__class__(e for s in (self, other) for e in s)
__or__ = union
def isdisjoint(self, other):
diff --git a/lib-python/3/aifc.py b/lib-python/3/aifc.py
--- a/lib-python/3/aifc.py
+++ b/lib-python/3/aifc.py
@@ -692,7 +692,9 @@
self._patchheader()
def close(self):
- if self._file:
+ if self._file is None:
+ return
+ try:
self._ensure_header_written(0)
if self._datawritten & 1:
# quick pad to even size
@@ -703,10 +705,12 @@
self._datalength != self._datawritten or \
self._marklength:
self._patchheader()
+ finally:
# Prevent ref cycles
self._convert = None
- self._file.close()
+ f = self._file
self._file = None
+ f.close()
#
# Internal methods.
diff --git a/lib-python/3/argparse.py b/lib-python/3/argparse.py
--- a/lib-python/3/argparse.py
+++ b/lib-python/3/argparse.py
@@ -736,10 +736,10 @@
- default -- The value to be produced if the option is not specified.
- - type -- The type which the command-line arguments should be converted
- to, should be one of 'string', 'int', 'float', 'complex' or a
- callable object that accepts a single string argument. If None,
- 'string' is assumed.
+ - type -- A callable that accepts a single string argument, and
+ returns the converted value. The standard Python types str, int,
+ float, and complex are useful examples of such callables. If None,
+ str is used.
- choices -- A container of values that should be allowed. If not None,
after a command-line argument has been converted to the appropriate
@@ -1701,9 +1701,12 @@
return args
def parse_known_args(self, args=None, namespace=None):
- # args default to the system args
if args is None:
+ # args default to the system args
args = _sys.argv[1:]
+ else:
+ # make sure that args are mutable
+ args = list(args)
# default Namespace built from parser defaults
if namespace is None:
@@ -1714,10 +1717,7 @@
if action.dest is not SUPPRESS:
if not hasattr(namespace, action.dest):
if action.default is not SUPPRESS:
- default = action.default
- if isinstance(action.default, str):
- default = self._get_value(action, default)
- setattr(namespace, action.dest, default)
+ setattr(namespace, action.dest, action.default)
# add any parser defaults that aren't present
for dest in self._defaults:
@@ -1945,12 +1945,23 @@
if positionals:
self.error(_('too few arguments'))
- # make sure all required actions were present
+ # make sure all required actions were present, and convert defaults.
for action in self._actions:
- if action.required:
- if action not in seen_actions:
+ if action not in seen_actions:
+ if action.required:
name = _get_action_name(action)
self.error(_('argument %s is required') % name)
+ else:
+ # Convert action default now instead of doing it before
+ # parsing arguments to avoid calling convert functions
+ # twice (which may fail) if the argument was given, but
+ # only if it was defined already in the namespace
+ if (action.default is not None and
+ isinstance(action.default, str) and
+ hasattr(namespace, action.dest) and
+ action.default is getattr(namespace, action.dest)):
+ setattr(namespace, action.dest,
+ self._get_value(action, action.default))
# make sure all required groups had one option present
for group in self._mutually_exclusive_groups:
@@ -1976,7 +1987,7 @@
for arg_string in arg_strings:
# for regular arguments, just add them back into the list
- if arg_string[0] not in self.fromfile_prefix_chars:
+ if not arg_string or arg_string[0] not in self.fromfile_prefix_chars:
new_arg_strings.append(arg_string)
# replace arguments referencing files with the file content
@@ -2186,9 +2197,12 @@
# Value conversion methods
# ========================
def _get_values(self, action, arg_strings):
- # for everything but PARSER args, strip out '--'
+ # for everything but PARSER, REMAINDER args, strip out first '--'
if action.nargs not in [PARSER, REMAINDER]:
- arg_strings = [s for s in arg_strings if s != '--']
+ try:
+ arg_strings.remove('--')
+ except ValueError:
+ pass
# optional argument produces a default when not present
if not arg_strings and action.nargs == OPTIONAL:
diff --git a/lib-python/3/asyncore.py b/lib-python/3/asyncore.py
--- a/lib-python/3/asyncore.py
+++ b/lib-python/3/asyncore.py
@@ -225,6 +225,7 @@
debug = False
connected = False
accepting = False
+ connecting = False
closing = False
addr = None
ignore_log_types = frozenset(['warning'])
@@ -248,7 +249,7 @@
try:
self.addr = sock.getpeername()
except socket.error as err:
- if err.args[0] == ENOTCONN:
+ if err.args[0] in (ENOTCONN, EINVAL):
# To handle the case where we got an unconnected
# socket.
self.connected = False
@@ -342,9 +343,11 @@
def connect(self, address):
self.connected = False
+ self.connecting = True
err = self.socket.connect_ex(address)
if err in (EINPROGRESS, EALREADY, EWOULDBLOCK) \
or err == EINVAL and os.name in ('nt', 'ce'):
+ self.addr = address
return
if err in (0, EISCONN):
self.addr = address
@@ -390,7 +393,7 @@
else:
return data
except socket.error as why:
- # winsock sometimes throws ENOTCONN
+ # winsock sometimes raises ENOTCONN
if why.args[0] in _DISCONNECTED:
self.handle_close()
return b''
@@ -400,6 +403,7 @@
def close(self):
self.connected = False
self.accepting = False
+ self.connecting = False
self.del_channel()
try:
self.socket.close()
@@ -438,7 +442,8 @@
# sockets that are connected
self.handle_accept()
elif not self.connected:
- self.handle_connect_event()
+ if self.connecting:
+ self.handle_connect_event()
self.handle_read()
else:
self.handle_read()
@@ -449,6 +454,7 @@
raise socket.error(err, _strerror(err))
self.handle_connect()
self.connected = True
+ self.connecting = False
def handle_write_event(self):
if self.accepting:
@@ -457,12 +463,8 @@
return
if not self.connected:
- #check for errors
- err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
- if err != 0:
- raise socket.error(err, _strerror(err))
-
- self.handle_connect_event()
+ if self.connecting:
+ self.handle_connect_event()
self.handle_write()
def handle_expt_event(self):
diff --git a/lib-python/3/bdb.py b/lib-python/3/bdb.py
--- a/lib-python/3/bdb.py
+++ b/lib-python/3/bdb.py
@@ -22,6 +22,7 @@
self.skip = set(skip) if skip else None
self.breaks = {}
self.fncache = {}
+ self.frame_returning = None
def canonic(self, filename):
if filename == "<" + filename[1:-1] + ">":
@@ -80,7 +81,11 @@
def dispatch_return(self, frame, arg):
if self.stop_here(frame) or frame == self.returnframe:
- self.user_return(frame, arg)
+ try:
+ self.frame_returning = frame
+ self.user_return(frame, arg)
+ finally:
+ self.frame_returning = None
if self.quitting: raise BdbQuit
return self.trace_dispatch
@@ -186,6 +191,14 @@
def set_step(self):
"""Stop after one line of code."""
+ # Issue #13183: pdb skips frames after hitting a breakpoint and running
+ # step commands.
+ # Restore the trace function in the caller (that may not have been set
+ # for performance reasons) when returning from the current frame.
+ if self.frame_returning:
+ caller_frame = self.frame_returning.f_back
+ if caller_frame and not caller_frame.f_trace:
+ caller_frame.f_trace = self.trace_dispatch
self._set_stopinfo(None, None)
def set_next(self, frame):
diff --git a/lib-python/3/calendar.py b/lib-python/3/calendar.py
--- a/lib-python/3/calendar.py
+++ b/lib-python/3/calendar.py
@@ -161,7 +161,11 @@
oneday = datetime.timedelta(days=1)
while True:
yield date
- date += oneday
+ try:
+ date += oneday
+ except OverflowError:
+ # Adding one day could fail after datetime.MAXYEAR
+ break
if date.month != month and date.weekday() == self.firstweekday:
break
diff --git a/lib-python/3/cgi.py b/lib-python/3/cgi.py
--- a/lib-python/3/cgi.py
+++ b/lib-python/3/cgi.py
@@ -214,17 +214,17 @@
"""
import http.client
- boundary = ""
+ boundary = b""
if 'boundary' in pdict:
boundary = pdict['boundary']
if not valid_boundary(boundary):
raise ValueError('Invalid boundary in multipart form: %r'
% (boundary,))
- nextpart = "--" + boundary
- lastpart = "--" + boundary + "--"
+ nextpart = b"--" + boundary
+ lastpart = b"--" + boundary + b"--"
partdict = {}
- terminator = ""
+ terminator = b""
while terminator != lastpart:
bytes = -1
@@ -243,7 +243,7 @@
raise ValueError('Maximum content length exceeded')
data = fp.read(bytes)
else:
- data = ""
+ data = b""
# Read lines until end of part.
lines = []
while 1:
@@ -251,7 +251,7 @@
if not line:
terminator = lastpart # End outer loop
break
- if line.startswith("--"):
+ if line.startswith(b"--"):
terminator = line.rstrip()
if terminator in (nextpart, lastpart):
break
@@ -263,12 +263,12 @@
if lines:
# Strip final line terminator
line = lines[-1]
- if line[-2:] == "\r\n":
+ if line[-2:] == b"\r\n":
line = line[:-2]
- elif line[-1:] == "\n":
+ elif line[-1:] == b"\n":
line = line[:-1]
lines[-1] = line
- data = "".join(lines)
+ data = b"".join(lines)
line = headers['content-disposition']
if not line:
continue
diff --git a/lib-python/3/cgitb.py b/lib-python/3/cgitb.py
--- a/lib-python/3/cgitb.py
+++ b/lib-python/3/cgitb.py
@@ -293,14 +293,19 @@
if self.logdir is not None:
suffix = ['.txt', '.html'][self.format=="html"]
(fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir)
+
try:
file = os.fdopen(fd, 'w')
file.write(doc)
file.close()
- msg = '<p> %s contains the description of this error.' % path
+ msg = '%s contains the description of this error.' % path
except:
- msg = '<p> Tried to save traceback to %s, but failed.' % path
- self.file.write(msg + '\n')
+ msg = 'Tried to save traceback to %s, but failed.' % path
+
+ if self.format == 'html':
+ self.file.write('<p>%s</p>\n' % msg)
+ else:
+ self.file.write(msg + '\n')
try:
self.file.flush()
except: pass
diff --git a/lib-python/3/collections.py b/lib-python/3/collections.py
--- a/lib-python/3/collections.py
+++ b/lib-python/3/collections.py
@@ -281,6 +281,10 @@
'Return self as a plain tuple. Used by copy and pickle.'
return tuple(self)
+ def __getstate__(self):
+ 'Exclude the OrderedDict from pickling'
+ return None
+
{field_defs}
'''
diff --git a/lib-python/3/concurrent/futures/_base.py b/lib-python/3/concurrent/futures/_base.py
--- a/lib-python/3/concurrent/futures/_base.py
+++ b/lib-python/3/concurrent/futures/_base.py
@@ -112,12 +112,14 @@
def __init__(self, num_pending_calls, stop_on_exception):
self.num_pending_calls = num_pending_calls
self.stop_on_exception = stop_on_exception
+ self.lock = threading.Lock()
super().__init__()
def _decrement_pending_calls(self):
- self.num_pending_calls -= 1
- if not self.num_pending_calls:
- self.event.set()
+ with self.lock:
+ self.num_pending_calls -= 1
+ if not self.num_pending_calls:
+ self.event.set()
def add_result(self, future):
super().add_result(future)
@@ -517,7 +519,7 @@
"""Returns a iterator equivalent to map(fn, iter).
Args:
- fn: A callable that will take take as many arguments as there are
+ fn: A callable that will take as many arguments as there are
passed iterables.
timeout: The maximum number of seconds to wait. If None, then there
is no limit on the wait time.
diff --git a/lib-python/3/configparser.py b/lib-python/3/configparser.py
--- a/lib-python/3/configparser.py
+++ b/lib-python/3/configparser.py
@@ -99,10 +99,9 @@
yes, on for True). Returns False or True.
items(section=_UNSET, raw=False, vars=None)
- If section is given, return a list of tuples with (section_name,
- section_proxy) for each section, including DEFAULTSECT. Otherwise,
- return a list of tuples with (name, value) for each option
- in the section.
+ If section is given, return a list of tuples with (name, value) for
+ each option in the section. Otherwise, return a list of tuples with
+ (section_name, section_proxy) for each section, including DEFAULTSECT.
remove_section(section)
Remove the given file section and all its options.
@@ -852,6 +851,19 @@
value_getter = lambda option: d[option]
return [(option, value_getter(option)) for option in d.keys()]
+ def popitem(self):
+ """Remove a section from the parser and return it as
+ a (section_name, section_proxy) tuple. If no section is present, raise
+ KeyError.
+
+ The section DEFAULT is never returned because it cannot be removed.
+ """
+ for key in self.sections():
+ value = self[key]
+ del self[key]
+ return key, value
+ raise KeyError
+
def optionxform(self, optionstr):
return optionstr.lower()
@@ -947,7 +959,8 @@
# XXX this is not atomic if read_dict fails at any point. Then again,
# no update method in configparser is atomic in this implementation.
- self.remove_section(key)
+ if key in self._sections:
+ self._sections[key].clear()
self.read_dict({key: value})
def __delitem__(self, key):
diff --git a/lib-python/3/ctypes/test/test_bitfields.py b/lib-python/3/ctypes/test/test_bitfields.py
--- a/lib-python/3/ctypes/test/test_bitfields.py
+++ b/lib-python/3/ctypes/test/test_bitfields.py
@@ -240,5 +240,25 @@
_anonymous_ = ["_"]
_fields_ = [("_", X)]
+ @unittest.skipUnless(hasattr(ctypes, "c_uint32"), "c_int32 is required")
+ def test_uint32(self):
+ class X(Structure):
+ _fields_ = [("a", c_uint32, 32)]
+ x = X()
+ x.a = 10
+ self.assertEqual(x.a, 10)
+ x.a = 0xFDCBA987
+ self.assertEqual(x.a, 0xFDCBA987)
+
+ @unittest.skipUnless(hasattr(ctypes, "c_uint64"), "c_int64 is required")
+ def test_uint64(self):
+ class X(Structure):
+ _fields_ = [("a", c_uint64, 64)]
+ x = X()
+ x.a = 10
+ self.assertEqual(x.a, 10)
+ x.a = 0xFEDCBA9876543211
+ self.assertEqual(x.a, 0xFEDCBA9876543211)
+
if __name__ == "__main__":
unittest.main()
diff --git a/lib-python/3/ctypes/test/test_numbers.py b/lib-python/3/ctypes/test/test_numbers.py
--- a/lib-python/3/ctypes/test/test_numbers.py
+++ b/lib-python/3/ctypes/test/test_numbers.py
@@ -217,6 +217,16 @@
# probably be changed:
self.assertRaises(TypeError, c_int, c_long(42))
+ def test_float_overflow(self):
+ import sys
+ big_int = int(sys.float_info.max) * 2
+ for t in float_types + [c_longdouble]:
+ self.assertRaises(OverflowError, t, big_int)
+ if (hasattr(t, "__ctype_be__")):
+ self.assertRaises(OverflowError, t.__ctype_be__, big_int)
+ if (hasattr(t, "__ctype_le__")):
+ self.assertRaises(OverflowError, t.__ctype_le__, big_int)
+
## def test_perf(self):
## check_perf()
diff --git a/lib-python/3/ctypes/test/test_returnfuncptrs.py b/lib-python/3/ctypes/test/test_returnfuncptrs.py
--- a/lib-python/3/ctypes/test/test_returnfuncptrs.py
+++ b/lib-python/3/ctypes/test/test_returnfuncptrs.py
@@ -1,5 +1,6 @@
import unittest
from ctypes import *
+import os
import _ctypes_test
@@ -33,5 +34,34 @@
self.assertRaises(ArgumentError, strchr, b"abcdef", 3.0)
self.assertRaises(TypeError, strchr, b"abcdef")
+ def test_from_dll(self):
+ dll = CDLL(_ctypes_test.__file__)
+ # _CFuncPtr instances are now callable with a tuple argument
+ # which denotes a function name and a dll:
+ strchr = CFUNCTYPE(c_char_p, c_char_p, c_char)(("my_strchr", dll))
+ self.assertTrue(strchr(b"abcdef", b"b"), "bcdef")
+ self.assertEqual(strchr(b"abcdef", b"x"), None)
+ self.assertRaises(ArgumentError, strchr, b"abcdef", 3.0)
+ self.assertRaises(TypeError, strchr, b"abcdef")
+
+ # Issue 6083: Reference counting bug
+ def test_from_dll_refcount(self):
+ class BadSequence(tuple):
+ def __getitem__(self, key):
+ if key == 0:
+ return "my_strchr"
+ if key == 1:
+ return CDLL(_ctypes_test.__file__)
+ raise IndexError
+
+ # _CFuncPtr instances are now callable with a tuple argument
+ # which denotes a function name and a dll:
+ strchr = CFUNCTYPE(c_char_p, c_char_p, c_char)(
+ BadSequence(("my_strchr", CDLL(_ctypes_test.__file__))))
+ self.assertTrue(strchr(b"abcdef", b"b"), "bcdef")
+ self.assertEqual(strchr(b"abcdef", b"x"), None)
+ self.assertRaises(ArgumentError, strchr, b"abcdef", 3.0)
+ self.assertRaises(TypeError, strchr, b"abcdef")
+
if __name__ == "__main__":
unittest.main()
diff --git a/lib-python/3/ctypes/test/test_structures.py b/lib-python/3/ctypes/test/test_structures.py
--- a/lib-python/3/ctypes/test/test_structures.py
+++ b/lib-python/3/ctypes/test/test_structures.py
@@ -1,6 +1,7 @@
import unittest
from ctypes import *
from struct import calcsize
+import _testcapi
class SubclassesTest(unittest.TestCase):
def test_subclass(self):
@@ -199,6 +200,14 @@
"_pack_": -1}
self.assertRaises(ValueError, type(Structure), "X", (Structure,), d)
+ # Issue 15989
+ d = {"_fields_": [("a", c_byte)],
+ "_pack_": _testcapi.INT_MAX + 1}
+ self.assertRaises(ValueError, type(Structure), "X", (Structure,), d)
+ d = {"_fields_": [("a", c_byte)],
+ "_pack_": _testcapi.UINT_MAX + 2}
+ self.assertRaises(ValueError, type(Structure), "X", (Structure,), d)
+
def test_initializers(self):
class Person(Structure):
_fields_ = [("name", c_char*6),
diff --git a/lib-python/3/ctypes/test/test_win32.py b/lib-python/3/ctypes/test/test_win32.py
--- a/lib-python/3/ctypes/test/test_win32.py
+++ b/lib-python/3/ctypes/test/test_win32.py
@@ -3,6 +3,7 @@
from ctypes import *
from ctypes.test import is_resource_enabled
import unittest, sys
+from test import support
import _ctypes_test
@@ -60,7 +61,9 @@
def test_COMError(self):
from _ctypes import COMError
- self.assertEqual(COMError.__doc__, "Raised when a COM method call failed.")
+ if support.HAVE_DOCSTRINGS:
+ self.assertEqual(COMError.__doc__,
+ "Raised when a COM method call failed.")
ex = COMError(-1, "text", ("details",))
self.assertEqual(ex.hresult, -1)
diff --git a/lib-python/3/curses/__init__.py b/lib-python/3/curses/__init__.py
--- a/lib-python/3/curses/__init__.py
+++ b/lib-python/3/curses/__init__.py
@@ -5,7 +5,7 @@
import curses
from curses import textpad
- curses.initwin()
+ curses.initscr()
...
"""
diff --git a/lib-python/3/datetime.py b/lib-python/3/datetime.py
--- a/lib-python/3/datetime.py
+++ b/lib-python/3/datetime.py
@@ -1821,6 +1821,8 @@
return (self._offset, self._name)
def __eq__(self, other):
+ if type(other) != timezone:
+ return False
return self._offset == other._offset
def __hash__(self):
diff --git a/lib-python/3/decimal.py b/lib-python/3/decimal.py
--- a/lib-python/3/decimal.py
+++ b/lib-python/3/decimal.py
@@ -1555,7 +1555,13 @@
def __float__(self):
"""Float representation."""
- return float(str(self))
+ if self._isnan():
+ if self.is_snan():
+ raise ValueError("Cannot convert signaling NaN to float")
+ s = "-nan" if self._sign else "nan"
+ else:
+ s = str(self)
+ return float(s)
def __int__(self):
"""Converts self to an int, truncating if necessary."""
diff --git a/lib-python/3/distutils/__init__.py b/lib-python/3/distutils/__init__.py
--- a/lib-python/3/distutils/__init__.py
+++ b/lib-python/3/distutils/__init__.py
@@ -13,5 +13,5 @@
# Updated automatically by the Python release process.
#
#--start constants--
-__version__ = "3.2.3"
+__version__ = "3.2.5"
#--end constants--
diff --git a/lib-python/3/distutils/command/bdist_rpm.py b/lib-python/3/distutils/command/bdist_rpm.py
--- a/lib-python/3/distutils/command/bdist_rpm.py
+++ b/lib-python/3/distutils/command/bdist_rpm.py
@@ -3,7 +3,7 @@
Implements the Distutils 'bdist_rpm' command (create RPM source and binary
distributions)."""
-import sys, os
+import subprocess, sys, os
from distutils.core import Command
from distutils.debug import DEBUG
from distutils.util import get_platform
@@ -190,7 +190,7 @@
if self.fix_python:
self.python = sys.executable
else:
- self.python = "python"
+ self.python = "python3"
elif self.fix_python:
raise DistutilsOptionError(
"--python and --fix-python are mutually exclusive options")
@@ -320,6 +320,7 @@
rpm_cmd.append('-bb')
else:
rpm_cmd.append('-ba')
+ rpm_cmd.extend(['--define', '__python %s' % self.python])
if self.rpm3_mode:
rpm_cmd.extend(['--define',
'_topdir %s' % os.path.abspath(self.rpm_base)])
@@ -405,6 +406,21 @@
'Summary: ' + self.distribution.get_description(),
]
+ # Workaround for #14443 which affects some RPM based systems such as
+ # RHEL6 (and probably derivatives)
+ vendor_hook = subprocess.getoutput('rpm --eval %{__os_install_post}')
+ # Generate a potential replacement value for __os_install_post (whilst
+ # normalizing the whitespace to simplify the test for whether the
+ # invocation of brp-python-bytecompile passes in __python):
+ vendor_hook = '\n'.join([' %s \\' % line.strip()
+ for line in vendor_hook.splitlines()])
+ problem = "brp-python-bytecompile \\\n"
+ fixed = "brp-python-bytecompile %{__python} \\\n"
+ fixed_hook = vendor_hook.replace(problem, fixed)
+ if fixed_hook != vendor_hook:
+ spec_file.append('# Workaround for http://bugs.python.org/issue14443')
+ spec_file.append('%define __os_install_post ' + fixed_hook + '\n')
+
# put locale summaries into spec file
# XXX not supported for now (hard to put a dictionary
# in a config file -- arg!)
diff --git a/lib-python/3/distutils/command/build_ext.py b/lib-python/3/distutils/command/build_ext.py
--- a/lib-python/3/distutils/command/build_ext.py
+++ b/lib-python/3/distutils/command/build_ext.py
@@ -667,10 +667,10 @@
if os.name == "os2":
ext_path[len(ext_path) - 1] = ext_path[len(ext_path) - 1][:8]
# extensions in debug_mode are named 'module_d.pyd' under windows
- so_ext = get_config_var('SO')
+ ext_suffix = get_config_var('EXT_SUFFIX')
if os.name == 'nt' and self.debug:
- return os.path.join(*ext_path) + '_d' + so_ext
- return os.path.join(*ext_path) + so_ext
+ return os.path.join(*ext_path) + '_d' + ext_suffix
+ return os.path.join(*ext_path) + ext_suffix
def get_export_symbols(self, ext):
"""Return the list of symbols that a shared extension has to
diff --git a/lib-python/3/distutils/command/check.py b/lib-python/3/distutils/command/check.py
--- a/lib-python/3/distutils/command/check.py
+++ b/lib-python/3/distutils/command/check.py
@@ -23,6 +23,9 @@
def system_message(self, level, message, *children, **kwargs):
self.messages.append((level, message, children, kwargs))
+ return nodes.system_message(message, level=level,
+ type=self.levels[level],
+ *children, **kwargs)
HAS_DOCUTILS = True
except Exception:
diff --git a/lib-python/3/distutils/command/install.py b/lib-python/3/distutils/command/install.py
--- a/lib-python/3/distutils/command/install.py
+++ b/lib-python/3/distutils/command/install.py
@@ -278,8 +278,8 @@
if self.user and (self.prefix or self.exec_prefix or self.home or
self.install_base or self.install_platbase):
- raise DistutilsOptionError("can't combine user with with prefix/"
- "exec_prefix/home or install_(plat)base")
+ raise DistutilsOptionError("can't combine user with prefix, "
+ "exec_prefix/home, or install_(plat)base")
# Next, stuff that's wrong (or dubious) only on certain platforms.
if os.name != "posix":
diff --git a/lib-python/3/distutils/command/upload.py b/lib-python/3/distutils/command/upload.py
--- a/lib-python/3/distutils/command/upload.py
+++ b/lib-python/3/distutils/command/upload.py
@@ -125,7 +125,7 @@
if self.sign:
data['gpg_signature'] = (os.path.basename(filename) + ".asc",
- open(filename+".asc").read())
+ open(filename+".asc", "rb").read())
# set up the authentication
user_pass = (self.username + ":" + self.password).encode('ascii')
diff --git a/lib-python/3/distutils/config.py b/lib-python/3/distutils/config.py
--- a/lib-python/3/distutils/config.py
+++ b/lib-python/3/distutils/config.py
@@ -4,7 +4,6 @@
that uses .pypirc in the distutils.command package.
"""
import os
-import sys
from configparser import ConfigParser
from distutils.cmd import Command
@@ -43,16 +42,8 @@
def _store_pypirc(self, username, password):
"""Creates a default .pypirc file."""
rc = self._get_rc_file()
- f = open(rc, 'w')
- try:
+ with os.fdopen(os.open(rc, os.O_CREAT | os.O_WRONLY, 0o600), 'w') as f:
f.write(DEFAULT_PYPIRC % (username, password))
- finally:
- f.close()
- try:
- os.chmod(rc, 0o600)
- except OSError:
- # should do something better here
- pass
def _read_pypirc(self):
"""Reads the .pypirc file."""
diff --git a/lib-python/3/distutils/dir_util.py b/lib-python/3/distutils/dir_util.py
--- a/lib-python/3/distutils/dir_util.py
+++ b/lib-python/3/distutils/dir_util.py
@@ -141,6 +141,10 @@
src_name = os.path.join(src, n)
dst_name = os.path.join(dst, n)
+ if n.startswith('.nfs'):
+ # skip NFS rename files
+ continue
+
if preserve_symlinks and os.path.islink(src_name):
link_dest = os.readlink(src_name)
if verbose >= 1:
diff --git a/lib-python/3/distutils/sysconfig.py b/lib-python/3/distutils/sysconfig.py
--- a/lib-python/3/distutils/sysconfig.py
+++ b/lib-python/3/distutils/sysconfig.py
@@ -146,7 +146,7 @@
"I don't know where Python installs its library "
"on platform '%s'" % os.name)
-_USE_CLANG = None
+
def customize_compiler(compiler):
"""Do any platform-specific customization of a CCompiler instance.
@@ -155,42 +155,28 @@
varies across Unices and is stored in Python's Makefile.
"""
if compiler.compiler_type == "unix":
- (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \
+ if sys.platform == "darwin":
+ # Perform first-time customization of compiler-related
+ # config vars on OS X now that we know we need a compiler.
+ # This is primarily to support Pythons from binary
+ # installers. The kind and paths to build tools on
+ # the user system may vary significantly from the system
+ # that Python itself was built on. Also the user OS
+ # version and build tools may not support the same set
+ # of CPU architectures for universal builds.
+ global _config_vars
+ if not _config_vars.get('CUSTOMIZED_OSX_COMPILER', ''):
+ import _osx_support
+ _osx_support.customize_compiler(_config_vars)
+ _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True'
+
+ (cc, cxx, opt, cflags, ccshared, ldshared, shlib_suffix, ar, ar_flags) = \
get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS',
- 'CCSHARED', 'LDSHARED', 'SO', 'AR', 'ARFLAGS')
+ 'CCSHARED', 'LDSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS')
newcc = None
if 'CC' in os.environ:
- newcc = os.environ['CC']
- elif sys.platform == 'darwin' and cc == 'gcc-4.2':
- # Issue #13590:
- # Since Apple removed gcc-4.2 in Xcode 4.2, we can no
- # longer assume it is available for extension module builds.
- # If Python was built with gcc-4.2, check first to see if
- # it is available on this system; if not, try to use clang
- # instead unless the caller explicitly set CC.
- global _USE_CLANG
- if _USE_CLANG is None:
- from distutils import log
- from subprocess import Popen, PIPE
- p = Popen("! type gcc-4.2 && type clang && exit 2",
- shell=True, stdout=PIPE, stderr=PIPE)
- p.wait()
- if p.returncode == 2:
- _USE_CLANG = True
- log.warn("gcc-4.2 not found, using clang instead")
- else:
- _USE_CLANG = False
- if _USE_CLANG:
- newcc = 'clang'
- if newcc:
- # On OS X, if CC is overridden, use that as the default
- # command for LDSHARED as well
- if (sys.platform == 'darwin'
- and 'LDSHARED' not in os.environ
- and ldshared.startswith(cc)):
- ldshared = newcc + ldshared[len(cc):]
- cc = newcc
+ cc = os.environ['CC']
if 'CXX' in os.environ:
cxx = os.environ['CXX']
if 'LDSHARED' in os.environ:
@@ -225,7 +211,7 @@
linker_exe=cc,
archiver=archiver)
- compiler.shared_lib_extension = so_ext
+ compiler.shared_lib_extension = shlib_suffix
def get_config_h_filename():
@@ -480,6 +466,7 @@
g['INCLUDEPY'] = get_python_inc(plat_specific=0)
g['SO'] = '.pyd'
+ g['EXT_SUFFIX'] = '.pyd'
g['EXE'] = ".exe"
g['VERSION'] = get_python_version().replace(".", "")
g['BINDIR'] = os.path.dirname(os.path.abspath(sys.executable))
@@ -499,6 +486,7 @@
g['INCLUDEPY'] = get_python_inc(plat_specific=0)
g['SO'] = '.pyd'
+ g['EXT_SUFFIX'] = '.pyd'
g['EXE'] = ".exe"
global _config_vars
@@ -543,43 +531,11 @@
srcdir = os.path.join(base, _config_vars['srcdir'])
_config_vars['srcdir'] = os.path.normpath(srcdir)
+ # OS X platforms require special customization to handle
+ # multi-architecture, multi-os-version installers
if sys.platform == 'darwin':
- kernel_version = os.uname()[2] # Kernel version (8.4.3)
- major_version = int(kernel_version.split('.')[0])
-
- if major_version < 8:
- # On Mac OS X before 10.4, check if -arch and -isysroot
- # are in CFLAGS or LDFLAGS and remove them if they are.
- # This is needed when building extensions on a 10.3 system
- # using a universal build of python.
- for key in ('LDFLAGS', 'BASECFLAGS',
- # a number of derived variables. These need to be
- # patched up as well.
- 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
- flags = _config_vars[key]
- flags = re.sub('-arch\s+\w+\s', ' ', flags, re.ASCII)
- flags = re.sub('-isysroot [^ \t]*', ' ', flags)
- _config_vars[key] = flags
-
- else:
-
- # Allow the user to override the architecture flags using
- # an environment variable.
- # NOTE: This name was introduced by Apple in OSX 10.5 and
- # is used by several scripting languages distributed with
- # that OS release.
-
- if 'ARCHFLAGS' in os.environ:
- arch = os.environ['ARCHFLAGS']
- for key in ('LDFLAGS', 'BASECFLAGS',
- # a number of derived variables. These need to be
- # patched up as well.
- 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'):
-
- flags = _config_vars[key]
- flags = re.sub('-arch\s+\w+\s', ' ', flags)
- flags = flags + ' ' + arch
- _config_vars[key] = flags
+ import _osx_support
+ _osx_support.customize_config_vars(_config_vars)
if args:
vals = []
diff --git a/lib-python/3/distutils/tests/test_bdist_dumb.py b/lib-python/3/distutils/tests/test_bdist_dumb.py
--- a/lib-python/3/distutils/tests/test_bdist_dumb.py
+++ b/lib-python/3/distutils/tests/test_bdist_dumb.py
@@ -88,9 +88,9 @@
fp.close()
contents = sorted(os.path.basename(fn) for fn in contents)
- wanted = ['foo-0.1-py%s.%s.egg-info' % sys.version_info[:2],
- 'foo.%s.pyc' % imp.get_tag(),
- 'foo.py']
+ wanted = ['foo-0.1-py%s.%s.egg-info' % sys.version_info[:2], 'foo.py']
+ if not sys.dont_write_bytecode:
+ wanted.append('foo.%s.pyc' % imp.get_tag())
self.assertEqual(contents, sorted(wanted))
def test_suite():
diff --git a/lib-python/3/distutils/tests/test_bdist_msi.py b/lib-python/3/distutils/tests/test_bdist_msi.py
--- a/lib-python/3/distutils/tests/test_bdist_msi.py
+++ b/lib-python/3/distutils/tests/test_bdist_msi.py
@@ -1,12 +1,11 @@
"""Tests for distutils.command.bdist_msi."""
+import sys
import unittest
-import sys
-
from test.support import run_unittest
-
from distutils.tests import support
- at unittest.skipUnless(sys.platform=="win32", "These tests are only for win32")
+
+ at unittest.skipUnless(sys.platform == 'win32', 'these tests require Windows')
class BDistMSITestCase(support.TempdirManager,
support.LoggingSilencer,
unittest.TestCase):
@@ -14,10 +13,11 @@
def test_minimal(self):
# minimal test XXX need more tests
from distutils.command.bdist_msi import bdist_msi
- pkg_pth, dist = self.create_dist()
+ project_dir, dist = self.create_dist()
cmd = bdist_msi(dist)
cmd.ensure_finalized()
+
def test_suite():
return unittest.makeSuite(BDistMSITestCase)
diff --git a/lib-python/3/distutils/tests/test_build_ext.py b/lib-python/3/distutils/tests/test_build_ext.py
--- a/lib-python/3/distutils/tests/test_build_ext.py
+++ b/lib-python/3/distutils/tests/test_build_ext.py
@@ -73,8 +73,9 @@
self.assertEqual(xx.foo(2, 5), 7)
self.assertEqual(xx.foo(13,15), 28)
self.assertEqual(xx.new().demo(), None)
- doc = 'This is a template module just for instruction.'
- self.assertEqual(xx.__doc__, doc)
+ if support.HAVE_DOCSTRINGS:
+ doc = 'This is a template module just for instruction.'
+ self.assertEqual(xx.__doc__, doc)
self.assertTrue(isinstance(xx.Null(), xx.Null))
self.assertTrue(isinstance(xx.Str(), xx.Str))
@@ -317,8 +318,8 @@
finally:
os.chdir(old_wd)
self.assertTrue(os.path.exists(so_file))
- so_ext = sysconfig.get_config_var('SO')
- self.assertTrue(so_file.endswith(so_ext))
+ ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
+ self.assertTrue(so_file.endswith(ext_suffix))
so_dir = os.path.dirname(so_file)
self.assertEqual(so_dir, other_tmp_dir)
@@ -327,7 +328,7 @@
cmd.run()
so_file = cmd.get_outputs()[0]
self.assertTrue(os.path.exists(so_file))
- self.assertTrue(so_file.endswith(so_ext))
+ self.assertTrue(so_file.endswith(ext_suffix))
so_dir = os.path.dirname(so_file)
self.assertEqual(so_dir, cmd.build_lib)
@@ -354,7 +355,7 @@
self.assertEqual(lastdir, 'bar')
def test_ext_fullpath(self):
- ext = sysconfig.get_config_vars()['SO']
+ ext = sysconfig.get_config_var('EXT_SUFFIX')
# building lxml.etree inplace
#etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c')
#etree_ext = Extension('lxml.etree', [etree_c])
diff --git a/lib-python/3/distutils/tests/test_dir_util.py b/lib-python/3/distutils/tests/test_dir_util.py
--- a/lib-python/3/distutils/tests/test_dir_util.py
+++ b/lib-python/3/distutils/tests/test_dir_util.py
@@ -76,7 +76,6 @@
remove_tree(self.root_target, verbose=0)
-
def test_copy_tree_verbosity(self):
mkpath(self.target, verbose=0)
@@ -88,11 +87,8 @@
mkpath(self.target, verbose=0)
a_file = os.path.join(self.target, 'ok.txt')
- f = open(a_file, 'w')
- try:
+ with open(a_file, 'w') as f:
f.write('some content')
- finally:
- f.close()
wanted = ['copying %s -> %s' % (a_file, self.target2)]
copy_tree(self.target, self.target2, verbose=1)
@@ -101,6 +97,21 @@
remove_tree(self.root_target, verbose=0)
remove_tree(self.target2, verbose=0)
+ def test_copy_tree_skips_nfs_temp_files(self):
+ mkpath(self.target, verbose=0)
+
+ a_file = os.path.join(self.target, 'ok.txt')
+ nfs_file = os.path.join(self.target, '.nfs123abc')
+ for f in a_file, nfs_file:
+ with open(f, 'w') as fh:
+ fh.write('some content')
+
+ copy_tree(self.target, self.target2)
+ self.assertEqual(os.listdir(self.target2), ['ok.txt'])
+
+ remove_tree(self.root_target, verbose=0)
+ remove_tree(self.target2, verbose=0)
+
def test_ensure_relative(self):
if os.sep == '/':
self.assertEqual(ensure_relative('/home/foo'), 'home/foo')
diff --git a/lib-python/3/distutils/tests/test_install.py b/lib-python/3/distutils/tests/test_install.py
--- a/lib-python/3/distutils/tests/test_install.py
+++ b/lib-python/3/distutils/tests/test_install.py
@@ -23,7 +23,7 @@
def _make_ext_name(modname):
if os.name == 'nt' and sys.executable.endswith('_d.exe'):
modname += '_d'
- return modname + sysconfig.get_config_var('SO')
+ return modname + sysconfig.get_config_var('EXT_SUFFIX')
class InstallTestCase(support.TempdirManager,
@@ -165,7 +165,7 @@
cmd.home = 'home'
self.assertRaises(DistutilsOptionError, cmd.finalize_options)
- # can't combine user with with prefix/exec_prefix/home or
+ # can't combine user with prefix/exec_prefix/home or
# install_(plat)base
cmd.prefix = None
cmd.user = 'user'
diff --git a/lib-python/3/distutils/tests/test_msvc9compiler.py b/lib-python/3/distutils/tests/test_msvc9compiler.py
--- a/lib-python/3/distutils/tests/test_msvc9compiler.py
+++ b/lib-python/3/distutils/tests/test_msvc9compiler.py
@@ -104,7 +104,7 @@
unittest.TestCase):
def test_no_compiler(self):
- # makes sure query_vcvarsall throws
+ # makes sure query_vcvarsall raises
# a DistutilsPlatformError if the compiler
# is not found
from distutils.msvc9compiler import query_vcvarsall
diff --git a/lib-python/3/distutils/tests/test_register.py b/lib-python/3/distutils/tests/test_register.py
--- a/lib-python/3/distutils/tests/test_register.py
+++ b/lib-python/3/distutils/tests/test_register.py
@@ -1,5 +1,4 @@
"""Tests for distutils.command.register."""
-import sys
import os
import unittest
import getpass
@@ -10,11 +9,14 @@
from distutils.command import register as register_module
from distutils.command.register import register
-from distutils.core import Distribution
from distutils.errors import DistutilsSetupError
-from distutils.tests import support
-from distutils.tests.test_config import PYPIRC, PyPIRCCommandTestCase
+from distutils.tests.test_config import PyPIRCCommandTestCase
+
+try:
+ import docutils
+except ImportError:
+ docutils = None
PYPIRC_NOPASSWORD = """\
[distutils]
@@ -193,6 +195,7 @@
self.assertEqual(headers['Content-length'], '290')
self.assertTrue((b'tarek') in req.data)
+ @unittest.skipUnless(docutils is not None, 'needs docutils')
def test_strict(self):
# testing the script option
# when on, the register command stops if
@@ -205,13 +208,6 @@
cmd.strict = 1
self.assertRaises(DistutilsSetupError, cmd.run)
- # we don't test the reSt feature if docutils
- # is not installed
- try:
- import docutils
- except ImportError:
- return
-
# metadata are OK but long_description is broken
metadata = {'url': 'xxx', 'author': 'xxx',
'author_email': 'éxéxé',
@@ -265,6 +261,22 @@
finally:
del register_module.input
+ @unittest.skipUnless(docutils is not None, 'needs docutils')
+ def test_register_invalid_long_description(self):
+ description = ':funkie:`str`' # mimic Sphinx-specific markup
+ metadata = {'url': 'xxx', 'author': 'xxx',
+ 'author_email': 'xxx',
+ 'name': 'xxx', 'version': 'xxx',
+ 'long_description': description}
+ cmd = self._get_cmd(metadata)
+ cmd.ensure_finalized()
+ cmd.strict = True
+ inputs = Inputs('2', 'tarek', 'tarek at ziade.org')
+ register_module.input = inputs
+ self.addCleanup(delattr, register_module, 'input')
+
+ self.assertRaises(DistutilsSetupError, cmd.run)
+
def test_check_metadata_deprecated(self):
# makes sure make_metadata is deprecated
cmd = self._get_cmd()
diff --git a/lib-python/3/distutils/tests/test_sdist.py b/lib-python/3/distutils/tests/test_sdist.py
--- a/lib-python/3/distutils/tests/test_sdist.py
+++ b/lib-python/3/distutils/tests/test_sdist.py
@@ -6,6 +6,7 @@
import zipfile
from os.path import join
from textwrap import dedent
+from test.support import captured_stdout, check_warnings, run_unittest
try:
import zlib
@@ -13,7 +14,6 @@
except ImportError:
ZLIB_SUPPORT = False
-from test.support import captured_stdout, check_warnings, run_unittest
from distutils.command.sdist import sdist, show_formats
from distutils.core import Distribution
@@ -83,9 +83,8 @@
@unittest.skipUnless(ZLIB_SUPPORT, 'Need zlib support to run')
def test_prune_file_list(self):
- # this test creates a package with some vcs dirs in it
- # and launch sdist to make sure they get pruned
- # on all systems
+ # this test creates a project with some VCS dirs and an NFS rename
+ # file, then launches sdist to check they get pruned on all systems
# creating VCS directories with some files in them
os.mkdir(join(self.tmp_dir, 'somecode', '.svn'))
@@ -99,6 +98,8 @@
self.write_file((self.tmp_dir, 'somecode', '.git',
'ok'), 'xxx')
+ self.write_file((self.tmp_dir, 'somecode', '.nfs0001'), 'xxx')
+
# now building a sdist
dist, cmd = self.get_cmd()
@@ -326,6 +327,7 @@
# filling data_files by pointing files in package_data
dist.package_data = {'somecode': ['*.txt']}
self.write_file((self.tmp_dir, 'somecode', 'doc.txt'), '#')
+ cmd.formats = ['gztar']
cmd.ensure_finalized()
cmd.run()
diff --git a/lib-python/3/distutils/tests/test_sysconfig.py b/lib-python/3/distutils/tests/test_sysconfig.py
--- a/lib-python/3/distutils/tests/test_sysconfig.py
+++ b/lib-python/3/distutils/tests/test_sysconfig.py
@@ -102,7 +102,27 @@
import sysconfig as global_sysconfig
self.assertEqual(global_sysconfig.get_config_var('CFLAGS'), sysconfig.get_config_var('CFLAGS'))
self.assertEqual(global_sysconfig.get_config_var('LDFLAGS'), sysconfig.get_config_var('LDFLAGS'))
- self.assertEqual(global_sysconfig.get_config_var('LDSHARED'),sysconfig.get_config_var('LDSHARED'))
+
+ @unittest.skipIf(sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'),'compiler flags customized')
+ def test_sysconfig_compiler_vars(self):
+ # On OS X, binary installers support extension module building on
+ # various levels of the operating system with differing Xcode
+ # configurations. This requires customization of some of the
+ # compiler configuration directives to suit the environment on
+ # the installed machine. Some of these customizations may require
+ # running external programs and, so, are deferred until needed by
+ # the first extension module build. With Python 3.3, only
+ # the Distutils version of sysconfig is used for extension module
+ # builds, which happens earlier in the Distutils tests. This may
+ # cause the following tests to fail since no tests have caused
+ # the global version of sysconfig to call the customization yet.
+ # The solution for now is to simply skip this test in this case.
+ # The longer-term solution is to only have one version of sysconfig.
+
+ import sysconfig as global_sysconfig
+ if sysconfig.get_config_var('CUSTOMIZED_OSX_COMPILER'):
+ return
+ self.assertEqual(global_sysconfig.get_config_var('LDSHARED'), sysconfig.get_config_var('LDSHARED'))
self.assertEqual(global_sysconfig.get_config_var('CC'), sysconfig.get_config_var('CC'))
diff --git a/lib-python/3/distutils/tests/test_util.py b/lib-python/3/distutils/tests/test_util.py
--- a/lib-python/3/distutils/tests/test_util.py
+++ b/lib-python/3/distutils/tests/test_util.py
@@ -13,6 +13,7 @@
from distutils.sysconfig import get_config_vars
from distutils import sysconfig
from distutils.tests import support
+import _osx_support
class UtilTestCase(support.EnvironGuard, unittest.TestCase):
@@ -92,6 +93,7 @@
('Darwin Kernel Version 8.11.1: '
'Wed Oct 10 18:23:28 PDT 2007; '
'root:xnu-792.25.20~1/RELEASE_I386'), 'i386'))
+ _osx_support._remove_original_values(get_config_vars())
get_config_vars()['MACOSX_DEPLOYMENT_TARGET'] = '10.3'
get_config_vars()['CFLAGS'] = ('-fno-strict-aliasing -DNDEBUG -g '
@@ -105,6 +107,7 @@
sys.maxsize = cursize
More information about the pypy-commit
mailing list