[pypy-commit] pypy py3.6: Update the stdlib (merge branch vendor/stdlib-3.6)

rlamy pypy.commits at gmail.com
Thu Jul 13 10:50:02 EDT 2017


Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch: py3.6
Changeset: r91866:7b7912136af7
Date: 2017-07-13 16:48 +0200
http://bitbucket.org/pypy/pypy/changeset/7b7912136af7/

Log:	Update the stdlib (merge branch vendor/stdlib-3.6)

diff too long, truncating to 2000 out of 7633 lines

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
@@ -277,7 +277,7 @@
 try:
     UnsupportedOperation = io.UnsupportedOperation
 except AttributeError:
-    class UnsupportedOperation(ValueError, OSError):
+    class UnsupportedOperation(OSError, ValueError):
         pass
 
 
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
@@ -303,6 +303,8 @@
     # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk
     # _framesize -- size of one frame in the file
 
+    _file = None  # Set here since __del__ checks it
+
     def initfp(self, file):
         self._version = 0
         self._convert = None
@@ -344,9 +346,15 @@
 
     def __init__(self, f):
         if isinstance(f, str):
-            f = builtins.open(f, 'rb')
-        # else, assume it is an open file object already
-        self.initfp(f)
+            file_object = builtins.open(f, 'rb')
+            try:
+                self.initfp(file_object)
+            except:
+                file_object.close()
+                raise
+        else:
+            # assume it is an open file object already
+            self.initfp(f)
 
     def __enter__(self):
         return self
@@ -541,18 +549,23 @@
     # _datalength -- the size of the audio samples written to the header
     # _datawritten -- the size of the audio samples actually written
 
+    _file = None  # Set here since __del__ checks it
+
     def __init__(self, f):
         if isinstance(f, str):
-            filename = f
-            f = builtins.open(f, 'wb')
+            file_object = builtins.open(f, 'wb')
+            try:
+                self.initfp(file_object)
+            except:
+                file_object.close()
+                raise
+
+            # treat .aiff file extensions as non-compressed audio
+            if f.endswith('.aiff'):
+                self._aifc = 0
         else:
-            # else, assume it is an open file object already
-            filename = '???'
-        self.initfp(f)
-        if filename[-5:] == '.aiff':
-            self._aifc = 0
-        else:
-            self._aifc = 1
+            # assume it is an open file object already
+            self.initfp(f)
 
     def initfp(self, file):
         self._file = file
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
@@ -182,7 +182,7 @@
         self._root_section = self._Section(self, None)
         self._current_section = self._root_section
 
-        self._whitespace_matcher = _re.compile(r'\s+')
+        self._whitespace_matcher = _re.compile(r'\s+', _re.ASCII)
         self._long_break_matcher = _re.compile(r'\n\n\n+')
 
     # ===============================
diff --git a/lib-python/3/asyncio/events.py b/lib-python/3/asyncio/events.py
--- a/lib-python/3/asyncio/events.py
+++ b/lib-python/3/asyncio/events.py
@@ -11,6 +11,7 @@
 
 import functools
 import inspect
+import os
 import reprlib
 import socket
 import subprocess
@@ -611,6 +612,9 @@
 # A TLS for the running event loop, used by _get_running_loop.
 class _RunningLoop(threading.local):
     _loop = None
+    _pid = None
+
+
 _running_loop = _RunningLoop()
 
 
@@ -620,7 +624,9 @@
     This is a low-level function intended to be used by event loops.
     This function is thread-specific.
     """
-    return _running_loop._loop
+    running_loop = _running_loop._loop
+    if running_loop is not None and _running_loop._pid == os.getpid():
+        return running_loop
 
 
 def _set_running_loop(loop):
@@ -629,6 +635,7 @@
     This is a low-level function intended to be used by event loops.
     This function is thread-specific.
     """
+    _running_loop._pid = os.getpid()
     _running_loop._loop = loop
 
 
diff --git a/lib-python/3/asyncio/subprocess.py b/lib-python/3/asyncio/subprocess.py
--- a/lib-python/3/asyncio/subprocess.py
+++ b/lib-python/3/asyncio/subprocess.py
@@ -24,6 +24,8 @@
         self._limit = limit
         self.stdin = self.stdout = self.stderr = None
         self._transport = None
+        self._process_exited = False
+        self._pipe_fds = []
 
     def __repr__(self):
         info = [self.__class__.__name__]
@@ -43,12 +45,14 @@
             self.stdout = streams.StreamReader(limit=self._limit,
                                                loop=self._loop)
             self.stdout.set_transport(stdout_transport)
+            self._pipe_fds.append(1)
 
         stderr_transport = transport.get_pipe_transport(2)
         if stderr_transport is not None:
             self.stderr = streams.StreamReader(limit=self._limit,
                                                loop=self._loop)
             self.stderr.set_transport(stderr_transport)
+            self._pipe_fds.append(2)
 
         stdin_transport = transport.get_pipe_transport(0)
         if stdin_transport is not None:
@@ -86,9 +90,18 @@
             else:
                 reader.set_exception(exc)
 
+        if fd in self._pipe_fds:
+            self._pipe_fds.remove(fd)
+        self._maybe_close_transport()
+
     def process_exited(self):
-        self._transport.close()
-        self._transport = None
+        self._process_exited = True
+        self._maybe_close_transport()
+
+    def _maybe_close_transport(self):
+        if len(self._pipe_fds) == 0 and self._process_exited:
+            self._transport.close()
+            self._transport = None
 
 
 class Process:
diff --git a/lib-python/3/asyncio/tasks.py b/lib-python/3/asyncio/tasks.py
--- a/lib-python/3/asyncio/tasks.py
+++ b/lib-python/3/asyncio/tasks.py
@@ -487,7 +487,8 @@
     """
 
     warnings.warn("asyncio.async() function is deprecated, use ensure_future()",
-                  DeprecationWarning)
+                  DeprecationWarning,
+                  stacklevel=2)
 
     return ensure_future(coro_or_future, loop=loop)
 
diff --git a/lib-python/3/asyncio/test_utils.py b/lib-python/3/asyncio/test_utils.py
--- a/lib-python/3/asyncio/test_utils.py
+++ b/lib-python/3/asyncio/test_utils.py
@@ -449,12 +449,15 @@
         self.set_event_loop(loop)
         return loop
 
+    def unpatch_get_running_loop(self):
+        events._get_running_loop = self._get_running_loop
+
     def setUp(self):
         self._get_running_loop = events._get_running_loop
         events._get_running_loop = lambda: None
 
     def tearDown(self):
-        events._get_running_loop = self._get_running_loop
+        self.unpatch_get_running_loop()
 
         events.set_event_loop(None)
 
diff --git a/lib-python/3/base64.py b/lib-python/3/base64.py
--- a/lib-python/3/base64.py
+++ b/lib-python/3/base64.py
@@ -541,7 +541,8 @@
 def encodestring(s):
     """Legacy alias of encodebytes()."""
     import warnings
-    warnings.warn("encodestring() is a deprecated alias, use encodebytes()",
+    warnings.warn("encodestring() is a deprecated alias since 3.1, "
+                  "use encodebytes()",
                   DeprecationWarning, 2)
     return encodebytes(s)
 
@@ -554,7 +555,8 @@
 def decodestring(s):
     """Legacy alias of decodebytes()."""
     import warnings
-    warnings.warn("decodestring() is a deprecated alias, use decodebytes()",
+    warnings.warn("decodestring() is a deprecated alias since Python 3.1, "
+                  "use decodebytes()",
                   DeprecationWarning, 2)
     return decodebytes(s)
 
diff --git a/lib-python/3/collections/__init__.py b/lib-python/3/collections/__init__.py
--- a/lib-python/3/collections/__init__.py
+++ b/lib-python/3/collections/__init__.py
@@ -189,6 +189,7 @@
         link = self.__map[key]
         link_prev = link.prev
         link_next = link.next
+        soft_link = link_next.prev
         link_prev.next = link_next
         link_next.prev = link_prev
         root = self.__root
@@ -196,12 +197,14 @@
             last = root.prev
             link.prev = last
             link.next = root
-            last.next = root.prev = link
+            root.prev = soft_link
+            last.next = link
         else:
             first = root.next
             link.prev = root
             link.next = first
-            root.next = first.prev = link
+            first.prev = soft_link
+            root.next = link
 
     def __sizeof__(self):
         sizeof = _sys.getsizeof
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
@@ -143,6 +143,7 @@
 import functools
 import io
 import itertools
+import os
 import re
 import sys
 import warnings
@@ -687,7 +688,7 @@
 
         Return list of successfully read files.
         """
-        if isinstance(filenames, str):
+        if isinstance(filenames, (str, os.PathLike)):
             filenames = [filenames]
         read_ok = []
         for filename in filenames:
@@ -696,6 +697,8 @@
                     self._read(fp, filename)
             except OSError:
                 continue
+            if isinstance(filename, os.PathLike):
+                filename = os.fspath(filename)
             read_ok.append(filename)
         return read_ok
 
diff --git a/lib-python/3/contextlib.py b/lib-python/3/contextlib.py
--- a/lib-python/3/contextlib.py
+++ b/lib-python/3/contextlib.py
@@ -105,7 +105,7 @@
                 # raised inside the "with" statement from being suppressed.
                 return exc is not value
             except RuntimeError as exc:
-                # Don't re-raise the passed in exception. (issue27112)
+                # Don't re-raise the passed in exception. (issue27122)
                 if exc is value:
                     return False
                 # Likewise, avoid suppressing if a StopIteration exception
diff --git a/lib-python/3/ctypes/__init__.py b/lib-python/3/ctypes/__init__.py
--- a/lib-python/3/ctypes/__init__.py
+++ b/lib-python/3/ctypes/__init__.py
@@ -325,6 +325,10 @@
     """
     _func_flags_ = _FUNCFLAG_CDECL
     _func_restype_ = c_int
+    # default values for repr
+    _name = '<uninitialized>'
+    _handle = 0
+    _FuncPtr = None
 
     def __init__(self, name, mode=DEFAULT_MODE, handle=None,
                  use_errno=False,
diff --git a/lib-python/3/ctypes/test/test_callbacks.py b/lib-python/3/ctypes/test/test_callbacks.py
--- a/lib-python/3/ctypes/test/test_callbacks.py
+++ b/lib-python/3/ctypes/test/test_callbacks.py
@@ -246,6 +246,7 @@
     def test_callback_large_struct(self):
         class Check: pass
 
+        # This should mirror the structure in Modules/_ctypes/_ctypes_test.c
         class X(Structure):
             _fields_ = [
                 ('first', c_ulong),
@@ -257,6 +258,11 @@
             check.first = s.first
             check.second = s.second
             check.third = s.third
+            # See issue #29565.
+            # The structure should be passed by value, so
+            # any changes to it should not be reflected in
+            # the value passed
+            s.first = s.second = s.third = 0x0badf00d
 
         check = Check()
         s = X()
@@ -277,6 +283,11 @@
         self.assertEqual(check.first, 0xdeadbeef)
         self.assertEqual(check.second, 0xcafebabe)
         self.assertEqual(check.third, 0x0bad1dea)
+        # See issue #29565.
+        # Ensure that the original struct is unchanged.
+        self.assertEqual(s.first, check.first)
+        self.assertEqual(s.second, check.second)
+        self.assertEqual(s.third, check.third)
 
 ################################################################
 
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
@@ -3,6 +3,7 @@
 from ctypes.test import need_symbol
 from struct import calcsize
 import _testcapi
+import _ctypes_test
 
 class SubclassesTest(unittest.TestCase):
     def test_subclass(self):
@@ -391,6 +392,28 @@
                          (1, 0, 0, 0, 0, 0))
         self.assertRaises(TypeError, lambda: Z(1, 2, 3, 4, 5, 6, 7))
 
+    def test_pass_by_value(self):
+        # This should mirror the structure in Modules/_ctypes/_ctypes_test.c
+        class X(Structure):
+            _fields_ = [
+                ('first', c_ulong),
+                ('second', c_ulong),
+                ('third', c_ulong),
+            ]
+
+        s = X()
+        s.first = 0xdeadbeef
+        s.second = 0xcafebabe
+        s.third = 0x0bad1dea
+        dll = CDLL(_ctypes_test.__file__)
+        func = dll._testfunc_large_struct_update_value
+        func.argtypes = (X,)
+        func.restype = None
+        func(s)
+        self.assertEqual(s.first, 0xdeadbeef)
+        self.assertEqual(s.second, 0xcafebabe)
+        self.assertEqual(s.third, 0x0bad1dea)
+
 class PointerMemberTestCase(unittest.TestCase):
 
     def test(self):
diff --git a/lib-python/3/curses/ascii.py b/lib-python/3/curses/ascii.py
--- a/lib-python/3/curses/ascii.py
+++ b/lib-python/3/curses/ascii.py
@@ -53,19 +53,19 @@
 
 def isalnum(c): return isalpha(c) or isdigit(c)
 def isalpha(c): return isupper(c) or islower(c)
-def isascii(c): return _ctoi(c) <= 127          # ?
+def isascii(c): return 0 <= _ctoi(c) <= 127          # ?
 def isblank(c): return _ctoi(c) in (9, 32)
-def iscntrl(c): return _ctoi(c) <= 31 or _ctoi(c) == 127
-def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57
-def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126
-def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122
-def isprint(c): return _ctoi(c) >= 32 and _ctoi(c) <= 126
+def iscntrl(c): return 0 <= _ctoi(c) <= 31 or _ctoi(c) == 127
+def isdigit(c): return 48 <= _ctoi(c) <= 57
+def isgraph(c): return 33 <= _ctoi(c) <= 126
+def islower(c): return 97 <= _ctoi(c) <= 122
+def isprint(c): return 32 <= _ctoi(c) <= 126
 def ispunct(c): return isgraph(c) and not isalnum(c)
 def isspace(c): return _ctoi(c) in (9, 10, 11, 12, 13, 32)
-def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90
+def isupper(c): return 65 <= _ctoi(c) <= 90
 def isxdigit(c): return isdigit(c) or \
-    (_ctoi(c) >= 65 and _ctoi(c) <= 70) or (_ctoi(c) >= 97 and _ctoi(c) <= 102)
-def isctrl(c): return _ctoi(c) < 32
+    (65 <= _ctoi(c) <= 70) or (97 <= _ctoi(c) <= 102)
+def isctrl(c): return 0 <= _ctoi(c) < 32
 def ismeta(c): return _ctoi(c) > 127
 
 def ascii(c):
diff --git a/lib-python/3/curses/textpad.py b/lib-python/3/curses/textpad.py
--- a/lib-python/3/curses/textpad.py
+++ b/lib-python/3/curses/textpad.py
@@ -43,16 +43,20 @@
     def __init__(self, win, insert_mode=False):
         self.win = win
         self.insert_mode = insert_mode
-        (self.maxy, self.maxx) = win.getmaxyx()
-        self.maxy = self.maxy - 1
-        self.maxx = self.maxx - 1
+        self._update_max_yx()
         self.stripspaces = 1
         self.lastcmd = None
         win.keypad(1)
 
+    def _update_max_yx(self):
+        maxy, maxx = self.win.getmaxyx()
+        self.maxy = maxy - 1
+        self.maxx = maxx - 1
+
     def _end_of_line(self, y):
         """Go to the location of the first blank on the given line,
         returning the index of the last non-blank character."""
+        self._update_max_yx()
         last = self.maxx
         while True:
             if curses.ascii.ascii(self.win.inch(y, last)) != curses.ascii.SP:
@@ -64,8 +68,10 @@
         return last
 
     def _insert_printable_char(self, ch):
+        self._update_max_yx()
         (y, x) = self.win.getyx()
-        if y < self.maxy or x < self.maxx:
+        backyx = None
+        while y < self.maxy or x < self.maxx:
             if self.insert_mode:
                 oldch = self.win.inch()
             # The try-catch ignores the error we trigger from some curses
@@ -75,14 +81,20 @@
                 self.win.addch(ch)
             except curses.error:
                 pass
-            if self.insert_mode:
-                (backy, backx) = self.win.getyx()
-                if curses.ascii.isprint(oldch):
-                    self._insert_printable_char(oldch)
-                    self.win.move(backy, backx)
+            if not self.insert_mode or not curses.ascii.isprint(oldch):
+                break
+            ch = oldch
+            (y, x) = self.win.getyx()
+            # Remember where to put the cursor back since we are in insert_mode
+            if backyx is None:
+                backyx = y, x
+
+        if backyx is not None:
+            self.win.move(*backyx)
 
     def do_command(self, ch):
         "Process a single editing command."
+        self._update_max_yx()
         (y, x) = self.win.getyx()
         self.lastcmd = ch
         if curses.ascii.isprint(ch):
@@ -148,6 +160,7 @@
     def gather(self):
         "Collect and return the contents of the window."
         result = ""
+        self._update_max_yx()
         for y in range(self.maxy+1):
             self.win.move(y, 0)
             stop = self._end_of_line(y)
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
@@ -1053,7 +1053,7 @@
         hour, minute (required)
         second, microsecond (default to zero)
         tzinfo (default to None)
-        fold (keyword only, default to True)
+        fold (keyword only, default to zero)
         """
         if isinstance(hour, bytes) and len(hour) == 6 and hour[0]&0x7F < 24:
             # Pickle support
diff --git a/lib-python/3/dbm/dumb.py b/lib-python/3/dbm/dumb.py
--- a/lib-python/3/dbm/dumb.py
+++ b/lib-python/3/dbm/dumb.py
@@ -97,8 +97,9 @@
         try:
             f = _io.open(self._dirfile, 'r', encoding="Latin-1")
         except OSError:
-            pass
+            self._modified = not self._readonly
         else:
+            self._modified = False
             with f:
                 for line in f:
                     line = line.rstrip()
@@ -113,7 +114,7 @@
         # CAUTION:  It's vital that _commit() succeed, and _commit() can
         # be called from __del__().  Therefore we must never reference a
         # global in this routine.
-        if self._index is None:
+        if self._index is None or not self._modified:
             return  # nothing to do
 
         try:
@@ -197,6 +198,7 @@
         elif not isinstance(val, (bytes, bytearray)):
             raise TypeError("values must be bytes or strings")
         self._verify_open()
+        self._modified = True
         if key not in self._index:
             self._addkey(key, self._addval(val))
         else:
@@ -229,6 +231,7 @@
         if isinstance(key, str):
             key = key.encode('utf-8')
         self._verify_open()
+        self._modified = True
         # The blocks used by the associated value are lost.
         del self._index[key]
         # XXX It's unclear why we do a _commit() here (the code always
diff --git a/lib-python/3/distutils/command/wininst-14.0-amd64.exe b/lib-python/3/distutils/command/wininst-14.0-amd64.exe
index 22299543a97ffc1525a3b1c778cb158d6c6430ad..253c2e2eccefa79393827f44f85680536906574a
GIT binary patch

[cut]

diff --git a/lib-python/3/distutils/command/wininst-14.0.exe b/lib-python/3/distutils/command/wininst-14.0.exe
index 0dac1103d98db0af1e9027c41fe921136c5f6396..46f5f356676c800f99742deb6bf4c0a96aa166c0
GIT binary patch

[cut]

diff --git a/lib-python/3/distutils/tests/test_bdist_rpm.py b/lib-python/3/distutils/tests/test_bdist_rpm.py
--- a/lib-python/3/distutils/tests/test_bdist_rpm.py
+++ b/lib-python/3/distutils/tests/test_bdist_rpm.py
@@ -94,7 +94,7 @@
     @unittest.skipIf(find_executable('rpmbuild') is None,
                      'the rpmbuild command is not found')
     def test_no_optimize_flag(self):
-        # let's create a package that brakes bdist_rpm
+        # let's create a package that breaks bdist_rpm
         tmp_dir = self.mkdtemp()
         os.environ['HOME'] = tmp_dir   # to confine dir '.rpmdb' creation
         pkg_dir = os.path.join(tmp_dir, 'foo')
diff --git a/lib-python/3/enum.py b/lib-python/3/enum.py
--- a/lib-python/3/enum.py
+++ b/lib-python/3/enum.py
@@ -1,7 +1,7 @@
 import sys
 from types import MappingProxyType, DynamicClassAttribute
 from functools import reduce
-from operator import or_ as _or_, and_ as _and_, xor, neg
+from operator import or_ as _or_
 
 # try _collections first to reduce startup cost
 try:
@@ -690,7 +690,9 @@
             pseudo_member = object.__new__(cls)
             pseudo_member._name_ = None
             pseudo_member._value_ = value
-            cls._value2member_map_[value] = pseudo_member
+            # use setdefault in case another thread already created a composite
+            # with this value
+            pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
         return pseudo_member
 
     def __contains__(self, other):
@@ -785,7 +787,9 @@
                 pseudo_member = int.__new__(cls, value)
                 pseudo_member._name_ = None
                 pseudo_member._value_ = value
-                cls._value2member_map_[value] = pseudo_member
+                # use setdefault in case another thread already created a composite
+                # with this value
+                pseudo_member = cls._value2member_map_.setdefault(value, pseudo_member)
         return pseudo_member
 
     def __or__(self, other):
@@ -835,18 +839,21 @@
     # _decompose is only called if the value is not named
     not_covered = value
     negative = value < 0
+    # issue29167: wrap accesses to _value2member_map_ in a list to avoid race
+    #             conditions between iterating over it and having more psuedo-
+    #             members added to it
     if negative:
         # only check for named flags
         flags_to_check = [
                 (m, v)
-                for v, m in flag._value2member_map_.items()
+                for v, m in list(flag._value2member_map_.items())
                 if m.name is not None
                 ]
     else:
         # check for named flags and powers-of-two flags
         flags_to_check = [
                 (m, v)
-                for v, m in flag._value2member_map_.items()
+                for v, m in list(flag._value2member_map_.items())
                 if m.name is not None or _power_of_two(v)
                 ]
     members = []
diff --git a/lib-python/3/functools.py b/lib-python/3/functools.py
--- a/lib-python/3/functools.py
+++ b/lib-python/3/functools.py
@@ -421,7 +421,7 @@
 def _make_key(args, kwds, typed,
              kwd_mark = (object(),),
              fasttypes = {int, str, frozenset, type(None)},
-             sorted=sorted, tuple=tuple, type=type, len=len):
+             tuple=tuple, type=type, len=len):
     """Make a cache key from optionally typed positional and keyword arguments
 
     The key is constructed in a way that is flat as possible rather than
@@ -434,14 +434,13 @@
     """
     key = args
     if kwds:
-        sorted_items = sorted(kwds.items())
         key += kwd_mark
-        for item in sorted_items:
+        for item in kwds.items():
             key += item
     if typed:
         key += tuple(type(v) for v in args)
         if kwds:
-            key += tuple(type(v) for k, v in sorted_items)
+            key += tuple(type(v) for v in kwds.values())
     elif len(key) == 1 and type(key[0]) in fasttypes:
         return key[0]
     return _HashedSeq(key)
@@ -493,6 +492,7 @@
     hits = misses = 0
     full = False
     cache_get = cache.get    # bound method to lookup a key or return None
+    cache_len = cache.__len__  # get cache size without calling len()
     lock = RLock()           # because linkedlist updates aren't threadsafe
     root = []                # root of the circular doubly linked list
     root[:] = [root, root, None, None]     # initialize by pointing to self
@@ -574,14 +574,16 @@
                     last = root[PREV]
                     link = [last, root, key, result]
                     last[NEXT] = root[PREV] = cache[key] = link
-                    full = (len(cache) >= maxsize)
+                    # Use the cache_len bound method instead of the len() function
+                    # which could potentially be wrapped in an lru_cache itself.
+                    full = (cache_len() >= maxsize)
                 misses += 1
             return result
 
     def cache_info():
         """Report cache statistics"""
         with lock:
-            return _CacheInfo(hits, misses, maxsize, len(cache))
+            return _CacheInfo(hits, misses, maxsize, cache_len())
 
     def cache_clear():
         """Clear the cache and cache statistics"""
diff --git a/lib-python/3/getpass.py b/lib-python/3/getpass.py
--- a/lib-python/3/getpass.py
+++ b/lib-python/3/getpass.py
@@ -7,7 +7,6 @@
                  echoing of the password contents while reading.
 
 On Windows, the msvcrt module will be used.
-On the Mac EasyDialogs.AskPassword is used, if available.
 
 """
 
diff --git a/lib-python/3/idlelib/colorizer.py b/lib-python/3/idlelib/colorizer.py
--- a/lib-python/3/idlelib/colorizer.py
+++ b/lib-python/3/idlelib/colorizer.py
@@ -21,7 +21,7 @@
     # 1st 'file' colorized normal, 2nd as builtin, 3rd as string
     builtin = r"([^.'\"\\#]\b|^)" + any("BUILTIN", builtinlist) + r"\b"
     comment = any("COMMENT", [r"#[^\n]*"])
-    stringprefix = r"(\br|u|ur|R|U|UR|Ur|uR|b|B|br|Br|bR|BR|rb|rB|Rb|RB)?"
+    stringprefix = r"(?i:\br|u|f|fr|rf|b|br|rb)?"
     sqstring = stringprefix + r"'[^'\\\n]*(\\.[^'\\\n]*)*'?"
     dqstring = stringprefix + r'"[^"\\\n]*(\\.[^"\\\n]*)*"?'
     sq3string = stringprefix + r"'''[^'\\]*((\\.|'(?!''))[^'\\]*)*(''')?"
@@ -261,8 +261,15 @@
     top = Toplevel(parent)
     top.title("Test ColorDelegator")
     x, y = map(int, parent.geometry().split('+')[1:])
-    top.geometry("200x100+%d+%d" % (x + 250, y + 175))
-    source = "if somename: x = 'abc' # comment\nprint\n"
+    top.geometry("700x250+%d+%d" % (x + 20, y + 175))
+    source = ("# Following has syntax errors\n"
+        "if True: then int 1\nelif False: print 0\nelse: float(None)\n"
+        "if iF + If + IF: 'keywork matching must respect case'\n"
+        "# All valid prefixes for unicode and byte strings should be colored\n"
+        "'x', '''x''', \"x\", \"\"\"x\"\"\"\n"
+        "r'x', u'x', R'x', U'x', f'x', F'x', ur'is invalid'\n"
+        "fr'x', Fr'x', fR'x', FR'x', rf'x', rF'x', Rf'x', RF'x'\n"
+        "b'x',B'x', br'x',Br'x',bR'x',BR'x', rb'x'.rB'x',Rb'x',RB'x'\n")
     text = Text(top, background="white")
     text.pack(expand=1, fill="both")
     text.insert("insert", source)
diff --git a/lib-python/3/idlelib/help.html b/lib-python/3/idlelib/help.html
--- a/lib-python/3/idlelib/help.html
+++ b/lib-python/3/idlelib/help.html
@@ -90,7 +90,7 @@
 
   <div class="section" id="idle">
 <span id="id1"></span><h1>25.5. IDLE<a class="headerlink" href="#idle" title="Permalink to this headline">¶</a></h1>
-<p><strong>Source code:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/idlelib/">Lib/idlelib/</a></p>
+<p><strong>Source code:</strong> <a class="reference external" href="https://github.com/python/cpython/tree/3.5/Lib/idlelib">Lib/idlelib/</a></p>
 <hr class="docutils" id="index-0" />
 <p>IDLE is Python’s Integrated Development and Learning Environment.</p>
 <p>IDLE has the following features:</p>
diff --git a/lib-python/3/imaplib.py b/lib-python/3/imaplib.py
--- a/lib-python/3/imaplib.py
+++ b/lib-python/3/imaplib.py
@@ -419,7 +419,7 @@
         self.literal = _Authenticator(authobject).process
         typ, dat = self._simple_command('AUTHENTICATE', mech)
         if typ != 'OK':
-            raise self.error(dat[-1])
+            raise self.error(dat[-1].decode('utf-8', 'replace'))
         self.state = 'AUTH'
         return typ, dat
 
diff --git a/lib-python/3/importlib/_bootstrap_external.py b/lib-python/3/importlib/_bootstrap_external.py
--- a/lib-python/3/importlib/_bootstrap_external.py
+++ b/lib-python/3/importlib/_bootstrap_external.py
@@ -1447,6 +1447,4 @@
     _setup(_bootstrap_module)
     supported_loaders = _get_supported_file_loaders()
     sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
-    if _os.__name__ == 'nt':
-        sys.meta_path.append(WindowsRegistryFinder)
     sys.meta_path.append(PathFinder)
diff --git a/lib-python/3/inspect.py b/lib-python/3/inspect.py
--- a/lib-python/3/inspect.py
+++ b/lib-python/3/inspect.py
@@ -1422,7 +1422,6 @@
         except OSError:
             lines = index = None
         else:
-            start = max(start, 1)
             start = max(0, min(start, len(lines) - context))
             lines = lines[start:start+context]
             index = lineno - 1 - start
diff --git a/lib-python/3/logging/__init__.py b/lib-python/3/logging/__init__.py
--- a/lib-python/3/logging/__init__.py
+++ b/lib-python/3/logging/__init__.py
@@ -131,9 +131,14 @@
 
     Otherwise, the string "Level %s" % level is returned.
     """
-    # See Issues #22386 and #27937 for why it's this way
-    return (_levelToName.get(level) or _nameToLevel.get(level) or
-            "Level %s" % level)
+    # See Issues #22386, #27937 and #29220 for why it's this way
+    result = _levelToName.get(level)
+    if result is not None:
+        return result
+    result = _nameToLevel.get(level)
+    if result is not None:
+        return result
+    return "Level %s" % level
 
 def addLevelName(level, levelName):
     """
diff --git a/lib-python/3/mailbox.py b/lib-python/3/mailbox.py
--- a/lib-python/3/mailbox.py
+++ b/lib-python/3/mailbox.py
@@ -313,11 +313,12 @@
         # final position in order to prevent race conditions with changes
         # from other programs
         try:
-            if hasattr(os, 'link'):
+            try:
                 os.link(tmp_file.name, dest)
+            except (AttributeError, PermissionError):
+                os.rename(tmp_file.name, dest)
+            else:
                 os.remove(tmp_file.name)
-            else:
-                os.rename(tmp_file.name, dest)
         except OSError as e:
             os.remove(tmp_file.name)
             if e.errno == errno.EEXIST:
@@ -1200,13 +1201,14 @@
         for key in self.iterkeys():
             if key - 1 != prev:
                 changes.append((key, prev + 1))
-                if hasattr(os, 'link'):
+                try:
                     os.link(os.path.join(self._path, str(key)),
                             os.path.join(self._path, str(prev + 1)))
-                    os.unlink(os.path.join(self._path, str(key)))
-                else:
+                except (AttributeError, PermissionError):
                     os.rename(os.path.join(self._path, str(key)),
                               os.path.join(self._path, str(prev + 1)))
+                else:
+                    os.unlink(os.path.join(self._path, str(key)))
             prev += 1
         self._next_key = prev + 1
         if len(changes) == 0:
@@ -2076,13 +2078,14 @@
                 else:
                     raise
             try:
-                if hasattr(os, 'link'):
+                try:
                     os.link(pre_lock.name, f.name + '.lock')
                     dotlock_done = True
-                    os.unlink(pre_lock.name)
-                else:
+                except (AttributeError, PermissionError):
                     os.rename(pre_lock.name, f.name + '.lock')
                     dotlock_done = True
+                else:
+                    os.unlink(pre_lock.name)
             except FileExistsError:
                 os.remove(pre_lock.name)
                 raise ExternalClashError('dot lock unavailable: %s' %
diff --git a/lib-python/3/multiprocessing/context.py b/lib-python/3/multiprocessing/context.py
--- a/lib-python/3/multiprocessing/context.py
+++ b/lib-python/3/multiprocessing/context.py
@@ -196,7 +196,7 @@
     def get_start_method(self, allow_none=False):
         return self._name
 
-    def set_start_method(self, method=None):
+    def set_start_method(self, method, force=False):
         raise ValueError('cannot set start method of concrete context')
 
     @property
diff --git a/lib-python/3/multiprocessing/spawn.py b/lib-python/3/multiprocessing/spawn.py
--- a/lib-python/3/multiprocessing/spawn.py
+++ b/lib-python/3/multiprocessing/spawn.py
@@ -217,7 +217,7 @@
         process.ORIGINAL_DIR = data['orig_dir']
 
     if 'start_method' in data:
-        set_start_method(data['start_method'])
+        set_start_method(data['start_method'], force=True)
 
     if 'init_main_from_name' in data:
         _fixup_main_from_name(data['init_main_from_name'])
diff --git a/lib-python/3/pathlib.py b/lib-python/3/pathlib.py
--- a/lib-python/3/pathlib.py
+++ b/lib-python/3/pathlib.py
@@ -192,7 +192,9 @@
                         s = self._ext_to_normal(_getfinalpathname(s))
                     except FileNotFoundError:
                         previous_s = s
-                        s = os.path.abspath(os.path.join(s, os.pardir))
+                        s = os.path.dirname(s)
+                        if previous_s == s:
+                            return path
                     else:
                         if previous_s is None:
                             return s
@@ -1233,7 +1235,7 @@
                 if not exist_ok or not self.is_dir():
                     raise
             except OSError as e:
-                if e.errno != ENOENT:
+                if e.errno != ENOENT or self.parent == self:
                     raise
                 self.parent.mkdir(parents=True)
                 self._accessor.mkdir(self, mode)
diff --git a/lib-python/3/platform.py b/lib-python/3/platform.py
--- a/lib-python/3/platform.py
+++ b/lib-python/3/platform.py
@@ -110,7 +110,7 @@
 
 """
 
-__version__ = '1.0.7'
+__version__ = '1.0.8'
 
 import collections
 import sys, os, re, subprocess
@@ -1198,7 +1198,9 @@
         elif buildtime:
             builddate = builddate + ' ' + buildtime
 
-    if hasattr(sys, '_mercurial'):
+    if hasattr(sys, '_git'):
+        _, branch, revision = sys._git
+    elif hasattr(sys, '_mercurial'):
         _, branch, revision = sys._mercurial
     elif hasattr(sys, 'subversion'):
         # sys.subversion was added in Python 2.5
diff --git a/lib-python/3/pstats.py b/lib-python/3/pstats.py
--- a/lib-python/3/pstats.py
+++ b/lib-python/3/pstats.py
@@ -48,11 +48,14 @@
     printed.
 
     The sort_stats() method now processes some additional options (i.e., in
-    addition to the old -1, 0, 1, or 2).  It takes an arbitrary number of
-    quoted strings to select the sort order.  For example sort_stats('time',
-    'name') sorts on the major key of 'internal function time', and on the
-    minor key of 'the name of the function'.  Look at the two tables in
-    sort_stats() and get_sort_arg_defs(self) for more examples.
+    addition to the old -1, 0, 1, or 2 that are respectively interpreted as
+    'stdname', 'calls', 'time', and 'cumulative').  It takes an arbitrary number
+    of quoted strings to select the sort order.
+
+    For example sort_stats('time', 'name') sorts on the major key of 'internal
+    function time', and on the minor key of 'the name of the function'.  Look at
+    the two tables in sort_stats() and get_sort_arg_defs(self) for more
+    examples.
 
     All methods return self, so you can string together commands like:
         Stats('foo', 'goo').strip_dirs().sort_stats('calls').\
diff --git a/lib-python/3/pydoc_data/topics.py b/lib-python/3/pydoc_data/topics.py
--- a/lib-python/3/pydoc_data/topics.py
+++ b/lib-python/3/pydoc_data/topics.py
@@ -1,7 +1,6 @@
 # -*- coding: utf-8 -*-
-# Autogenerated by Sphinx on Fri Dec 16 16:33:16 2016
-topics = {'assert': '\n'
-           'The "assert" statement\n'
+# Autogenerated by Sphinx on Sat Mar  4 12:14:44 2017
+topics = {'assert': 'The "assert" statement\n'
            '**********************\n'
            '\n'
            'Assert statements are a convenient way to insert debugging '
@@ -39,8 +38,7 @@
            'Assignments to "__debug__" are illegal.  The value for the '
            'built-in\n'
            'variable is determined when the interpreter starts.\n',
- 'assignment': '\n'
-               'Assignment statements\n'
+ 'assignment': 'Assignment statements\n'
                '*********************\n'
                '\n'
                'Assignment statements are used to (re)bind names to values and '
@@ -405,8 +403,7 @@
                'See also: **PEP 526** - Variable and attribute annotation '
                'syntax\n'
                '  **PEP 484** - Type hints\n',
- 'atom-identifiers': '\n'
-                     'Identifiers (Names)\n'
+ 'atom-identifiers': 'Identifiers (Names)\n'
                      '*******************\n'
                      '\n'
                      'An identifier occurring as an atom is a name.  See '
@@ -446,8 +443,7 @@
                      'happen. If the class name consists only of underscores, '
                      'no\n'
                      'transformation is done.\n',
- 'atom-literals': '\n'
-                  'Literals\n'
+ 'atom-literals': 'Literals\n'
                   '********\n'
                   '\n'
                   'Python supports string and bytes literals and various '
@@ -476,8 +472,7 @@
                   'may obtain\n'
                   'the same object or a different object with the same '
                   'value.\n',
- 'attribute-access': '\n'
-                     'Customizing attribute access\n'
+ 'attribute-access': 'Customizing attribute access\n'
                      '****************************\n'
                      '\n'
                      'The following methods can be defined to customize the '
@@ -851,8 +846,7 @@
                      '* *__class__* assignment works only if both classes have '
                      'the same\n'
                      '  *__slots__*.\n',
- 'attribute-references': '\n'
-                         'Attribute references\n'
+ 'attribute-references': 'Attribute references\n'
                          '********************\n'
                          '\n'
                          'An attribute reference is a primary followed by a '
@@ -875,8 +869,7 @@
                          'determined by the object.  Multiple evaluations of '
                          'the same attribute\n'
                          'reference may yield different objects.\n',
- 'augassign': '\n'
-              'Augmented assignment statements\n'
+ 'augassign': 'Augmented assignment statements\n'
               '*******************************\n'
               '\n'
               'Augmented assignment is the combination, in a single statement, '
@@ -940,8 +933,7 @@
               'about\n'
               'class and instance attributes applies as for regular '
               'assignments.\n',
- 'binary': '\n'
-           'Binary arithmetic operations\n'
+ 'binary': 'Binary arithmetic operations\n'
            '****************************\n'
            '\n'
            'The binary arithmetic operations have the conventional priority\n'
@@ -1029,8 +1021,7 @@
            'The "-" (subtraction) operator yields the difference of its '
            'arguments.\n'
            'The numeric arguments are first converted to a common type.\n',
- 'bitwise': '\n'
-            'Binary bitwise operations\n'
+ 'bitwise': 'Binary bitwise operations\n'
             '*************************\n'
             '\n'
             'Each of the three bitwise operations has a different priority '
@@ -1050,8 +1041,7 @@
             'The "|" operator yields the bitwise (inclusive) OR of its '
             'arguments,\n'
             'which must be integers.\n',
- 'bltin-code-objects': '\n'
-                       'Code Objects\n'
+ 'bltin-code-objects': 'Code Objects\n'
                        '************\n'
                        '\n'
                        'Code objects are used by the implementation to '
@@ -1074,8 +1064,7 @@
                        '\n'
                        'See The standard type hierarchy for more '
                        'information.\n',
- 'bltin-ellipsis-object': '\n'
-                          'The Ellipsis Object\n'
+ 'bltin-ellipsis-object': 'The Ellipsis Object\n'
                           '*******************\n'
                           '\n'
                           'This object is commonly used by slicing (see '
@@ -1087,8 +1076,7 @@
                           '"Ellipsis" singleton.\n'
                           '\n'
                           'It is written as "Ellipsis" or "...".\n',
- 'bltin-null-object': '\n'
-                      'The Null Object\n'
+ 'bltin-null-object': 'The Null Object\n'
                       '***************\n'
                       '\n'
                       "This object is returned by functions that don't "
@@ -1100,8 +1088,7 @@
                       'same singleton.\n'
                       '\n'
                       'It is written as "None".\n',
- 'bltin-type-objects': '\n'
-                       'Type Objects\n'
+ 'bltin-type-objects': 'Type Objects\n'
                        '************\n'
                        '\n'
                        'Type objects represent the various object types.  An '
@@ -1113,8 +1100,7 @@
                        'all standard built-in types.\n'
                        '\n'
                        'Types are written like this: "<class \'int\'>".\n',
- 'booleans': '\n'
-             'Boolean operations\n'
+ 'booleans': 'Boolean operations\n'
              '******************\n'
              '\n'
              '   or_test  ::= and_test | or_test "or" and_test\n'
@@ -1163,8 +1149,7 @@
              'its\n'
              'argument (for example, "not \'foo\'" produces "False" rather '
              'than "\'\'".)\n',
- 'break': '\n'
-          'The "break" statement\n'
+ 'break': 'The "break" statement\n'
           '*********************\n'
           '\n'
           '   break_stmt ::= "break"\n'
@@ -1185,8 +1170,7 @@
           'clause, that "finally" clause is executed before really leaving '
           'the\n'
           'loop.\n',
- 'callable-types': '\n'
-                   'Emulating callable objects\n'
+ 'callable-types': 'Emulating callable objects\n'
                    '**************************\n'
                    '\n'
                    'object.__call__(self[, args...])\n'
@@ -1195,8 +1179,7 @@
                    'this method\n'
                    '   is defined, "x(arg1, arg2, ...)" is a shorthand for\n'
                    '   "x.__call__(arg1, arg2, ...)".\n',
- 'calls': '\n'
-          'Calls\n'
+ 'calls': 'Calls\n'
           '*****\n'
           '\n'
           'A call calls a callable object (e.g., a *function*) with a '
@@ -1217,7 +1200,8 @@
           '                            ("," "*" expression | "," '
           'keyword_item)*\n'
           '   keywords_arguments   ::= (keyword_item | "**" expression)\n'
-          '                          ("," keyword_item | "**" expression)*\n'
+          '                          ("," keyword_item | "," "**" '
+          'expression)*\n'
           '   keyword_item         ::= identifier "=" expression\n'
           '\n'
           'An optional trailing comma may be present after the positional and\n'
@@ -1382,8 +1366,7 @@
           '   The class must define a "__call__()" method; the effect is then '
           'the\n'
           '   same as if that method was called.\n',
- 'class': '\n'
-          'Class definitions\n'
+ 'class': 'Class definitions\n'
           '*****************\n'
           '\n'
           'A class definition defines a class object (see section The '
@@ -1469,8 +1452,7 @@
           '\n'
           'See also: **PEP 3115** - Metaclasses in Python 3 **PEP 3129** -\n'
           '  Class Decorators\n',
- 'comparisons': '\n'
-                'Comparisons\n'
+ 'comparisons': 'Comparisons\n'
                 '***********\n'
                 '\n'
                 'Unlike C, all comparison operations in Python have the same '
@@ -1623,7 +1605,7 @@
                 'restriction that\n'
                 '  ranges do not support order comparison.  Equality '
                 'comparison across\n'
-                '  these types results in unequality, and ordering comparison '
+                '  these types results in inequality, and ordering comparison '
                 'across\n'
                 '  these types raises "TypeError".\n'
                 '\n'
@@ -1762,6 +1744,12 @@
                 '  to sequences, but not to sets or mappings). See also the\n'
                 '  "total_ordering()" decorator.\n'
                 '\n'
+                '* The "hash()" result should be consistent with equality. '
+                'Objects\n'
+                '  that are equal should either have the same hash value, or '
+                'be marked\n'
+                '  as unhashable.\n'
+                '\n'
                 'Python does not enforce these consistency rules. In fact, '
                 'the\n'
                 'not-a-number values are an example for not following these '
@@ -1833,8 +1821,7 @@
                 'is determined using the "id()" function.  "x is not y" yields '
                 'the\n'
                 'inverse truth value. [4]\n',
- 'compound': '\n'
-             'Compound statements\n'
+ 'compound': 'Compound statements\n'
              '*******************\n'
              '\n'
              'Compound statements contain (groups of) other statements; they '
@@ -2725,8 +2712,7 @@
              '    body is transformed into the namespace\'s "__doc__" item '
              'and\n'
              "    therefore the class's *docstring*.\n",
- 'context-managers': '\n'
-                     'With Statement Context Managers\n'
+ 'context-managers': 'With Statement Context Managers\n'
                      '*******************************\n'
                      '\n'
                      'A *context manager* is an object that defines the '
@@ -2788,8 +2774,7 @@
                      '     The specification, background, and examples for the '
                      'Python "with"\n'
                      '     statement.\n',
- 'continue': '\n'
-             'The "continue" statement\n'
+ 'continue': 'The "continue" statement\n'
              '************************\n'
              '\n'
              '   continue_stmt ::= "continue"\n'
@@ -2806,8 +2791,7 @@
              '"finally" clause, that "finally" clause is executed before '
              'really\n'
              'starting the next loop cycle.\n',
- 'conversions': '\n'
-                'Arithmetic conversions\n'
+ 'conversions': 'Arithmetic conversions\n'
                 '**********************\n'
                 '\n'
                 'When a description of an arithmetic operator below uses the '
@@ -2833,8 +2817,7 @@
                 "left argument to the '%' operator).  Extensions must define "
                 'their own\n'
                 'conversion behavior.\n',
- 'customization': '\n'
-                  'Basic customization\n'
+ 'customization': 'Basic customization\n'
                   '*******************\n'
                   '\n'
                   'object.__new__(cls[, ...])\n'
@@ -3153,15 +3136,18 @@
                   'on members\n'
                   '   of hashed collections including "set", "frozenset", and '
                   '"dict".\n'
-                  '   "__hash__()" should return an integer.  The only '
-                  'required property\n'
+                  '   "__hash__()" should return an integer. The only required '
+                  'property\n'
                   '   is that objects which compare equal have the same hash '
                   'value; it is\n'
-                  '   advised to somehow mix together (e.g. using exclusive '
-                  'or) the hash\n'
-                  '   values for the components of the object that also play a '
-                  'part in\n'
-                  '   comparison of objects.\n'
+                  '   advised to mix together the hash values of the '
+                  'components of the\n'
+                  '   object that also play a part in comparison of objects by '
+                  'packing\n'
+                  '   them into a tuple and hashing the tuple. Example:\n'
+                  '\n'
+                  '      def __hash__(self):\n'
+                  '          return hash((self.name, self.nick, self.color))\n'
                   '\n'
                   '   Note: "hash()" truncates the value returned from an '
                   "object's\n"
@@ -3273,8 +3259,7 @@
                   '   neither "__len__()" nor "__bool__()", all its instances '
                   'are\n'
                   '   considered true.\n',
- 'debugger': '\n'
-             '"pdb" --- The Python Debugger\n'
+ 'debugger': '"pdb" --- The Python Debugger\n'
              '*****************************\n'
              '\n'
              '**Source code:** Lib/pdb.py\n'
@@ -3939,8 +3924,7 @@
              '[1] Whether a frame is considered to originate in a certain '
              'module\n'
              '    is determined by the "__name__" in the frame globals.\n',
- 'del': '\n'
-        'The "del" statement\n'
+ 'del': 'The "del" statement\n'
         '*******************\n'
         '\n'
         '   del_stmt ::= "del" target_list\n'
@@ -3969,8 +3953,7 @@
         'Changed in version 3.2: Previously it was illegal to delete a name\n'
         'from the local namespace if it occurs as a free variable in a nested\n'
         'block.\n',
- 'dict': '\n'
-         'Dictionary displays\n'
+ 'dict': 'Dictionary displays\n'
          '*******************\n'
          '\n'
          'A dictionary display is a possibly empty series of key/datum pairs\n'
@@ -4014,8 +3997,7 @@
          'should be *hashable*, which excludes all mutable objects.)  Clashes\n'
          'between duplicate keys are not detected; the last datum (textually\n'
          'rightmost in the display) stored for a given key value prevails.\n',
- 'dynamic-features': '\n'
-                     'Interaction with dynamic features\n'
+ 'dynamic-features': 'Interaction with dynamic features\n'
                      '*********************************\n'
                      '\n'
                      'Name resolution of free variables occurs at runtime, not '
@@ -4051,8 +4033,7 @@
                      'override the global and local namespace.  If only one '
                      'namespace is\n'
                      'specified, it is used for both.\n',
- 'else': '\n'
-         'The "if" statement\n'
+ 'else': 'The "if" statement\n'
          '******************\n'
          '\n'
          'The "if" statement is used for conditional execution:\n'
@@ -4069,8 +4050,7 @@
          '(and no other part of the "if" statement is executed or evaluated).\n'
          'If all expressions are false, the suite of the "else" clause, if\n'
          'present, is executed.\n',
- 'exceptions': '\n'
-               'Exceptions\n'
+ 'exceptions': 'Exceptions\n'
                '**********\n'
                '\n'
                'Exceptions are a means of breaking out of the normal flow of '
@@ -4146,8 +4126,7 @@
                '    these operations is not available at the time the module '
                'is\n'
                '    compiled.\n',
- 'execmodel': '\n'
-              'Execution model\n'
+ 'execmodel': 'Execution model\n'
               '***************\n'
               '\n'
               '\n'
@@ -4478,8 +4457,7 @@
               '    these operations is not available at the time the module '
               'is\n'
               '    compiled.\n',
- 'exprlists': '\n'
-              'Expression lists\n'
+ 'exprlists': 'Expression lists\n'
               '****************\n'
               '\n'
               '   expression_list    ::= expression ( "," expression )* [","]\n'
@@ -4516,8 +4494,7 @@
               'value of that expression. (To create an empty tuple, use an '
               'empty pair\n'
               'of parentheses: "()".)\n',
- 'floating': '\n'
-             'Floating point literals\n'
+ 'floating': 'Floating point literals\n'
              '***********************\n'
              '\n'
              'Floating point literals are described by the following lexical\n'
@@ -4553,8 +4530,7 @@
              'Changed in version 3.6: Underscores are now allowed for '
              'grouping\n'
              'purposes in literals.\n',
- 'for': '\n'
-        'The "for" statement\n'
+ 'for': 'The "for" statement\n'
         '*******************\n'
         '\n'
         'The "for" statement is used to iterate over the elements of a '
@@ -4626,8 +4602,7 @@
         '\n'
         '     for x in a[:]:\n'
         '         if x < 0: a.remove(x)\n',
- 'formatstrings': '\n'
-                  'Format String Syntax\n'
+ 'formatstrings': 'Format String Syntax\n'
                   '********************\n'
                   '\n'
                   'The "str.format()" method and the "Formatter" class share '
@@ -5346,8 +5321,7 @@
                   '       9     9    11  1001\n'
                   '      10     A    12  1010\n'
                   '      11     B    13  1011\n',
- 'function': '\n'
-             'Function definitions\n'
+ 'function': 'Function definitions\n'
              '********************\n'
              '\n'
              'A function definition defines a user-defined function object '
@@ -5516,8 +5490,7 @@
              '\n'
              '  **PEP 3107** - Function Annotations\n'
              '     The original specification for function annotations.\n',
- 'global': '\n'
-           'The "global" statement\n'
+ 'global': 'The "global" statement\n'
            '**********************\n'
            '\n'
            '   global_stmt ::= "global" identifier ("," identifier)*\n'
@@ -5561,8 +5534,7 @@
            'code containing the function call.  The same applies to the '
            '"eval()"\n'
            'and "compile()" functions.\n',
- 'id-classes': '\n'
-               'Reserved classes of identifiers\n'
+ 'id-classes': 'Reserved classes of identifiers\n'
                '*******************************\n'
                '\n'
                'Certain classes of identifiers (besides keywords) have '
@@ -5610,8 +5582,7 @@
                '   to help avoid name clashes between "private" attributes of '
                'base and\n'
                '   derived classes. See section Identifiers (Names).\n',
- 'identifiers': '\n'
-                'Identifiers and keywords\n'
+ 'identifiers': 'Identifiers and keywords\n'
                 '************************\n'
                 '\n'
                 'Identifiers (also referred to as *names*) are described by '
@@ -5759,8 +5730,7 @@
                 '   to help avoid name clashes between "private" attributes of '
                 'base and\n'
                 '   derived classes. See section Identifiers (Names).\n',
- 'if': '\n'
-       'The "if" statement\n'
+ 'if': 'The "if" statement\n'
        '******************\n'
        '\n'
        'The "if" statement is used for conditional execution:\n'
@@ -5776,8 +5746,7 @@
        '(and no other part of the "if" statement is executed or evaluated).\n'
        'If all expressions are false, the suite of the "else" clause, if\n'
        'present, is executed.\n',
- 'imaginary': '\n'
-              'Imaginary literals\n'
+ 'imaginary': 'Imaginary literals\n'
               '******************\n'
               '\n'
               'Imaginary literals are described by the following lexical '
@@ -5797,8 +5766,7 @@
               '\n'
               '   3.14j   10.j    10j     .001j   1e100j   3.14e-10j   '
               '3.14_15_93j\n',
- 'import': '\n'
-           'The "import" statement\n'
+ 'import': 'The "import" statement\n'
            '**********************\n'
            '\n'
            '   import_stmt     ::= "import" module ["as" name] ( "," module '
@@ -6059,8 +6027,7 @@
            '\n'
            '  **PEP 236** - Back to the __future__\n'
            '     The original proposal for the __future__ mechanism.\n',
- 'in': '\n'
-       'Membership test operations\n'
+ 'in': 'Membership test operations\n'
        '**************************\n'
        '\n'
        'The operators "in" and "not in" test for membership.  "x in s"\n'
@@ -6095,8 +6062,7 @@
        '\n'
        'The operator "not in" is defined to have the inverse true value of\n'
        '"in".\n',
- 'integers': '\n'
-             'Integer literals\n'
+ 'integers': 'Integer literals\n'
              '****************\n'
              '\n'
              'Integer literals are described by the following lexical '
@@ -6142,8 +6108,7 @@
              'Changed in version 3.6: Underscores are now allowed for '
              'grouping\n'
              'purposes in literals.\n',
- 'lambda': '\n'
-           'Lambdas\n'
+ 'lambda': 'Lambdas\n'
            '*******\n'
            '\n'
            '   lambda_expr        ::= "lambda" [parameter_list]: expression\n'
@@ -6166,8 +6131,7 @@
            'Note that functions created with lambda expressions cannot '
            'contain\n'
            'statements or annotations.\n',
- 'lists': '\n'
-          'List displays\n'
+ 'lists': 'List displays\n'
           '*************\n'
           '\n'
           'A list display is a possibly empty series of expressions enclosed '
@@ -6184,8 +6148,7 @@
           'from left to right and placed into the list object in that order.\n'
           'When a comprehension is supplied, the list is constructed from the\n'
           'elements resulting from the comprehension.\n',
- 'naming': '\n'
-           'Naming and binding\n'
+ 'naming': 'Naming and binding\n'
            '******************\n'
            '\n'
            '\n'
@@ -6398,8 +6361,7 @@
            'override the global and local namespace.  If only one namespace '
            'is\n'
            'specified, it is used for both.\n',
- 'nonlocal': '\n'
-             'The "nonlocal" statement\n'
+ 'nonlocal': 'The "nonlocal" statement\n'
              '************************\n'
              '\n'
              '   nonlocal_stmt ::= "nonlocal" identifier ("," identifier)*\n'
@@ -6430,8 +6392,7 @@
              '\n'
              '  **PEP 3104** - Access to Names in Outer Scopes\n'
              '     The specification for the "nonlocal" statement.\n',
- 'numbers': '\n'
-            'Numeric literals\n'
+ 'numbers': 'Numeric literals\n'
             '****************\n'
             '\n'
             'There are three types of numeric literals: integers, floating '
@@ -6445,8 +6406,7 @@
             'is actually an expression composed of the unary operator \'"-"\' '
             'and the\n'
             'literal "1".\n',
- 'numeric-types': '\n'
-                  'Emulating numeric types\n'
+ 'numeric-types': 'Emulating numeric types\n'
                   '***********************\n'
                   '\n'
                   'The following methods can be defined to emulate numeric '
@@ -6622,8 +6582,7 @@
                   '     "__index__()" is defined "__int__()" should also be '
                   'defined, and\n'
                   '     both should return the same value.\n',
- 'objects': '\n'
-            'Objects, values and types\n'
+ 'objects': 'Objects, values and types\n'
             '*************************\n'
             '\n'
             "*Objects* are Python's abstraction for data.  All data in a "
@@ -6751,8 +6710,7 @@
             'created empty lists. (Note that "c = d = []" assigns the same '
             'object\n'
             'to both "c" and "d".)\n',
- 'operator-summary': '\n'
-                     'Operator precedence\n'
+ 'operator-summary': 'Operator precedence\n'
                      '*******************\n'
                      '\n'
                      'The following table summarizes the operator precedence '
@@ -6925,8 +6883,7 @@
                      'arithmetic\n'
                      '    or bitwise unary operator on its right, that is, '
                      '"2**-1" is "0.5".\n',
- 'pass': '\n'
-         'The "pass" statement\n'
+ 'pass': 'The "pass" statement\n'
          '********************\n'
          '\n'
          '   pass_stmt ::= "pass"\n'
@@ -6939,8 +6896,7 @@
          '   def f(arg): pass    # a function that does nothing (yet)\n'
          '\n'
          '   class C: pass       # a class with no methods (yet)\n',
- 'power': '\n'
-          'The power operator\n'
+ 'power': 'The power operator\n'
           '******************\n'
           '\n'
           'The power operator binds more tightly than unary operators on its\n'
@@ -6974,8 +6930,7 @@
           'Raising a negative number to a fractional power results in a '
           '"complex"\n'
           'number. (In earlier versions it raised a "ValueError".)\n',
- 'raise': '\n'
-          'The "raise" statement\n'
+ 'raise': 'The "raise" statement\n'
           '*********************\n'
           '\n'
           '   raise_stmt ::= "raise" [expression ["from" expression]]\n'
@@ -7060,8 +7015,7 @@
           'Exceptions, and information about handling exceptions is in '
           'section\n'
           'The try statement.\n',
- 'return': '\n'
-           'The "return" statement\n'
+ 'return': 'The "return" statement\n'
            '**********************\n'
            '\n'
            '   return_stmt ::= "return" [expression_list]\n'
@@ -7096,8 +7050,7 @@
            '"StopAsyncIteration" to be raised.  A non-empty "return" statement '
            'is\n'
            'a syntax error in an asynchronous generator function.\n',
- 'sequence-types': '\n'
-                   'Emulating container types\n'
+ 'sequence-types': 'Emulating container types\n'
                    '*************************\n'
                    '\n'
                    'The following methods can be defined to implement '
@@ -7318,8 +7271,7 @@
                    '   iteration protocol via "__getitem__()", see this '
                    'section in the\n'
                    '   language reference.\n',
- 'shifting': '\n'
-             'Shifting operations\n'
+ 'shifting': 'Shifting operations\n'
              '*******************\n'
              '\n'
              'The shifting operations have lower priority than the arithmetic\n'
@@ -7343,8 +7295,7 @@
              'operand is\n'
              '  larger than "sys.maxsize" an "OverflowError" exception is '
              'raised.\n',
- 'slicings': '\n'
-             'Slicings\n'
+ 'slicings': 'Slicings\n'
              '********\n'
              '\n'
              'A slicing selects a range of items in a sequence object (e.g., '
@@ -7395,8 +7346,7 @@
              'as lower bound, upper bound and stride, respectively, '
              'substituting\n'
              '"None" for missing expressions.\n',
- 'specialattrs': '\n'
-                 'Special Attributes\n'
+ 'specialattrs': 'Special Attributes\n'
                  '******************\n'
                  '\n'
                  'The implementation adds a few special read-only attributes '
@@ -7481,8 +7431,7 @@
                  '[5] To format only a tuple you should therefore provide a\n'
                  '    singleton tuple whose only element is the tuple to be '
                  'formatted.\n',
- 'specialnames': '\n'
-                 'Special method names\n'
+ 'specialnames': 'Special method names\n'
                  '********************\n'
                  '\n'
                  'A class can implement certain operations that are invoked by '
@@ -7843,15 +7792,18 @@
                  'on members\n'
                  '   of hashed collections including "set", "frozenset", and '
                  '"dict".\n'
-                 '   "__hash__()" should return an integer.  The only required '
+                 '   "__hash__()" should return an integer. The only required '
                  'property\n'
                  '   is that objects which compare equal have the same hash '
                  'value; it is\n'
-                 '   advised to somehow mix together (e.g. using exclusive or) '
-                 'the hash\n'
-                 '   values for the components of the object that also play a '
-                 'part in\n'
-                 '   comparison of objects.\n'
+                 '   advised to mix together the hash values of the components '
+                 'of the\n'
+                 '   object that also play a part in comparison of objects by '
+                 'packing\n'
+                 '   them into a tuple and hashing the tuple. Example:\n'
+                 '\n'
+                 '      def __hash__(self):\n'
+                 '          return hash((self.name, self.nick, self.color))\n'
                  '\n'
                  '   Note: "hash()" truncates the value returned from an '
                  "object's\n"
@@ -9270,8 +9222,7 @@
                  'special method *must* be set on the class object itself in '
                  'order to be\n'
                  'consistently invoked by the interpreter).\n',
- 'string-methods': '\n'
-                   'String Methods\n'
+ 'string-methods': 'String Methods\n'
                    '**************\n'
                    '\n'
                    'Strings implement all of the common sequence operations, '
@@ -9508,12 +9459,11 @@
                    'characters\n'
                    '   and there is at least one character, false otherwise. '
                    'Decimal\n'
-                   '   characters are those from general category "Nd". This '
-                   'category\n'
-                   '   includes digit characters, and all characters that can '
-                   'be used to\n'
-                   '   form decimal-radix numbers, e.g. U+0660, ARABIC-INDIC '
-                   'DIGIT ZERO.\n'
+                   '   characters are those that can be used to form numbers '
+                   'in base 10,\n'
+                   '   e.g. U+0660, ARABIC-INDIC DIGIT ZERO.  Formally a '
+                   'decimal character\n'
+                   '   is a character in the Unicode General Category "Nd".\n'
                    '\n'
                    'str.isdigit()\n'
                    '\n'
@@ -9523,10 +9473,13 @@
                    'include decimal\n'
                    '   characters and digits that need special handling, such '
                    'as the\n'
-                   '   compatibility superscript digits.  Formally, a digit is '
-                   'a character\n'
-                   '   that has the property value Numeric_Type=Digit or\n'
-                   '   Numeric_Type=Decimal.\n'
+                   '   compatibility superscript digits. This covers digits '
+                   'which cannot\n'
+                   '   be used to form numbers in base 10, like the Kharosthi '
+                   'numbers.\n'
+                   '   Formally, a digit is a character that has the property '
+                   'value\n'
+                   '   Numeric_Type=Digit or Numeric_Type=Decimal.\n'
                    '\n'
                    'str.isidentifier()\n'
                    '\n'
@@ -10072,8 +10025,7 @@
                    "      '00042'\n"
                    '      >>> "-42".zfill(5)\n'
                    "      '-0042'\n",
- 'strings': '\n'
-            'String and Bytes literals\n'
+ 'strings': 'String and Bytes literals\n'
             '*************************\n'
             '\n'
             'String literals are described by the following lexical '
@@ -10307,8 +10259,7 @@
             'followed by a newline is interpreted as those two characters as '
             'part\n'
             'of the literal, *not* as a line continuation.\n',
- 'subscriptions': '\n'
-                  'Subscriptions\n'
+ 'subscriptions': 'Subscriptions\n'
                   '*************\n'
                   '\n'
                   'A subscription selects an item of a sequence (string, tuple '
@@ -10365,8 +10316,7 @@
                   "A string's items are characters.  A character is not a "
                   'separate data\n'
                   'type but a string of exactly one character.\n',
- 'truth': '\n'
-          'Truth Value Testing\n'
+ 'truth': 'Truth Value Testing\n'
           '*******************\n'
           '\n'
           'Any object can be tested for truth value, for use in an "if" or\n'
@@ -10398,8 +10348,7 @@
           'otherwise stated. (Important exception: the Boolean operations '
           '"or"\n'
           'and "and" always return one of their operands.)\n',
- 'try': '\n'
-        'The "try" statement\n'
+ 'try': 'The "try" statement\n'
         '*******************\n'
         '\n'
         'The "try" statement specifies exception handlers and/or cleanup code\n'
@@ -10546,8 +10495,7 @@
         'Exceptions, and information on using the "raise" statement to '
         'generate\n'
         'exceptions may be found in section The raise statement.\n',
- 'types': '\n'
-          'The standard type hierarchy\n'
+ 'types': 'The standard type hierarchy\n'
           '***************************\n'
           '\n'
           'Below is a list of the types that are built into Python.  '
@@ -11262,14 +11210,14 @@
           'the\n'
           '   dictionary containing the class\'s namespace; "__bases__" is a '
           'tuple\n'
-          '   (possibly empty or a singleton) containing the base classes, in '
-          'the\n'
-          '   order of their occurrence in the base class list; "__doc__" is '
-          'the\n'
-          '   class\'s documentation string, or "None" if undefined;\n'
-          '   "__annotations__" (optional) is a dictionary containing '
-          '*variable\n'
-          '   annotations* collected during class body execution.\n'
+          '   containing the base classes, in the order of their occurrence '
+          'in\n'
+          '   the base class list; "__doc__" is the class\'s documentation '
+          'string,\n'
+          '   or "None" if undefined; "__annotations__" (optional) is a\n'
+          '   dictionary containing *variable annotations* collected during '
+          'class\n'
+          '   body execution.\n'
           '\n'
           'Class instances\n'
           '   A class instance is created by calling a class object (see '
@@ -11549,8 +11497,7 @@
           '      under "User-defined methods". Class method objects are '
           'created\n'
           '      by the built-in "classmethod()" constructor.\n',
- 'typesfunctions': '\n'
-                   'Functions\n'
+ 'typesfunctions': 'Functions\n'
                    '*********\n'
                    '\n'
                    'Function objects are created by function definitions.  The '
@@ -11567,8 +11514,7 @@
                    'different object types.\n'
                    '\n'
                    'See Function definitions for more information.\n',
- 'typesmapping': '\n'
-                 'Mapping Types --- "dict"\n'
+ 'typesmapping': 'Mapping Types --- "dict"\n'
                  '************************\n'
                  '\n'
                  'A *mapping* object maps *hashable* values to arbitrary '
@@ -11925,8 +11871,7 @@
                  "   {'bacon'}\n"
                  "   >>> keys ^ {'sausage', 'juice'}\n"
                  "   {'juice', 'sausage', 'bacon', 'spam'}\n",
- 'typesmethods': '\n'
-                 'Methods\n'
+ 'typesmethods': 'Methods\n'
                  '*******\n'
                  '\n'
                  'Methods are functions that are called using the attribute '
@@ -11983,8 +11928,7 @@
                  "   'my name is method'\n"
                  '\n'
                  'See The standard type hierarchy for more information.\n',
- 'typesmodules': '\n'
-                 'Modules\n'
+ 'typesmodules': 'Modules\n'
                  '*******\n'
                  '\n'
                  'The only special operation on a module is attribute access: '
@@ -12021,8 +11965,7 @@
                  'written as\n'
                  '"<module \'os\' from '
                  '\'/usr/local/lib/pythonX.Y/os.pyc\'>".\n',
- 'typesseq': '\n'
-             'Sequence Types --- "list", "tuple", "range"\n'
+ 'typesseq': 'Sequence Types --- "list", "tuple", "range"\n'
              '*******************************************\n'
              '\n'
              'There are three basic sequence types: lists, tuples, and range\n'
@@ -12170,9 +12113,9 @@
              '\n'
              '3. If *i* or *j* is negative, the index is relative to the end '
              'of\n'
-             '   the string: "len(s) + i" or "len(s) + j" is substituted.  But '
-             'note\n'
-             '   that "-0" is still "0".\n'
+             '   sequence *s*: "len(s) + i" or "len(s) + j" is substituted.  '
+             'But\n'
+             '   note that "-0" is still "0".\n'
              '\n'
              '4. The slice of *s* from *i* to *j* is defined as the sequence '
              'of\n'
@@ -12191,12 +12134,17 @@
              '   (j-i)/k".  In other words, the indices are "i", "i+k", '
              '"i+2*k",\n'
              '   "i+3*k" and so on, stopping when *j* is reached (but never\n'
-             '   including *j*).  If *i* or *j* is greater than "len(s)", use\n'
-             '   "len(s)".  If *i* or *j* are omitted or "None", they become '
-             '"end"\n'
-             '   values (which end depends on the sign of *k*).  Note, *k* '
-             'cannot be\n'
-             '   zero. If *k* is "None", it is treated like "1".\n'
+             '   including *j*).  When *k* is positive, *i* and *j* are '
+             'reduced to\n'
+             '   "len(s)" if they are greater. When *k* is negative, *i* and '
+             '*j* are\n'
+             '   reduced to "len(s) - 1" if they are greater.  If *i* or *j* '
+             'are\n'
+             '   omitted or "None", they become "end" values (which end '
+             'depends on\n'
+             '   the sign of *k*).  Note, *k* cannot be zero. If *k* is '
+             '"None", it\n'
+             '   is treated like "1".\n'
              '\n'
              '6. Concatenating immutable sequences always results in a new\n'
              '   object. This means that building up a sequence by repeated\n'
@@ -12714,8 +12662,7 @@
              '  * The linspace recipe shows how to implement a lazy version '
              'of\n'
              '    range that suitable for floating point applications.\n',
- 'typesseq-mutable': '\n'
-                     'Mutable Sequence Types\n'
+ 'typesseq-mutable': 'Mutable Sequence Types\n'
                      '**********************\n'
                      '\n'
                      'The operations in the following table are defined on '
@@ -12855,8 +12802,7 @@
                      'referenced multiple\n'
                      '   times, as explained for "s * n" under Common Sequence '
                      'Operations.\n',
- 'unary': '\n'
-          'Unary arithmetic and bitwise operations\n'
+ 'unary': 'Unary arithmetic and bitwise operations\n'
           '***************************************\n'
           '\n'
           'All unary arithmetic and bitwise operations have the same '
@@ -12878,8 +12824,7 @@
           'In all three cases, if the argument does not have the proper type, '
           'a\n'
           '"TypeError" exception is raised.\n',
- 'while': '\n'
-          'The "while" statement\n'
+ 'while': 'The "while" statement\n'
           '*********************\n'
           '\n'
           'The "while" statement is used for repeated execution as long as an\n'
@@ -12903,8 +12848,7 @@
           'executed in the first suite skips the rest of the suite and goes '
           'back\n'
           'to testing the expression.\n',
- 'with': '\n'
-         'The "with" statement\n'
+ 'with': 'The "with" statement\n'
          '********************\n'
          '\n'
          'The "with" statement is used to wrap the execution of a block with\n'
@@ -12977,8 +12921,7 @@
          '     The specification, background, and examples for the Python '
          '"with"\n'
          '     statement.\n',
- 'yield': '\n'
-          'The "yield" statement\n'
+ 'yield': 'The "yield" statement\n'
           '*********************\n'
           '\n'
           '   yield_stmt ::= yield_expression\n'
diff --git a/lib-python/3/random.py b/lib-python/3/random.py
--- a/lib-python/3/random.py
+++ b/lib-python/3/random.py
@@ -254,7 +254,7 @@
         try:
             i = self._randbelow(len(seq))
         except ValueError:
-            raise IndexError('Cannot choose from an empty sequence')
+            raise IndexError('Cannot choose from an empty sequence') from None
         return seq[i]
 
     def shuffle(self, x, random=None):
diff --git a/lib-python/3/secrets.py b/lib-python/3/secrets.py
--- a/lib-python/3/secrets.py
+++ b/lib-python/3/secrets.py
@@ -26,6 +26,8 @@
 
 def randbelow(exclusive_upper_bound):
     """Return a random int in the range [0, n)."""
+    if exclusive_upper_bound <= 0:
+        raise ValueError("Upper bound must be positive.")
     return _sysrand._randbelow(exclusive_upper_bound)
 
 DEFAULT_ENTROPY = 32  # number of bytes to return by default
diff --git a/lib-python/3/shlex.py b/lib-python/3/shlex.py
--- a/lib-python/3/shlex.py
+++ b/lib-python/3/shlex.py
@@ -232,11 +232,6 @@
                             break   # emit current token
                         else:
                             continue
-                elif self.posix and nextchar in self.quotes:
-                    self.state = nextchar
-                elif self.posix and nextchar in self.escape:
-                    escapedstate = 'a'
-                    self.state = nextchar
                 elif self.state == 'c':
                     if nextchar in self.punctuation_chars:
                         self.token += nextchar
@@ -245,6 +240,11 @@
                             self._pushback_chars.append(nextchar)
                         self.state = ' '
                         break
+                elif self.posix and nextchar in self.quotes:
+                    self.state = nextchar
+                elif self.posix and nextchar in self.escape:
+                    escapedstate = 'a'
+                    self.state = nextchar
                 elif (nextchar in self.wordchars or nextchar in self.quotes
                       or self.whitespace_split):
                     self.token += nextchar
diff --git a/lib-python/3/shutil.py b/lib-python/3/shutil.py
--- a/lib-python/3/shutil.py
+++ b/lib-python/3/shutil.py
@@ -10,7 +10,13 @@
 import fnmatch
 import collections
 import errno
-import tarfile
+
+try:
+    import zlib
+    del zlib
+    _ZLIB_SUPPORTED = True
+except ImportError:
+    _ZLIB_SUPPORTED = False
 
 try:
     import bz2
@@ -602,23 +608,22 @@
 
     Returns the output filename.
     """
-    tar_compression = {'gzip': 'gz', None: ''}
-    compress_ext = {'gzip': '.gz'}
-
-    if _BZ2_SUPPORTED:
-        tar_compression['bzip2'] = 'bz2'
-        compress_ext['bzip2'] = '.bz2'
-
-    if _LZMA_SUPPORTED:
-        tar_compression['xz'] = 'xz'
-        compress_ext['xz'] = '.xz'
-
-    # flags for compression program, each element of list will be an argument
-    if compress is not None and compress not in compress_ext:
+    if compress is None:
+        tar_compression = ''
+    elif _ZLIB_SUPPORTED and compress == 'gzip':
+        tar_compression = 'gz'
+    elif _BZ2_SUPPORTED and compress == 'bzip2':
+        tar_compression = 'bz2'
+    elif _LZMA_SUPPORTED and compress == 'xz':
+        tar_compression = 'xz'
+    else:
         raise ValueError("bad value for 'compress', or compression format not "
                          "supported : {0}".format(compress))
 
-    archive_name = base_name + '.tar' + compress_ext.get(compress, '')
+    import tarfile  # late import for breaking circular dependency
+
+    compress_ext = '.' + tar_compression if compress else ''
+    archive_name = base_name + '.tar' + compress_ext
     archive_dir = os.path.dirname(archive_name)
 
     if archive_dir and not os.path.exists(archive_dir):
@@ -644,7 +649,7 @@
         return tarinfo
 
     if not dry_run:
-        tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress])


More information about the pypy-commit mailing list