[pypy-commit] pypy vendor/stdlib: update to v2.7.16

mattip pypy.commits at gmail.com
Mon May 20 07:30:38 EDT 2019


Author: Matti Picus <matti.picus at gmail.com>
Branch: vendor/stdlib
Changeset: r96641:1779edf5c1e3
Date: 2019-05-20 12:55 +0300
http://bitbucket.org/pypy/pypy/changeset/1779edf5c1e3/

Log:	update to v2.7.16

diff too long, truncating to 2000 out of 46268 lines

diff --git a/lib-python/2.7/HTMLParser.py b/lib-python/2.7/HTMLParser.py
--- a/lib-python/2.7/HTMLParser.py
+++ b/lib-python/2.7/HTMLParser.py
@@ -462,11 +462,12 @@
             else:
                 # Cannot use name2codepoint directly, because HTMLParser supports apos,
                 # which is not part of HTML 4
-                import htmlentitydefs
                 if HTMLParser.entitydefs is None:
-                    entitydefs = HTMLParser.entitydefs = {'apos':u"'"}
+                    import htmlentitydefs
+                    entitydefs = {'apos':u"'"}
                     for k, v in htmlentitydefs.name2codepoint.iteritems():
                         entitydefs[k] = unichr(v)
+                    HTMLParser.entitydefs = entitydefs
                 try:
                     return self.entitydefs[s]
                 except KeyError:
diff --git a/lib-python/2.7/SocketServer.py b/lib-python/2.7/SocketServer.py
--- a/lib-python/2.7/SocketServer.py
+++ b/lib-python/2.7/SocketServer.py
@@ -229,6 +229,9 @@
                 # shutdown request and wastes cpu at all other times.
                 r, w, e = _eintr_retry(select.select, [self], [], [],
                                        poll_interval)
+                # bpo-35017: shutdown() called during select(), exit immediately.
+                if self.__shutdown_request:
+                    break
                 if self in r:
                     self._handle_request_noblock()
         finally:
diff --git a/lib-python/2.7/_pyio.py b/lib-python/2.7/_pyio.py
--- a/lib-python/2.7/_pyio.py
+++ b/lib-python/2.7/_pyio.py
@@ -1619,6 +1619,7 @@
         self.buffer.write(b)
         if self._line_buffering and (haslf or "\r" in s):
             self.flush()
+        self._set_decoded_chars('')
         self._snapshot = None
         if self._decoder:
             self._decoder.reset()
diff --git a/lib-python/2.7/_strptime.py b/lib-python/2.7/_strptime.py
--- a/lib-python/2.7/_strptime.py
+++ b/lib-python/2.7/_strptime.py
@@ -254,8 +254,8 @@
         # format directives (%m, etc.).
         regex_chars = re_compile(r"([\\.^$*+?\(\){}\[\]|])")
         format = regex_chars.sub(r"\\\1", format)
-        whitespace_replacement = re_compile('\s+')
-        format = whitespace_replacement.sub('\s+', format)
+        whitespace_replacement = re_compile(r'\s+')
+        format = whitespace_replacement.sub(r'\\s+', format)
         while '%' in format:
             directive_index = format.index('%')+1
             processed_format = "%s%s%s" % (processed_format,
diff --git a/lib-python/2.7/_threading_local.py b/lib-python/2.7/_threading_local.py
--- a/lib-python/2.7/_threading_local.py
+++ b/lib-python/2.7/_threading_local.py
@@ -57,11 +57,7 @@
 
   >>> class MyLocal(local):
   ...     number = 2
-  ...     initialized = False
   ...     def __init__(self, **kw):
-  ...         if self.initialized:
-  ...             raise SystemError('__init__ called too many times')
-  ...         self.initialized = True
   ...         self.__dict__.update(kw)
   ...     def squared(self):
   ...         return self.number ** 2
@@ -98,7 +94,7 @@
   >>> thread.start()
   >>> thread.join()
   >>> log
-  [[('color', 'red'), ('initialized', True)], 11]
+  [[('color', 'red')], 11]
 
 without affecting this thread's data:
 
diff --git a/lib-python/2.7/aifc.py b/lib-python/2.7/aifc.py
--- a/lib-python/2.7/aifc.py
+++ b/lib-python/2.7/aifc.py
@@ -288,6 +288,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._decomp = None
@@ -306,6 +308,7 @@
         else:
             raise Error, 'not an AIFF or AIFF-C file'
         self._comm_chunk_read = 0
+        self._ssnd_chunk = None
         while 1:
             self._ssnd_seek_needed = 1
             try:
@@ -341,10 +344,16 @@
             self._decomp.SetParams(params)
 
     def __init__(self, f):
-        if type(f) == type(''):
+        if isinstance(f, basestring):
             f = __builtin__.open(f, 'rb')
-        # else, assume it is an open file object already
-        self.initfp(f)
+            try:
+                self.initfp(f)
+            except:
+                f.close()
+                raise
+        else:
+            # assume it is an open file object already
+            self.initfp(f)
 
     #
     # User visible methods.
@@ -562,8 +571,10 @@
     # _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 type(f) == type(''):
+        if isinstance(f, basestring):
             filename = f
             f = __builtin__.open(f, 'wb')
         else:
diff --git a/lib-python/2.7/argparse.py b/lib-python/2.7/argparse.py
--- a/lib-python/2.7/argparse.py
+++ b/lib-python/2.7/argparse.py
@@ -324,7 +324,11 @@
             if len(prefix) + len(usage) > text_width:
 
                 # break usage into wrappable parts
-                part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
+                part_regexp = (
+                    r'\(.*?\)+(?=\s|$)|'
+                    r'\[.*?\]+(?=\s|$)|'
+                    r'\S+'
+                )
                 opt_usage = format(optionals, groups)
                 pos_usage = format(positionals, groups)
                 opt_parts = _re.findall(part_regexp, opt_usage)
diff --git a/lib-python/2.7/asynchat.py b/lib-python/2.7/asynchat.py
--- a/lib-python/2.7/asynchat.py
+++ b/lib-python/2.7/asynchat.py
@@ -133,7 +133,7 @@
                 # no terminator, collect it all
                 self.collect_incoming_data (self.ac_in_buffer)
                 self.ac_in_buffer = ''
-            elif isinstance(terminator, int) or isinstance(terminator, long):
+            elif isinstance(terminator, (int, long)):
                 # numeric terminator
                 n = terminator
                 if lb < n:
diff --git a/lib-python/2.7/asyncore.py b/lib-python/2.7/asyncore.py
--- a/lib-python/2.7/asyncore.py
+++ b/lib-python/2.7/asyncore.py
@@ -633,7 +633,11 @@
         write = send
 
         def close(self):
-            os.close(self.fd)
+            if self.fd < 0:
+                return
+            fd = self.fd
+            self.fd = -1
+            os.close(fd)
 
         def fileno(self):
             return self.fd
diff --git a/lib-python/2.7/bsddb/test/test_associate.py b/lib-python/2.7/bsddb/test/test_associate.py
--- a/lib-python/2.7/bsddb/test/test_associate.py
+++ b/lib-python/2.7/bsddb/test/test_associate.py
@@ -114,6 +114,22 @@
             dupDB.close()
             self.fail("DBError exception was expected")
 
+    @unittest.skipUnless(db.version() >= (4, 6), 'Needs 4.6+')
+    def test_associateListError(self):
+        db1 = db.DB(self.env)
+        db1.open('bad.db', "a.db", db.DB_BTREE, db.DB_CREATE)
+        db2 = db.DB(self.env)
+        db2.open('bad.db', "b.db", db.DB_BTREE, db.DB_CREATE)
+
+        db1.associate(db2, lambda a, b: [0])
+
+        msg = "TypeError: The list returned by DB->associate callback" \
+              " should be a list of strings."
+        with test_support.captured_output("stderr") as s:
+            db1.put("0", "1")
+        db1.close()
+        db2.close()
+        self.assertEquals(s.getvalue().strip(), msg)
 
 
 #----------------------------------------------------------------------
@@ -233,7 +249,7 @@
         self.assertEqual(vals, None, vals)
 
         vals = secDB.pget('Unknown', txn=txn)
-        self.assertTrue(vals[0] == 99 or vals[0] == '99', vals)
+        self.assertIn(vals[0], (99, '99'), vals)
         vals[1].index('Unknown')
         vals[1].index('Unnamed')
         vals[1].index('unknown')
@@ -247,7 +263,8 @@
             if type(self.keytype) == type(''):
                 self.assertTrue(int(rec[0]))  # for primary db, key is a number
             else:
-                self.assertTrue(rec[0] and type(rec[0]) == type(0))
+                self.assertTrue(rec[0])
+                self.assertIs(type(rec[0]), int)
             count = count + 1
             if verbose:
                 print rec
@@ -262,7 +279,7 @@
 
         # test cursor pget
         vals = self.cur.pget('Unknown', flags=db.DB_LAST)
-        self.assertTrue(vals[1] == 99 or vals[1] == '99', vals)
+        self.assertIn(vals[1], (99, '99'), vals)
         self.assertEqual(vals[0], 'Unknown')
         vals[2].index('Unknown')
         vals[2].index('Unnamed')
diff --git a/lib-python/2.7/bsddb/test/test_basics.py b/lib-python/2.7/bsddb/test/test_basics.py
--- a/lib-python/2.7/bsddb/test/test_basics.py
+++ b/lib-python/2.7/bsddb/test/test_basics.py
@@ -597,7 +597,7 @@
 
         d.put("abcde", "ABCDE");
         num = d.truncate()
-        self.assertTrue(num >= 1, "truncate returned <= 0 on non-empty database")
+        self.assertGreaterEqual(num, 1, "truncate returned <= 0 on non-empty database")
         num = d.truncate()
         self.assertEqual(num, 0,
                 "truncate on empty DB returned nonzero (%r)" % (num,))
@@ -616,9 +616,9 @@
     if db.version() >= (4, 6):
         def test08_exists(self) :
             self.d.put("abcde", "ABCDE")
-            self.assertTrue(self.d.exists("abcde") == True,
+            self.assertEqual(self.d.exists("abcde"), True,
                     "DB->exists() returns wrong value")
-            self.assertTrue(self.d.exists("x") == False,
+            self.assertEqual(self.d.exists("x"), False,
                     "DB->exists() returns wrong value")
 
     #----------------------------------------
@@ -773,7 +773,7 @@
             if verbose:
                 print 'log file: ' + log
             logs = self.env.log_archive(db.DB_ARCH_REMOVE)
-            self.assertTrue(not logs)
+            self.assertFalse(logs)
 
         self.txn = self.env.txn_begin()
 
@@ -785,9 +785,9 @@
             self.d.put("abcde", "ABCDE", txn=txn)
             txn.commit()
             txn = self.env.txn_begin()
-            self.assertTrue(self.d.exists("abcde", txn=txn) == True,
+            self.assertEqual(self.d.exists("abcde", txn=txn), True,
                     "DB->exists() returns wrong value")
-            self.assertTrue(self.d.exists("x", txn=txn) == False,
+            self.assertEqual(self.d.exists("x", txn=txn), False,
                     "DB->exists() returns wrong value")
             txn.abort()
 
@@ -802,7 +802,7 @@
         d.put("abcde", "ABCDE");
         txn = self.env.txn_begin()
         num = d.truncate(txn)
-        self.assertTrue(num >= 1, "truncate returned <= 0 on non-empty database")
+        self.assertGreaterEqual(num, 1, "truncate returned <= 0 on non-empty database")
         num = d.truncate(txn)
         self.assertEqual(num, 0,
                 "truncate on empty DB returned nonzero (%r)" % (num,))
@@ -1086,7 +1086,7 @@
         a = "example of private object"
         self.obj.set_private(a)
         b = self.obj.get_private()
-        self.assertTrue(a is b)  # Object identity
+        self.assertIs(a, b)  # Object identity
 
     def test03_leak_assignment(self) :
         a = "example of private object"
diff --git a/lib-python/2.7/bsddb/test/test_dbenv.py b/lib-python/2.7/bsddb/test/test_dbenv.py
--- a/lib-python/2.7/bsddb/test/test_dbenv.py
+++ b/lib-python/2.7/bsddb/test/test_dbenv.py
@@ -54,15 +54,15 @@
                 self.env.set_cache_max(0, size)
                 size2 = self.env.get_cache_max()
                 self.assertEqual(0, size2[0])
-                self.assertTrue(size <= size2[1])
-                self.assertTrue(2*size > size2[1])
+                self.assertLessEqual(size, size2[1])
+                self.assertGreater(2*size, size2[1])
 
     if db.version() >= (4, 4) :
         def test_mutex_stat(self) :
             self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
                     db.DB_INIT_LOCK)
             stat = self.env.mutex_stat()
-            self.assertTrue("mutex_inuse_max" in stat)
+            self.assertIn("mutex_inuse_max", stat)
 
         def test_lg_filemode(self) :
             for i in [0600, 0660, 0666] :
@@ -128,8 +128,8 @@
                 i = i*1024*1024
                 self.env.set_lg_regionmax(i)
                 j = self.env.get_lg_regionmax()
-                self.assertTrue(i <= j)
-                self.assertTrue(2*i > j)
+                self.assertLessEqual(i, j)
+                self.assertGreater(2*i, j)
 
         def test_lk_detect(self) :
             flags= [db.DB_LOCK_DEFAULT, db.DB_LOCK_EXPIRE, db.DB_LOCK_MAXLOCKS,
@@ -150,10 +150,10 @@
         def test_lg_bsize(self) :
             log_size = 70*1024
             self.env.set_lg_bsize(log_size)
-            self.assertTrue(self.env.get_lg_bsize() >= log_size)
-            self.assertTrue(self.env.get_lg_bsize() < 4*log_size)
+            self.assertGreaterEqual(self.env.get_lg_bsize(), log_size)
+            self.assertLess(self.env.get_lg_bsize(), 4*log_size)
             self.env.set_lg_bsize(4*log_size)
-            self.assertTrue(self.env.get_lg_bsize() >= 4*log_size)
+            self.assertGreaterEqual(self.env.get_lg_bsize(), 4*log_size)
 
         def test_setget_data_dirs(self) :
             dirs = ("a", "b", "c", "d")
@@ -185,7 +185,7 @@
             self.assertEqual(cachesize2[0], cachesize3[0])
             self.assertEqual(cachesize2[2], cachesize3[2])
             # In Berkeley DB 5.1, the cachesize can change when opening the Env
-            self.assertTrue(cachesize2[1] <= cachesize3[1])
+            self.assertLessEqual(cachesize2[1], cachesize3[1])
 
         def test_set_cachesize_dbenv_db(self) :
             # You can not configure the cachesize using
@@ -299,7 +299,7 @@
             msg = "This is a test..."
             self.env.log_printf(msg)
             logc = self.env.log_cursor()
-            self.assertTrue(msg in (logc.last()[1]))
+            self.assertIn(msg, logc.last()[1])
 
     if db.version() >= (4, 7) :
         def test_log_config(self) :
@@ -341,21 +341,21 @@
             txn.commit()
             logc = self.env.log_cursor()
             logc.last()  # Skip the commit
-            self.assertTrue(msg in (logc.prev()[1]))
+            self.assertIn(msg, logc.prev()[1])
 
             msg = "This is another test..."
             txn = self.env.txn_begin()
             self.env.log_printf(msg, txn=txn)
             txn.abort()  # Do not store the new message
             logc.last()  # Skip the abort
-            self.assertTrue(msg not in (logc.prev()[1]))
+            self.assertNotIn(msg, logc.prev()[1])
 
             msg = "This is a third test..."
             txn = self.env.txn_begin()
             self.env.log_printf(msg, txn=txn)
             txn.commit()  # Do not store the new message
             logc.last()  # Skip the commit
-            self.assertTrue(msg in (logc.prev()[1]))
+            self.assertIn(msg, logc.prev()[1])
 
 
 class DBEnv_memp(DBEnv):
@@ -372,39 +372,39 @@
 
     def test_memp_1_trickle(self) :
         self.db.put("hi", "bye")
-        self.assertTrue(self.env.memp_trickle(100) > 0)
+        self.assertGreater(self.env.memp_trickle(100), 0)
 
 # Preserve the order, do "memp_trickle" test first
     def test_memp_2_sync(self) :
         self.db.put("hi", "bye")
         self.env.memp_sync()  # Full flush
         # Nothing to do...
-        self.assertTrue(self.env.memp_trickle(100) == 0)
+        self.assertEqual(self.env.memp_trickle(100), 0)
 
         self.db.put("hi", "bye2")
         self.env.memp_sync((1, 0))  # NOP, probably
         # Something to do... or not
-        self.assertTrue(self.env.memp_trickle(100) >= 0)
+        self.assertGreaterEqual(self.env.memp_trickle(100), 0)
 
         self.db.put("hi", "bye3")
         self.env.memp_sync((123, 99))  # Full flush
         # Nothing to do...
-        self.assertTrue(self.env.memp_trickle(100) == 0)
+        self.assertEqual(self.env.memp_trickle(100), 0)
 
     def test_memp_stat_1(self) :
         stats = self.env.memp_stat()  # No param
-        self.assertTrue(len(stats)==2)
-        self.assertTrue("cache_miss" in stats[0])
+        self.assertEqual(len(stats), 2)
+        self.assertIn("cache_miss", stats[0])
         stats = self.env.memp_stat(db.DB_STAT_CLEAR)  # Positional param
-        self.assertTrue("cache_miss" in stats[0])
+        self.assertIn("cache_miss", stats[0])
         stats = self.env.memp_stat(flags=0)  # Keyword param
-        self.assertTrue("cache_miss" in stats[0])
+        self.assertIn("cache_miss", stats[0])
 
     def test_memp_stat_2(self) :
         stats=self.env.memp_stat()[1]
-        self.assertTrue(len(stats))==1
-        self.assertTrue("test" in stats)
-        self.assertTrue("page_in" in stats["test"])
+        self.assertEqual(len(stats), 1)
+        self.assertIn("test", stats)
+        self.assertIn("page_in", stats["test"])
 
 class DBEnv_logcursor(DBEnv):
     def setUp(self):
@@ -426,28 +426,28 @@
         DBEnv.tearDown(self)
 
     def _check_return(self, value) :
-        self.assertTrue(isinstance(value, tuple))
+        self.assertIsInstance(value, tuple)
         self.assertEqual(len(value), 2)
-        self.assertTrue(isinstance(value[0], tuple))
+        self.assertIsInstance(value[0], tuple)
         self.assertEqual(len(value[0]), 2)
-        self.assertTrue(isinstance(value[0][0], int))
-        self.assertTrue(isinstance(value[0][1], int))
-        self.assertTrue(isinstance(value[1], str))
+        self.assertIsInstance(value[0][0], int)
+        self.assertIsInstance(value[0][1], int)
+        self.assertIsInstance(value[1], str)
 
     # Preserve test order
     def test_1_first(self) :
         logc = self.env.log_cursor()
         v = logc.first()
         self._check_return(v)
-        self.assertTrue((1, 1) < v[0])
-        self.assertTrue(len(v[1])>0)
+        self.assertLess((1, 1), v[0])
+        self.assertGreater(len(v[1]), 0)
 
     def test_2_last(self) :
         logc = self.env.log_cursor()
         lsn_first = logc.first()[0]
         v = logc.last()
         self._check_return(v)
-        self.assertTrue(lsn_first < v[0])
+        self.assertLess(lsn_first, v[0])
 
     def test_3_next(self) :
         logc = self.env.log_cursor()
@@ -456,16 +456,16 @@
         lsn_first = logc.first()[0]
         v = logc.next()
         self._check_return(v)
-        self.assertTrue(lsn_first < v[0])
-        self.assertTrue(lsn_last > v[0])
+        self.assertLess(lsn_first, v[0])
+        self.assertGreater(lsn_last, v[0])
 
         v2 = logc.next()
-        self.assertTrue(v2[0] > v[0])
-        self.assertTrue(lsn_last > v2[0])
+        self.assertGreater(v2[0], v[0])
+        self.assertGreater(lsn_last, v2[0])
 
         v3 = logc.next()
-        self.assertTrue(v3[0] > v2[0])
-        self.assertTrue(lsn_last > v3[0])
+        self.assertGreater(v3[0], v2[0])
+        self.assertGreater(lsn_last, v3[0])
 
     def test_4_prev(self) :
         logc = self.env.log_cursor()
@@ -474,16 +474,16 @@
         lsn_last = logc.last()[0]
         v = logc.prev()
         self._check_return(v)
-        self.assertTrue(lsn_first < v[0])
-        self.assertTrue(lsn_last > v[0])
+        self.assertLess(lsn_first, v[0])
+        self.assertGreater(lsn_last, v[0])
 
         v2 = logc.prev()
-        self.assertTrue(v2[0] < v[0])
-        self.assertTrue(lsn_first < v2[0])
+        self.assertLess(v2[0], v[0])
+        self.assertLess(lsn_first, v2[0])
 
         v3 = logc.prev()
-        self.assertTrue(v3[0] < v2[0])
-        self.assertTrue(lsn_first < v3[0])
+        self.assertLess(v3[0], v2[0])
+        self.assertLess(lsn_first, v3[0])
 
     def test_5_current(self) :
         logc = self.env.log_cursor()
diff --git a/lib-python/2.7/bsddb/test/test_dbshelve.py b/lib-python/2.7/bsddb/test/test_dbshelve.py
--- a/lib-python/2.7/bsddb/test/test_dbshelve.py
+++ b/lib-python/2.7/bsddb/test/test_dbshelve.py
@@ -248,7 +248,7 @@
             self.assertEqual(value.L, [x] * 10)
 
         else:
-            self.assertTrue(0, 'Unknown key type, fix the test')
+            self.fail('Unknown key type, fix the test')
 
 #----------------------------------------------------------------------
 
diff --git a/lib-python/2.7/bsddb/test/test_dbtables.py b/lib-python/2.7/bsddb/test/test_dbtables.py
--- a/lib-python/2.7/bsddb/test/test_dbtables.py
+++ b/lib-python/2.7/bsddb/test/test_dbtables.py
@@ -82,8 +82,8 @@
             colval = pickle.loads(values[0][colname])
         else :
             colval = pickle.loads(bytes(values[0][colname], "iso8859-1"))
-        self.assertTrue(colval > 3.141)
-        self.assertTrue(colval < 3.142)
+        self.assertGreater(colval, 3.141)
+        self.assertLess(colval, 3.142)
 
 
     def test02(self):
diff --git a/lib-python/2.7/bsddb/test/test_distributed_transactions.py b/lib-python/2.7/bsddb/test/test_distributed_transactions.py
--- a/lib-python/2.7/bsddb/test/test_distributed_transactions.py
+++ b/lib-python/2.7/bsddb/test/test_distributed_transactions.py
@@ -79,7 +79,7 @@
         recovered_txns=self.dbenv.txn_recover()
         self.assertEqual(self.num_txns,len(recovered_txns))
         for gid,txn in recovered_txns :
-            self.assertTrue(gid in txns)
+            self.assertIn(gid, txns)
         del txn
         del recovered_txns
 
@@ -122,7 +122,7 @@
     # Be sure there are not pending transactions.
     # Check also database size.
         recovered_txns=self.dbenv.txn_recover()
-        self.assertTrue(len(recovered_txns)==0)
+        self.assertEqual(len(recovered_txns), 0)
         self.assertEqual(len(committed_txns),self.db.stat()["nkeys"])
 
 class DBTxn_distributedSYNC(DBTxn_distributed):
diff --git a/lib-python/2.7/bsddb/test/test_lock.py b/lib-python/2.7/bsddb/test/test_lock.py
--- a/lib-python/2.7/bsddb/test/test_lock.py
+++ b/lib-python/2.7/bsddb/test/test_lock.py
@@ -2,6 +2,7 @@
 TestCases for testing the locking sub-system.
 """
 
+import sys
 import time
 
 import unittest
@@ -10,7 +11,6 @@
 
 if have_threads :
     from threading import Thread
-    import sys
     if sys.version_info[0] < 3 :
         from threading import currentThread
     else :
@@ -129,7 +129,14 @@
         end_time=time.time()
         deadlock_detection.end=True
         # Floating point rounding
-        self.assertTrue((end_time-start_time) >= 0.0999)
+        if sys.platform == 'win32':
+            # bpo-30850: On Windows, tolerate 50 ms whereas 100 ms is expected.
+            # The lock sometimes times out after only 58 ms. Windows clocks
+            # have a bad resolution and bad accuracy.
+            min_dt = 0.050
+        else:
+            min_dt = 0.0999
+        self.assertGreaterEqual(end_time-start_time, min_dt)
         self.env.lock_put(lock)
         t.join()
 
@@ -137,7 +144,7 @@
         self.env.lock_id_free(anID2)
 
         if db.version() >= (4,6):
-            self.assertTrue(deadlock_detection.count>0)
+            self.assertGreater(deadlock_detection.count, 0)
 
     def theThread(self, lockType):
         import sys
diff --git a/lib-python/2.7/bsddb/test/test_misc.py b/lib-python/2.7/bsddb/test/test_misc.py
--- a/lib-python/2.7/bsddb/test/test_misc.py
+++ b/lib-python/2.7/bsddb/test/test_misc.py
@@ -25,7 +25,7 @@
     def test02_db_home(self):
         env = db.DBEnv()
         # check for crash fixed when db_home is used before open()
-        self.assertTrue(env.db_home is None)
+        self.assertIsNone(env.db_home)
         env.open(self.homeDir, db.DB_CREATE)
         if sys.version_info[0] < 3 :
             self.assertEqual(self.homeDir, env.db_home)
diff --git a/lib-python/2.7/bsddb/test/test_recno.py b/lib-python/2.7/bsddb/test/test_recno.py
--- a/lib-python/2.7/bsddb/test/test_recno.py
+++ b/lib-python/2.7/bsddb/test/test_recno.py
@@ -18,7 +18,7 @@
         def assertIsInstance(self, obj, datatype, msg=None) :
             return self.assertEqual(type(obj), datatype, msg=msg)
         def assertGreaterEqual(self, a, b, msg=None) :
-            return self.assertTrue(a>=b, msg=msg)
+            return self.assertGreaterEqual(a, b, msg=msg)
 
 
     def setUp(self):
diff --git a/lib-python/2.7/bsddb/test/test_replication.py b/lib-python/2.7/bsddb/test/test_replication.py
--- a/lib-python/2.7/bsddb/test/test_replication.py
+++ b/lib-python/2.7/bsddb/test/test_replication.py
@@ -186,20 +186,18 @@
         d = d.values()[0]  # There is only one
         self.assertEqual(d[0], "127.0.0.1")
         self.assertEqual(d[1], client_port)
-        self.assertTrue((d[2]==db.DB_REPMGR_CONNECTED) or \
-                (d[2]==db.DB_REPMGR_DISCONNECTED))
+        self.assertIn(d[2], (db.DB_REPMGR_CONNECTED, db.DB_REPMGR_DISCONNECTED))
 
         d = self.dbenvClient.repmgr_site_list()
         self.assertEqual(len(d), 1)
         d = d.values()[0]  # There is only one
         self.assertEqual(d[0], "127.0.0.1")
         self.assertEqual(d[1], master_port)
-        self.assertTrue((d[2]==db.DB_REPMGR_CONNECTED) or \
-                (d[2]==db.DB_REPMGR_DISCONNECTED))
+        self.assertIn(d[2], (db.DB_REPMGR_CONNECTED, db.DB_REPMGR_DISCONNECTED))
 
         if db.version() >= (4,6) :
             d = self.dbenvMaster.repmgr_stat(flags=db.DB_STAT_CLEAR);
-            self.assertTrue("msgs_queued" in d)
+            self.assertIn("msgs_queued", d)
 
         self.dbMaster=db.DB(self.dbenvMaster)
         txn=self.dbenvMaster.txn_begin()
@@ -247,7 +245,7 @@
         if time.time()>=timeout and startup_timeout:
             self.skipTest("replication test skipped due to random failure, "
                 "see issue 3892")
-        self.assertTrue(time.time()<timeout)
+        self.assertLess(time.time(), timeout)
         self.assertEqual("123", v)
 
         txn=self.dbenvMaster.txn_begin()
@@ -260,7 +258,7 @@
             txn.commit()
             if v is None :
                 time.sleep(0.02)
-        self.assertTrue(time.time()<timeout)
+        self.assertLess(time.time(), timeout)
         self.assertEqual(None, v)
 
 class DBBaseReplication(DBReplication) :
@@ -381,7 +379,7 @@
         while (time.time()<timeout) and not (self.confirmed_master and
                 self.client_startupdone) :
             time.sleep(0.02)
-        self.assertTrue(time.time()<timeout)
+        self.assertLess(time.time(), timeout)
 
         self.dbMaster=db.DB(self.dbenvMaster)
         txn=self.dbenvMaster.txn_begin()
@@ -410,7 +408,7 @@
             break
 
         d = self.dbenvMaster.rep_stat(flags=db.DB_STAT_CLEAR);
-        self.assertTrue("master_changes" in d)
+        self.assertIn("master_changes", d)
 
         txn=self.dbenvMaster.txn_begin()
         self.dbMaster.put("ABC", "123", txn=txn)
@@ -424,7 +422,7 @@
             txn.commit()
             if v is None :
                 time.sleep(0.02)
-        self.assertTrue(time.time()<timeout)
+        self.assertLess(time.time(), timeout)
         self.assertEqual("123", v)
 
         txn=self.dbenvMaster.txn_begin()
@@ -437,7 +435,7 @@
             txn.commit()
             if v is None :
                 time.sleep(0.02)
-        self.assertTrue(time.time()<timeout)
+        self.assertLess(time.time(), timeout)
         self.assertEqual(None, v)
 
     if db.version() >= (4,7) :
diff --git a/lib-python/2.7/bsddb/test/test_sequence.py b/lib-python/2.7/bsddb/test/test_sequence.py
--- a/lib-python/2.7/bsddb/test/test_sequence.py
+++ b/lib-python/2.7/bsddb/test/test_sequence.py
@@ -82,7 +82,7 @@
         stat = self.seq.stat()
         for param in ('nowait', 'min', 'max', 'value', 'current',
                       'flags', 'cache_size', 'last_value', 'wait'):
-            self.assertTrue(param in stat, "parameter %s isn't in stat info" % param)
+            self.assertIn(param, stat, "parameter %s isn't in stat info" % param)
 
     if db.version() >= (4,7) :
         # This code checks a crash solved in Berkeley DB 4.7
diff --git a/lib-python/2.7/bsddb/test/test_thread.py b/lib-python/2.7/bsddb/test/test_thread.py
--- a/lib-python/2.7/bsddb/test/test_thread.py
+++ b/lib-python/2.7/bsddb/test/test_thread.py
@@ -85,7 +85,7 @@
         readers_per_writer=self.readers//self.writers
         self.assertEqual(self.records,self.writers*records_per_writer)
         self.assertEqual(self.readers,self.writers*readers_per_writer)
-        self.assertTrue((records_per_writer%readers_per_writer)==0)
+        self.assertEqual(records_per_writer%readers_per_writer, 0)
         readers = []
 
         for x in xrange(self.readers):
@@ -213,7 +213,7 @@
         readers_per_writer=self.readers//self.writers
         self.assertEqual(self.records,self.writers*records_per_writer)
         self.assertEqual(self.readers,self.writers*readers_per_writer)
-        self.assertTrue((records_per_writer%readers_per_writer)==0)
+        self.assertEqual(records_per_writer%readers_per_writer, 0)
 
         readers = []
         for x in xrange(self.readers):
@@ -339,7 +339,7 @@
         readers_per_writer=self.readers//self.writers
         self.assertEqual(self.records,self.writers*records_per_writer)
         self.assertEqual(self.readers,self.writers*readers_per_writer)
-        self.assertTrue((records_per_writer%readers_per_writer)==0)
+        self.assertEqual(records_per_writer%readers_per_writer, 0)
 
         readers=[]
         for x in xrange(self.readers):
diff --git a/lib-python/2.7/cProfile.py b/lib-python/2.7/cProfile.py
--- a/lib-python/2.7/cProfile.py
+++ b/lib-python/2.7/cProfile.py
@@ -64,11 +64,11 @@
 # ____________________________________________________________
 
 class Profile(_lsprof.Profiler):
-    """Profile(custom_timer=None, time_unit=None, subcalls=True, builtins=True)
+    """Profile(timer=None, timeunit=None, subcalls=True, builtins=True)
 
     Builds a profiler object using the specified timer function.
     The default timer is a fast built-in one based on real time.
-    For custom timer functions returning integers, time_unit can
+    For custom timer functions returning integers, timeunit can
     be a float specifying a scale (i.e. how long each integer unit
     is, in seconds).
     """
@@ -161,7 +161,7 @@
 # ____________________________________________________________
 
 def main():
-    import os, sys
+    import os, sys, pstats
     from optparse import OptionParser
     usage = "cProfile.py [-o output_file_path] [-s sort] scriptfile [arg] ..."
     parser = OptionParser(usage=usage)
@@ -170,7 +170,8 @@
         help="Save stats to <outfile>", default=None)
     parser.add_option('-s', '--sort', dest="sort",
         help="Sort order when printing to stdout, based on pstats.Stats class",
-        default=-1)
+        default=-1,
+        choices=sorted(pstats.Stats.sort_arg_dict_default))
 
     if not sys.argv[1:]:
         parser.print_usage()
diff --git a/lib-python/2.7/cgi.py b/lib-python/2.7/cgi.py
--- a/lib-python/2.7/cgi.py
+++ b/lib-python/2.7/cgi.py
@@ -184,11 +184,12 @@
     return urlparse.parse_qs(qs, keep_blank_values, strict_parsing)
 
 
-def parse_qsl(qs, keep_blank_values=0, strict_parsing=0):
+def parse_qsl(qs, keep_blank_values=0, strict_parsing=0, max_num_fields=None):
     """Parse a query given as a string argument."""
     warn("cgi.parse_qsl is deprecated, use urlparse.parse_qsl instead",
          PendingDeprecationWarning, 2)
-    return urlparse.parse_qsl(qs, keep_blank_values, strict_parsing)
+    return urlparse.parse_qsl(qs, keep_blank_values, strict_parsing,
+                              max_num_fields)
 
 def parse_multipart(fp, pdict):
     """Parse multipart input.
@@ -393,7 +394,8 @@
     """
 
     def __init__(self, fp=None, headers=None, outerboundary="",
-                 environ=os.environ, keep_blank_values=0, strict_parsing=0):
+                 environ=os.environ, keep_blank_values=0, strict_parsing=0,
+                 max_num_fields=None):
         """Constructor.  Read multipart/* until last part.
 
         Arguments, all optional:
@@ -420,10 +422,14 @@
             If false (the default), errors are silently ignored.
             If true, errors raise a ValueError exception.
 
+        max_num_fields: int. If set, then __init__ throws a ValueError
+            if there are more than n fields read by parse_qsl().
+
         """
         method = 'GET'
         self.keep_blank_values = keep_blank_values
         self.strict_parsing = strict_parsing
+        self.max_num_fields = max_num_fields
         if 'REQUEST_METHOD' in environ:
             method = environ['REQUEST_METHOD'].upper()
         self.qs_on_post = None
@@ -606,10 +612,9 @@
         qs = self.fp.read(self.length)
         if self.qs_on_post:
             qs += '&' + self.qs_on_post
-        self.list = list = []
-        for key, value in urlparse.parse_qsl(qs, self.keep_blank_values,
-                                            self.strict_parsing):
-            list.append(MiniFieldStorage(key, value))
+        query = urlparse.parse_qsl(qs, self.keep_blank_values,
+                                   self.strict_parsing, self.max_num_fields)
+        self.list = [MiniFieldStorage(key, value) for key, value in query]
         self.skip_lines()
 
     FieldStorageClass = None
@@ -621,19 +626,38 @@
             raise ValueError, 'Invalid boundary in multipart form: %r' % (ib,)
         self.list = []
         if self.qs_on_post:
-            for key, value in urlparse.parse_qsl(self.qs_on_post,
-                                self.keep_blank_values, self.strict_parsing):
-                self.list.append(MiniFieldStorage(key, value))
+            query = urlparse.parse_qsl(self.qs_on_post,
+                                       self.keep_blank_values,
+                                       self.strict_parsing,
+                                       self.max_num_fields)
+            self.list.extend(MiniFieldStorage(key, value)
+                             for key, value in query)
             FieldStorageClass = None
 
+        # Propagate max_num_fields into the sub class appropriately
+        max_num_fields = self.max_num_fields
+        if max_num_fields is not None:
+            max_num_fields -= len(self.list)
+
         klass = self.FieldStorageClass or self.__class__
         part = klass(self.fp, {}, ib,
-                     environ, keep_blank_values, strict_parsing)
+                     environ, keep_blank_values, strict_parsing,
+                     max_num_fields)
+
         # Throw first part away
         while not part.done:
             headers = rfc822.Message(self.fp)
             part = klass(self.fp, headers, ib,
-                         environ, keep_blank_values, strict_parsing)
+                         environ, keep_blank_values, strict_parsing,
+                         max_num_fields)
+
+            if max_num_fields is not None:
+                max_num_fields -= 1
+                if part.list:
+                    max_num_fields -= len(part.list)
+                if max_num_fields < 0:
+                    raise ValueError('Max number of fields exceeded')
+
             self.list.append(part)
         self.skip_lines()
 
diff --git a/lib-python/2.7/cgitb.py b/lib-python/2.7/cgitb.py
--- a/lib-python/2.7/cgitb.py
+++ b/lib-python/2.7/cgitb.py
@@ -125,7 +125,7 @@
         args, varargs, varkw, locals = inspect.getargvalues(frame)
         call = ''
         if func != '?':
-            call = 'in ' + strong(func) + \
+            call = 'in ' + strong(pydoc.html.escape(func)) + \
                 inspect.formatargvalues(args, varargs, varkw, locals,
                     formatvalue=lambda value: '=' + pydoc.html.repr(value))
 
@@ -285,7 +285,7 @@
 
         if self.display:
             if plain:
-                doc = doc.replace('&', '&').replace('<', '<')
+                doc = pydoc.html.escape(doc)
                 self.file.write('<pre>' + doc + '</pre>\n')
             else:
                 self.file.write(doc + '\n')
diff --git a/lib-python/2.7/codecs.py b/lib-python/2.7/codecs.py
--- a/lib-python/2.7/codecs.py
+++ b/lib-python/2.7/codecs.py
@@ -472,15 +472,17 @@
             self.charbuffer = "".join(self.linebuffer)
             self.linebuffer = None
 
+        if chars < 0:
+            # For compatibility with other read() methods that take a
+            # single argument
+            chars = size
+
         # read until we get the required number of characters (if available)
         while True:
             # can the request be satisfied from the character buffer?
             if chars >= 0:
                 if len(self.charbuffer) >= chars:
                     break
-            elif size >= 0:
-                if len(self.charbuffer) >= size:
-                    break
             # we need more data
             if size < 0:
                 newdata = self.stream.read()
diff --git a/lib-python/2.7/compiler/pyassem.py b/lib-python/2.7/compiler/pyassem.py
--- a/lib-python/2.7/compiler/pyassem.py
+++ b/lib-python/2.7/compiler/pyassem.py
@@ -581,7 +581,7 @@
 
 def twobyte(val):
     """Convert an int argument into high and low bytes"""
-    assert isinstance(val, int)
+    assert isinstance(val, (int, long))
     return divmod(val, 256)
 
 class LineAddrTable:
diff --git a/lib-python/2.7/compiler/transformer.py b/lib-python/2.7/compiler/transformer.py
--- a/lib-python/2.7/compiler/transformer.py
+++ b/lib-python/2.7/compiler/transformer.py
@@ -1526,7 +1526,7 @@
 def debug_tree(tree):
     l = []
     for elt in tree:
-        if isinstance(elt, int):
+        if isinstance(elt, (int, long)):
             l.append(_names.get(elt, elt))
         elif isinstance(elt, str):
             l.append(elt)
diff --git a/lib-python/2.7/copy_reg.py b/lib-python/2.7/copy_reg.py
--- a/lib-python/2.7/copy_reg.py
+++ b/lib-python/2.7/copy_reg.py
@@ -127,7 +127,11 @@
                         continue
                     # mangled names
                     elif name.startswith('__') and not name.endswith('__'):
-                        names.append('_%s%s' % (c.__name__, name))
+                        stripped = c.__name__.lstrip('_')
+                        if stripped:
+                            names.append('_%s%s' % (stripped, name))
+                        else:
+                            names.append(name)
                     else:
                         names.append(name)
 
diff --git a/lib-python/2.7/csv.py b/lib-python/2.7/csv.py
--- a/lib-python/2.7/csv.py
+++ b/lib-python/2.7/csv.py
@@ -217,7 +217,7 @@
         matches = []
         for restr in ('(?P<delim>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?P=delim)', # ,".*?",
                       '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?P<delim>[^\w\n"\'])(?P<space> ?)',   #  ".*?",
-                      '(?P<delim>>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)',  # ,".*?"
+                      '(?P<delim>[^\w\n"\'])(?P<space> ?)(?P<quote>["\']).*?(?P=quote)(?:$|\n)',   # ,".*?"
                       '(?:^|\n)(?P<quote>["\']).*?(?P=quote)(?:$|\n)'):                            #  ".*?" (no delim, no space)
             regexp = re.compile(restr, re.DOTALL | re.MULTILINE)
             matches = regexp.findall(data)
diff --git a/lib-python/2.7/ctypes/__init__.py b/lib-python/2.7/ctypes/__init__.py
--- a/lib-python/2.7/ctypes/__init__.py
+++ b/lib-python/2.7/ctypes/__init__.py
@@ -342,6 +342,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/2.7/ctypes/test/test_anon.py b/lib-python/2.7/ctypes/test/test_anon.py
--- a/lib-python/2.7/ctypes/test/test_anon.py
+++ b/lib-python/2.7/ctypes/test/test_anon.py
@@ -1,4 +1,5 @@
 import unittest
+from test.support import cpython_only
 from ctypes import *
 
 class AnonTest(unittest.TestCase):
@@ -35,6 +36,18 @@
                                                       {"_fields_": [],
                                                        "_anonymous_": ["x"]}))
 
+    @cpython_only
+    def test_issue31490(self):
+        # There shouldn't be an assertion failure in case the class has an
+        # attribute whose name is specified in _anonymous_ but not in _fields_.
+
+        # AttributeError: 'x' is specified in _anonymous_ but not in _fields_
+        with self.assertRaises(AttributeError):
+            class Name(Structure):
+                _fields_ = []
+                _anonymous_ = ["x"]
+                x = 42
+
     def test_nested(self):
         class ANON_S(Structure):
             _fields_ = [("a", c_int)]
diff --git a/lib-python/2.7/ctypes/test/test_arrays.py b/lib-python/2.7/ctypes/test/test_arrays.py
--- a/lib-python/2.7/ctypes/test/test_arrays.py
+++ b/lib-python/2.7/ctypes/test/test_arrays.py
@@ -1,4 +1,6 @@
 import unittest
+from test.support import precisionbigmemtest, _2G
+import sys
 from ctypes import *
 
 from ctypes.test import need_symbol
@@ -132,5 +134,10 @@
         t2 = my_int * 1
         self.assertIs(t1, t2)
 
+    @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
+    @precisionbigmemtest(size=_2G, memuse=1, dry_run=False)
+    def test_large_array(self, size):
+        a = c_char * size
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/lib-python/2.7/ctypes/test/test_as_parameter.py b/lib-python/2.7/ctypes/test/test_as_parameter.py
--- a/lib-python/2.7/ctypes/test/test_as_parameter.py
+++ b/lib-python/2.7/ctypes/test/test_as_parameter.py
@@ -24,7 +24,7 @@
         f.argtypes = [c_byte, c_wchar, c_int, c_long, c_float, c_double]
         result = f(self.wrap(1), self.wrap(u"x"), self.wrap(3), self.wrap(4), self.wrap(5.0), self.wrap(6.0))
         self.assertEqual(result, 139)
-        self.assertTrue(type(result), int)
+        self.assertIs(type(result), int)
 
     def test_pointers(self):
         f = dll._testfunc_p_p
diff --git a/lib-python/2.7/ctypes/test/test_callbacks.py b/lib-python/2.7/ctypes/test/test_callbacks.py
--- a/lib-python/2.7/ctypes/test/test_callbacks.py
+++ b/lib-python/2.7/ctypes/test/test_callbacks.py
@@ -250,6 +250,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),
@@ -261,6 +262,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()
@@ -281,6 +287,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/2.7/ctypes/test/test_frombuffer.py b/lib-python/2.7/ctypes/test/test_frombuffer.py
--- a/lib-python/2.7/ctypes/test/test_frombuffer.py
+++ b/lib-python/2.7/ctypes/test/test_frombuffer.py
@@ -78,12 +78,21 @@
                           (c_int * 1).from_buffer_copy, a, 16 * sizeof(c_int))
 
     def test_abstract(self):
+        from ctypes import _Pointer, _SimpleCData, _CFuncPtr
+
         self.assertRaises(TypeError, Array.from_buffer, bytearray(10))
         self.assertRaises(TypeError, Structure.from_buffer, bytearray(10))
         self.assertRaises(TypeError, Union.from_buffer, bytearray(10))
+        self.assertRaises(TypeError, _CFuncPtr.from_buffer, bytearray(10))
+        self.assertRaises(TypeError, _Pointer.from_buffer, bytearray(10))
+        self.assertRaises(TypeError, _SimpleCData.from_buffer, bytearray(10))
+
         self.assertRaises(TypeError, Array.from_buffer_copy, b"123")
         self.assertRaises(TypeError, Structure.from_buffer_copy, b"123")
         self.assertRaises(TypeError, Union.from_buffer_copy, b"123")
+        self.assertRaises(TypeError, _CFuncPtr.from_buffer_copy, b"123")
+        self.assertRaises(TypeError, _Pointer.from_buffer_copy, b"123")
+        self.assertRaises(TypeError, _SimpleCData.from_buffer_copy, b"123")
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/lib-python/2.7/ctypes/test/test_funcptr.py b/lib-python/2.7/ctypes/test/test_funcptr.py
--- a/lib-python/2.7/ctypes/test/test_funcptr.py
+++ b/lib-python/2.7/ctypes/test/test_funcptr.py
@@ -123,5 +123,10 @@
         self.assertEqual(strtok(None, "\n"), "c")
         self.assertEqual(strtok(None, "\n"), None)
 
+    def test_abstract(self):
+        from ctypes import _CFuncPtr
+
+        self.assertRaises(TypeError, _CFuncPtr, 13, "name", 42, "iid")
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/lib-python/2.7/ctypes/test/test_loading.py b/lib-python/2.7/ctypes/test/test_loading.py
--- a/lib-python/2.7/ctypes/test/test_loading.py
+++ b/lib-python/2.7/ctypes/test/test_loading.py
@@ -3,6 +3,7 @@
 import os
 from ctypes.util import find_library
 from ctypes.test import is_resource_enabled
+import test.test_support as support
 
 libc_name = None
 if os.name == "nt":
@@ -27,6 +28,12 @@
         CDLL(os.path.basename(libc_name))
         self.assertRaises(OSError, CDLL, self.unknowndll)
 
+    @support.requires_unicode
+    @unittest.skipUnless(libc_name is not None, 'could not find libc')
+    def test_load_unicode(self):
+        CDLL(unicode(libc_name))
+        self.assertRaises(OSError, CDLL, unicode(self.unknowndll))
+
     @unittest.skipUnless(libc_name is not None, 'could not find libc')
     @unittest.skipUnless(libc_name is not None and
                          os.path.basename(libc_name) == "libc.so.6",
diff --git a/lib-python/2.7/ctypes/test/test_parameters.py b/lib-python/2.7/ctypes/test/test_parameters.py
--- a/lib-python/2.7/ctypes/test/test_parameters.py
+++ b/lib-python/2.7/ctypes/test/test_parameters.py
@@ -1,5 +1,6 @@
 import unittest, sys
 from ctypes.test import need_symbol
+import test.support
 
 class SimpleTypesTestCase(unittest.TestCase):
 
@@ -174,6 +175,36 @@
         # ArgumentError: argument 1: ValueError: 99
         self.assertRaises(ArgumentError, func, 99)
 
+    def test_abstract(self):
+        from ctypes import (Array, Structure, Union, _Pointer,
+                            _SimpleCData, _CFuncPtr)
+
+        self.assertRaises(TypeError, Array.from_param, 42)
+        self.assertRaises(TypeError, Structure.from_param, 42)
+        self.assertRaises(TypeError, Union.from_param, 42)
+        self.assertRaises(TypeError, _CFuncPtr.from_param, 42)
+        self.assertRaises(TypeError, _Pointer.from_param, 42)
+        self.assertRaises(TypeError, _SimpleCData.from_param, 42)
+
+    @test.support.cpython_only
+    def test_issue31311(self):
+        # __setstate__ should neither raise a SystemError nor crash in case
+        # of a bad __dict__.
+        from ctypes import Structure
+
+        class BadStruct(Structure):
+            @property
+            def __dict__(self):
+                pass
+        with self.assertRaises(TypeError):
+            BadStruct().__setstate__({}, b'foo')
+
+        class WorseStruct(Structure):
+            @property
+            def __dict__(self):
+                1/0.0
+        with self.assertRaises(ZeroDivisionError):
+            WorseStruct().__setstate__({}, b'foo')
 
 ################################################################
 
diff --git a/lib-python/2.7/ctypes/test/test_pep3118.py b/lib-python/2.7/ctypes/test/test_pep3118.py
--- a/lib-python/2.7/ctypes/test/test_pep3118.py
+++ b/lib-python/2.7/ctypes/test/test_pep3118.py
@@ -109,6 +109,34 @@
 # This table contains format strings as they look on little endian
 # machines.  The test replaces '<' with '>' on big endian machines.
 #
+
+# Platform-specific type codes
+s_bool = {1: '?', 2: 'H', 4: 'L', 8: 'Q'}[sizeof(c_bool)]
+s_short = {2: 'h', 4: 'l', 8: 'q'}[sizeof(c_short)]
+s_ushort = {2: 'H', 4: 'L', 8: 'Q'}[sizeof(c_ushort)]
+s_int = {2: 'h', 4: 'i', 8: 'q'}[sizeof(c_int)]
+s_uint = {2: 'H', 4: 'I', 8: 'Q'}[sizeof(c_uint)]
+s_long = {4: 'l', 8: 'q'}[sizeof(c_long)]
+s_ulong = {4: 'L', 8: 'Q'}[sizeof(c_ulong)]
+s_longlong = "q"
+s_ulonglong = "Q"
+s_float = "f"
+s_double = "d"
+s_longdouble = "g"
+
+# Alias definitions in ctypes/__init__.py
+if c_int is c_long:
+    s_int = s_long
+if c_uint is c_ulong:
+    s_uint = s_ulong
+if c_longlong is c_long:
+    s_longlong = s_long
+if c_ulonglong is c_ulong:
+    s_ulonglong = s_ulong
+if c_longdouble is c_double:
+    s_longdouble = s_double
+
+
 native_types = [
     # type                      format                  shape           calc itemsize
 
@@ -117,52 +145,51 @@
     (c_char,                    "<c",                   None,           c_char),
     (c_byte,                    "<b",                   None,           c_byte),
     (c_ubyte,                   "<B",                   None,           c_ubyte),
-    (c_short,                   "<h",                   None,           c_short),
-    (c_ushort,                  "<H",                   None,           c_ushort),
+    (c_short,                   "<" + s_short,          None,           c_short),
+    (c_ushort,                  "<" + s_ushort,         None,           c_ushort),
 
-    # c_int and c_uint may be aliases to c_long
-    #(c_int,                     "<i",                   None,           c_int),
-    #(c_uint,                    "<I",                   None,           c_uint),
+    (c_int,                     "<" + s_int,            None,           c_int),
+    (c_uint,                    "<" + s_uint,           None,           c_uint),
 
-    (c_long,                    "<l",                   None,           c_long),
-    (c_ulong,                   "<L",                   None,           c_ulong),
+    (c_long,                    "<" + s_long,           None,           c_long),
+    (c_ulong,                   "<" + s_ulong,          None,           c_ulong),
 
-    # c_longlong and c_ulonglong are aliases on 64-bit platforms
-    #(c_longlong,                "<q",                   None,           c_longlong),
-    #(c_ulonglong,               "<Q",                   None,           c_ulonglong),
+    (c_longlong,                "<" + s_longlong,       None,           c_longlong),
+    (c_ulonglong,               "<" + s_ulonglong,      None,           c_ulonglong),
 
     (c_float,                   "<f",                   None,           c_float),
     (c_double,                  "<d",                   None,           c_double),
-    # c_longdouble may be an alias to c_double
 
-    (c_bool,                    "<?",                   None,           c_bool),
+    (c_longdouble,              "<" + s_longdouble,     None,           c_longdouble),
+
+    (c_bool,                    "<" + s_bool,           None,           c_bool),
     (py_object,                 "<O",                   None,           py_object),
 
     ## pointers
 
     (POINTER(c_byte),           "&<b",                  None,           POINTER(c_byte)),
-    (POINTER(POINTER(c_long)),  "&&<l",                 None,           POINTER(POINTER(c_long))),
+    (POINTER(POINTER(c_long)),  "&&<" + s_long,         None,           POINTER(POINTER(c_long))),
 
     ## arrays and pointers
 
     (c_double * 4,              "<d",                   (4,),           c_double),
     (c_float * 4 * 3 * 2,       "<f",                   (2,3,4),        c_float),
-    (POINTER(c_short) * 2,      "&<h",                  (2,),           POINTER(c_short)),
-    (POINTER(c_short) * 2 * 3,  "&<h",                  (3,2,),         POINTER(c_short)),
-    (POINTER(c_short * 2),      "&(2)<h",               None,           POINTER(c_short)),
+    (POINTER(c_short) * 2,      "&<" + s_short,         (2,),           POINTER(c_short)),
+    (POINTER(c_short) * 2 * 3,  "&<" + s_short,         (3,2,),         POINTER(c_short)),
+    (POINTER(c_short * 2),      "&(2)<" + s_short,      None,             POINTER(c_short)),
 
     ## structures and unions
 
-    (Point,                     "T{<l:x:<l:y:}",        None,           Point),
+    (Point,                     "T{<l:x:<l:y:}".replace('l', s_long),  None,  Point),
     # packed structures do not implement the pep
-    (PackedPoint,               "B",                    None,           PackedPoint),
-    (Point2,                    "T{<l:x:<l:y:}",        None,           Point2),
-    (EmptyStruct,               "T{}",                  None,           EmptyStruct),
+    (PackedPoint,               "B",                                   None,  PackedPoint),
+    (Point2,                    "T{<l:x:<l:y:}".replace('l', s_long),  None,  Point2),
+    (EmptyStruct,               "T{}",                                 None,  EmptyStruct),
     # the pep does't support unions
-    (aUnion,                    "B",                    None,           aUnion),
+    (aUnion,                    "B",                                   None,  aUnion),
     # structure with sub-arrays
-    (StructWithArrays,          "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", None,  StructWithArrays),
-    (StructWithArrays * 3,      "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}", (3,),  StructWithArrays),
+    (StructWithArrays, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}".replace('l', s_long), None, StructWithArrays),
+    (StructWithArrays * 3, "T{(2,3)<l:x:(4)T{<l:x:<l:y:}:y:}".replace('l', s_long), (3,), StructWithArrays),
 
     ## pointer to incomplete structure
     (Incomplete,                "B",                    None,           Incomplete),
@@ -170,7 +197,7 @@
 
     # 'Complete' is a structure that starts incomplete, but is completed after the
     # pointer type to it has been created.
-    (Complete,                  "T{<l:a:}",             None,           Complete),
+    (Complete,                  "T{<l:a:}".replace('l', s_long), None, Complete),
     # Unfortunately the pointer format string is not fixed...
     (POINTER(Complete),         "&B",                   None,           POINTER(Complete)),
 
@@ -193,10 +220,10 @@
 # and little endian machines.
 #
 endian_types = [
-    (BEPoint,                   "T{>l:x:>l:y:}",        None,           BEPoint),
-    (LEPoint,                   "T{<l:x:<l:y:}",        None,           LEPoint),
-    (POINTER(BEPoint),          "&T{>l:x:>l:y:}",       None,           POINTER(BEPoint)),
-    (POINTER(LEPoint),          "&T{<l:x:<l:y:}",       None,           POINTER(LEPoint)),
+    (BEPoint, "T{>l:x:>l:y:}".replace('l', s_long), None, BEPoint),
+    (LEPoint, "T{<l:x:<l:y:}".replace('l', s_long), None, LEPoint),
+    (POINTER(BEPoint), "&T{>l:x:>l:y:}".replace('l', s_long), None, POINTER(BEPoint)),
+    (POINTER(LEPoint), "&T{<l:x:<l:y:}".replace('l', s_long), None, POINTER(LEPoint)),
     ]
 
 if __name__ == "__main__":
diff --git a/lib-python/2.7/ctypes/test/test_pointers.py b/lib-python/2.7/ctypes/test/test_pointers.py
--- a/lib-python/2.7/ctypes/test/test_pointers.py
+++ b/lib-python/2.7/ctypes/test/test_pointers.py
@@ -210,6 +210,11 @@
         from ctypes import _pointer_type_cache
         del _pointer_type_cache[id(P)]
 
+    def test_abstract(self):
+        from ctypes import _Pointer
+
+        self.assertRaises(TypeError, _Pointer.set_type, 42)
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/lib-python/2.7/ctypes/test/test_strings.py b/lib-python/2.7/ctypes/test/test_strings.py
--- a/lib-python/2.7/ctypes/test/test_strings.py
+++ b/lib-python/2.7/ctypes/test/test_strings.py
@@ -61,6 +61,13 @@
 ##        print BUF.from_param(c_char_p("python"))
 ##        print BUF.from_param(BUF(*"pyth"))
 
+    def test_del_segfault(self):
+        BUF = c_char * 4
+        buf = BUF()
+        with self.assertRaises(AttributeError):
+            del buf.raw
+
+
 @need_symbol('c_wchar')
 class WStringArrayTestCase(unittest.TestCase):
     def test(self):
diff --git a/lib-python/2.7/ctypes/test/test_struct_fields.py b/lib-python/2.7/ctypes/test/test_struct_fields.py
--- a/lib-python/2.7/ctypes/test/test_struct_fields.py
+++ b/lib-python/2.7/ctypes/test/test_struct_fields.py
@@ -46,5 +46,29 @@
         Y._fields_ = []
         self.assertRaises(AttributeError, setattr, X, "_fields_", [])
 
+    # __set__ and __get__ should raise a TypeError in case their self
+    # argument is not a ctype instance.
+    def test___set__(self):
+        class MyCStruct(Structure):
+            _fields_ = (("field", c_int),)
+        self.assertRaises(TypeError,
+                          MyCStruct.field.__set__, 'wrong type self', 42)
+
+        class MyCUnion(Union):
+            _fields_ = (("field", c_int),)
+        self.assertRaises(TypeError,
+                          MyCUnion.field.__set__, 'wrong type self', 42)
+
+    def test___get__(self):
+        class MyCStruct(Structure):
+            _fields_ = (("field", c_int),)
+        self.assertRaises(TypeError,
+                          MyCStruct.field.__get__, 'wrong type self', 42)
+
+        class MyCUnion(Union):
+            _fields_ = (("field", c_int),)
+        self.assertRaises(TypeError,
+                          MyCUnion.field.__get__, 'wrong type self', 42)
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/lib-python/2.7/ctypes/test/test_structures.py b/lib-python/2.7/ctypes/test/test_structures.py
--- a/lib-python/2.7/ctypes/test/test_structures.py
+++ b/lib-python/2.7/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):
@@ -401,6 +402,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/2.7/ctypes/test/test_win32.py b/lib-python/2.7/ctypes/test/test_win32.py
--- a/lib-python/2.7/ctypes/test/test_win32.py
+++ b/lib-python/2.7/ctypes/test/test_win32.py
@@ -53,6 +53,24 @@
         windll.user32.GetDesktopWindow()
 
 @unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
+class ReturnStructSizesTestCase(unittest.TestCase):
+    def test_sizes(self):
+        dll = CDLL(_ctypes_test.__file__)
+        for i in range(1, 11):
+            fields = [ ("f%d" % f, c_char) for f in range(1, i + 1)]
+            class S(Structure):
+                _fields_ = fields
+            f = getattr(dll, "TestSize%d" % i)
+            f.restype = S
+            res = f()
+            for i, f in enumerate(fields):
+                value = getattr(res, f[0])
+                expected = chr(ord('a') + i)
+                self.assertEquals(value, expected)
+
+
+
+ at unittest.skipUnless(sys.platform == "win32", 'Windows-specific test')
 class TestWintypes(unittest.TestCase):
     def test_HWND(self):
         from ctypes import wintypes
diff --git a/lib-python/2.7/curses/ascii.py b/lib-python/2.7/curses/ascii.py
--- a/lib-python/2.7/curses/ascii.py
+++ b/lib-python/2.7/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/2.7/curses/has_key.py b/lib-python/2.7/curses/has_key.py
--- a/lib-python/2.7/curses/has_key.py
+++ b/lib-python/2.7/curses/has_key.py
@@ -182,7 +182,7 @@
         L = []
         _curses.initscr()
         for key in _capability_names.keys():
-            system = key in _curses
+            system = _curses.has_key(key)
             python = has_key(key)
             if system != python:
                 L.append( 'Mismatch for key %s, system=%i, Python=%i'
diff --git a/lib-python/2.7/curses/textpad.py b/lib-python/2.7/curses/textpad.py
--- a/lib-python/2.7/curses/textpad.py
+++ b/lib-python/2.7/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/2.7/decimal.py b/lib-python/2.7/decimal.py
--- a/lib-python/2.7/decimal.py
+++ b/lib-python/2.7/decimal.py
@@ -1909,7 +1909,7 @@
         if not other and not self:
             return context._raise_error(InvalidOperation,
                                         'at least one of pow() 1st argument '
-                                        'and 2nd argument must be nonzero ;'
+                                        'and 2nd argument must be nonzero; '
                                         '0**0 is not defined')
 
         # compute sign of result
diff --git a/lib-python/2.7/difflib.py b/lib-python/2.7/difflib.py
--- a/lib-python/2.7/difflib.py
+++ b/lib-python/2.7/difflib.py
@@ -1103,7 +1103,7 @@
 
 import re
 
-def IS_LINE_JUNK(line, pat=re.compile(r"\s*#?\s*$").match):
+def IS_LINE_JUNK(line, pat=re.compile(r"\s*(?:#\s*)?$").match):
     r"""
     Return 1 for ignorable line: iff `line` is blank or contains a single '#'.
 
diff --git a/lib-python/2.7/distutils/archive_util.py b/lib-python/2.7/distutils/archive_util.py
--- a/lib-python/2.7/distutils/archive_util.py
+++ b/lib-python/2.7/distutils/archive_util.py
@@ -162,7 +162,15 @@
             zip = zipfile.ZipFile(zip_filename, "w",
                                   compression=zipfile.ZIP_DEFLATED)
 
+            if base_dir != os.curdir:
+                path = os.path.normpath(os.path.join(base_dir, ''))
+                zip.write(path, path)
+                log.info("adding '%s'", path)
             for dirpath, dirnames, filenames in os.walk(base_dir):
+                for name in dirnames:
+                    path = os.path.normpath(os.path.join(dirpath, name, ''))
+                    zip.write(path, path)
+                    log.info("adding '%s'", path)
                 for name in filenames:
                     path = os.path.normpath(os.path.join(dirpath, name))
                     if os.path.isfile(path):
diff --git a/lib-python/2.7/distutils/ccompiler.py b/lib-python/2.7/distutils/ccompiler.py
--- a/lib-python/2.7/distutils/ccompiler.py
+++ b/lib-python/2.7/distutils/ccompiler.py
@@ -160,7 +160,7 @@
             self.set_executable(key, args[key])
 
     def set_executable(self, key, value):
-        if isinstance(value, str):
+        if isinstance(value, basestring):
             setattr(self, key, split_quoted(value))
         else:
             setattr(self, key, value)
diff --git a/lib-python/2.7/distutils/command/bdist_dumb.py b/lib-python/2.7/distutils/command/bdist_dumb.py
--- a/lib-python/2.7/distutils/command/bdist_dumb.py
+++ b/lib-python/2.7/distutils/command/bdist_dumb.py
@@ -35,7 +35,7 @@
                     ('skip-build', None,
                      "skip rebuilding everything (for testing/debugging)"),
                     ('relative', None,
-                     "build the archive using relative paths"
+                     "build the archive using relative paths "
                      "(default: false)"),
                     ('owner=', 'u',
                      "Owner name used when creating a tar file"
diff --git a/lib-python/2.7/distutils/command/bdist_msi.py b/lib-python/2.7/distutils/command/bdist_msi.py
--- a/lib-python/2.7/distutils/command/bdist_msi.py
+++ b/lib-python/2.7/distutils/command/bdist_msi.py
@@ -99,14 +99,14 @@
                     ('no-target-compile', 'c',
                      "do not compile .py to .pyc on the target system"),
                     ('no-target-optimize', 'o',
-                     "do not compile .py to .pyo (optimized)"
+                     "do not compile .py to .pyo (optimized) "
                      "on the target system"),
                     ('dist-dir=', 'd',
                      "directory to put final built distributions in"),
                     ('skip-build', None,
                      "skip rebuilding everything (for testing/debugging)"),
                     ('install-script=', None,
-                     "basename of installation script to be run after"
+                     "basename of installation script to be run after "
                      "installation or before deinstallation"),
                     ('pre-install-script=', None,
                      "Fully qualified filename of a script to be run before "
diff --git a/lib-python/2.7/distutils/command/bdist_rpm.py b/lib-python/2.7/distutils/command/bdist_rpm.py
--- a/lib-python/2.7/distutils/command/bdist_rpm.py
+++ b/lib-python/2.7/distutils/command/bdist_rpm.py
@@ -63,7 +63,7 @@
          "RPM \"vendor\" (eg. \"Joe Blow <joe at example.com>\") "
          "[default: maintainer or author from setup script]"),
         ('packager=', None,
-         "RPM packager (eg. \"Jane Doe <jane at example.net>\")"
+         "RPM packager (eg. \"Jane Doe <jane at example.net>\") "
          "[default: vendor]"),
         ('doc-files=', None,
          "list of documentation files (space or comma-separated)"),
diff --git a/lib-python/2.7/distutils/command/bdist_wininst.py b/lib-python/2.7/distutils/command/bdist_wininst.py
--- a/lib-python/2.7/distutils/command/bdist_wininst.py
+++ b/lib-python/2.7/distutils/command/bdist_wininst.py
@@ -35,7 +35,7 @@
                     ('no-target-compile', 'c',
                      "do not compile .py to .pyc on the target system"),
                     ('no-target-optimize', 'o',
-                     "do not compile .py to .pyo (optimized)"
+                     "do not compile .py to .pyo (optimized) "
                      "on the target system"),
                     ('dist-dir=', 'd',
                      "directory to put final built distributions in"),
@@ -46,7 +46,7 @@
                     ('skip-build', None,
                      "skip rebuilding everything (for testing/debugging)"),
                     ('install-script=', None,
-                     "basename of installation script to be run after"
+                     "basename of installation script to be run after "
                      "installation or before deinstallation"),
                     ('pre-install-script=', None,
                      "Fully qualified filename of a script to be run before "
diff --git a/lib-python/2.7/distutils/command/build_ext.py b/lib-python/2.7/distutils/command/build_ext.py
--- a/lib-python/2.7/distutils/command/build_ext.py
+++ b/lib-python/2.7/distutils/command/build_ext.py
@@ -366,7 +366,7 @@
             ext_name, build_info = ext
 
             log.warn(("old-style (ext_name, build_info) tuple found in "
-                      "ext_modules for extension '%s'"
+                      "ext_modules for extension '%s' "
                       "-- please convert to Extension instance" % ext_name))
 
             if not (isinstance(ext_name, str) and
diff --git a/lib-python/2.7/distutils/command/upload.py b/lib-python/2.7/distutils/command/upload.py
--- a/lib-python/2.7/distutils/command/upload.py
+++ b/lib-python/2.7/distutils/command/upload.py
@@ -55,7 +55,9 @@
 
     def run(self):
         if not self.distribution.dist_files:
-            raise DistutilsOptionError("No dist file created in earlier command")
+            msg = ("Must create and upload files in one command "
+                   "(e.g. setup.py sdist upload)")
+            raise DistutilsOptionError(msg)
         for command, pyversion, filename in self.distribution.dist_files:
             self.upload_file(command, pyversion, filename)
 
@@ -155,8 +157,6 @@
                 body.write(fn)
                 body.write("\r\n\r\n")
                 body.write(value)
-                if value and value[-1] == '\r':
-                    body.write('\n')  # write an extra newline (lurve Macs)
         body.write(end_boundary)
         body = body.getvalue()
 
diff --git a/lib-python/2.7/distutils/spawn.py b/lib-python/2.7/distutils/spawn.py
--- a/lib-python/2.7/distutils/spawn.py
+++ b/lib-python/2.7/distutils/spawn.py
@@ -208,7 +208,8 @@
     os.environ['PATH'].  Returns the complete filename or None if not found.
     """
     if path is None:
-        path = os.environ['PATH']
+        path = os.environ.get('PATH', os.defpath)
+
     paths = path.split(os.pathsep)
     base, ext = os.path.splitext(executable)
 
diff --git a/lib-python/2.7/distutils/tests/test_archive_util.py b/lib-python/2.7/distutils/tests/test_archive_util.py
--- a/lib-python/2.7/distutils/tests/test_archive_util.py
+++ b/lib-python/2.7/distutils/tests/test_archive_util.py
@@ -98,7 +98,7 @@
         try:
             names = tar.getnames()
             names.sort()
-            return tuple(names)
+            return names
         finally:
             tar.close()
 
diff --git a/lib-python/2.7/distutils/tests/test_bdist_dumb.py b/lib-python/2.7/distutils/tests/test_bdist_dumb.py
--- a/lib-python/2.7/distutils/tests/test_bdist_dumb.py
+++ b/lib-python/2.7/distutils/tests/test_bdist_dumb.py
@@ -86,7 +86,7 @@
         finally:
             fp.close()
 
-        contents = sorted(os.path.basename(fn) for fn in contents)
+        contents = sorted(filter(None, map(os.path.basename, contents)))
         wanted = ['foo-0.1-py%s.%s.egg-info' % sys.version_info[:2], 'foo.py']
         if not sys.dont_write_bytecode:
             wanted.append('foo.pyc')
diff --git a/lib-python/2.7/distutils/tests/test_bdist_rpm.py b/lib-python/2.7/distutils/tests/test_bdist_rpm.py
--- a/lib-python/2.7/distutils/tests/test_bdist_rpm.py
+++ b/lib-python/2.7/distutils/tests/test_bdist_rpm.py
@@ -99,7 +99,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/2.7/distutils/tests/test_build_ext.py b/lib-python/2.7/distutils/tests/test_build_ext.py
--- a/lib-python/2.7/distutils/tests/test_build_ext.py
+++ b/lib-python/2.7/distutils/tests/test_build_ext.py
@@ -20,6 +20,7 @@
 
 class BuildExtTestCase(support.TempdirManager,
                        support.LoggingSilencer,
+                       support.EnvironGuard,
                        unittest.TestCase):
     def setUp(self):
         super(BuildExtTestCase, self).setUp()
diff --git a/lib-python/2.7/distutils/tests/test_ccompiler.py b/lib-python/2.7/distutils/tests/test_ccompiler.py
--- a/lib-python/2.7/distutils/tests/test_ccompiler.py
+++ b/lib-python/2.7/distutils/tests/test_ccompiler.py
@@ -24,6 +24,30 @@
 
 class CCompilerTestCase(support.EnvironGuard, unittest.TestCase):
 
+    def test_set_executables(self):
+        class MyCCompiler(CCompiler):
+            executables = {'compiler': '', 'compiler_cxx': '', 'linker': ''}
+
+        compiler = MyCCompiler()
+
+        # set executable as list
+        compiler.set_executables(compiler=['env', 'OMPI_MPICC=clang', 'mpicc'])
+        self.assertEqual(compiler.compiler, ['env',
+                                             'OMPI_MPICC=clang',
+                                             'mpicc'])
+
+        # set executable as string
+        compiler.set_executables(compiler_cxx='env OMPI_MPICXX=clang++ mpicxx')
+        self.assertEqual(compiler.compiler_cxx, ['env',
+                                                 'OMPI_MPICXX=clang++',
+                                                 'mpicxx'])
+
+        # set executable as unicode string
+        compiler.set_executables(linker=u'env OMPI_MPICXX=clang++ mpiCC')
+        self.assertEqual(compiler.linker, [u'env',
+                                           u'OMPI_MPICXX=clang++',
+                                           u'mpiCC'])
+
     def test_gen_lib_options(self):
         compiler = FakeCompiler()
         libdirs = ['lib1', 'lib2']
diff --git a/lib-python/2.7/distutils/tests/test_check.py b/lib-python/2.7/distutils/tests/test_check.py
--- a/lib-python/2.7/distutils/tests/test_check.py
+++ b/lib-python/2.7/distutils/tests/test_check.py
@@ -8,6 +8,12 @@
 from distutils.tests import support
 from distutils.errors import DistutilsSetupError
 
+try:
+    import pygments
+except ImportError:
+    pygments = None
+
+
 class CheckTestCase(support.LoggingSilencer,
                     support.TempdirManager,
                     unittest.TestCase):
@@ -120,9 +126,15 @@
             pkg_info, dist = self.create_dist(long_description=rest_with_code)
             cmd = check(dist)
             cmd.check_restructuredtext()
-            self.assertEqual(cmd._warnings, 0)
             msgs = cmd._check_rst_data(rest_with_code)
-            self.assertEqual(len(msgs), 0)
+            if pygments is not None:
+                self.assertEqual(len(msgs), 0)
+            else:
+                self.assertEqual(len(msgs), 1)
+                self.assertEqual(
+                    str(msgs[0][1]),
+                    'Cannot analyze code. Pygments package not found.'
+                )
 
     def test_check_all(self):
 
diff --git a/lib-python/2.7/distutils/tests/test_install.py b/lib-python/2.7/distutils/tests/test_install.py
--- a/lib-python/2.7/distutils/tests/test_install.py
+++ b/lib-python/2.7/distutils/tests/test_install.py
@@ -26,6 +26,7 @@
 
 
 class InstallTestCase(support.TempdirManager,
+                      support.EnvironGuard,
                       support.LoggingSilencer,
                       unittest.TestCase):
 
diff --git a/lib-python/2.7/distutils/tests/test_sdist.py b/lib-python/2.7/distutils/tests/test_sdist.py
--- a/lib-python/2.7/distutils/tests/test_sdist.py
+++ b/lib-python/2.7/distutils/tests/test_sdist.py
@@ -130,7 +130,9 @@
             zip_file.close()
 
         # making sure everything has been pruned correctly
-        self.assertEqual(len(content), 4)
+        expected = ['', 'PKG-INFO', 'README', 'setup.py',
+                    'somecode/', 'somecode/__init__.py']
+        self.assertEqual(sorted(content), ['fake-1.0/' + x for x in expected])
 
     @unittest.skipUnless(zlib, "requires zlib")
     def test_make_distribution(self):
@@ -246,7 +248,13 @@
             zip_file.close()
 
         # making sure everything was added
-        self.assertEqual(len(content), 12)
+        expected = ['', 'PKG-INFO', 'README', 'buildout.cfg',
+                    'data/', 'data/data.dt', 'inroot.txt',
+                    'scripts/', 'scripts/script.py', 'setup.py',
+                    'some/', 'some/file.txt', 'some/other_file.txt',
+                    'somecode/', 'somecode/__init__.py', 'somecode/doc.dat',
+                    'somecode/doc.txt']
+        self.assertEqual(sorted(content), ['fake-1.0/' + x for x in expected])
 
         # checking the MANIFEST
         f = open(join(self.tmp_dir, 'MANIFEST'))
diff --git a/lib-python/2.7/distutils/tests/test_spawn.py b/lib-python/2.7/distutils/tests/test_spawn.py
--- a/lib-python/2.7/distutils/tests/test_spawn.py
+++ b/lib-python/2.7/distutils/tests/test_spawn.py
@@ -1,8 +1,11 @@
 """Tests for distutils.spawn."""
+import os
+import stat
+import sys
+import time
 import unittest
-import os
-import time
-from test.test_support import captured_stdout, run_unittest
+from test.support import captured_stdout, run_unittest
+from test import support as test_support
 
 from distutils.spawn import _nt_quote_args
 from distutils.spawn import spawn, find_executable
@@ -53,6 +56,48 @@
         os.chmod(exe, 0777)
         spawn([exe])  # should work without any error
 
+    def test_find_executable(self):
+        with test_support.temp_dir() as tmp_dir:
+            # use TESTFN to get a pseudo-unique filename
+            program_noeext = test_support.TESTFN
+            # Give the temporary program an ".exe" suffix for all.
+            # It's needed on Windows and not harmful on other platforms.
+            program = program_noeext + ".exe"
+
+            filename = os.path.join(tmp_dir, program)
+            with open(filename, "wb"):
+                pass
+            os.chmod(filename, stat.S_IXUSR)
+
+            # test path parameter
+            rv = find_executable(program, path=tmp_dir)
+            self.assertEqual(rv, filename)
+
+            if sys.platform == 'win32':
+                # test without ".exe" extension
+                rv = find_executable(program_noeext, path=tmp_dir)
+                self.assertEqual(rv, filename)
+
+            # test find in the current directory
+            with test_support.change_cwd(tmp_dir):
+                rv = find_executable(program)
+                self.assertEqual(rv, program)
+
+            # test non-existent program
+            dont_exist_program = "dontexist_" + program
+            rv = find_executable(dont_exist_program , path=tmp_dir)
+            self.assertIsNone(rv)
+
+            # test os.defpath: missing PATH environment variable
+            with test_support.EnvironmentVarGuard() as env:
+                from distutils import spawn
+                with test_support.swap_attr(spawn.os, 'defpath', tmp_dir):
+                    env.pop('PATH')
+
+                    rv = find_executable(program)
+                    self.assertEqual(rv, filename)
+
+
 def test_suite():
     return unittest.makeSuite(SpawnTestCase)
 
diff --git a/lib-python/2.7/distutils/tests/test_upload.py b/lib-python/2.7/distutils/tests/test_upload.py
--- a/lib-python/2.7/distutils/tests/test_upload.py
+++ b/lib-python/2.7/distutils/tests/test_upload.py
@@ -128,6 +128,32 @@
         auth = self.last_open.req.headers['Authorization']
         self.assertNotIn('\n', auth)
 
+    # bpo-32304: archives whose last byte was b'\r' were corrupted due to
+    # normalization intended for Mac OS 9.
+    def test_upload_correct_cr(self):
+        # content that ends with \r should not be modified.
+        tmp = self.mkdtemp()
+        path = os.path.join(tmp, 'xxx')
+        self.write_file(path, content='yy\r')


More information about the pypy-commit mailing list