From 71084d584ff953f5463757ec6536406320560b4d Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Aug 01 2017 03:19:03 +0000 Subject: import python-2.7.5-58.el7 --- diff --git a/SOURCES/00147-add-debug-malloc-stats.patch b/SOURCES/00147-add-debug-malloc-stats.patch index 0ab8c94..48952f0 100644 --- a/SOURCES/00147-add-debug-malloc-stats.patch +++ b/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 @@ diff -up Python-2.7.2/Include/dictobject.h.add-debug-malloc-stats Python-2.7.2/I #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 @@ diff -up Python-2.7.2/Include/floatobject.h.add-debug-malloc-stats Python-2.7.2/ #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 @@ diff -up Python-2.7.2/Include/frameobject.h.add-debug-malloc-stats Python-2.7.2/ /* 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 @@ diff -up Python-2.7.2/Include/intobject.h.add-debug-malloc-stats Python-2.7.2/In #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 @@ diff -up Python-2.7.2/Include/listobject.h.add-debug-malloc-stats Python-2.7.2/I #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 @@ diff -up Python-2.7.2/Include/methodobject.h.add-debug-malloc-stats Python-2.7.2 #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 @@ diff -up Python-2.7.2/Include/object.h.add-debug-malloc-stats Python-2.7.2/Inclu #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 @@ diff -up Python-2.7.2/Include/objimpl.h.add-debug-malloc-stats Python-2.7.2/Incl 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 @@ diff -up Python-2.7.2/Include/stringobject.h.add-debug-malloc-stats Python-2.7.2 #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 @@ diff -up Python-2.7.2/Include/unicodeobject.h.add-debug-malloc-stats Python-2.7. #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 @@ diff -up Python-2.7.2/Lib/test/test_sys.py.add-debug-malloc-stats Python-2.7.2/L + 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 @@ diff -up Python-2.7.2/Lib/test/test_sys.py.add-debug-malloc-stats Python-2.7.2/L + # 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 @@ diff -up Python-2.7.2/Objects/classobject.c.add-debug-malloc-stats Python-2.7.2/ + "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 @@ diff -up Python-2.7.2/Objects/dictobject.c.add-debug-malloc-stats Python-2.7.2/O 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 @@ diff -up Python-2.7.2/Objects/floatobject.c.add-debug-malloc-stats Python-2.7.2/ 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 @@ diff -up Python-2.7.2/Objects/frameobject.c.add-debug-malloc-stats Python-2.7.2/ + 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 @@ diff -up Python-2.7.2/Objects/intobject.c.add-debug-malloc-stats Python-2.7.2/Ob 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 @@ diff -up Python-2.7.2/Objects/listobject.c.add-debug-malloc-stats Python-2.7.2/O 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 @@ diff -up Python-2.7.2/Objects/methodobject.c.add-debug-malloc-stats Python-2.7.2 /* 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 @@ diff -up Python-2.7.2/Objects/object.c.add-debug-malloc-stats Python-2.7.2/Objec /* 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 @@ diff -up Python-2.7.2/Objects/obmalloc.c.add-debug-malloc-stats Python-2.7.2/Obj 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 @@ diff -up Python-2.7.2/Objects/obmalloc.c.add-debug-malloc-stats Python-2.7.2/Obj #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 @@ diff -up Python-2.7.2/Objects/setobject.c.add-debug-malloc-stats Python-2.7.2/Ob 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 @@ diff -up Python-2.7.2/Objects/stringobject.c.add-debug-malloc-stats Python-2.7.2 + "%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 @@ diff -up Python-2.7.2/Objects/tupleobject.c.add-debug-malloc-stats Python-2.7.2/ 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 @@ diff -up Python-2.7.2/Objects/unicodeobject.c.add-debug-malloc-stats Python-2.7. #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 @@ diff -up Python-2.7.2/Python/pythonrun.c.add-debug-malloc-stats Python-2.7.2/Pyt #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 @@ diff -up Python-2.7.2/Python/sysmodule.c.add-debug-malloc-stats Python-2.7.2/Pyt + if (!fp) { + PyErr_SetString(PyExc_ValueError, "file is closed"); + Py_DECREF(file); -+ return NULL; ++ return NULL; + } + + _PyObject_DebugMallocStats(fp); @@ -700,7 +751,7 @@ diff -up Python-2.7.2/Python/sysmodule.c.add-debug-malloc-stats Python-2.7.2/Pyt #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}, diff --git a/SOURCES/00234-PEP493-updated-implementation.patch b/SOURCES/00234-PEP493-updated-implementation.patch index d6468bd..275fc53 100644 --- a/SOURCES/00234-PEP493-updated-implementation.patch +++ b/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) diff --git a/SOURCES/00255-Fix-ssl-module-parsing-of-GEN_RID-subject-alternative-name-fields-in-X.509-certs.patch b/SOURCES/00255-Fix-ssl-module-parsing-of-GEN_RID-subject-alternative-name-fields-in-X.509-certs.patch new file mode 100644 index 0000000..e28bb04 --- /dev/null +++ b/SOURCES/00255-Fix-ssl-module-parsing-of-GEN_RID-subject-alternative-name-fields-in-X.509-certs.patch @@ -0,0 +1,235 @@ + +# HG changeset patch +# User Christian Heimes +# 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', ''), ++ ('othername', ''), ++ ('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(""); ++ } 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; + diff --git a/SOURCES/00256-fix-incorrect-parsing-of-regular-expressions.patch b/SOURCES/00256-fix-incorrect-parsing-of-regular-expressions.patch new file mode 100644 index 0000000..9c467b8 --- /dev/null +++ b/SOURCES/00256-fix-incorrect-parsing-of-regular-expressions.patch @@ -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)') + ++ 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 (?:(?![ ]*$) # Not a blank line + (?![ ]*>>>) # Not a line starting with PS1 +- .*$\n? # But any other line ++ .+$\n? # But any other line + )*) + ''', re.MULTILINE | re.VERBOSE) + + diff --git a/SOURCES/00257-threading-wait-clamp-remaining-time.patch b/SOURCES/00257-threading-wait-clamp-remaining-time.patch new file mode 100644 index 0000000..526d941 --- /dev/null +++ b/SOURCES/00257-threading-wait-clamp-remaining-time.patch @@ -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__: diff --git a/SOURCES/00263-fix-ssl-reference-leaks.patch b/SOURCES/00263-fix-ssl-reference-leaks.patch new file mode 100644 index 0000000..34d22c6 --- /dev/null +++ b/SOURCES/00263-fix-ssl-reference-leaks.patch @@ -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: diff --git a/SOURCES/00265-protect-key-list-during-fork.patch b/SOURCES/00265-protect-key-list-during-fork.patch new file mode 100644 index 0000000..1f820f8 --- /dev/null +++ b/SOURCES/00265-protect-key-list-during-fork.patch @@ -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 + #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 diff --git a/SOURCES/00266-fix-shutil.make_archive-ignoring-empty-dirs.patch b/SOURCES/00266-fix-shutil.make_archive-ignoring-empty-dirs.patch new file mode 100644 index 0000000..aa2d6ef --- /dev/null +++ b/SOURCES/00266-fix-shutil.make_archive-ignoring-empty-dirs.patch @@ -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. diff --git a/SOURCES/00268-set-stream-name-to-None.patch b/SOURCES/00268-set-stream-name-to-None.patch new file mode 100644 index 0000000..0a79050 --- /dev/null +++ b/SOURCES/00268-set-stream-name-to-None.patch @@ -0,0 +1,20 @@ + +# HG changeset patch +# User Vinay Sajip +# 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() + diff --git a/SOURCES/macros.python b/SOURCES/macros.python new file mode 100644 index 0000000..8b168b5 --- /dev/null +++ b/SOURCES/macros.python @@ -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 +} diff --git a/SOURCES/macros.python2 b/SOURCES/macros.python2 index 982b51f..169d48f 100644 --- a/SOURCES/macros.python2 +++ b/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 +} diff --git a/SPECS/python.spec b/SPECS/python.spec index 8e64529..a9fd32f 100644 --- a/SPECS/python.spec +++ b/SPECS/python.spec @@ -106,7 +106,7 @@ Summary: An interpreted, interactive, object-oriented programming language 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 @@ Source4: systemtap-example.stp # 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 @@ -204,6 +203,16 @@ Source8: cert-verification.cfg # 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 @@ Patch233: 00233-Computed-Goto-dispatch.patch # 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 # @@ -1108,6 +1120,56 @@ Patch241: 00241-CVE-2016-5636-buffer-overflow-in-zipimport-module-fix.patch # 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 ^^^) # # When adding new patches to "python" and "python3" in Fedora 17 onwards, @@ -1511,6 +1573,13 @@ mv Modules/cryptmodule.c Modules/_cryptmodule.c %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 @@ sed -i -e "s/'pyconfig.h'/'%{_pyconfig_h}'/" \ # 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 @@ rm -fr %{buildroot} %endif %{_bindir}/python%{pybasever}-config %{_libdir}/libpython%{pybasever}.so +%{_sysconfdir}/rpm/macros.python %{_sysconfdir}/rpm/macros.python2 %files tools @@ -2380,6 +2451,46 @@ rm -fr %{buildroot} # ====================================================== %changelog +* Wed May 03 2017 Charalampos Stratakis - 2.7.5-58 +- Set stream to None in case an _open() fails. +Resolves: rhbz#1432003 + +* Tue Apr 11 2017 Charalampos Stratakis - 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 - 2.7.5-56 +- Fix shutil.make_archive ignoring empty directories when creating zip files +Resolves: rhbz#1439734 + +* Thu Mar 23 2017 Tomas Orsava - 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 - 2.7.5-54 +- Protect key list during fork() +Resolves: rhbz#1268226 + +* Mon Mar 13 2017 Charalampos Stratakis - 2.7.5-53 +- Fix _ssl.c reference leaks +Resolves: rhbz#1272562 + +* Mon Feb 27 2017 Charalampos Stratakis - 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 - 2.7.5-51 +- Enable certificate verification by default +Resolves: rhbz#1219110 + +* Wed Jan 18 2017 Charalampos Stratakis - 2.7.5-50 +- Fix incorrect parsing of certain regular expressions +Resolves: rhbz#1373363 + +* Tue Jan 17 2017 Charalampos Stratakis - 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 - 2.7.5-48 - Fix for CVE-2016-1000110 HTTPoxy attack Resolves: rhbz#1359164