An interpreted, interactive, object-oriented programming language
CentOS Sources
2017-08-01 71084d584ff953f5463757ec6536406320560b4d
import python-2.7.5-58.el7
8 files added
4 files modified
1372 ■■■■■ changed files
SOURCES/00147-add-debug-malloc-stats.patch 249 ●●●●● patch | view | raw | blame | history
SOURCES/00234-PEP493-updated-implementation.patch 39 ●●●●● patch | view | raw | blame | history
SOURCES/00255-Fix-ssl-module-parsing-of-GEN_RID-subject-alternative-name-fields-in-X.509-certs.patch 235 ●●●●● patch | view | raw | blame | history
SOURCES/00256-fix-incorrect-parsing-of-regular-expressions.patch 80 ●●●●● patch | view | raw | blame | history
SOURCES/00257-threading-wait-clamp-remaining-time.patch 20 ●●●●● patch | view | raw | blame | history
SOURCES/00263-fix-ssl-reference-leaks.patch 14 ●●●●● patch | view | raw | blame | history
SOURCES/00265-protect-key-list-during-fork.patch 114 ●●●●● patch | view | raw | blame | history
SOURCES/00266-fix-shutil.make_archive-ignoring-empty-dirs.patch 376 ●●●●● patch | view | raw | blame | history
SOURCES/00268-set-stream-name-to-None.patch 20 ●●●●● patch | view | raw | blame | history
SOURCES/macros.python 73 ●●●●● patch | view | raw | blame | history
SOURCES/macros.python2 35 ●●●●● patch | view | raw | blame | history
SPECS/python.spec 117 ●●●●● patch | view | raw | blame | history
SOURCES/00147-add-debug-malloc-stats.patch
@@ -1,7 +1,8 @@
diff -up Python-2.7.2/Include/dictobject.h.add-debug-malloc-stats Python-2.7.2/Include/dictobject.h
--- Python-2.7.2/Include/dictobject.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/dictobject.h    2011-09-16 19:03:25.105821625 -0400
@@ -150,6 +150,8 @@ PyAPI_FUNC(PyObject *) PyDict_GetItemStr
diff --git a/Include/dictobject.h b/Include/dictobject.h
index ece01c6..acc1df0 100644
--- a/Include/dictobject.h
+++ b/Include/dictobject.h
@@ -150,6 +150,8 @@ PyAPI_FUNC(PyObject *) PyDict_GetItemString(PyObject *dp, const char *key);
 PyAPI_FUNC(int) PyDict_SetItemString(PyObject *dp, const char *key, PyObject *item);
 PyAPI_FUNC(int) PyDict_DelItemString(PyObject *dp, const char *key);
 
@@ -10,10 +11,11 @@
 #ifdef __cplusplus
 }
 #endif
diff -up Python-2.7.2/Include/floatobject.h.add-debug-malloc-stats Python-2.7.2/Include/floatobject.h
--- Python-2.7.2/Include/floatobject.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/floatobject.h    2011-09-16 19:03:25.106821625 -0400
@@ -132,6 +132,7 @@ PyAPI_FUNC(PyObject *) _PyFloat_FormatAd
diff --git a/Include/floatobject.h b/Include/floatobject.h
index 54e8825..33c6ac0 100644
--- a/Include/floatobject.h
+++ b/Include/floatobject.h
@@ -132,6 +132,7 @@ PyAPI_FUNC(PyObject *) _PyFloat_FormatAdvanced(PyObject *obj,
    failure.  Used in builtin_round in bltinmodule.c. */
 PyAPI_FUNC(PyObject *) _Py_double_round(double x, int ndigits);
 
@@ -21,10 +23,11 @@
 
 
 #ifdef __cplusplus
diff -up Python-2.7.2/Include/frameobject.h.add-debug-malloc-stats Python-2.7.2/Include/frameobject.h
--- Python-2.7.2/Include/frameobject.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/frameobject.h    2011-09-16 19:03:25.107821625 -0400
@@ -80,6 +80,8 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(Py
diff --git a/Include/frameobject.h b/Include/frameobject.h
index 17e7679..66d9d8b 100644
--- a/Include/frameobject.h
+++ b/Include/frameobject.h
@@ -80,6 +80,8 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(PyFrameObject *);
 
 PyAPI_FUNC(int) PyFrame_ClearFreeList(void);
 
@@ -33,10 +36,11 @@
 /* Return the line of code the frame is currently executing. */
 PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *);
 
diff -up Python-2.7.2/Include/intobject.h.add-debug-malloc-stats Python-2.7.2/Include/intobject.h
--- Python-2.7.2/Include/intobject.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/intobject.h    2011-09-16 19:03:25.107821625 -0400
@@ -74,6 +74,8 @@ PyAPI_FUNC(PyObject *) _PyInt_FormatAdva
diff --git a/Include/intobject.h b/Include/intobject.h
index 252eea9..4003736 100644
--- a/Include/intobject.h
+++ b/Include/intobject.h
@@ -75,6 +75,8 @@ PyAPI_FUNC(PyObject *) _PyInt_FormatAdvanced(PyObject *obj,
                          char *format_spec,
                          Py_ssize_t format_spec_len);
 
@@ -45,10 +49,11 @@
 #ifdef __cplusplus
 }
 #endif
diff -up Python-2.7.2/Include/listobject.h.add-debug-malloc-stats Python-2.7.2/Include/listobject.h
--- Python-2.7.2/Include/listobject.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/listobject.h    2011-09-16 19:03:25.107821625 -0400
@@ -62,6 +62,8 @@ PyAPI_FUNC(PyObject *) _PyList_Extend(Py
diff --git a/Include/listobject.h b/Include/listobject.h
index c445873..04664d7 100644
--- a/Include/listobject.h
+++ b/Include/listobject.h
@@ -62,6 +62,8 @@ PyAPI_FUNC(PyObject *) _PyList_Extend(PyListObject *, PyObject *);
 #define PyList_SET_ITEM(op, i, v) (((PyListObject *)(op))->ob_item[i] = (v))
 #define PyList_GET_SIZE(op)    Py_SIZE(op)
 
@@ -57,9 +62,10 @@
 #ifdef __cplusplus
 }
 #endif
diff -up Python-2.7.2/Include/methodobject.h.add-debug-malloc-stats Python-2.7.2/Include/methodobject.h
--- Python-2.7.2/Include/methodobject.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/methodobject.h    2011-09-16 19:03:25.108821625 -0400
diff --git a/Include/methodobject.h b/Include/methodobject.h
index 6e160b6..1944517 100644
--- a/Include/methodobject.h
+++ b/Include/methodobject.h
@@ -87,6 +87,10 @@ typedef struct {
 
 PyAPI_FUNC(int) PyCFunction_ClearFreeList(void);
@@ -71,10 +77,11 @@
 #ifdef __cplusplus
 }
 #endif
diff -up Python-2.7.2/Include/object.h.add-debug-malloc-stats Python-2.7.2/Include/object.h
--- Python-2.7.2/Include/object.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/object.h    2011-09-16 19:03:25.108821625 -0400
@@ -980,6 +980,13 @@ PyAPI_DATA(PyObject *) _PyTrash_delete_l
diff --git a/Include/object.h b/Include/object.h
index afbc68d..ce5febf 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -1005,6 +1005,13 @@ PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void);
             _PyTrash_thread_deposit_object((PyObject*)op); \
     } while (0);
 
@@ -88,9 +95,10 @@
 #ifdef __cplusplus
 }
 #endif
diff -up Python-2.7.2/Include/objimpl.h.add-debug-malloc-stats Python-2.7.2/Include/objimpl.h
--- Python-2.7.2/Include/objimpl.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/objimpl.h    2011-09-16 19:03:25.108821625 -0400
diff --git a/Include/objimpl.h b/Include/objimpl.h
index 55e83ec..331b456 100644
--- a/Include/objimpl.h
+++ b/Include/objimpl.h
@@ -101,13 +101,13 @@ PyAPI_FUNC(void) PyObject_Free(void *);
 
 /* Macros */
@@ -106,10 +114,23 @@
 PyAPI_FUNC(void *) _PyObject_DebugMallocApi(char api, size_t nbytes);
 PyAPI_FUNC(void *) _PyObject_DebugReallocApi(char api, void *p, size_t nbytes);
 PyAPI_FUNC(void) _PyObject_DebugFreeApi(char api, void *p);
diff -up Python-2.7.2/Include/stringobject.h.add-debug-malloc-stats Python-2.7.2/Include/stringobject.h
--- Python-2.7.2/Include/stringobject.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/stringobject.h    2011-09-16 19:03:25.109821625 -0400
@@ -204,6 +204,8 @@ PyAPI_FUNC(PyObject *) _PyBytes_FormatAd
diff --git a/Include/setobject.h b/Include/setobject.h
index 52b07d5..143b175 100644
--- a/Include/setobject.h
+++ b/Include/setobject.h
@@ -93,6 +93,7 @@ PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key,
 PyAPI_FUNC(PyObject *) PySet_Pop(PyObject *set);
 PyAPI_FUNC(int) _PySet_Update(PyObject *set, PyObject *iterable);
+PyAPI_FUNC(void) _PySet_DebugMallocStats(FILE *out);
 #ifdef __cplusplus
 }
 #endif
diff --git a/Include/stringobject.h b/Include/stringobject.h
index 18b5b41..de78d76 100644
--- a/Include/stringobject.h
+++ b/Include/stringobject.h
@@ -204,6 +204,8 @@ PyAPI_FUNC(PyObject *) _PyBytes_FormatAdvanced(PyObject *obj,
                            char *format_spec,
                            Py_ssize_t format_spec_len);
 
@@ -118,9 +139,23 @@
 #ifdef __cplusplus
 }
 #endif
diff -up Python-2.7.2/Include/unicodeobject.h.add-debug-malloc-stats Python-2.7.2/Include/unicodeobject.h
--- Python-2.7.2/Include/unicodeobject.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
+++ Python-2.7.2/Include/unicodeobject.h    2011-09-16 19:03:25.109821625 -0400
diff --git a/Include/tupleobject.h b/Include/tupleobject.h
index a5ab733..e233f47 100644
--- a/Include/tupleobject.h
+++ b/Include/tupleobject.h
@@ -54,7 +54,7 @@ PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *);
 #define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v)
 PyAPI_FUNC(int) PyTuple_ClearFreeList(void);
-
+PyAPI_FUNC(void) _PyTuple_DebugMallocStats(FILE *out);
 #ifdef __cplusplus
 }
 #endif
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h
index 9ab724a..b91250a 100644
--- a/Include/unicodeobject.h
+++ b/Include/unicodeobject.h
@@ -1406,6 +1406,8 @@ PyAPI_FUNC(int) _PyUnicode_IsAlpha(
     Py_UNICODE ch       /* Unicode character */
     );
@@ -130,10 +165,11 @@
 #ifdef __cplusplus
 }
 #endif
diff -up Python-2.7.2/Lib/test/test_sys.py.add-debug-malloc-stats Python-2.7.2/Lib/test/test_sys.py
--- Python-2.7.2/Lib/test/test_sys.py.add-debug-malloc-stats    2011-09-16 19:03:25.048821626 -0400
+++ Python-2.7.2/Lib/test/test_sys.py    2011-09-16 19:03:25.110821625 -0400
@@ -473,6 +473,32 @@ class SysModuleTest(unittest.TestCase):
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 82243f3..8f1e1a0 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -488,6 +488,32 @@ class SysModuleTest(unittest.TestCase):
         p.wait()
         self.assertIn(executable, ["''", repr(sys.executable)])
 
@@ -149,7 +185,7 @@
+        out, err = p.communicate()
+        p.wait()
+        self.assertIn("arenas allocated current", err)
+
+
+        # Verify that we can redirect the output to a file (not a file-like
+        # object, though):
+        with open('mallocstats.txt', 'w') as out:
@@ -161,15 +197,16 @@
+        # Verify that the destination must be a file:
+        with self.assertRaises(TypeError):
+            sys._debugmallocstats(42)
+
+
+
 class SizeofTest(unittest.TestCase):
 
     def setUp(self):
diff -up Python-2.7.2/Objects/classobject.c.add-debug-malloc-stats Python-2.7.2/Objects/classobject.c
--- Python-2.7.2/Objects/classobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/classobject.c    2011-09-16 19:03:25.110821625 -0400
@@ -2670,3 +2670,12 @@ PyMethod_Fini(void)
diff --git a/Objects/classobject.c b/Objects/classobject.c
index 2c9c216..2ba7077 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -2694,3 +2694,12 @@ PyMethod_Fini(void)
 {
     (void)PyMethod_ClearFreeList();
 }
@@ -182,9 +219,10 @@
+                           "free PyMethodObject",
+                           numfree, sizeof(PyMethodObject));
+}
diff -up Python-2.7.2/Objects/dictobject.c.add-debug-malloc-stats Python-2.7.2/Objects/dictobject.c
--- Python-2.7.2/Objects/dictobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/dictobject.c    2011-09-16 19:03:25.111821625 -0400
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index ba36b18..b8a5c7f 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -225,6 +225,15 @@ show_track(void)
 static PyDictObject *free_list[PyDict_MAXFREELIST];
 static int numfree = 0;
@@ -201,9 +239,10 @@
 void
 PyDict_Fini(void)
 {
diff -up Python-2.7.2/Objects/floatobject.c.add-debug-malloc-stats Python-2.7.2/Objects/floatobject.c
--- Python-2.7.2/Objects/floatobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/floatobject.c    2011-09-16 19:03:25.111821625 -0400
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index ba867ef..533511d 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -35,6 +35,22 @@ typedef struct _floatblock PyFloatBlock;
 static PyFloatBlock *block_list = NULL;
 static PyFloatObject *free_list = NULL;
@@ -227,10 +266,11 @@
 static PyFloatObject *
 fill_free_list(void)
 {
diff -up Python-2.7.2/Objects/frameobject.c.add-debug-malloc-stats Python-2.7.2/Objects/frameobject.c
--- Python-2.7.2/Objects/frameobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/frameobject.c    2011-09-16 19:03:25.112821625 -0400
@@ -980,3 +980,13 @@ PyFrame_Fini(void)
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index f9e4a0e..337fc58 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -982,3 +982,13 @@ PyFrame_Fini(void)
     Py_XDECREF(builtin_object);
     builtin_object = NULL;
 }
@@ -244,9 +284,10 @@
+                           numfree, sizeof(PyFrameObject));
+}
+
diff -up Python-2.7.2/Objects/intobject.c.add-debug-malloc-stats Python-2.7.2/Objects/intobject.c
--- Python-2.7.2/Objects/intobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/intobject.c    2011-09-16 19:03:25.112821625 -0400
diff --git a/Objects/intobject.c b/Objects/intobject.c
index 28182f9..f442ea0 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -44,6 +44,23 @@ typedef struct _intblock PyIntBlock;
 static PyIntBlock *block_list = NULL;
 static PyIntObject *free_list = NULL;
@@ -271,9 +312,10 @@
 static PyIntObject *
 fill_free_list(void)
 {
diff -up Python-2.7.2/Objects/listobject.c.add-debug-malloc-stats Python-2.7.2/Objects/listobject.c
--- Python-2.7.2/Objects/listobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/listobject.c    2011-09-16 19:03:25.113821625 -0400
diff --git a/Objects/listobject.c b/Objects/listobject.c
index f753643..e6fa17d 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -109,6 +109,15 @@ PyList_Fini(void)
     }
 }
@@ -290,9 +332,10 @@
 PyObject *
 PyList_New(Py_ssize_t size)
 {
diff -up Python-2.7.2/Objects/methodobject.c.add-debug-malloc-stats Python-2.7.2/Objects/methodobject.c
--- Python-2.7.2/Objects/methodobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/methodobject.c    2011-09-16 19:03:25.113821625 -0400
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 0b60ca3..3193135 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -412,6 +412,15 @@ PyCFunction_Fini(void)
     (void)PyCFunction_ClearFreeList();
 }
@@ -309,10 +352,11 @@
 /* PyCFunction_New() is now just a macro that calls PyCFunction_NewEx(),
    but it's part of the API so we need to keep a function around that
    existing C extensions can call.
diff -up Python-2.7.2/Objects/object.c.add-debug-malloc-stats Python-2.7.2/Objects/object.c
--- Python-2.7.2/Objects/object.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/object.c    2011-09-16 19:04:46.463820849 -0400
@@ -2334,6 +2334,23 @@ PyMem_Free(void *p)
diff --git a/Objects/object.c b/Objects/object.c
index 14f4e9f..68aedcd 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2355,6 +2355,23 @@ PyMem_Free(void *p)
     PyMem_FREE(p);
 }
 
@@ -336,10 +380,11 @@
 
 /* These methods are used to control infinite recursion in repr, str, print,
    etc.  Container objects that may recursively contain themselves,
diff -up Python-2.7.2/Objects/obmalloc.c.add-debug-malloc-stats Python-2.7.2/Objects/obmalloc.c
--- Python-2.7.2/Objects/obmalloc.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/obmalloc.c    2011-09-16 19:03:25.114821625 -0400
@@ -508,12 +508,10 @@ static struct arena_object* usable_arena
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index 38ebc37..2c05359 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -508,12 +508,10 @@ static struct arena_object* usable_arenas = NULL;
 /* Number of arenas allocated that haven't been free()'d. */
 static size_t narenas_currently_allocated = 0;
 
@@ -373,7 +418,7 @@
     arenaobj->freepools = NULL;
     /* pool_address <- first pool-aligned address in the arena
        nfreepools <- number of whole pools that fit after alignment */
@@ -1694,17 +1690,19 @@ _PyObject_DebugDumpAddress(const void *p
@@ -1694,17 +1690,19 @@ _PyObject_DebugDumpAddress(const void *p)
     }
 }
 
@@ -518,9 +563,10 @@
 #ifdef Py_USING_MEMORY_DEBUGGER
 /* Make this function last so gcc won't inline it since the definition is
  * after the reference.
diff -up Python-2.7.2/Objects/setobject.c.add-debug-malloc-stats Python-2.7.2/Objects/setobject.c
--- Python-2.7.2/Objects/setobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/setobject.c    2011-09-16 19:03:25.115821625 -0400
diff --git a/Objects/setobject.c b/Objects/setobject.c
index af1ce16..3439b7c 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -1088,6 +1088,16 @@ PySet_Fini(void)
     Py_CLEAR(emptyfrozenset);
 }
@@ -538,10 +584,11 @@
 static PyObject *
 set_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
diff -up Python-2.7.2/Objects/stringobject.c.add-debug-malloc-stats Python-2.7.2/Objects/stringobject.c
--- Python-2.7.2/Objects/stringobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/stringobject.c    2011-09-16 19:03:25.116821625 -0400
@@ -4822,3 +4822,43 @@ void _Py_ReleaseInternedStrings(void)
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 1209197..b8646dd 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -4843,3 +4843,43 @@ void _Py_ReleaseInternedStrings(void)
     PyDict_Clear(interned);
     Py_CLEAR(interned);
 }
@@ -585,9 +632,10 @@
+            "%zi/%zi "
+            "mortal/immortal\n", mortal_size, immortal_size);
+}
diff -up Python-2.7.2/Objects/tupleobject.c.add-debug-malloc-stats Python-2.7.2/Objects/tupleobject.c
--- Python-2.7.2/Objects/tupleobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/tupleobject.c    2011-09-16 19:03:25.116821625 -0400
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 00f2e47..7682d81 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -44,6 +44,22 @@ show_track(void)
 }
 #endif
@@ -611,10 +659,11 @@
 
 PyObject *
 PyTuple_New(register Py_ssize_t size)
diff -up Python-2.7.2/Objects/unicodeobject.c.add-debug-malloc-stats Python-2.7.2/Objects/unicodeobject.c
--- Python-2.7.2/Objects/unicodeobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
+++ Python-2.7.2/Objects/unicodeobject.c    2011-09-16 19:03:25.118821625 -0400
@@ -8883,6 +8883,12 @@ _PyUnicode_Fini(void)
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 6bea370..ced9acf 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -8920,6 +8920,12 @@ _PyUnicode_Fini(void)
     (void)PyUnicode_ClearFreeList();
 }
 
@@ -627,10 +676,11 @@
 #ifdef __cplusplus
 }
 #endif
diff -up Python-2.7.2/Python/pythonrun.c.add-debug-malloc-stats Python-2.7.2/Python/pythonrun.c
--- Python-2.7.2/Python/pythonrun.c.add-debug-malloc-stats    2011-09-16 19:03:25.025821626 -0400
+++ Python-2.7.2/Python/pythonrun.c    2011-09-16 19:03:25.118821625 -0400
@@ -549,7 +549,7 @@ Py_Finalize(void)
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index f0fbd74..0b73f3a 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -557,7 +557,7 @@ Py_Finalize(void)
 #endif /* Py_TRACE_REFS */
 #ifdef PYMALLOC_DEBUG
     if (Py_GETENV("PYTHONMALLOCSTATS"))
@@ -639,10 +689,11 @@
 #endif
 
     call_ll_exitfuncs();
diff -up Python-2.7.2/Python/sysmodule.c.add-debug-malloc-stats Python-2.7.2/Python/sysmodule.c
--- Python-2.7.2/Python/sysmodule.c.add-debug-malloc-stats    2011-09-16 19:03:25.007821626 -0400
+++ Python-2.7.2/Python/sysmodule.c    2011-09-16 19:03:25.119821625 -0400
@@ -872,6 +872,57 @@ a 11-tuple where the entries in the tupl
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 2a7c207..fbb637b 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -873,6 +873,57 @@ a 11-tuple where the entries in the tuple are counts of:\n\
 extern "C" {
 #endif
 
@@ -676,7 +727,7 @@
+    if (!fp) {
+        PyErr_SetString(PyExc_ValueError, "file is closed");
+        Py_DECREF(file);
+        return NULL;
+        return NULL;
+    }
+
+    _PyObject_DebugMallocStats(fp);
@@ -700,7 +751,7 @@
 #ifdef Py_TRACE_REFS
 /* Defined in objects.c because it uses static globals if that file */
 extern PyObject *_Py_GetObjects(PyObject *, PyObject *);
@@ -970,6 +1021,8 @@ static PyMethodDef sys_methods[] = {
@@ -971,6 +1022,8 @@ static PyMethodDef sys_methods[] = {
     {"settrace",        sys_settrace, METH_O, settrace_doc},
     {"gettrace",        sys_gettrace, METH_NOARGS, gettrace_doc},
     {"call_tracing", sys_call_tracing, METH_VARARGS, call_tracing_doc},
SOURCES/00234-PEP493-updated-implementation.patch
@@ -42,7 +42,7 @@
+
+    # Check for a system-wide override of the default behaviour
+    context_factory = {
+        'platform_default': _create_unverified_context,
+        'platform_default': create_default_context,
+        'enable': create_default_context,
+        'disable': _create_unverified_context
+    }
@@ -77,7 +77,7 @@
 import asyncore
 import socket
 import select
@@ -1149,6 +1149,52 @@
@@ -1149,6 +1149,57 @@
         self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
         self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
 
@@ -91,17 +91,17 @@
+        local_ssl = support.import_fresh_module("ssl")
+        # Certificate verification is enabled by default
+        self.assertIs(local_ssl._create_default_https_context,
+                      local_ssl._create_unverified_context)
+        # Turn verification on
+        local_ssl._https_verify_certificates(enable=True)
+        self.assertIs(local_ssl._create_default_https_context,
+                      local_ssl.create_default_context)
+        # Turn verification off
+        # Turn default verification off
+        local_ssl._https_verify_certificates(enable=False)
+        self.assertIs(local_ssl._create_default_https_context,
+                      local_ssl._create_unverified_context)
+        # The default behaviour is verification on
+        # And back on
+        local_ssl._https_verify_certificates(enable=True)
+        self.assertIs(local_ssl._create_default_https_context,
+                      local_ssl.create_default_context)
+        # The default behaviour is to enable
+        local_ssl._https_verify_certificates(enable=False)
+        local_ssl._https_verify_certificates()
+        self.assertIs(local_ssl._create_default_https_context,
+                      local_ssl.create_default_context)
@@ -109,16 +109,21 @@
+    def test__https_verify_envvar(self):
+        # Unit test to check the PYTHONHTTPSVERIFY handling
+        # Need to use a subprocess so it can still be run under -E
+        # Checks are inverted due to the 0 == success return code convention
+        https_is_verified = """import ssl, sys;\
+            sys.exit(ssl._create_default_https_context is not
+                     ssl.create_default_context)"""
+        https_is_not_verified = """import ssl, sys;\
+            sys.exit(ssl._create_default_https_context is not
+                     ssl._create_unverified_context)"""
+        https_is_verified = """import ssl, sys; \
+            status = "Error: _create_default_https_context does not verify certs" \
+                       if ssl._create_default_https_context is \
+                          ssl._create_unverified_context \
+                     else None; \
+            sys.exit(status)"""
+        https_is_not_verified = """import ssl, sys; \
+            status = "Error: _create_default_https_context verifies certs" \
+                       if ssl._create_default_https_context is \
+                          ssl.create_default_context \
+                     else None; \
+            sys.exit(status)"""
+        extra_env = {}
+        # Omitting it leaves verification off
+        assert_python_ok("-c", https_is_not_verified, **extra_env)
+        # Omitting it leaves verification on
+        assert_python_ok("-c", https_is_verified, **extra_env)
+        # Setting it to zero turns verification off
+        extra_env[ssl._https_verify_envvar] = "0"
+        assert_python_ok("-c", https_is_not_verified, **extra_env)
SOURCES/00255-Fix-ssl-module-parsing-of-GEN_RID-subject-alternative-name-fields-in-X.509-certs.patch
New file
@@ -0,0 +1,235 @@
# HG changeset patch
# User Christian Heimes <christian@python.org>
# Date 1473197135 -7200
# Node ID 74805fd9e7343649372d0b9c76b4490b2975a674
# Parent  6f4f19217d9be12be7a9c86cf1e118b140564b4f
Issue #27691: Fix ssl module's parsing of GEN_RID subject alternative name fields in X.509 certs.
diff --git a/Lib/test/allsans.pem b/Lib/test/allsans.pem
new file mode 100644
--- /dev/null
+++ b/Lib/test/allsans.pem
@@ -0,0 +1,37 @@
+-----BEGIN PRIVATE KEY-----
+MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOoy7/QOtTjQ0niE
+6uDcTwtkC0R2Tvy1AjVnXohCntZfdzbTGDoYTgXSOLsP8A697jUiJ8VCePGH50xG
+Z4DKnAF3a9O3a9nr2pLXb0iY3XOMv+YEBii7CfI+3oxFYgCl0sMgHzDD2ZTVYAsm
+DWgLUVsE2gHEccRwrM2tPf2EgR+FAgMBAAECgYEA3qyfyYVSeTrTYxO93x6ZaVMu
+A2IZp9zSxMQL9bKiI2GRj+cV2ebSCGbg2btFnD6qBor7FWsmYz+8g6FNN/9sY4az
+61rMqMtQvLBe+7L8w70FeTze4qQ4Y1oQri0qD6tBWhDVlpnbI5Py9bkZKD67yVUk
+elcEA/5x4PrYXkuqsAECQQD80NjT0mDvaY0JOOaQFSEpMv6QiUA8GGX8Xli7IoKb
+tAolPG8rQBa+qSpcWfDMTrWw/aWHuMEEQoP/bVDH9W4FAkEA7SYQbBAKnojZ5A3G
+kOHdV7aeivRQxQk/JN8Fb8oKB9Csvpv/BsuGxPKXHdhFa6CBTTsNRtHQw/szPo4l
+xMIjgQJAPoMxqibR+0EBM6+TKzteSL6oPXsCnBl4Vk/J5vPgkbmR7KUl4+7j8N8J
+b2554TrxKEN/w7CGYZRE6UrRd7ATNQJAWD7Yz41sli+wfPdPU2xo1BHljyl4wMk/
+EPZYbI/PCbdyAH/F935WyQTIjNeEhZc1Zkq6FwdOWw8ns3hrv3rKgQJAHXv1BqUa
+czGPIFxX2TNoqtcl6/En4vrxVB1wzsfzkkDAg98kBl7qsF+S3qujSzKikjeaVbI2
+/CyWR2P3yLtOmA==
+-----END PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIDcjCCAtugAwIBAgIJAN5dc9TOWjB7MA0GCSqGSIb3DQEBCwUAMF0xCzAJBgNV
+BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
+IFNvZnR3YXJlIEZvdW5kYXRpb24xEDAOBgNVBAMMB2FsbHNhbnMwHhcNMTYwODA1
+MTAyMTExWhcNMjYwODAzMTAyMTExWjBdMQswCQYDVQQGEwJYWTEXMBUGA1UEBwwO
+Q2FzdGxlIEFudGhyYXgxIzAhBgNVBAoMGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0
+aW9uMRAwDgYDVQQDDAdhbGxzYW5zMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
+gQDqMu/0DrU40NJ4hOrg3E8LZAtEdk78tQI1Z16IQp7WX3c20xg6GE4F0ji7D/AO
+ve41IifFQnjxh+dMRmeAypwBd2vTt2vZ69qS129ImN1zjL/mBAYouwnyPt6MRWIA
+pdLDIB8ww9mU1WALJg1oC1FbBNoBxHHEcKzNrT39hIEfhQIDAQABo4IBODCCATQw
+ggEwBgNVHREEggEnMIIBI4IHYWxsc2Fuc6AeBgMqAwSgFwwVc29tZSBvdGhlciBp
+ZGVudGlmaWVyoDUGBisGAQUCAqArMCmgEBsOS0VSQkVST1MuUkVBTE2hFTAToAMC
+AQGhDDAKGwh1c2VybmFtZYEQdXNlckBleGFtcGxlLm9yZ4IPd3d3LmV4YW1wbGUu
+b3JnpGcwZTELMAkGA1UEBhMCWFkxFzAVBgNVBAcMDkNhc3RsZSBBbnRocmF4MSMw
+IQYDVQQKDBpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEYMBYGA1UEAwwPZGly
+bmFtZSBleGFtcGxlhhdodHRwczovL3d3dy5weXRob24ub3JnL4cEfwAAAYcQAAAA
+AAAAAAAAAAAAAAAAAYgEKgMEBTANBgkqhkiG9w0BAQsFAAOBgQAy16h+F+nOmeiT
+VWR0fc8F/j6FcadbLseAUaogcC15OGxCl4UYpLV88HBkABOoGCpP155qwWTwOrdG
+iYPGJSusf1OnJEbvzFejZf6u078bPd9/ZL4VWLjv+FPGkjd+N+/OaqMvgj8Lu99f
+3Y/C4S7YbHxxwff6C6l2Xli+q6gnuQ==
+-----END CERTIFICATE-----
diff --git a/Lib/test/make_ssl_certs.py b/Lib/test/make_ssl_certs.py
--- a/Lib/test/make_ssl_certs.py
+++ b/Lib/test/make_ssl_certs.py
@@ -20,7 +20,28 @@ req_template = """
     CN                     = {hostname}
     [req_x509_extensions]
-    subjectAltName         = DNS:{hostname}
+    subjectAltName         = @san
+
+    [san]
+    DNS.1 = {hostname}
+    {extra_san}
+
+    [dir_sect]
+    C                      = XY
+    L                      = Castle Anthrax
+    O                      = Python Software Foundation
+    CN                     = dirname example
+
+    [princ_name]
+    realm = EXP:0, GeneralString:KERBEROS.REALM
+    principal_name = EXP:1, SEQUENCE:principal_seq
+
+    [principal_seq]
+    name_type = EXP:0, INTEGER:1
+    name_string = EXP:1, SEQUENCE:principals
+
+    [principals]
+    princ1 = GeneralString:username
     [ ca ]
     default_ca      = CA_default
@@ -67,7 +88,7 @@ req_template = """
 here = os.path.abspath(os.path.dirname(__file__))
-def make_cert_key(hostname, sign=False):
+def make_cert_key(hostname, sign=False, extra_san=''):
     print("creating cert for " + hostname)
     tempnames = []
     for i in range(3):
@@ -75,8 +96,9 @@ def make_cert_key(hostname, sign=False):
             tempnames.append(f.name)
     req_file, cert_file, key_file = tempnames
     try:
+        req = req_template.format(hostname=hostname, extra_san=extra_san)
         with open(req_file, 'w') as f:
-            f.write(req_template.format(hostname=hostname))
+            f.write(req)
         args = ['req', '-new', '-days', '3650', '-nodes',
                 '-newkey', 'rsa:1024', '-keyout', key_file,
                 '-config', req_file]
@@ -120,7 +142,7 @@ def make_ca():
         f.write('unique_subject = no')
     with tempfile.NamedTemporaryFile("w") as t:
-        t.write(req_template.format(hostname='our-ca-server'))
+        t.write(req_template.format(hostname='our-ca-server', extra_san=''))
         t.flush()
         with tempfile.NamedTemporaryFile() as f:
             args = ['req', '-new', '-days', '3650', '-extensions', 'v3_ca', '-nodes',
@@ -171,6 +193,25 @@ if __name__ == '__main__':
         f.write(key)
         f.write(cert)
+    extra_san = [
+        'otherName.1 = 1.2.3.4;UTF8:some other identifier',
+        'otherName.2 = 1.3.6.1.5.2.2;SEQUENCE:princ_name',
+        'email.1 = user@example.org',
+        'DNS.2 = www.example.org',
+        # GEN_X400
+        'dirName.1 = dir_sect',
+        # GEN_EDIPARTY
+        'URI.1 = https://www.python.org/',
+        'IP.1 = 127.0.0.1',
+        'IP.2 = ::1',
+        'RID.1 = 1.2.3.4.5',
+    ]
+
+    cert, key = make_cert_key('allsans', extra_san='\n'.join(extra_san))
+    with open('allsans.pem', 'w') as f:
+        f.write(key)
+        f.write(cert)
+
     unmake_ca()
     print("\n\nPlease change the values in test_ssl.py, test_parse_cert function related to notAfter,notBefore and serialNumber")
     check_call(['openssl','x509','-in','keycert.pem','-dates','-serial','-noout'])
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py
index fa59641..9d5816b 100644
--- a/Lib/test/test_ssl.py
+++ b/Lib/test/test_ssl.py
@@ -57,6 +57,8 @@ CRLFILE = data_file("revocation.crl")
 SIGNED_CERTFILE = data_file("keycert3.pem")
 SIGNED_CERTFILE2 = data_file("keycert4.pem")
 SIGNING_CA = data_file("pycacert.pem")
+# cert with all kinds of subject alt names
+ALLSANFILE = data_file("allsans.pem")
 SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
@@ -236,6 +238,28 @@ class BasicSocketTests(unittest.TestCase):
                          ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
                         )
+    def test_parse_all_sans(self):
+        p = ssl._ssl._test_decode_cert(ALLSANFILE)
+        self.assertEqual(p['subjectAltName'],
+            (
+                ('DNS', 'allsans'),
+                ('othername', '<unsupported>'),
+                ('othername', '<unsupported>'),
+                ('email', 'user@example.org'),
+                ('DNS', 'www.example.org'),
+                ('DirName',
+                    ((('countryName', 'XY'),),
+                    (('localityName', 'Castle Anthrax'),),
+                    (('organizationName', 'Python Software Foundation'),),
+                    (('commonName', 'dirname example'),))),
+                ('URI', 'https://www.python.org/'),
+                ('IP Address', '127.0.0.1'),
+                ('IP Address', '0:0:0:0:0:0:0:1\n'),
+                ('Registered ID', '1.2.3.4.5')
+            )
+        )
+
+
     def test_DER_to_PEM(self):
         with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
             pem = f.read()
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -953,6 +953,35 @@ static PyObject *
                 PyTuple_SET_ITEM(t, 1, v);
                 break;
+            case GEN_RID:
+                t = PyTuple_New(2);
+                if (t == NULL)
+                    goto fail;
+
+                v = PyUnicode_FromString("Registered ID");
+                if (v == NULL) {
+                    Py_DECREF(t);
+                    goto fail;
+                }
+                PyTuple_SET_ITEM(t, 0, v);
+
+                len = i2t_ASN1_OBJECT(buf, sizeof(buf)-1, name->d.rid);
+                if (len < 0) {
+                    Py_DECREF(t);
+                    _setSSLError(NULL, 0, __FILE__, __LINE__);
+                    goto fail;
+                } else if (len >= (int)sizeof(buf)) {
+                    v = PyUnicode_FromString("<INVALID>");
+                } else {
+                    v = PyUnicode_FromStringAndSize(buf, len);
+                }
+                if (v == NULL) {
+                    Py_DECREF(t);
+                    goto fail;
+                }
+                PyTuple_SET_ITEM(t, 1, v);
+                break;
+
             default:
                 /* for everything else, we use the OpenSSL print form */
                 switch (gntype) {
@@ -978,8 +1007,12 @@ static PyObject *
                     goto fail;
                 }
                 vptr = strchr(buf, ':');
-                if (vptr == NULL)
+                if (vptr == NULL) {
+                    PyErr_Format(PyExc_ValueError,
+                                 "Invalid value %.200s",
+                                 buf);
                     goto fail;
+                }
                 t = PyTuple_New(2);
                 if (t == NULL)
                     goto fail;
SOURCES/00256-fix-incorrect-parsing-of-regular-expressions.patch
New file
@@ -0,0 +1,80 @@
diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py
index 7cda2b6..15d2324 100644
--- a/Lib/sre_compile.py
+++ b/Lib/sre_compile.py
@@ -355,8 +355,6 @@ def _optimize_unicode(charset, fixup):
 def _simple(av):
     # check if av is a "simple" operator
     lo, hi = av[2].getwidth()
-    if lo == 0 and hi == MAXREPEAT:
-        raise error, "nothing to repeat"
     return lo == hi == 1 and av[2][0][0] != SUBPATTERN
 def _compile_info(code, pattern, flags):
diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py
index 75f8c96..644441d 100644
--- a/Lib/sre_parse.py
+++ b/Lib/sre_parse.py
@@ -147,7 +147,7 @@ class SubPattern:
         REPEATCODES = (MIN_REPEAT, MAX_REPEAT)
         for op, av in self.data:
             if op is BRANCH:
-                i = sys.maxint
+                i = MAXREPEAT - 1
                 j = 0
                 for av in av[1]:
                     l, h = av.getwidth()
@@ -165,14 +165,14 @@ class SubPattern:
                 hi = hi + j
             elif op in REPEATCODES:
                 i, j = av[2].getwidth()
-                lo = lo + long(i) * av[0]
-                hi = hi + long(j) * av[1]
+                lo = lo + i * av[0]
+                hi = hi + j * av[1]
             elif op in UNITCODES:
                 lo = lo + 1
                 hi = hi + 1
             elif op == SUCCESS:
                 break
-        self.width = int(min(lo, sys.maxint)), int(min(hi, sys.maxint))
+        self.width = min(lo, MAXREPEAT - 1), min(hi, MAXREPEAT)
         return self.width
 class Tokenizer:
diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index 18a81a2..f0827d8 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -897,6 +897,17 @@ class ReTests(unittest.TestCase):
         with self.assertRaisesRegexp(sre_constants.error, '\?foo'):
             re.compile('(?P<?foo>)')
+    def test_bug_2537(self):
+        # issue 2537: empty submatches
+        for outer_op in ('{0,}', '*', '+', '{1,187}'):
+            for inner_op in ('{0,}', '*', '?'):
+                r = re.compile("^((x|y)%s)%s" % (inner_op, outer_op))
+                m = r.match("xyyzy")
+                self.assertEqual(m.group(0), "xyy")
+                self.assertEqual(m.group(1), "")
+                self.assertEqual(m.group(2), "y")
+
+
 def run_re_tests():
     from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR
diff --git a/Lib/doctest.py b/Lib/doctest.py
index 90bcca1..0ee40a2 100644
--- a/Lib/doctest.py
+++ b/Lib/doctest.py
@@ -564,7 +564,7 @@ class DocTestParser:
         # Want consists of any non-blank lines that do not start with PS1.
         (?P<want> (?:(?![ ]*$)    # Not a blank line
                      (?![ ]*>>>)  # Not a line starting with PS1
-                     .*$\n?       # But any other line
+                     .+$\n?       # But any other line
                   )*)
         ''', re.MULTILINE | re.VERBOSE)
SOURCES/00257-threading-wait-clamp-remaining-time.patch
New file
@@ -0,0 +1,20 @@
diff --git a/Lib/threading.py b/Lib/threading.py
index e4c7f35..91b3849 100644
--- a/Lib/threading.py
+++ b/Lib/threading.py
@@ -351,13 +351,14 @@ class _Condition(_Verbose):
                     gotit = waiter.acquire(0)
                     if gotit:
                         break
-                    remaining = endtime - _time()
+                    remaining = min(endtime - _time(), timeout)
                     if remaining <= 0:
                         break
                     if balancing:
                         delay = min(delay * 2, remaining, 0.05)
                     else:
                         delay = remaining
+                        endtime = _time() + remaining
                     _sleep(delay)
                 if not gotit:
                     if __debug__:
SOURCES/00263-fix-ssl-reference-leaks.patch
New file
@@ -0,0 +1,14 @@
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index a3ea254..d0a3830 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -2564,7 +2564,9 @@ load_cert_chain(PySSLContext *self, PyObject *args, PyObject *kwds)
     }
     SSL_CTX_set_default_passwd_cb(self->ctx, orig_passwd_cb);
     SSL_CTX_set_default_passwd_cb_userdata(self->ctx, orig_passwd_userdata);
+    Py_XDECREF(keyfile_bytes);
     PyMem_Free(pw_info.password);
+    PyMem_Free(certfile_bytes);
     Py_RETURN_NONE;
 error:
SOURCES/00265-protect-key-list-during-fork.patch
New file
@@ -0,0 +1,114 @@
diff --git a/Include/pythread.h b/Include/pythread.h
index dfd6157..f3e6259 100644
--- a/Include/pythread.h
+++ b/Include/pythread.h
@@ -30,6 +30,8 @@ PyAPI_FUNC(void) PyThread_delete_key(int);
 PyAPI_FUNC(int) PyThread_set_key_value(int, void *);
 PyAPI_FUNC(void *) PyThread_get_key_value(int);
 PyAPI_FUNC(void) PyThread_delete_key_value(int key);
+PyAPI_FUNC(int) _PyThread_AcquireKeyLock(void);
+PyAPI_FUNC(void) _PyThread_ReleaseKeyLock(void);
 /* Cleanup after a fork */
 PyAPI_FUNC(void) PyThread_ReInitTLS(void);
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 022d7aa..8f6cbb2 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -65,6 +65,10 @@ corresponding Unix manual entries for more information on calls.");
 #include "osdefs.h"
 #endif
+#ifdef WITH_THREAD
+#include "pythread.h"
+#endif
+
 #ifdef HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif /* HAVE_SYS_TYPES_H */
@@ -3796,7 +3800,18 @@ posix_fork1(PyObject *self, PyObject *noargs)
     pid_t pid;
     int result = 0;
     _PyImport_AcquireLock();
+#ifdef WITH_THREAD
+    if (_PyThread_AcquireKeyLock() == 0) {
+        _PyImport_ReleaseLock();
+        PyErr_SetString(PyExc_RuntimeError,
+                        "could not acquire thread key lock");
+        return NULL;
+    }
+#endif
     pid = fork1();
+#ifdef WITH_THREAD
+    _PyThread_ReleaseKeyLock();
+#endif
     if (pid == 0) {
         /* child: this clobbers and resets the import lock. */
         PyOS_AfterFork();
@@ -3829,7 +3844,18 @@ posix_fork(PyObject *self, PyObject *noargs)
     pid_t pid;
     int result = 0;
     _PyImport_AcquireLock();
+#ifdef WITH_THREAD
+    if (_PyThread_AcquireKeyLock() == 0) {
+        _PyImport_ReleaseLock();
+        PyErr_SetString(PyExc_RuntimeError,
+                        "could not acquire thread key lock");
+        return NULL;
+    }
+#endif
     pid = fork();
+#ifdef WITH_THREAD
+    _PyThread_ReleaseKeyLock();
+#endif
     if (pid == 0) {
         /* child: this clobbers and resets the import lock. */
         PyOS_AfterFork();
@@ -3955,7 +3981,18 @@ posix_forkpty(PyObject *self, PyObject *noargs)
     pid_t pid;
     _PyImport_AcquireLock();
+#ifdef WITH_THREAD
+    if (_PyThread_AcquireKeyLock() == 0) {
+        _PyImport_ReleaseLock();
+        PyErr_SetString(PyExc_RuntimeError,
+                        "could not acquire thread key lock");
+        return NULL;
+    }
+#endif
     pid = forkpty(&master_fd, NULL, NULL, NULL);
+#ifdef WITH_THREAD
+    _PyThread_ReleaseKeyLock();
+#endif
     if (pid == 0) {
         /* child: this clobbers and resets the import lock. */
         PyOS_AfterFork();
diff --git a/Python/thread.c b/Python/thread.c
index dd333e8..957739e 100644
--- a/Python/thread.c
+++ b/Python/thread.c
@@ -387,6 +387,24 @@ PyThread_delete_key_value(int key)
     PyThread_release_lock(keymutex);
 }
+int
+_PyThread_AcquireKeyLock(void)
+{
+    if (keymutex == NULL) {
+        keymutex = PyThread_allocate_lock();
+    }
+    if (keymutex == NULL) {
+        return 0;
+    }
+    return PyThread_acquire_lock(keymutex, 1);
+}
+
+void
+_PyThread_ReleaseKeyLock(void)
+{
+    PyThread_release_lock(keymutex);
+}
+
 /* Forget everything not associated with the current thread id.
  * This function is called from PyOS_AfterFork().  It is necessary
  * because other thread ids which were in use at the time of the fork
SOURCES/00266-fix-shutil.make_archive-ignoring-empty-dirs.patch
New file
@@ -0,0 +1,376 @@
diff --git a/Lib/shutil.py b/Lib/shutil.py
index 420802f..d0ff2ef 100644
--- a/Lib/shutil.py
+++ b/Lib/shutil.py
@@ -446,17 +446,24 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None):
                         zip_filename, base_dir)
         if not dry_run:
-            zip = zipfile.ZipFile(zip_filename, "w",
-                                  compression=zipfile.ZIP_DEFLATED)
-
-            for dirpath, dirnames, filenames in os.walk(base_dir):
-                for name in filenames:
-                    path = os.path.normpath(os.path.join(dirpath, name))
-                    if os.path.isfile(path):
-                        zip.write(path, path)
+            with zipfile.ZipFile(zip_filename, "w",
+                                 compression=zipfile.ZIP_DEFLATED) as zf:
+                path = os.path.normpath(base_dir)
+                zf.write(path, path)
+                if logger is not None:
+                    logger.info("adding '%s'", path)
+                for dirpath, dirnames, filenames in os.walk(base_dir):
+                    for name in sorted(dirnames):
+                        path = os.path.normpath(os.path.join(dirpath, name))
+                        zf.write(path, path)
                         if logger is not None:
                             logger.info("adding '%s'", path)
-            zip.close()
+                    for name in filenames:
+                        path = os.path.normpath(os.path.join(dirpath, name))
+                        if os.path.isfile(path):
+                            zf.write(path, path)
+                            if logger is not None:
+                                logger.info("adding '%s'", path)
     return zip_filename
diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py
index 9bdb724..9238489 100644
--- a/Lib/test/test_shutil.py
+++ b/Lib/test/test_shutil.py
@@ -10,13 +10,13 @@ import os.path
 import errno
 from os.path import splitdrive
 from distutils.spawn import find_executable, spawn
-from shutil import (_make_tarball, _make_zipfile, make_archive,
+from shutil import (make_archive,
                     register_archive_format, unregister_archive_format,
                     get_archive_formats)
 import tarfile
 import warnings
-from test import test_support
+from test import test_support as support
 from test.test_support import TESTFN, check_warnings, captured_stdout
 TESTFN2 = TESTFN + "2"
@@ -372,139 +372,135 @@ class TestShutil(unittest.TestCase):
     @unittest.skipUnless(zlib, "requires zlib")
     def test_make_tarball(self):
         # creating something to tar
-        tmpdir = self.mkdtemp()
-        self.write_file([tmpdir, 'file1'], 'xxx')
-        self.write_file([tmpdir, 'file2'], 'xxx')
-        os.mkdir(os.path.join(tmpdir, 'sub'))
-        self.write_file([tmpdir, 'sub', 'file3'], 'xxx')
+        root_dir, base_dir = self._create_files('')
         tmpdir2 = self.mkdtemp()
         # force shutil to create the directory
         os.rmdir(tmpdir2)
-        unittest.skipUnless(splitdrive(tmpdir)[0] == splitdrive(tmpdir2)[0],
+        unittest.skipUnless(splitdrive(root_dir)[0] == splitdrive(tmpdir2)[0],
                             "source and target should be on same drive")
         base_name = os.path.join(tmpdir2, 'archive')
         # working with relative paths to avoid tar warnings
-        old_dir = os.getcwd()
-        os.chdir(tmpdir)
-        try:
-            _make_tarball(splitdrive(base_name)[1], '.')
-        finally:
-            os.chdir(old_dir)
+        make_archive(splitdrive(base_name)[1], 'gztar', root_dir, '.')
         # check if the compressed tarball was created
         tarball = base_name + '.tar.gz'
-        self.assertTrue(os.path.exists(tarball))
+        self.assertTrue(os.path.isfile(tarball))
+        self.assertTrue(tarfile.is_tarfile(tarball))
+        with tarfile.open(tarball, 'r:gz') as tf:
+            self.assertEqual(sorted(tf.getnames()),
+                             ['.', './file1', './file2',
+                              './sub', './sub/file3', './sub2'])
         # trying an uncompressed one
         base_name = os.path.join(tmpdir2, 'archive')
-        old_dir = os.getcwd()
-        os.chdir(tmpdir)
-        try:
-            _make_tarball(splitdrive(base_name)[1], '.', compress=None)
-        finally:
-            os.chdir(old_dir)
+        make_archive(splitdrive(base_name)[1], 'tar', root_dir, '.')
         tarball = base_name + '.tar'
-        self.assertTrue(os.path.exists(tarball))
+        self.assertTrue(os.path.isfile(tarball))
+        self.assertTrue(tarfile.is_tarfile(tarball))
+        with tarfile.open(tarball, 'r') as tf:
+            self.assertEqual(sorted(tf.getnames()),
+                             ['.', './file1', './file2',
+                              './sub', './sub/file3', './sub2'])
     def _tarinfo(self, path):
-        tar = tarfile.open(path)
-        try:
+        with tarfile.open(path) as tar:
             names = tar.getnames()
             names.sort()
             return tuple(names)
-        finally:
-            tar.close()
-    def _create_files(self):
+    def _create_files(self, base_dir='dist'):
         # creating something to tar
-        tmpdir = self.mkdtemp()
-        dist = os.path.join(tmpdir, 'dist')
-        os.mkdir(dist)
-        self.write_file([dist, 'file1'], 'xxx')
-        self.write_file([dist, 'file2'], 'xxx')
+        root_dir = self.mkdtemp()
+        dist = os.path.join(root_dir, base_dir)
+        if not os.path.isdir(dist):
+            os.makedirs(dist)
+        self.write_file((dist, 'file1'), 'xxx')
+        self.write_file((dist, 'file2'), 'xxx')
         os.mkdir(os.path.join(dist, 'sub'))
-        self.write_file([dist, 'sub', 'file3'], 'xxx')
+        self.write_file((dist, 'sub', 'file3'), 'xxx')
         os.mkdir(os.path.join(dist, 'sub2'))
-        tmpdir2 = self.mkdtemp()
-        base_name = os.path.join(tmpdir2, 'archive')
-        return tmpdir, tmpdir2, base_name
+        if base_dir:
+            self.write_file((root_dir, 'outer'), 'xxx')
+        return root_dir, base_dir
     @unittest.skipUnless(zlib, "Requires zlib")
-    @unittest.skipUnless(find_executable('tar') and find_executable('gzip'),
+    @unittest.skipUnless(find_executable('tar'),
                          'Need the tar command to run')
     def test_tarfile_vs_tar(self):
-        tmpdir, tmpdir2, base_name =  self._create_files()
-        old_dir = os.getcwd()
-        os.chdir(tmpdir)
-        try:
-            _make_tarball(base_name, 'dist')
-        finally:
-            os.chdir(old_dir)
+        root_dir, base_dir = self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
+        make_archive(base_name, 'gztar', root_dir, base_dir)
         # check if the compressed tarball was created
         tarball = base_name + '.tar.gz'
-        self.assertTrue(os.path.exists(tarball))
+        self.assertTrue(os.path.isfile(tarball))
         # now create another tarball using `tar`
-        tarball2 = os.path.join(tmpdir, 'archive2.tar.gz')
-        tar_cmd = ['tar', '-cf', 'archive2.tar', 'dist']
-        gzip_cmd = ['gzip', '-f9', 'archive2.tar']
-        old_dir = os.getcwd()
-        os.chdir(tmpdir)
-        try:
-            with captured_stdout() as s:
-                spawn(tar_cmd)
-                spawn(gzip_cmd)
-        finally:
-            os.chdir(old_dir)
+        tarball2 = os.path.join(root_dir, 'archive2.tar')
+        tar_cmd = ['tar', '-cf', 'archive2.tar', base_dir]
+        with support.change_cwd(root_dir), captured_stdout():
+            spawn(tar_cmd)
-        self.assertTrue(os.path.exists(tarball2))
+        self.assertTrue(os.path.isfile(tarball2))
         # let's compare both tarballs
         self.assertEqual(self._tarinfo(tarball), self._tarinfo(tarball2))
         # trying an uncompressed one
-        base_name = os.path.join(tmpdir2, 'archive')
-        old_dir = os.getcwd()
-        os.chdir(tmpdir)
-        try:
-            _make_tarball(base_name, 'dist', compress=None)
-        finally:
-            os.chdir(old_dir)
+        make_archive(base_name, 'tar', root_dir, base_dir)
         tarball = base_name + '.tar'
-        self.assertTrue(os.path.exists(tarball))
+        self.assertTrue(os.path.isfile(tarball))
         # now for a dry_run
-        base_name = os.path.join(tmpdir2, 'archive')
-        old_dir = os.getcwd()
-        os.chdir(tmpdir)
-        try:
-            _make_tarball(base_name, 'dist', compress=None, dry_run=True)
-        finally:
-            os.chdir(old_dir)
+        make_archive(base_name, 'tar', root_dir, base_dir, dry_run=True)
         tarball = base_name + '.tar'
-        self.assertTrue(os.path.exists(tarball))
+        self.assertTrue(os.path.isfile(tarball))
     @unittest.skipUnless(zlib, "Requires zlib")
     @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run')
     def test_make_zipfile(self):
-        # creating something to tar
-        tmpdir = self.mkdtemp()
-        self.write_file([tmpdir, 'file1'], 'xxx')
-        self.write_file([tmpdir, 'file2'], 'xxx')
+        # creating something to zip
+        root_dir, base_dir = self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
-        tmpdir2 = self.mkdtemp()
-        # force shutil to create the directory
-        os.rmdir(tmpdir2)
-        base_name = os.path.join(tmpdir2, 'archive')
-        _make_zipfile(base_name, tmpdir)
+        res = make_archive(base_name, 'zip', root_dir, base_dir)
-        # check if the compressed tarball was created
-        tarball = base_name + '.zip'
-        self.assertTrue(os.path.exists(tarball))
+        self.assertEqual(res, base_name + '.zip')
+        self.assertTrue(os.path.isfile(res))
+        self.assertTrue(zipfile.is_zipfile(res))
+        with zipfile.ZipFile(res) as zf:
+            self.assertEqual(sorted(zf.namelist()),
+                             ['dist/', 'dist/file1', 'dist/file2',
+                             'dist/sub/', 'dist/sub/file3', 'dist/sub2/'])
+    @unittest.skipUnless(zlib, "Requires zlib")
+    @unittest.skipUnless(ZIP_SUPPORT, 'Need zip support to run')
+    @unittest.skipUnless(find_executable('zip'),
+                         'Need the zip command to run')
+    def test_zipfile_vs_zip(self):
+        root_dir, base_dir = self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
+        archive = make_archive(base_name, 'zip', root_dir, base_dir)
+
+        # check if ZIP file  was created
+        self.assertEqual(archive, base_name + '.zip')
+        self.assertTrue(os.path.isfile(archive))
+
+        # now create another ZIP file using `zip`
+        archive2 = os.path.join(root_dir, 'archive2.zip')
+        zip_cmd = ['zip', '-q', '-r', 'archive2.zip', base_dir]
+        with support.change_cwd(root_dir):
+            spawn(zip_cmd)
+
+        self.assertTrue(os.path.isfile(archive2))
+        # let's compare both ZIP files
+        with zipfile.ZipFile(archive) as zf:
+            names = zf.namelist()
+        with zipfile.ZipFile(archive2) as zf:
+            names2 = zf.namelist()
+        self.assertEqual(sorted(names), sorted(names2))
     def test_make_archive(self):
         tmpdir = self.mkdtemp()
@@ -521,39 +517,36 @@ class TestShutil(unittest.TestCase):
         else:
             group = owner = 'root'
-        base_dir, root_dir, base_name =  self._create_files()
-        base_name = os.path.join(self.mkdtemp() , 'archive')
+        root_dir, base_dir = self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
         res = make_archive(base_name, 'zip', root_dir, base_dir, owner=owner,
                            group=group)
-        self.assertTrue(os.path.exists(res))
+        self.assertTrue(os.path.isfile(res))
         res = make_archive(base_name, 'zip', root_dir, base_dir)
-        self.assertTrue(os.path.exists(res))
+        self.assertTrue(os.path.isfile(res))
         res = make_archive(base_name, 'tar', root_dir, base_dir,
                            owner=owner, group=group)
-        self.assertTrue(os.path.exists(res))
+        self.assertTrue(os.path.isfile(res))
         res = make_archive(base_name, 'tar', root_dir, base_dir,
                            owner='kjhkjhkjg', group='oihohoh')
-        self.assertTrue(os.path.exists(res))
+        self.assertTrue(os.path.isfile(res))
     @unittest.skipUnless(zlib, "Requires zlib")
     @unittest.skipUnless(UID_GID_SUPPORT, "Requires grp and pwd support")
     def test_tarfile_root_owner(self):
-        tmpdir, tmpdir2, base_name =  self._create_files()
-        old_dir = os.getcwd()
-        os.chdir(tmpdir)
+        root_dir, base_dir = self._create_files()
+        base_name = os.path.join(self.mkdtemp(), 'archive')
         group = grp.getgrgid(0)[0]
         owner = pwd.getpwuid(0)[0]
-        try:
-            archive_name = _make_tarball(base_name, 'dist', compress=None,
-                                         owner=owner, group=group)
-        finally:
-            os.chdir(old_dir)
+        with support.change_cwd(root_dir):
+            archive_name = make_archive(base_name, 'gztar', root_dir, 'dist',
+                                        owner=owner, group=group)
         # check if the compressed tarball was created
-        self.assertTrue(os.path.exists(archive_name))
+        self.assertTrue(os.path.isfile(archive_name))
         # now checks the rights
         archive = tarfile.open(archive_name)
@@ -859,7 +852,7 @@ class TestCopyFile(unittest.TestCase):
 def test_main():
-    test_support.run_unittest(TestShutil, TestMove, TestCopyFile)
+    support.run_unittest(TestShutil, TestMove, TestCopyFile)
 if __name__ == '__main__':
     test_main()
diff --git a/Lib/test/test_support.py b/Lib/test/test_support.py
index 42c1b4d..98a9275 100644
--- a/Lib/test/test_support.py
+++ b/Lib/test/test_support.py
@@ -491,6 +491,33 @@ TESTFN = "{}_{}_tmp".format(TESTFN, os.getpid())
 SAVEDCWD = os.getcwd()
 @contextlib.contextmanager
+def change_cwd(path, quiet=False):
+    """Return a context manager that changes the current working directory.
+
+    Arguments:
+
+      path: the directory to use as the temporary current working directory.
+
+      quiet: if False (the default), the context manager raises an exception
+        on error.  Otherwise, it issues only a warning and keeps the current
+        working directory the same.
+
+    """
+    saved_dir = os.getcwd()
+    try:
+        os.chdir(path)
+    except OSError:
+        if not quiet:
+            raise
+        warnings.warn('tests may fail, unable to change CWD to: ' + path,
+                      RuntimeWarning, stacklevel=3)
+    try:
+        yield os.getcwd()
+    finally:
+        os.chdir(saved_dir)
+
+
+@contextlib.contextmanager
 def temp_cwd(name='tempcwd', quiet=False):
     """
     Context manager that creates a temporary directory and set it as CWD.
SOURCES/00268-set-stream-name-to-None.patch
New file
@@ -0,0 +1,20 @@
# HG changeset patch
# User Vinay Sajip <vinay_sajip@yahoo.co.uk>
# Date 1402737594 -3600
# Node ID bb8b0c7fefd0c5ed99b3f336178a4f9554a1d0ef
# Parent  31adcc4c43916f7448c9dd8048ad5be7e5bb6456
Issue #21742: Set stream to None after closing.
diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py
--- a/Lib/logging/handlers.py
+++ b/Lib/logging/handlers.py
@@ -423,6 +423,7 @@ class WatchedFileHandler(logging.FileHan
                 # we have an open file handle, clean it up
                 self.stream.flush()
                 self.stream.close()
+                self.stream = None  # See Issue #21742: _open () might fail.
                 # open a new file handle and get new stat info from that fd
                 self.stream = self._open()
                 self._statstream()
SOURCES/macros.python
New file
@@ -0,0 +1,73 @@
%py_setup setup.py
%py_shbang_opts -s
# Use the slashes after expand so that the command starts on the same line as
# the macro
%py_build() %{expand:\\\
  CFLAGS="%{optflags}" %{__python} %{py_setup} %{?py_setup_args} build --executable="%{__python2} %{py_shbang_opts}" %{?*}
  sleep 1
}
%py_build_egg() %{expand:\\\
  CFLAGS="%{optflags}" %{__python} %{py_setup} %{?py_setup_args} bdist_egg %{?*}
  sleep 1
}
%py_build_wheel() %{expand:\\\
  CFLAGS="%{optflags}" %{__python} %{py_setup} %{?py_setup_args} bdist_wheel %{?*}
  sleep 1
}
%py_install() %{expand:\\\
  CFLAGS="%{optflags}" %{__python} %{py_setup} %{?py_setup_args} install -O1 --skip-build --root %{buildroot} %{?*}
}
%py_install_egg() %{expand:\\\
  mkdir -p %{buildroot}%{python_sitelib}
  easy_install -m --prefix %{buildroot}%{_prefix} -Z dist/*-py%{python_version}.egg %{?*}
}
%py_install_wheel() %{expand:\\\
  pip install -I dist/%{1} --root %{buildroot} --strip-file-prefix %{buildroot} --no-deps
}
%python_provide() %{lua:
  function string.starts(String,Start)
    return string.sub(String,1,string.len(Start))==Start
  end
  package = rpm.expand("%{?1}")
  vr = rpm.expand("%{?epoch:%{epoch}:}%{version}-%{release}")
  if (string.starts(package, "python2-")) then
    if (rpm.expand("%{?buildarch}") ~= "noarch") then
      str = "Provides: python-" .. string.sub(package,9,string.len(package)) .. "%{?_isa} = " .. vr
      print(rpm.expand(str))
    end
    print("\\nProvides: python-")
    print(string.sub(package,9,string.len(package)))
    print(" = ")
    print(vr)
    --Obsoleting the previous default python package
    print("\\nObsoletes: python-")
    print(string.sub(package,9,string.len(package)))
    print(" < ")
    print(vr)
  elseif (string.starts(package, "python" .. rpm.expand("%{python3_pkgversion}") .. "-")) then
    --No unversioned provides as python3 is not default
  elseif (rpm.expand("%{?python3_other_pkgversion}") ~= "" and string.starts(package, "python" .. rpm.expand("%{python3_other_pkgversion}") .. "-")) then
    --No unversioned provides as python3_other is not default
  elseif (string.starts(package, "pypy-")) then
    --No unversioned provides as pypy is not default
  elseif (string.starts(package, "pypy3-")) then
    --No unversioned provides as pypy is not default
  elseif (string.starts(package, "python-")) then
    --Providing the current default python
    print("Provides: python2-")
    print(string.sub(package,8,string.len(package)))
    print(" = ")
    print(vr)
  else
    print("%python_provide: ERROR: ")
    print(package)
    print(" not recognized.")
  end
}
SOURCES/macros.python2
@@ -1,4 +1,37 @@
%__python2 /usr/bin/python2
%python2_sitelib %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")
%python2_sitearch %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")
%python2_version %(%{__python2} -c "import sys; sys.stdout.write(sys.version[:3])")
%python2_version %(%{__python2} -c "import sys; sys.stdout.write('{0.major}.{0.minor}'.format(sys.version_info))")
%python2_version_nodots %(%{__python2} -c "import sys; sys.stdout.write('{0.major}{0.minor}'.format(sys.version_info))")
%py2_shbang_opts -s
# Use the slashes after expand so that the command starts on the same line as
# the macro
%py2_build() %{expand:\\\
  CFLAGS="%{optflags}" %{__python2} %{py_setup} %{?py_setup_args} build --executable="%{__python2} %{py2_shbang_opts}" %{?*}
  sleep 1
}
%py2_build_egg() %{expand:\\\
  CFLAGS="%{optflags}" %{__python2} %{py_setup} %{?py_setup_args} bdist_egg %{?*}
  sleep 1
}
%py2_build_wheel() %{expand:\\\
  CFLAGS="%{optflags}" %{__python2} %{py_setup} %{?py_setup_args} bdist_wheel %{?*}
  sleep 1
}
%py2_install() %{expand:\\\
  CFLAGS="%{optflags}" %{__python2} %{py_setup} %{?py_setup_args} install -O1 --skip-build --root %{buildroot} %{?*}
}
%py2_install_egg() %{expand:\\\
  mkdir -p %{buildroot}%{python2_sitelib}
  easy_install-%{python2_version} -m --prefix %{buildroot}%{_prefix} -Z dist/*-py%{python2_version}.egg %{?*}
}
%py2_install_wheel() %{expand:\\\
  pip%{python2_version} install -I dist/%{1} --root %{buildroot} --strip-file-prefix %{buildroot} --no-deps
}
SPECS/python.spec
@@ -106,7 +106,7 @@
Name: %{python}
# Remember to also rebase python-docs when changing this:
Version: 2.7.5
Release: 48%{?dist}
Release: 58%{?dist}
License: Python
Group: Development/Languages
Requires: %{python}-libs%{?_isa} = %{version}-%{release}
@@ -191,8 +191,7 @@
# Written by dmalcolm; not yet sent upstream
Source5: pyfuntop.stp
# Supply various useful macros for building python 2 modules:
#  __python2, python2_sitelib, python2_sitearch, python2_version
# Supply various useful macros for building Python 2 components:
Source6: macros.python2
Source7: pynche
@@ -203,6 +202,16 @@
# configuration for systemd's tmpfiles
Source9: python.conf
# Supply various useful macros for building Python components:
# NOTE: The %%python_provide macro is copied directly from Fedora/EPEL, but the
# %{python3_pkgversion} and %{python3_other_pkgversion} macros used within it
# are missing in RHEL. However, in their absence the lua code will run fine for
# Python 2 packages and will print an error only if invoked for Python 3
# packages (unless the python-srpm-macros package from EPEL is installed). That
# is a desirable behaviour as RHEL without EPEL does not support building
# Python 3 packages.
Source10: macros.python
# Modules/Setup.dist is ultimately used by the "makesetup" script to construct
# the Makefile and config.c
@@ -1061,6 +1070,9 @@
# Combined usage explained:
# https://www.python.org/dev/peps/pep-0493/#recommendation-for-combined-feature-backports
# Resolves: rhbz#1315758
# Patch was modified to enable the certificate verification globally as the platform default
# See also patch224
# Resolves: rhbz#1219110
Patch234: 00234-PEP493-updated-implementation.patch
# 0235 #
@@ -1107,6 +1119,56 @@
# Based on a patch by RĂ©mi Rampin
# Resolves: rhbz#1359164
Patch242: 00242-CVE-2016-1000110-httpoxy.patch
# 00255 #
# Fix Python's failure to decode X.509 certificates
# with a GEN_RID general name in subject alternative names.
# FIXED UPSTREAM: http://bugs.python.org/issue27691
# Resolves: rhbz#1364444
Patch255: 00255-Fix-ssl-module-parsing-of-GEN_RID-subject-alternative-name-fields-in-X.509-certs.patch
# 00256 #
# Fix Python's incorrect parsing of certain regular expressions
# FIXED UPSTREAM: http://bugs.python.org/issue18647
# Resolves: rhbz#1373363
Patch256: 00256-fix-incorrect-parsing-of-regular-expressions.patch
# 00257 #
# Python's threading library doesn't use the monotonic clock when handling wait timeouts,
# so when the system clock is set backwards, the wait doesn't return after the timeout,
# causing deadlocks.
# This patch works around the issue.
# Resolves: rhbz#1368076
# DOWNSTREAM ONLY PATCH
Patch257: 00257-threading-wait-clamp-remaining-time.patch
# 00263 #
# Fix reference leaks of certfile_bytes and keyfile_bytes at _ssl.c
# FIXED UPSTREAM: http://bugs.python.org/issue27267
# https://github.com/python/cpython/commit/b3e073cbb3af2999e6e589f55ec2fc8a109fdc14
# https://github.com/python/cpython/commit/3b91de5a76aad471476f5bc5943e44bf386c0e6d
# Resolves: rhbz#1272562
Patch263: 00263-fix-ssl-reference-leaks.patch
# 00265 #
# Protect the key list during fork() in order for the forked process to not inherit an inconsistent key list.
# Reported upstream: http://bugs.python.org/issue29640
# Resolves: rhbz#1268226
Patch265: 00265-protect-key-list-during-fork.patch
# 00266 #
# Make shutil.make_archive() to not ingore empty directories when creating a zip file.
# Also refactor and extend the shutil test suite.
# FIXED UPSTREAM: https://bugs.python.org/issue24982
# https://github.com/python/cpython/commit/04861dc82f595e3e2f0ab4b1a62de2f812c8fa37
# Resolves: rhbz#1439734
Patch266: 00266-fix-shutil.make_archive-ignoring-empty-dirs.patch
# 00268 #
# Set stream to None in case an _open() fails.
# FIXED UPSTREAM: https://bugs.python.org/issue21742
# Resolves: rhbz#1432003
Patch268: 00268-set-stream-name-to-None.patch
# (New patches go here ^^^)
#
@@ -1511,6 +1573,13 @@
%patch238 -p1
%patch241 -p1
%patch242 -p1
%patch255 -p1
%patch256 -p1
%patch257 -p1
%patch263 -p1
%patch265 -p1
%patch266 -p1
%patch268 -p1
# This shouldn't be necesarry, but is right now (2.2a3)
@@ -1880,6 +1949,7 @@
# Install macros for rpm:
mkdir -p %{buildroot}/%{_sysconfdir}/rpm
install -m 644 %{SOURCE6} %{buildroot}/%{_sysconfdir}/rpm
install -m 644 %{SOURCE10} %{buildroot}/%{_sysconfdir}/rpm
# Make python folder for config files under /etc
mkdir -p %{buildroot}/%{_sysconfdir}/python
@@ -2199,6 +2269,7 @@
%endif
%{_bindir}/python%{pybasever}-config
%{_libdir}/libpython%{pybasever}.so
%{_sysconfdir}/rpm/macros.python
%{_sysconfdir}/rpm/macros.python2
%files tools
@@ -2380,6 +2451,46 @@
# ======================================================
%changelog
* Wed May 03 2017 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-58
- Set stream to None in case an _open() fails.
Resolves: rhbz#1432003
* Tue Apr 11 2017 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-57
- Fix implicit declaration warnings of functions added by patches 147 and 265
Resolves: rhbz#1441237
* Mon Apr 10 2017 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-56
- Fix shutil.make_archive ignoring empty directories when creating zip files
Resolves: rhbz#1439734
* Thu Mar 23 2017 Tomas Orsava <torsava@redhat.com> - 2.7.5-55
- Update Python RPM macros with new ones from EPEL7 to simplify packaging
Resolves: rhbz#1297522
* Wed Mar 22 2017 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-54
- Protect key list during fork()
Resolves: rhbz#1268226
* Mon Mar 13 2017 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-53
- Fix _ssl.c reference leaks
Resolves: rhbz#1272562
* Mon Feb 27 2017 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-52
- Workaround Python's threading library issue with non returning wait, for signals with timeout
Resolves: rhbz#1368076
* Mon Jan 23 2017 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-51
- Enable certificate verification by default
Resolves: rhbz#1219110
* Wed Jan 18 2017 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-50
- Fix incorrect parsing of certain regular expressions
Resolves: rhbz#1373363
* Tue Jan 17 2017 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-49
- Fix ssl module's parsing of GEN_RID subject alternative name fields in X.509 certs
Resolves: rhbz#1364444
* Mon Aug 01 2016 Charalampos Stratakis <cstratak@redhat.com> - 2.7.5-48
- Fix for CVE-2016-1000110 HTTPoxy attack
Resolves: rhbz#1359164