diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2576193 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/Python-2.7.17-noexe.tar.xz diff --git a/.python2.metadata b/.python2.metadata new file mode 100644 index 0000000..dd6dfd3 --- /dev/null +++ b/.python2.metadata @@ -0,0 +1 @@ +e63124a9a86b4b52c09384915a0842adf00b9d45 SOURCES/Python-2.7.17-noexe.tar.xz diff --git a/SOURCES/00001-pydocnogui.patch b/SOURCES/00001-pydocnogui.patch new file mode 100644 index 0000000..0311f38 --- /dev/null +++ b/SOURCES/00001-pydocnogui.patch @@ -0,0 +1,28 @@ +diff -up Python-2.7.3/Lib/pydoc.py.no_gui Python-2.7.3/Lib/pydoc.py +--- Python-2.7.3/Lib/pydoc.py.no_gui 2012-04-09 19:07:31.000000000 -0400 ++++ Python-2.7.3/Lib/pydoc.py 2013-02-19 13:48:44.480054515 -0500 +@@ -19,9 +19,6 @@ of all available modules. + local machine to generate documentation web pages. Port number 0 can be + used to get an arbitrary unused port. + +-For platforms without a command line, "pydoc -g" starts the HTTP server +-and also pops up a little window for controlling it. +- + Run "pydoc -w " to write out the HTML documentation for a module + to a file named ".html". + +@@ -2346,13 +2340,10 @@ def cli(): + Start an HTTP server on the given port on the local machine. Port + number 0 can be used to get an arbitrary unused port. + +-%s -g +- Pop up a graphical interface for finding and serving documentation. +- + %s -w ... + Write out the HTML documentation for a module to a file in the current + directory. If contains a '%s', it is treated as a filename; if + it names a directory, documentation is written for all the contents. +-""" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep) ++""" % (cmd, os.sep, cmd, cmd, cmd, os.sep) + + if __name__ == '__main__': cli() diff --git a/SOURCES/00010-2.7.13-binutils-no-dep.patch b/SOURCES/00010-2.7.13-binutils-no-dep.patch new file mode 100644 index 0000000..d432623 --- /dev/null +++ b/SOURCES/00010-2.7.13-binutils-no-dep.patch @@ -0,0 +1,21 @@ +diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py +index ab10ec5..923d1b7 100644 +--- a/Lib/ctypes/util.py ++++ b/Lib/ctypes/util.py +@@ -140,11 +140,15 @@ elif os.name == "posix": + # assuming GNU binutils / ELF + if not f: + return None +- cmd = 'if ! type objdump >/dev/null 2>&1; then exit; fi;' \ ++ cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \ + 'objdump -p -j .dynamic 2>/dev/null "$1"' + proc = subprocess.Popen((cmd, '_get_soname', f), shell=True, + stdout=subprocess.PIPE) + [dump, _] = proc.communicate() ++ if proc.returncode == 10: ++ return os.path.basename(f) # This is good for GLibc, I think, ++ # and a dep on binutils is big (for ++ # live CDs). + res = re.search(br'\sSONAME\s+([^\s]+)', dump) + if not res: + return None diff --git a/SOURCES/00055-systemtap.patch b/SOURCES/00055-systemtap.patch new file mode 100644 index 0000000..6ccc747 --- /dev/null +++ b/SOURCES/00055-systemtap.patch @@ -0,0 +1,198 @@ +diff -up Python-2.7rc1/configure.ac.systemtap Python-2.7rc1/configure.ac +--- Python-2.7rc1/configure.ac.systemtap 2010-06-06 10:53:15.514975012 -0400 ++++ Python-2.7rc1/configure.ac 2010-06-06 10:53:15.520974361 -0400 +@@ -2616,6 +2616,38 @@ if test "$with_valgrind" != no; then + ) + fi + ++# Check for dtrace support ++AC_MSG_CHECKING(for --with-dtrace) ++AC_ARG_WITH(dtrace, ++ AC_HELP_STRING(--with(out)-dtrace, disable/enable dtrace support)) ++ ++if test ! -z "$with_dtrace" ++then ++ if dtrace -G -o /dev/null -s $srcdir/Include/pydtrace.d 2>/dev/null ++ then ++ AC_DEFINE(WITH_DTRACE, 1, ++ [Define if you want to compile in Dtrace support]) ++ with_dtrace="Sun" ++ DTRACEOBJS="Python/dtrace.o" ++ DTRADEHDRS="" ++ elif dtrace -h -o /dev/null -s $srcdir/Include/pydtrace.d ++ then ++ AC_DEFINE(WITH_DTRACE, 1, ++ [Define if you want to compile in Dtrace support]) ++ with_dtrace="Apple" ++ DTRACEOBJS="" ++ DTRADEHDRS="pydtrace.h" ++ else ++ with_dtrace="no" ++ fi ++else ++ with_dtrace="no" ++fi ++ ++AC_MSG_RESULT($with_dtrace) ++AC_SUBST(DTRACEOBJS) ++AC_SUBST(DTRACEHDRS) ++ + # Check for --with-wctype-functions + AC_MSG_CHECKING(for --with-wctype-functions) + AC_ARG_WITH(wctype-functions, +diff -up Python-2.7rc1/Include/pydtrace.d.systemtap Python-2.7rc1/Include/pydtrace.d +--- Python-2.7rc1/Include/pydtrace.d.systemtap 2010-06-06 10:53:15.520974361 -0400 ++++ Python-2.7rc1/Include/pydtrace.d 2010-06-06 10:53:15.520974361 -0400 +@@ -0,0 +1,10 @@ ++provider python { ++ probe function__entry(const char *, const char *, int); ++ probe function__return(const char *, const char *, int); ++}; ++ ++#pragma D attributes Evolving/Evolving/Common provider python provider ++#pragma D attributes Private/Private/Common provider python module ++#pragma D attributes Private/Private/Common provider python function ++#pragma D attributes Evolving/Evolving/Common provider python name ++#pragma D attributes Evolving/Evolving/Common provider python args +diff -up Python-2.7rc1/Makefile.pre.in.systemtap Python-2.7rc1/Makefile.pre.in +--- Python-2.7rc1/Makefile.pre.in.systemtap 2010-06-06 10:53:15.488978775 -0400 ++++ Python-2.7rc1/Makefile.pre.in 2010-06-06 11:05:30.411100568 -0400 +@@ -298,6 +298,7 @@ PYTHON_OBJS= \ + Python/formatter_unicode.o \ + Python/formatter_string.o \ + Python/$(DYNLOADFILE) \ ++ @DTRACEOBJS@ \ + $(LIBOBJS) \ + $(MACHDEP_OBJS) \ + $(THREADOBJ) +@@ -599,6 +600,18 @@ Python/formatter_unicode.o: $(srcdir)/Py + Python/formatter_string.o: $(srcdir)/Python/formatter_string.c \ + $(STRINGLIB_HEADERS) + ++# Only needed with --with-dtrace ++buildinclude: ++ mkdir -p Include ++ ++Include/pydtrace.h: buildinclude $(srcdir)/Include/pydtrace.d ++ dtrace -o $@ $(DFLAGS) -C -h -s $(srcdir)/Include/pydtrace.d ++ ++Python/ceval.o: Include/pydtrace.h ++ ++Python/dtrace.o: buildinclude $(srcdir)/Include/pydtrace.d Python/ceval.o ++ dtrace -o $@ $(DFLAGS) -C -G -s $(srcdir)/Include/pydtrace.d Python/ceval.o ++ + ############################################################################ + # Header files + +@@ -1251,7 +1264,7 @@ Python/thread.o: @THREADHEADERS@ + .PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure + .PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools + .PHONY: frameworkaltinstallunixtools recheck clean clobber distclean +-.PHONY: smelly funny patchcheck altmaninstall commoninstall ++.PHONY: smelly funny patchcheck altmaninstall commoninstall buildinclude + .PHONY: gdbhooks + + # IF YOU PUT ANYTHING HERE IT WILL GO AWAY +diff -up Python-2.7rc1/pyconfig.h.in.systemtap Python-2.7rc1/pyconfig.h.in +--- Python-2.7rc1/pyconfig.h.in.systemtap 2010-05-08 07:04:18.000000000 -0400 ++++ Python-2.7rc1/pyconfig.h.in 2010-06-06 10:53:15.521974070 -0400 +@@ -1074,6 +1074,9 @@ + /* Define if you want documentation strings in extension modules */ + #undef WITH_DOC_STRINGS + ++/* Define if you want to compile in Dtrace support */ ++#undef WITH_DTRACE ++ + /* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic + linker (dyld) instead of the old-style (NextStep) dynamic linker (rld). + Dyld is necessary to support frameworks. */ +diff -up Python-2.7rc1/Python/ceval.c.systemtap Python-2.7rc1/Python/ceval.c +--- Python-2.7rc1/Python/ceval.c.systemtap 2010-05-09 10:46:46.000000000 -0400 ++++ Python-2.7rc1/Python/ceval.c 2010-06-06 11:08:40.683100500 -0400 +@@ -19,6 +19,10 @@ + + #include + ++#ifdef WITH_DTRACE ++#include "pydtrace.h" ++#endif ++ + #ifndef WITH_TSC + + #define READ_TIMESTAMP(var) +@@ -671,6 +675,55 @@ PyEval_EvalCode(PyCodeObject *co, PyObje + NULL); + } + ++#ifdef WITH_DTRACE ++static void ++dtrace_entry(PyFrameObject *f) ++{ ++ const char *filename; ++ const char *fname; ++ int lineno; ++ ++ filename = PyString_AsString(f->f_code->co_filename); ++ fname = PyString_AsString(f->f_code->co_name); ++ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); ++ ++ PYTHON_FUNCTION_ENTRY((char *)filename, (char *)fname, lineno); ++ ++ /* ++ * Currently a USDT tail-call will not receive the correct arguments. ++ * Disable the tail call here. ++ */ ++#if defined(__sparc) ++ asm("nop"); ++#endif ++} ++ ++static void ++dtrace_return(PyFrameObject *f) ++{ ++ const char *filename; ++ const char *fname; ++ int lineno; ++ ++ filename = PyString_AsString(f->f_code->co_filename); ++ fname = PyString_AsString(f->f_code->co_name); ++ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); ++ PYTHON_FUNCTION_RETURN((char *)filename, (char *)fname, lineno); ++ ++ /* ++ * Currently a USDT tail-call will not receive the correct arguments. ++ * Disable the tail call here. ++ */ ++#if defined(__sparc) ++ asm("nop"); ++#endif ++} ++#else ++#define PYTHON_FUNCTION_ENTRY_ENABLED() 0 ++#define PYTHON_FUNCTION_RETURN_ENABLED() 0 ++#define dtrace_entry(f) ++#define dtrace_return(f) ++#endif + + /* Interpreter main loop */ + +@@ -909,6 +962,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + } + } + ++ if (PYTHON_FUNCTION_ENTRY_ENABLED()) ++ dtrace_entry(f); ++ + co = f->f_code; + names = co->co_names; + consts = co->co_consts; +@@ -3000,6 +3056,9 @@ fast_yield: + + /* pop frame */ + exit_eval_frame: ++ if (PYTHON_FUNCTION_RETURN_ENABLED()) ++ dtrace_return(f); ++ + Py_LeaveRecursiveCall(); + tstate->frame = f->f_back; + diff --git a/SOURCES/00102-2.7.13-lib64.patch b/SOURCES/00102-2.7.13-lib64.patch new file mode 100644 index 0000000..02d3f6c --- /dev/null +++ b/SOURCES/00102-2.7.13-lib64.patch @@ -0,0 +1,193 @@ +diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py +index b9f1c6c..7b23714 100644 +--- a/Lib/distutils/command/install.py ++++ b/Lib/distutils/command/install.py +@@ -42,14 +42,14 @@ else: + INSTALL_SCHEMES = { + 'unix_prefix': { + 'purelib': '$base/lib/python$py_version_short/site-packages', +- 'platlib': '$platbase/lib/python$py_version_short/site-packages', ++ 'platlib': '$platbase/lib64/python$py_version_short/site-packages', + 'headers': '$base/include/python$py_version_short/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'unix_home': { + 'purelib': '$base/lib/python', +- 'platlib': '$base/lib/python', ++ 'platlib': '$base/lib64/python', + 'headers': '$base/include/python/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', +diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py +index 031f809..ec5d584 100644 +--- a/Lib/distutils/sysconfig.py ++++ b/Lib/distutils/sysconfig.py +@@ -120,8 +120,12 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): + prefix = plat_specific and EXEC_PREFIX or PREFIX + + if os.name == "posix": ++ if plat_specific or standard_lib: ++ lib = "lib64" ++ else: ++ lib = "lib" + libpython = os.path.join(prefix, +- "lib", "python" + get_python_version()) ++ lib, "python" + get_python_version()) + if standard_lib: + return libpython + else: +diff --git a/Lib/site.py b/Lib/site.py +index c360802..868b7cb 100644 +--- a/Lib/site.py ++++ b/Lib/site.py +@@ -288,12 +288,16 @@ def getsitepackages(): + if sys.platform in ('os2emx', 'riscos'): + sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) + elif os.sep == '/': ++ sitepackages.append(os.path.join(prefix, "lib64", ++ "python" + sys.version[:3], ++ "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", + "python" + sys.version[:3], + "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", "site-python")) + else: + sitepackages.append(prefix) ++ sitepackages.append(os.path.join(prefix, "lib64", "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", "site-packages")) + return sitepackages + +diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py +index b4384ee..349f688 100644 +--- a/Lib/test/test_site.py ++++ b/Lib/test/test_site.py +@@ -254,17 +254,20 @@ class HelperFunctionsTests(unittest.TestCase): + self.assertEqual(dirs[0], wanted) + elif os.sep == '/': + # OS X, Linux, FreeBSD, etc +- self.assertEqual(len(dirs), 2) +- wanted = os.path.join('xoxo', 'lib', 'python' + sys.version[:3], ++ self.assertEqual(len(dirs), 3) ++ wanted = os.path.join('xoxo', 'lib64', 'python' + sys.version[:3], + 'site-packages') + self.assertEqual(dirs[0], wanted) +- wanted = os.path.join('xoxo', 'lib', 'site-python') ++ wanted = os.path.join('xoxo', 'lib', 'python' + sys.version[:3], ++ 'site-packages') + self.assertEqual(dirs[1], wanted) ++ wanted = os.path.join('xoxo', 'lib', 'site-python') ++ self.assertEqual(dirs[2], wanted) + else: + # other platforms + self.assertEqual(len(dirs), 2) + self.assertEqual(dirs[0], 'xoxo') +- wanted = os.path.join('xoxo', 'lib', 'site-packages') ++ wanted = os.path.join('xoxo', 'lib64', 'site-packages') + self.assertEqual(dirs[1], wanted) + + def test_no_home_directory(self): +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 4f59dd3..877698c 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -110,7 +110,7 @@ LIBDIR= @libdir@ + MANDIR= @mandir@ + INCLUDEDIR= @includedir@ + CONFINCLUDEDIR= $(exec_prefix)/include +-SCRIPTDIR= $(prefix)/lib ++SCRIPTDIR= $(prefix)/lib64 + + # Detailed destination directories + BINLIBDEST= $(LIBDIR)/python$(VERSION) +diff --git a/Modules/Setup.dist b/Modules/Setup.dist +index 2cf35a9..c4c88cb 100644 +--- a/Modules/Setup.dist ++++ b/Modules/Setup.dist +@@ -231,7 +231,7 @@ crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems + # Some more UNIX dependent modules -- off by default, since these + # are not supported by all UNIX systems: + +-nis nismodule.c -lnsl -ltirpc -I/usr/include/tirpc -I/usr/include/nsl -L/usr/lib/nsl ++nis nismodule.c -lnsl -ltirpc -I/usr/include/tirpc -I/usr/include/nsl -L/usr/lib64/nsl + termios termios.c # Steen Lumholt's termios module + resource resource.c # Jeremy Hylton's rlimit interface + +@@ -416,7 +416,7 @@ gdbm gdbmmodule.c -lgdbm + # Edit the variables DB and DBLIBVERto point to the db top directory + # and the subdirectory of PORT where you built it. + DBINC=/usr/include/libdb +-DBLIB=/usr/lib ++DBLIB=/usr/lib64 + _bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb + + # Historical Berkeley DB 1.85 +@@ -462,7 +462,7 @@ cPickle cPickle.c + # Andrew Kuchling's zlib module. + # This require zlib 1.1.3 (or later). + # See http://www.gzip.org/zlib/ +-zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz ++zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib64 -lz + + # Interface to the Expat XML parser + # More information on Expat can be found at www.libexpat.org. +diff --git a/Modules/getpath.c b/Modules/getpath.c +index fd33a01..c5c86fd 100644 +--- a/Modules/getpath.c ++++ b/Modules/getpath.c +@@ -108,7 +108,7 @@ static char prefix[MAXPATHLEN+1]; + static char exec_prefix[MAXPATHLEN+1]; + static char progpath[MAXPATHLEN+1]; + static char *module_search_path = NULL; +-static char lib_python[] = "lib/python" VERSION; ++static char lib_python[] = "lib64/python" VERSION; + + static void + reduce(char *dir) +@@ -548,7 +548,7 @@ calculate_path(void) + fprintf(stderr, + "Could not find platform dependent libraries \n"); + strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); +- joinpath(exec_prefix, "lib/lib-dynload"); ++ joinpath(exec_prefix, "lib64/lib-dynload"); + } + /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ + +diff --git a/setup.py b/setup.py +index 0288a6b..7905f6f 100644 +--- a/setup.py ++++ b/setup.py +@@ -456,7 +456,7 @@ class PyBuildExt(build_ext): + def detect_modules(self): + # Ensure that /usr/local is always used + if not cross_compiling: +- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') ++ add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib64') + add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') + if cross_compiling: + self.add_gcc_paths() +@@ -782,11 +782,11 @@ class PyBuildExt(build_ext): + elif curses_library: + readline_libs.append(curses_library) + elif self.compiler.find_library_file(lib_dirs + +- ['/usr/lib/termcap'], ++ ['/usr/lib64/termcap'], + 'termcap'): + readline_libs.append('termcap') + exts.append( Extension('readline', ['readline.c'], +- library_dirs=['/usr/lib/termcap'], ++ library_dirs=['/usr/lib64/termcap'], + extra_link_args=readline_extra_link_args, + libraries=readline_libs) ) + else: +@@ -821,8 +821,8 @@ class PyBuildExt(build_ext): + if krb5_h: + ssl_incs += krb5_h + ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs, +- ['/usr/local/ssl/lib', +- '/usr/contrib/ssl/lib/' ++ ['/usr/local/ssl/lib64', ++ '/usr/contrib/ssl/lib64/' + ] ) + + if (ssl_incs is not None and diff --git a/SOURCES/00104-lib64-fix-for-test_install.patch b/SOURCES/00104-lib64-fix-for-test_install.patch new file mode 100644 index 0000000..7852bf6 --- /dev/null +++ b/SOURCES/00104-lib64-fix-for-test_install.patch @@ -0,0 +1,13 @@ +--- Python-2.7.2/Lib/distutils/tests/test_install.py.lib64 2011-09-08 17:51:57.851405376 -0400 ++++ Python-2.7.2/Lib/distutils/tests/test_install.py 2011-09-08 18:40:46.754205096 -0400 +@@ -41,8 +41,9 @@ class InstallTestCase(support.TempdirMan + self.assertEqual(got, expected) + + libdir = os.path.join(destination, "lib", "python") ++ platlibdir = os.path.join(destination, "lib64", "python") + check_path(cmd.install_lib, libdir) +- check_path(cmd.install_platlib, libdir) ++ check_path(cmd.install_platlib, platlibdir) + check_path(cmd.install_purelib, libdir) + check_path(cmd.install_headers, + os.path.join(destination, "include", "python", "foopkg")) diff --git a/SOURCES/00111-no-static-lib.patch b/SOURCES/00111-no-static-lib.patch new file mode 100644 index 0000000..70dfb77 --- /dev/null +++ b/SOURCES/00111-no-static-lib.patch @@ -0,0 +1,50 @@ +diff -up Python-2.7.6/Makefile.pre.in.no-static-lib Python-2.7.6/Makefile.pre.in +--- Python-2.7.6/Makefile.pre.in.no-static-lib 2014-01-29 13:58:32.933226720 +0100 ++++ Python-2.7.6/Makefile.pre.in 2014-01-29 14:10:25.002247272 +0100 +@@ -437,7 +437,7 @@ coverage: + + + # Build the interpreter +-$(BUILDPYTHON): Modules/python.o $(LIBRARY) $(LDLIBRARY) ++$(BUILDPYTHON): Modules/python.o $(LDLIBRARY) + $(LINKCC) $(CFLAGS) $(LDFLAGS) $(LINKFORSHARED) -o $@ \ + Modules/python.o \ + $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) +@@ -464,18 +464,6 @@ sharedmods: $(BUILDPYTHON) pybuilddir.tx + _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ + $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build + +-# Build static library +-# avoid long command lines, same as LIBRARY_OBJS +-$(LIBRARY): $(LIBRARY_OBJS) +- -rm -f $@ +- $(AR) $(ARFLAGS) $@ Modules/getbuildinfo.o +- $(AR) $(ARFLAGS) $@ $(PARSER_OBJS) +- $(AR) $(ARFLAGS) $@ $(OBJECT_OBJS) +- $(AR) $(ARFLAGS) $@ $(PYTHON_OBJS) +- $(AR) $(ARFLAGS) $@ $(MODULE_OBJS) $(SIGNAL_OBJS) +- $(AR) $(ARFLAGS) $@ $(MODOBJS) +- $(RANLIB) $@ +- + libpython$(VERSION).so: $(LIBRARY_OBJS) + if test $(INSTSONAME) != $(LDLIBRARY); then \ + $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ +@@ -1097,18 +1085,6 @@ libainstall: all python-config + else true; \ + fi; \ + done +- @if test -d $(LIBRARY); then :; else \ +- if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ +- if test "$(SO)" = .dll; then \ +- $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \ +- else \ +- $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ +- $(RANLIB) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ +- fi; \ +- else \ +- echo Skip install of $(LIBRARY) - use make frameworkinstall; \ +- fi; \ +- fi + $(INSTALL_DATA) Modules/config.c $(DESTDIR)$(LIBPL)/config.c + $(INSTALL_DATA) Modules/python.o $(DESTDIR)$(LIBPL)/python.o + $(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in diff --git a/SOURCES/00112-2.7.13-debug-build.patch b/SOURCES/00112-2.7.13-debug-build.patch new file mode 100644 index 0000000..463f4d8 --- /dev/null +++ b/SOURCES/00112-2.7.13-debug-build.patch @@ -0,0 +1,324 @@ +From 898f93aa206e577dfe854c59bc62d0cea09cd5ed Mon Sep 17 00:00:00 2001 +From: Tomas Orsava +Date: Tue, 10 Jan 2017 16:19:50 +0100 +Subject: [PATCH] Patch to support building both optimized vs debug stacks DSO + ABIs, + +sharing the same .py and .pyc files, using "_d.so" to signify a debug build of +an extension module. +--- + Lib/distutils/command/build_ext.py | 7 ++++- + Lib/distutils/sysconfig.py | 5 ++-- + Lib/distutils/tests/test_install.py | 3 +- + Makefile.pre.in | 56 ++++++++++++++++++++----------------- + Misc/python-config.in | 2 +- + Modules/makesetup | 2 +- + Python/dynload_shlib.c | 11 ++++++-- + Python/sysmodule.c | 6 ++++ + configure.ac | 14 ++++++++-- + 9 files changed, 69 insertions(+), 37 deletions(-) + +diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py +index 2c68be3..029d144 100644 +--- a/Lib/distutils/command/build_ext.py ++++ b/Lib/distutils/command/build_ext.py +@@ -677,7 +677,10 @@ class build_ext (Command): + so_ext = get_config_var('SO') + if os.name == 'nt' and self.debug: + return os.path.join(*ext_path) + '_d' + so_ext +- return os.path.join(*ext_path) + so_ext ++ ++ # Similarly, extensions in debug mode are named 'module_d.so', to ++ # avoid adding the _d to the SO config variable: ++ return os.path.join(*ext_path) + (sys.pydebug and "_d" or "") + so_ext + + def get_export_symbols (self, ext): + """Return the list of symbols that a shared extension has to +@@ -762,6 +765,8 @@ class build_ext (Command): + template = "python%d.%d" + pythonlib = (template % + (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) ++ if sys.pydebug: ++ pythonlib += '_d' + return ext.libraries + [pythonlib] + else: + return ext.libraries +diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py +index 3e7f077..ec5d584 100644 +--- a/Lib/distutils/sysconfig.py ++++ b/Lib/distutils/sysconfig.py +@@ -90,7 +90,8 @@ def get_python_inc(plat_specific=0, prefix=None): + # Include is located in the srcdir + inc_dir = os.path.join(srcdir, "Include") + return inc_dir +- return os.path.join(prefix, "include", "python" + get_python_version()) ++ return os.path.join(prefix, "include", ++ "python" + get_python_version() + (sys.pydebug and '-debug' or '')) + elif os.name == "nt": + return os.path.join(prefix, "include") + elif os.name == "os2": +@@ -248,7 +249,7 @@ def get_makefile_filename(): + if python_build: + return os.path.join(project_base, "Makefile") + lib_dir = get_python_lib(plat_specific=1, standard_lib=1) +- return os.path.join(lib_dir, "config", "Makefile") ++ return os.path.join(lib_dir, "config" + (sys.pydebug and "-debug" or ""), "Makefile") + + + def parse_config_h(fp, g=None): +diff --git a/Lib/distutils/tests/test_install.py b/Lib/distutils/tests/test_install.py +index 78fac46..d1d0931 100644 +--- a/Lib/distutils/tests/test_install.py ++++ b/Lib/distutils/tests/test_install.py +@@ -20,8 +20,9 @@ from distutils.tests import support + + + def _make_ext_name(modname): +- if os.name == 'nt' and sys.executable.endswith('_d.exe'): ++ if sys.pydebug: + modname += '_d' ++ + return modname + sysconfig.get_config_var('SO') + + +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 997a2fc..467e782 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -116,8 +116,8 @@ SCRIPTDIR= $(prefix)/lib64 + # Detailed destination directories + BINLIBDEST= $(LIBDIR)/python$(VERSION) + LIBDEST= $(SCRIPTDIR)/python$(VERSION) +-INCLUDEPY= $(INCLUDEDIR)/python$(VERSION) +-CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(VERSION) ++INCLUDEPY= $(INCLUDEDIR)/python$(VERSION)$(DEBUG_SUFFIX) ++CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(VERSION)$(DEBUG_SUFFIX) + LIBP= $(LIBDIR)/python$(VERSION) + + # Symbols used for using shared libraries +@@ -131,6 +131,12 @@ DESTSHARED= $(BINLIBDEST)/lib-dynload + EXE= @EXEEXT@ + BUILDEXE= @BUILDEXEEXT@ + ++# DEBUG_EXT is used by ELF files (names and SONAMEs); it will be "_d" for a debug build ++# DEBUG_SUFFIX is used by filesystem paths; it will be "-debug" for a debug build ++# Both will be empty in an optimized build ++DEBUG_EXT= @DEBUG_EXT@ ++DEBUG_SUFFIX= @DEBUG_SUFFIX@ ++ + # Short name and location for Mac OS X Python framework + UNIVERSALSDK=@UNIVERSALSDK@ + PYTHONFRAMEWORK= @PYTHONFRAMEWORK@ +@@ -197,8 +203,8 @@ LIBOBJDIR= Python/ + LIBOBJS= @LIBOBJS@ + UNICODE_OBJS= @UNICODE_OBJS@ + +-PYTHON= python$(EXE) +-BUILDPYTHON= python$(BUILDEXE) ++PYTHON= python$(DEBUG_SUFFIX)$(EXE) ++BUILDPYTHON= python$(DEBUG_SUFFIX)$(BUILDEXE) + + PYTHON_FOR_REGEN=@PYTHON_FOR_REGEN@ + PYTHON_FOR_BUILD=@PYTHON_FOR_BUILD@ +@@ -547,7 +553,7 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o + _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ + $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build + +-libpython$(VERSION).so: $(LIBRARY_OBJS) ++libpython$(VERSION)$(DEBUG_EXT).so: $(LIBRARY_OBJS) + if test $(INSTSONAME) != $(LDLIBRARY); then \ + $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ + $(LN) -f $(INSTSONAME) $@; \ +@@ -954,18 +960,18 @@ bininstall: altbininstall + then rm -f $(DESTDIR)$(BINDIR)/$(PYTHON); \ + else true; \ + fi +- (cd $(DESTDIR)$(BINDIR); $(LN) -s python2$(EXE) $(PYTHON)) +- -rm -f $(DESTDIR)$(BINDIR)/python2$(EXE) +- (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)$(EXE) python2$(EXE)) +- -rm -f $(DESTDIR)$(BINDIR)/python2-config +- (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)-config python2-config) +- -rm -f $(DESTDIR)$(BINDIR)/python-config +- (cd $(DESTDIR)$(BINDIR); $(LN) -s python2-config python-config) ++ (cd $(DESTDIR)$(BINDIR); $(LN) -s python2$(DEBUG_SUFFIX)$(EXE) $(PYTHON)) ++ -rm -f $(DESTDIR)$(BINDIR)/python2$(DEBUG_SUFFIX)$(EXE) ++ (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)$(DEBUG_SUFFIX)$(EXE) python2$(DEBUG_SUFFIX)$(EXE)) ++ -rm -f $(DESTDIR)$(BINDIR)/python2$(DEBUG_SUFFIX)-config ++ (cd $(DESTDIR)$(BINDIR); $(LN) -s python$(VERSION)$(DEBUG_SUFFIX)-config python2$(DEBUG_SUFFIX)-config) ++ -rm -f $(DESTDIR)$(BINDIR)/python$(DEBUG_SUFFIX)-config ++ (cd $(DESTDIR)$(BINDIR); $(LN) -s python2$(DEBUG_SUFFIX)-config python$(DEBUG_SUFFIX)-config) + -test -d $(DESTDIR)$(LIBPC) || $(INSTALL) -d -m $(DIRMODE) $(DESTDIR)$(LIBPC) +- -rm -f $(DESTDIR)$(LIBPC)/python2.pc +- (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION).pc python2.pc) +- -rm -f $(DESTDIR)$(LIBPC)/python.pc +- (cd $(DESTDIR)$(LIBPC); $(LN) -s python2.pc python.pc) ++ -rm -f $(DESTDIR)$(LIBPC)/python2$(DEBUG_SUFFIX).pc ++ (cd $(DESTDIR)$(LIBPC); $(LN) -s python-$(VERSION)$(DEBUG_SUFFIX).pc python2$(DEBUG_SUFFIX).pc) ++ -rm -f $(DESTDIR)$(LIBPC)/python$(DEBUG_SUFFIX).pc ++ (cd $(DESTDIR)$(LIBPC); $(LN) -s python2$(DEBUG_SUFFIX).pc python$(DEBUG_SUFFIX).pc) + + # Install the interpreter with $(VERSION) affixed + # This goes into $(exec_prefix) +@@ -978,7 +984,7 @@ altbininstall: $(BUILDPYTHON) + else true; \ + fi; \ + done +- $(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE) ++ $(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(VERSION)$(DEBUG_SUFFIX)$(EXE) + if test -f $(LDLIBRARY); then \ + if test -n "$(DLLLIBRARY)" ; then \ + $(INSTALL_SHARED) $(DLLLIBRARY) $(DESTDIR)$(BINDIR); \ +@@ -1148,10 +1154,11 @@ $(srcdir)/Lib/$(PLATDIR): + fi; \ + cd $(srcdir)/Lib/$(PLATDIR); $(RUNSHARED) ./regen + +-python-config: $(srcdir)/Misc/python-config.in ++python$(DEBUG_SUFFIX)-config: $(srcdir)/Misc/python-config.in + # Substitution happens here, as the completely-expanded BINDIR + # is not available in configure +- sed -e "s,@EXENAME@,$(BINDIR)/python$(VERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config ++ sed -e "s,@EXENAME@,$(BINDIR)/python$(VERSION)$(DEBUG_SUFFIX)$(EXE)," < $(srcdir)/Misc/python-config.in >python$(DEBUG_SUFFIX)-config ++ + + # Install the include files + INCLDIRSTOMAKE=$(INCLUDEDIR) $(CONFINCLUDEDIR) $(INCLUDEPY) $(CONFINCLUDEPY) +@@ -1172,13 +1179,13 @@ inclinstall: + $(INSTALL_DATA) pyconfig.h $(DESTDIR)$(CONFINCLUDEPY)/pyconfig.h + + # Install the library and miscellaneous stuff needed for extending/embedding +-# This goes into $(exec_prefix) +-LIBPL= $(LIBP)/config ++# This goes into $(exec_prefix)$(DEBUG_SUFFIX) ++LIBPL= $(LIBP)/config$(DEBUG_SUFFIX) + + # pkgconfig directory + LIBPC= $(LIBDIR)/pkgconfig + +-libainstall: @DEF_MAKE_RULE@ python-config ++libainstall: @DEF_MAKE_RULE@ python$(DEBUG_SUFFIX)-config + @for i in $(LIBDIR) $(LIBP) $(LIBPL) $(LIBPC); \ + do \ + if test ! -d $(DESTDIR)$$i; then \ +@@ -1194,11 +1201,10 @@ libainstall: all python-config + $(INSTALL_DATA) Modules/Setup $(DESTDIR)$(LIBPL)/Setup + $(INSTALL_DATA) Modules/Setup.local $(DESTDIR)$(LIBPL)/Setup.local + $(INSTALL_DATA) Modules/Setup.config $(DESTDIR)$(LIBPL)/Setup.config +- $(INSTALL_DATA) Misc/python.pc $(DESTDIR)$(LIBPC)/python-$(VERSION).pc ++ $(INSTALL_DATA) Misc/python.pc $(DESTDIR)$(LIBPC)/python-$(VERSION)$(DEBUG_SUFFIX).pc + $(INSTALL_SCRIPT) $(srcdir)/Modules/makesetup $(DESTDIR)$(LIBPL)/makesetup + $(INSTALL_SCRIPT) $(srcdir)/install-sh $(DESTDIR)$(LIBPL)/install-sh +- $(INSTALL_SCRIPT) python-config $(DESTDIR)$(BINDIR)/python$(VERSION)-config +- rm python-config ++ $(INSTALL_SCRIPT) python$(DEBUG_SUFFIX)-config $(DESTDIR)$(BINDIR)/python$(VERSION)$(DEBUG_SUFFIX)-config + @if [ -s Modules/python.exp -a \ + "`echo $(MACHDEP) | sed 's/^\(...\).*/\1/'`" = "aix" ]; then \ + echo; echo "Installing support files for building shared extension modules on AIX:"; \ +diff --git a/Misc/python-config.in b/Misc/python-config.in +index a09e07c..c1691ef 100644 +--- a/Misc/python-config.in ++++ b/Misc/python-config.in +@@ -44,7 +44,7 @@ for opt in opt_flags: + print ' '.join(flags) + + elif opt in ('--libs', '--ldflags'): +- libs = ['-lpython' + pyver] ++ libs = ['-lpython' + pyver + (sys.pydebug and "_d" or "")] + libs += getvar('LIBS').split() + libs += getvar('SYSLIBS').split() + # add the prefix/lib/pythonX.Y/config dir, but only if there is no +diff --git a/Modules/makesetup b/Modules/makesetup +index 1bffcbf..f0bc743 100755 +--- a/Modules/makesetup ++++ b/Modules/makesetup +@@ -233,7 +233,7 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' | + *$mod.o*) base=$mod;; + *) base=${mod}module;; + esac +- file="$srcdir/$base\$(SO)" ++ file="$srcdir/$base\$(DEBUG_EXT)\$(SO)" + case $doconfig in + no) SHAREDMODS="$SHAREDMODS $file";; + esac +diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c +index 17ebab1..02a94aa 100644 +--- a/Python/dynload_shlib.c ++++ b/Python/dynload_shlib.c +@@ -46,11 +46,16 @@ const struct filedescr _PyImport_DynLoadFiletab[] = { + {"module.exe", "rb", C_EXTENSION}, + {"MODULE.EXE", "rb", C_EXTENSION}, + #else ++#ifdef Py_DEBUG ++ {"_d.so", "rb", C_EXTENSION}, ++ {"module_d.so", "rb", C_EXTENSION}, ++#else + {".so", "rb", C_EXTENSION}, + {"module.so", "rb", C_EXTENSION}, +-#endif +-#endif +-#endif ++#endif /* Py_DEBUG */ ++#endif /* __VMS */ ++#endif /* defined(PYOS_OS2) && defined(PYCC_GCC) */ ++#endif /* __CYGWIN__ */ + {0, 0} + }; + +diff --git a/Python/sysmodule.c b/Python/sysmodule.c +index aeff38a..183e3cc 100644 +--- a/Python/sysmodule.c ++++ b/Python/sysmodule.c +@@ -1524,6 +1524,12 @@ _PySys_Init(void) + PyString_FromString("legacy")); + #endif + ++#ifdef Py_DEBUG ++ PyDict_SetItemString(sysdict, "pydebug", Py_True); ++#else ++ PyDict_SetItemString(sysdict, "pydebug", Py_False); ++#endif ++ + #undef SET_SYS_FROM_STRING + if (PyErr_Occurred()) + return NULL; +diff --git a/configure.ac b/configure.ac +index 0a902c7..5caedb7 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -764,7 +764,7 @@ AC_SUBST(LIBRARY) + AC_MSG_CHECKING(LIBRARY) + if test -z "$LIBRARY" + then +- LIBRARY='libpython$(VERSION).a' ++ LIBRARY='libpython$(VERSION)$(DEBUG_EXT).a' + fi + AC_MSG_RESULT($LIBRARY) + +@@ -910,8 +910,8 @@ if test $enable_shared = "yes"; then + INSTSONAME="$LDLIBRARY".$SOVERSION + ;; + Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*) +- LDLIBRARY='libpython$(VERSION).so' +- BLDLIBRARY='-L. -lpython$(VERSION)' ++ LDLIBRARY='libpython$(VERSION)$(DEBUG_EXT).so' ++ BLDLIBRARY='-L. -lpython$(VERSION)$(DEBUG_EXT)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + case $ac_sys_system in + FreeBSD*) +@@ -1040,6 +1040,14 @@ else AC_MSG_RESULT(no); Py_DEBUG='false' + fi], + [AC_MSG_RESULT(no)]) + ++if test "$Py_DEBUG" = 'true' ++then ++ DEBUG_EXT=_d ++ DEBUG_SUFFIX=-debug ++fi ++AC_SUBST(DEBUG_EXT) ++AC_SUBST(DEBUG_SUFFIX) ++ + # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be + # merged with this chunk of code? + +-- +2.11.0 + diff --git a/SOURCES/00113-more-configuration-flags.patch b/SOURCES/00113-more-configuration-flags.patch new file mode 100644 index 0000000..2d447b2 --- /dev/null +++ b/SOURCES/00113-more-configuration-flags.patch @@ -0,0 +1,50 @@ +diff -up Python-2.6.5/configure.ac.more-configuration-flags Python-2.6.5/configure.ac +--- Python-2.6.5/configure.ac.more-configuration-flags 2010-05-24 18:51:25.410111792 -0400 ++++ Python-2.6.5/configure.ac 2010-05-24 18:59:23.954986388 -0400 +@@ -2515,6 +2515,30 @@ else AC_MSG_RESULT(no) + fi], + [AC_MSG_RESULT(no)]) + ++AC_MSG_CHECKING(for --with-count-allocs) ++AC_ARG_WITH(count-allocs, ++[ --with(out)count-allocs enable/disable per-type instance accounting], [ ++if test "$withval" != no ++then ++ AC_DEFINE(COUNT_ALLOCS, 1, ++ [Define to keep records of the number of instances of each type]) ++ AC_MSG_RESULT(yes) ++else AC_MSG_RESULT(no) ++fi], ++[AC_MSG_RESULT(no)]) ++ ++AC_MSG_CHECKING(for --with-call-profile) ++AC_ARG_WITH(call-profile, ++[ --with(out)-call-profile enable/disable statistics on function call invocation], [ ++if test "$withval" != no ++then ++ AC_DEFINE(CALL_PROFILE, 1, ++ [Define to keep records on function call invocation]) ++ AC_MSG_RESULT(yes) ++else AC_MSG_RESULT(no) ++fi], ++[AC_MSG_RESULT(no)]) ++ + # Check for Python-specific malloc support + AC_MSG_CHECKING(for --with-pymalloc) + AC_ARG_WITH(pymalloc, +diff -up Python-2.6.5/pyconfig.h.in.more-configuration-flags Python-2.6.5/pyconfig.h.in +--- Python-2.6.5/pyconfig.h.in.more-configuration-flags 2010-05-24 18:51:45.677988086 -0400 ++++ Python-2.6.5/pyconfig.h.in 2010-05-24 19:00:44.163987730 -0400 +@@ -1019,6 +1019,12 @@ + /* Define to profile with the Pentium timestamp counter */ + #undef WITH_TSC + ++/* Define to keep records of the number of instances of each type */ ++#undef COUNT_ALLOCS ++ ++/* Define to keep records on function call invocation */ ++#undef CALL_PROFILE ++ + /* Define if you want pymalloc to be disabled when running under valgrind */ + #undef WITH_VALGRIND + diff --git a/SOURCES/00114-statvfs-f_flag-constants.patch b/SOURCES/00114-statvfs-f_flag-constants.patch new file mode 100644 index 0000000..83e7b59 --- /dev/null +++ b/SOURCES/00114-statvfs-f_flag-constants.patch @@ -0,0 +1,47 @@ +diff -up Python-2.7rc1/Modules/posixmodule.c.statvfs-f-flag-constants Python-2.7rc1/Modules/posixmodule.c +--- Python-2.7rc1/Modules/posixmodule.c.statvfs-f-flag-constants 2010-05-15 17:45:30.000000000 -0400 ++++ Python-2.7rc1/Modules/posixmodule.c 2010-06-07 22:54:16.162068624 -0400 +@@ -9174,6 +9174,43 @@ all_ins(PyObject *d) + #endif + #endif + ++ /* These came from statvfs.h */ ++#ifdef ST_RDONLY ++ if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1; ++#endif /* ST_RDONLY */ ++#ifdef ST_NOSUID ++ if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1; ++#endif /* ST_NOSUID */ ++ ++ /* GNU extensions */ ++#ifdef ST_NODEV ++ if (ins(d, "ST_NODEV", (long)ST_NODEV)) return -1; ++#endif /* ST_NODEV */ ++#ifdef ST_NOEXEC ++ if (ins(d, "ST_NOEXEC", (long)ST_NOEXEC)) return -1; ++#endif /* ST_NOEXEC */ ++#ifdef ST_SYNCHRONOUS ++ if (ins(d, "ST_SYNCHRONOUS", (long)ST_SYNCHRONOUS)) return -1; ++#endif /* ST_SYNCHRONOUS */ ++#ifdef ST_MANDLOCK ++ if (ins(d, "ST_MANDLOCK", (long)ST_MANDLOCK)) return -1; ++#endif /* ST_MANDLOCK */ ++#ifdef ST_WRITE ++ if (ins(d, "ST_WRITE", (long)ST_WRITE)) return -1; ++#endif /* ST_WRITE */ ++#ifdef ST_APPEND ++ if (ins(d, "ST_APPEND", (long)ST_APPEND)) return -1; ++#endif /* ST_APPEND */ ++#ifdef ST_NOATIME ++ if (ins(d, "ST_NOATIME", (long)ST_NOATIME)) return -1; ++#endif /* ST_NOATIME */ ++#ifdef ST_NODIRATIME ++ if (ins(d, "ST_NODIRATIME", (long)ST_NODIRATIME)) return -1; ++#endif /* ST_NODIRATIME */ ++#ifdef ST_RELATIME ++ if (ins(d, "ST_RELATIME", (long)ST_RELATIME)) return -1; ++#endif /* ST_RELATIME */ ++ + #if defined(PYOS_OS2) + if (insertvalues(d)) return -1; + #endif diff --git a/SOURCES/00121-add-Modules-to-build-path.patch b/SOURCES/00121-add-Modules-to-build-path.patch new file mode 100644 index 0000000..6e3294d --- /dev/null +++ b/SOURCES/00121-add-Modules-to-build-path.patch @@ -0,0 +1,13 @@ +--- Python-2.7.5/Lib/site.py.orig 2013-05-16 12:47:55.000000000 +0200 ++++ Python-2.7.5/Lib/site.py 2013-05-16 12:56:20.089058109 +0200 +@@ -529,6 +529,10 @@ def main(): + + abs__file__() + known_paths = removeduppaths() ++ from sysconfig import is_python_build ++ if is_python_build(): ++ from _sysconfigdata import build_time_vars ++ sys.path.append(os.path.join(build_time_vars['abs_builddir'], 'Modules')) + if ENABLE_USER_SITE is None: + ENABLE_USER_SITE = check_enableusersite() + known_paths = addusersitepackages(known_paths) diff --git a/SOURCES/00131-disable-tests-in-test_io.patch b/SOURCES/00131-disable-tests-in-test_io.patch new file mode 100644 index 0000000..d81a2d0 --- /dev/null +++ b/SOURCES/00131-disable-tests-in-test_io.patch @@ -0,0 +1,11 @@ +diff -up Python-2.7.2/Lib/test/test_io.py.disable-tests-in-test_io Python-2.7.2/Lib/test/test_io.py +--- Python-2.7.2/Lib/test/test_io.py.disable-tests-in-test_io 2011-09-01 14:18:45.963304089 -0400 ++++ Python-2.7.2/Lib/test/test_io.py 2011-09-01 15:08:53.796098413 -0400 +@@ -2669,6 +2669,7 @@ class SignalsTest(unittest.TestCase): + self.check_interrupted_read_retry(lambda x: x, + mode="r") + ++ @unittest.skip('rhbz#732998') + @unittest.skipUnless(threading, 'Threading required for this test.') + def check_interrupted_write_retry(self, item, **fdopen_kwargs): + """Check that a buffered write, when it gets interrupted (either diff --git a/SOURCES/00132-add-rpmbuild-hooks-to-unittest.patch b/SOURCES/00132-add-rpmbuild-hooks-to-unittest.patch new file mode 100644 index 0000000..e63395f --- /dev/null +++ b/SOURCES/00132-add-rpmbuild-hooks-to-unittest.patch @@ -0,0 +1,68 @@ +diff -up Python-2.7.2/Lib/unittest/case.py.add-rpmbuild-hooks-to-unittest Python-2.7.2/Lib/unittest/case.py +--- Python-2.7.2/Lib/unittest/case.py.add-rpmbuild-hooks-to-unittest 2011-09-08 14:45:47.677169191 -0400 ++++ Python-2.7.2/Lib/unittest/case.py 2011-09-08 16:01:36.287858159 -0400 +@@ -1,6 +1,7 @@ + """Test case implementation""" + + import collections ++import os + import sys + import functools + import difflib +@@ -94,6 +95,43 @@ def expectedFailure(func): + return wrapper + + ++# Non-standard/downstream-only hooks for handling issues with specific test ++# cases: ++ ++def _skipInRpmBuild(reason): ++ """ ++ Non-standard/downstream-only decorator for marking a specific unit test ++ to be skipped when run within the %check of an rpmbuild. ++ ++ Specifically, this takes effect when WITHIN_PYTHON_RPM_BUILD is set within ++ the environment, and has no effect otherwise. ++ """ ++ if 'WITHIN_PYTHON_RPM_BUILD' in os.environ: ++ return skip(reason) ++ else: ++ return _id ++ ++def _expectedFailureInRpmBuild(func): ++ """ ++ Non-standard/downstream-only decorator for marking a specific unit test ++ as expected to fail within the %check of an rpmbuild. ++ ++ Specifically, this takes effect when WITHIN_PYTHON_RPM_BUILD is set within ++ the environment, and has no effect otherwise. ++ """ ++ @functools.wraps(func) ++ def wrapper(*args, **kwargs): ++ if 'WITHIN_PYTHON_RPM_BUILD' in os.environ: ++ try: ++ func(*args, **kwargs) ++ except Exception: ++ raise _ExpectedFailure(sys.exc_info()) ++ raise _UnexpectedSuccess ++ else: ++ # Call directly: ++ func(*args, **kwargs) ++ return wrapper ++ + class _AssertRaisesContext(object): + """A context manager used to implement TestCase.assertRaises* methods.""" + +diff -up Python-2.7.2/Lib/unittest/__init__.py.add-rpmbuild-hooks-to-unittest Python-2.7.2/Lib/unittest/__init__.py +--- Python-2.7.2/Lib/unittest/__init__.py.add-rpmbuild-hooks-to-unittest 2011-09-08 14:59:39.534112310 -0400 ++++ Python-2.7.2/Lib/unittest/__init__.py 2011-09-08 15:07:09.191081562 -0400 +@@ -57,7 +57,8 @@ __unittest = True + + from .result import TestResult + from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf, +- skipUnless, expectedFailure) ++ skipUnless, expectedFailure, ++ _skipInRpmBuild, _expectedFailureInRpmBuild) + from .suite import BaseTestSuite, TestSuite + from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, + findTestCases) diff --git a/SOURCES/00133-skip-test_dl.patch b/SOURCES/00133-skip-test_dl.patch new file mode 100644 index 0000000..04ad05b --- /dev/null +++ b/SOURCES/00133-skip-test_dl.patch @@ -0,0 +1,13 @@ +diff -up Python-2.7.2/Lib/test/test_dl.py.skip-test_dl Python-2.7.2/Lib/test/test_dl.py +--- Python-2.7.2/Lib/test/test_dl.py.skip-test_dl 2011-09-08 15:18:40.529034289 -0400 ++++ Python-2.7.2/Lib/test/test_dl.py 2011-09-08 16:29:45.184742670 -0400 +@@ -13,6 +13,9 @@ sharedlibs = [ + ('/usr/lib/libc.dylib', 'getpid'), + ] + ++# (also, "dl" is deprecated in favor of ctypes) ++@unittest._skipInRpmBuild('fails on 64-bit builds: ' ++ 'module dl requires sizeof(int) == sizeof(long) == sizeof(char*)') + def test_main(): + for s, func in sharedlibs: + try: diff --git a/SOURCES/00136-skip-tests-of-seeking-stdin-in-rpmbuild.patch b/SOURCES/00136-skip-tests-of-seeking-stdin-in-rpmbuild.patch new file mode 100644 index 0000000..4d7626f --- /dev/null +++ b/SOURCES/00136-skip-tests-of-seeking-stdin-in-rpmbuild.patch @@ -0,0 +1,11 @@ +diff -up Python-2.7.6/Lib/test/test_file2k.py.stdin-test Python-2.7.6/Lib/test/test_file2k.py +--- Python-2.7.6/Lib/test/test_file2k.py.stdin-test 2013-11-10 08:36:40.000000000 +0100 ++++ Python-2.7.6/Lib/test/test_file2k.py 2014-01-29 14:28:01.029488055 +0100 +@@ -223,6 +223,7 @@ class OtherFileTests(unittest.TestCase): + else: + f.close() + ++ @unittest._skipInRpmBuild('seems not to raise the exception when run in Koji') + def testStdinSeek(self): + if sys.platform == 'osf1V5': + # This causes the interpreter to exit on OSF1 v5.1. diff --git a/SOURCES/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch b/SOURCES/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch new file mode 100644 index 0000000..7122a29 --- /dev/null +++ b/SOURCES/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch @@ -0,0 +1,12 @@ +diff -up Python-2.7.3/Lib/distutils/tests/test_bdist_rpm.py.mark-tests-that-fail-in-rpmbuild Python-2.7.3/Lib/distutils/tests/test_bdist_rpm.py +--- Python-2.7.3/Lib/distutils/tests/test_bdist_rpm.py.mark-tests-that-fail-in-rpmbuild 2012-04-09 19:07:29.000000000 -0400 ++++ Python-2.7.3/Lib/distutils/tests/test_bdist_rpm.py 2012-04-13 00:20:08.223819263 -0400 +@@ -24,6 +24,7 @@ setup(name='foo', version='0.1', py_modu + + """ + ++@unittest._skipInRpmBuild("don't try to nest one rpm build inside another rpm build") + class BuildRpmTestCase(support.TempdirManager, + support.EnvironGuard, + support.LoggingSilencer, +diff -up Python-2.7.3/Lib/distutils/tests/test_build_ext.py.mark-tests-that-fail-in-rpmbuild Python-2.7.3/Lib/distutils/tests/test_build_ext.py diff --git a/SOURCES/00138-fix-distutils-tests-in-debug-build.patch b/SOURCES/00138-fix-distutils-tests-in-debug-build.patch new file mode 100644 index 0000000..1fd1091 --- /dev/null +++ b/SOURCES/00138-fix-distutils-tests-in-debug-build.patch @@ -0,0 +1,68 @@ +diff -up Python-2.7.2/Lib/distutils/tests/test_build_ext.py.mark-tests-that-fail-in-rpmbuild Python-2.7.2/Lib/distutils/tests/test_build_ext.py +--- Python-2.7.2/Lib/distutils/tests/test_build_ext.py.mark-tests-that-fail-in-rpmbuild 2011-09-08 16:07:25.033834312 -0400 ++++ Python-2.7.2/Lib/distutils/tests/test_build_ext.py 2011-09-08 17:43:15.656441082 -0400 +@@ -330,6 +332,7 @@ class BuildExtTestCase(support.TempdirMa + self.assertEqual(lastdir, 'bar') + + def test_ext_fullpath(self): ++ debug_ext = sysconfig.get_config_var("DEBUG_EXT") + ext = sysconfig.get_config_vars()['SO'] + dist = Distribution() + cmd = build_ext(dist) +@@ -337,14 +340,14 @@ class BuildExtTestCase(support.TempdirMa + cmd.distribution.package_dir = {'': 'src'} + cmd.distribution.packages = ['lxml', 'lxml.html'] + curdir = os.getcwd() +- wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) ++ wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + debug_ext + ext) + path = cmd.get_ext_fullpath('lxml.etree') + self.assertEqual(wanted, path) + + # building lxml.etree not inplace + cmd.inplace = 0 + cmd.build_lib = os.path.join(curdir, 'tmpdir') +- wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + ext) ++ wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + debug_ext + ext) + path = cmd.get_ext_fullpath('lxml.etree') + self.assertEqual(wanted, path) + +@@ -354,13 +357,13 @@ class BuildExtTestCase(support.TempdirMa + cmd.distribution.packages = ['twisted', 'twisted.runner.portmap'] + path = cmd.get_ext_fullpath('twisted.runner.portmap') + wanted = os.path.join(curdir, 'tmpdir', 'twisted', 'runner', +- 'portmap' + ext) ++ 'portmap' + debug_ext + ext) + self.assertEqual(wanted, path) + + # building twisted.runner.portmap inplace + cmd.inplace = 1 + path = cmd.get_ext_fullpath('twisted.runner.portmap') +- wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext) ++ wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + debug_ext + ext) + self.assertEqual(wanted, path) + + def test_build_ext_inplace(self): +@@ -373,8 +376,9 @@ class BuildExtTestCase(support.TempdirMa + cmd.distribution.package_dir = {'': 'src'} + cmd.distribution.packages = ['lxml', 'lxml.html'] + curdir = os.getcwd() ++ debug_ext = sysconfig.get_config_var("DEBUG_EXT") + ext = sysconfig.get_config_var("SO") +- wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) ++ wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + debug_ext + ext) + path = cmd.get_ext_fullpath('lxml.etree') + self.assertEqual(wanted, path) + +@@ -412,10 +416,11 @@ class BuildExtTestCase(support.TempdirMa + dist = Distribution({'name': 'UpdateManager'}) + cmd = build_ext(dist) + cmd.ensure_finalized() ++ debug_ext = sysconfig.get_config_var("DEBUG_EXT") + ext = sysconfig.get_config_var("SO") + ext_name = os.path.join('UpdateManager', 'fdsend') + ext_path = cmd.get_ext_fullpath(ext_name) +- wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext) ++ wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + debug_ext + ext) + self.assertEqual(ext_path, wanted) + + @unittest.skipUnless(sys.platform == 'win32', 'these tests require Windows') diff --git a/SOURCES/00139-skip-test_float-known-failure-on-arm.patch b/SOURCES/00139-skip-test_float-known-failure-on-arm.patch new file mode 100644 index 0000000..9d0bfad --- /dev/null +++ b/SOURCES/00139-skip-test_float-known-failure-on-arm.patch @@ -0,0 +1,11 @@ +diff -up Python-2.7.2/Lib/test/test_float.py.skip-test_float-known-failure-on-arm Python-2.7.2/Lib/test/test_float.py +--- Python-2.7.2/Lib/test/test_float.py.skip-test_float-known-failure-on-arm 2011-09-08 19:34:09.000986128 -0400 ++++ Python-2.7.2/Lib/test/test_float.py 2011-09-08 19:34:57.969982779 -0400 +@@ -1072,6 +1072,7 @@ class HexFloatTestCase(unittest.TestCase + self.identical(got, expected) + + ++ @unittest.skip('Known failure on ARM: http://bugs.python.org/issue8265') + def test_from_hex(self): + MIN = self.MIN; + MAX = self.MAX; diff --git a/SOURCES/00140-skip-test_ctypes-known-failure-on-sparc.patch b/SOURCES/00140-skip-test_ctypes-known-failure-on-sparc.patch new file mode 100644 index 0000000..95aa41e --- /dev/null +++ b/SOURCES/00140-skip-test_ctypes-known-failure-on-sparc.patch @@ -0,0 +1,11 @@ +diff -up Python-2.7.2/Lib/ctypes/test/test_callbacks.py.skip-test_ctypes-known-failure-on-sparc Python-2.7.2/Lib/ctypes/test/test_callbacks.py +--- Python-2.7.2/Lib/ctypes/test/test_callbacks.py.skip-test_ctypes-known-failure-on-sparc 2011-09-08 19:42:35.541951490 -0400 ++++ Python-2.7.2/Lib/ctypes/test/test_callbacks.py 2011-09-08 19:43:40.676947036 -0400 +@@ -67,6 +67,7 @@ class Callbacks(unittest.TestCase): + self.check_type(c_longlong, 42) + self.check_type(c_longlong, -42) + ++ @unittest.skip('Known failure on Sparc: http://bugs.python.org/issue8314') + def test_ulonglong(self): + # test some 64-bit values, with and without msb set. + self.check_type(c_ulonglong, 10955412242170339782) diff --git a/SOURCES/00142-skip-failing-pty-tests-in-rpmbuild.patch b/SOURCES/00142-skip-failing-pty-tests-in-rpmbuild.patch new file mode 100644 index 0000000..2f51165 --- /dev/null +++ b/SOURCES/00142-skip-failing-pty-tests-in-rpmbuild.patch @@ -0,0 +1,22 @@ +diff -up Python-2.7.6/Lib/test/test_openpty.py.tty-fail Python-2.7.6/Lib/test/test_openpty.py +--- Python-2.7.6/Lib/test/test_openpty.py.tty-fail 2014-01-29 14:31:43.761343267 +0100 ++++ Python-2.7.6/Lib/test/test_openpty.py 2014-01-29 14:32:19.284090165 +0100 +@@ -8,6 +8,7 @@ if not hasattr(os, "openpty"): + + + class OpenptyTest(unittest.TestCase): ++ @unittest._skipInRpmBuild('sometimes fails in Koji, possibly due to a mock issue (rhbz#714627)') + def test(self): + master, slave = os.openpty() + self.addCleanup(os.close, master) +diff -up Python-2.7.6/Lib/test/test_pty.py.tty-fail Python-2.7.6/Lib/test/test_pty.py +--- Python-2.7.6/Lib/test/test_pty.py.tty-fail 2013-11-10 08:36:40.000000000 +0100 ++++ Python-2.7.6/Lib/test/test_pty.py 2014-01-29 14:31:43.761343267 +0100 +@@ -111,6 +111,7 @@ class PtyTest(unittest.TestCase): + os.close(master_fd) + + ++ @unittest._skipInRpmBuild('sometimes fails in Koji, possibly due to a mock issue (rhbz#714627)') + def test_fork(self): + debug("calling pty.fork()") + pid, master_fd = pty.fork() diff --git a/SOURCES/00143-tsc-on-ppc.patch b/SOURCES/00143-tsc-on-ppc.patch new file mode 100644 index 0000000..447c6e3 --- /dev/null +++ b/SOURCES/00143-tsc-on-ppc.patch @@ -0,0 +1,58 @@ +diff -up Python-2.7.2/Python/ceval.c.tsc-on-ppc Python-2.7.2/Python/ceval.c +--- Python-2.7.2/Python/ceval.c.tsc-on-ppc 2011-08-23 14:59:48.051300849 -0400 ++++ Python-2.7.2/Python/ceval.c 2011-08-23 15:33:25.412162902 -0400 +@@ -37,24 +37,42 @@ typedef unsigned long long uint64; + */ + #if defined(__ppc__) || defined (__powerpc__) + +-#define READ_TIMESTAMP(var) ppc_getcounter(&var) ++#if defined( __powerpc64__) || defined(__LP64__) ++/* 64-bit PowerPC */ ++#define READ_TIMESTAMP(var) ppc64_getcounter(&var) ++static void ++ppc64_getcounter(uint64 *v) ++{ ++ /* On 64-bit PowerPC we can read the 64-bit timebase directly into a ++ 64-bit register */ ++ uint64 timebase; ++#ifdef _ARCH_PWR4 ++ asm volatile ("mfspr %0,268" : "=r" (timebase)); ++#else ++ asm volatile ("mftb %0" : "=r" (timebase)); ++#endif ++ *v = timebase; ++} ++ ++#else ++/* 32-bit PowerPC */ ++#define READ_TIMESTAMP(var) ppc32_getcounter(&var) + + static void +-ppc_getcounter(uint64 *v) ++ppc32_getcounter(uint64 *v) + { +- register unsigned long tbu, tb, tbu2; ++ union { long long ll; long ii[2]; } u; ++ long tmp; + + loop: +- asm volatile ("mftbu %0" : "=r" (tbu) ); +- asm volatile ("mftb %0" : "=r" (tb) ); +- asm volatile ("mftbu %0" : "=r" (tbu2)); +- if (__builtin_expect(tbu != tbu2, 0)) goto loop; +- +- /* The slightly peculiar way of writing the next lines is +- compiled better by GCC than any other way I tried. */ +- ((long*)(v))[0] = tbu; +- ((long*)(v))[1] = tb; ++ asm volatile ("mftbu %0" : "=r" (u.ii[0]) ); ++ asm volatile ("mftb %0" : "=r" (u.ii[1]) ); ++ asm volatile ("mftbu %0" : "=r" (tmp)); ++ if (__builtin_expect(u.ii[0] != tmp, 0)) goto loop; ++ ++ *v = u.ll; + } ++#endif /* powerpc 32/64 bit */ + + #elif defined(__i386__) + diff --git a/SOURCES/00144-no-gdbm.patch b/SOURCES/00144-no-gdbm.patch new file mode 100644 index 0000000..0378d44 --- /dev/null +++ b/SOURCES/00144-no-gdbm.patch @@ -0,0 +1,12 @@ +diff -up Python-2.7.2/Modules/Setup.dist.no-gdbm Python-2.7.2/Modules/Setup.dist +--- Python-2.7.2/Modules/Setup.dist.no-gdbm 2011-09-13 14:25:43.496095926 -0400 ++++ Python-2.7.2/Modules/Setup.dist 2011-09-13 14:25:46.491095724 -0400 +@@ -396,7 +396,7 @@ dl dlmodule.c + # + # First, look at Setup.config; configure may have set this for you. + +-gdbm gdbmmodule.c -lgdbm ++# gdbm gdbmmodule.c -lgdbm + + + # Sleepycat Berkeley DB interface. diff --git a/SOURCES/00146-hashlib-fips.patch b/SOURCES/00146-hashlib-fips.patch new file mode 100644 index 0000000..badb629 --- /dev/null +++ b/SOURCES/00146-hashlib-fips.patch @@ -0,0 +1,732 @@ +diff -up Python-2.7.2/Lib/hashlib.py.hashlib-fips Python-2.7.2/Lib/hashlib.py +--- Python-2.7.2/Lib/hashlib.py.hashlib-fips 2011-06-11 11:46:24.000000000 -0400 ++++ Python-2.7.2/Lib/hashlib.py 2011-09-14 00:21:26.194252001 -0400 +@@ -6,9 +6,12 @@ + + __doc__ = """hashlib module - A common interface to many hash functions. + +-new(name, string='') - returns a new hash object implementing the +- given hash function; initializing the hash +- using the given string data. ++new(name, string='', usedforsecurity=True) ++ - returns a new hash object implementing the given hash function; ++ initializing the hash using the given string data. ++ ++ "usedforsecurity" is a non-standard extension for better supporting ++ FIPS-compliant environments (see below) + + Named constructor functions are also available, these are much faster + than using new(): +@@ -24,6 +27,20 @@ the zlib module. + Choose your hash function wisely. Some have known collision weaknesses. + sha384 and sha512 will be slow on 32 bit platforms. + ++Our implementation of hashlib uses OpenSSL. ++ ++OpenSSL has a "FIPS mode", which, if enabled, may restrict the available hashes ++to only those that are compliant with FIPS regulations. For example, it may ++deny the use of MD5, on the grounds that this is not secure for uses such as ++authentication, system integrity checking, or digital signatures. ++ ++If you need to use such a hash for non-security purposes (such as indexing into ++a data structure for speed), you can override the keyword argument ++"usedforsecurity" from True to False to signify that your code is not relying ++on the hash for security purposes, and this will allow the hash to be usable ++even in FIPS mode. This is not a standard feature of Python 2.7's hashlib, and ++is included here to better support FIPS mode. ++ + Hash objects have these methods: + - update(arg): Update the hash object with the string arg. Repeated calls + are equivalent to a single call with the concatenation of all +@@ -63,76 +80,41 @@ algorithms = __always_supported + 'pbkdf2_hmac') + + +-def __get_builtin_constructor(name): +- try: +- if name in ('SHA1', 'sha1'): +- import _sha +- return _sha.new +- elif name in ('MD5', 'md5'): +- import _md5 +- return _md5.new +- elif name in ('SHA256', 'sha256', 'SHA224', 'sha224'): +- import _sha256 +- bs = name[3:] +- if bs == '256': +- return _sha256.sha256 +- elif bs == '224': +- return _sha256.sha224 +- elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'): +- import _sha512 +- bs = name[3:] +- if bs == '512': +- return _sha512.sha512 +- elif bs == '384': +- return _sha512.sha384 +- except ImportError: +- pass # no extension module, this hash is unsupported. +- +- raise ValueError('unsupported hash type ' + name) +- +- + def __get_openssl_constructor(name): + try: + f = getattr(_hashlib, 'openssl_' + name) + # Allow the C module to raise ValueError. The function will be + # defined but the hash not actually available thanks to OpenSSL. +- f() ++ # ++ # We pass "usedforsecurity=False" to disable FIPS-based restrictions: ++ # at this stage we're merely seeing if the function is callable, ++ # rather than using it for actual work. ++ f(usedforsecurity=False) + # Use the C function directly (very fast) + return f + except (AttributeError, ValueError): +- return __get_builtin_constructor(name) ++ raise + +- +-def __py_new(name, string=''): +- """new(name, string='') - Return a new hashing object using the named algorithm; +- optionally initialized with a string. +- """ +- return __get_builtin_constructor(name)(string) +- +- +-def __hash_new(name, string=''): ++def __hash_new(name, string='', usedforsecurity=True): + """new(name, string='') - Return a new hashing object using the named algorithm; + optionally initialized with a string. ++ Override 'usedforsecurity' to False when using for non-security purposes in ++ a FIPS environment + """ + try: +- return _hashlib.new(name, string) ++ return _hashlib.new(name, string, usedforsecurity) + except ValueError: +- # If the _hashlib module (OpenSSL) doesn't support the named +- # hash, try using our builtin implementations. +- # This allows for SHA224/256 and SHA384/512 support even though +- # the OpenSSL library prior to 0.9.8 doesn't provide them. +- return __get_builtin_constructor(name)(string) +- ++ raise + + try: + import _hashlib + new = __hash_new + __get_hash = __get_openssl_constructor + algorithms_available = algorithms_available.union( + _hashlib.openssl_md_meth_names) + except ImportError: +- new = __py_new +- __get_hash = __get_builtin_constructor ++ # We don't build the legacy modules ++ raise + + for __func_name in __always_supported: + # try them all, some may not work due to the OpenSSL +@@ -143,4 +125,4 @@ for __func_name in __always_supported: + + # Cleanup locals() + del __always_supported, __func_name, __get_hash +-del __py_new, __hash_new, __get_openssl_constructor ++del __hash_new, __get_openssl_constructor +diff -up Python-2.7.2/Lib/test/test_hashlib.py.hashlib-fips Python-2.7.2/Lib/test/test_hashlib.py +--- Python-2.7.2/Lib/test/test_hashlib.py.hashlib-fips 2011-06-11 11:46:25.000000000 -0400 ++++ Python-2.7.2/Lib/test/test_hashlib.py 2011-09-14 01:08:55.525254195 -0400 +@@ -32,6 +32,19 @@ def hexstr(s): + r = r + h[(i >> 4) & 0xF] + h[i & 0xF] + return r + ++def openssl_enforces_fips(): ++ # Use the "openssl" command (if present) to try to determine if the local ++ # OpenSSL is configured to enforce FIPS ++ from subprocess import Popen, PIPE ++ try: ++ p = Popen(['openssl', 'md5'], ++ stdin=PIPE, stdout=PIPE, stderr=PIPE) ++ except OSError: ++ # "openssl" command not found ++ return False ++ stdout, stderr = p.communicate(input=b'abc') ++ return b'unknown cipher' in stderr ++OPENSSL_ENFORCES_FIPS = openssl_enforces_fips() + + class HashLibTestCase(unittest.TestCase): + supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1', +@@ -61,10 +74,10 @@ class HashLibTestCase(unittest.TestCase) + # of hashlib.new given the algorithm name. + for algorithm, constructors in self.constructors_to_test.items(): + constructors.add(getattr(hashlib, algorithm)) +- def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm): ++ def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm, usedforsecurity=True): + if data is None: +- return hashlib.new(_alg) +- return hashlib.new(_alg, data) ++ return hashlib.new(_alg, usedforsecurity=usedforsecurity) ++ return hashlib.new(_alg, data, usedforsecurity=usedforsecurity) + constructors.add(_test_algorithm_via_hashlib_new) + + _hashlib = self._conditional_import_module('_hashlib') +@@ -78,28 +91,13 @@ class HashLibTestCase(unittest.TestCase) + if constructor: + constructors.add(constructor) + +- _md5 = self._conditional_import_module('_md5') +- if _md5: +- self.constructors_to_test['md5'].add(_md5.new) +- _sha = self._conditional_import_module('_sha') +- if _sha: +- self.constructors_to_test['sha1'].add(_sha.new) +- _sha256 = self._conditional_import_module('_sha256') +- if _sha256: +- self.constructors_to_test['sha224'].add(_sha256.sha224) +- self.constructors_to_test['sha256'].add(_sha256.sha256) +- _sha512 = self._conditional_import_module('_sha512') +- if _sha512: +- self.constructors_to_test['sha384'].add(_sha512.sha384) +- self.constructors_to_test['sha512'].add(_sha512.sha512) +- + super(HashLibTestCase, self).__init__(*args, **kwargs) + + def test_hash_array(self): + a = array.array("b", range(10)) + constructors = self.constructors_to_test.itervalues() + for cons in itertools.chain.from_iterable(constructors): +- c = cons(a) ++ c = cons(a, usedforsecurity=False) + c.hexdigest() + + def test_algorithms_attribute(self): +@@ -115,28 +113,9 @@ class HashLibTestCase(unittest.TestCase) + self.assertRaises(ValueError, hashlib.new, 'spam spam spam spam spam') + self.assertRaises(TypeError, hashlib.new, 1) + +- def test_get_builtin_constructor(self): +- get_builtin_constructor = hashlib.__dict__[ +- '__get_builtin_constructor'] +- self.assertRaises(ValueError, get_builtin_constructor, 'test') +- try: +- import _md5 +- except ImportError: +- pass +- # This forces an ImportError for "import _md5" statements +- sys.modules['_md5'] = None +- try: +- self.assertRaises(ValueError, get_builtin_constructor, 'md5') +- finally: +- if '_md5' in locals(): +- sys.modules['_md5'] = _md5 +- else: +- del sys.modules['_md5'] +- self.assertRaises(TypeError, get_builtin_constructor, 3) +- + def test_hexdigest(self): + for name in self.supported_hash_names: +- h = hashlib.new(name) ++ h = hashlib.new(name, usedforsecurity=False) + self.assertTrue(hexstr(h.digest()) == h.hexdigest()) + + def test_large_update(self): +@@ -145,16 +125,16 @@ class HashLibTestCase(unittest.TestCase) + abcs = aas + bees + cees + + for name in self.supported_hash_names: +- m1 = hashlib.new(name) ++ m1 = hashlib.new(name, usedforsecurity=False) + m1.update(aas) + m1.update(bees) + m1.update(cees) + +- m2 = hashlib.new(name) ++ m2 = hashlib.new(name, usedforsecurity=False) + m2.update(abcs) + self.assertEqual(m1.digest(), m2.digest(), name+' update problem.') + +- m3 = hashlib.new(name, abcs) ++ m3 = hashlib.new(name, abcs, usedforsecurity=False) + self.assertEqual(m1.digest(), m3.digest(), name+' new problem.') + + def check(self, name, data, digest): +@@ -162,7 +142,7 @@ class HashLibTestCase(unittest.TestCase) + # 2 is for hashlib.name(...) and hashlib.new(name, ...) + self.assertGreaterEqual(len(constructors), 2) + for hash_object_constructor in constructors: +- computed = hash_object_constructor(data).hexdigest() ++ computed = hash_object_constructor(data, usedforsecurity=False).hexdigest() + self.assertEqual( + computed, digest, + "Hash algorithm %s constructed using %s returned hexdigest" +@@ -172,7 +152,8 @@ class HashLibTestCase(unittest.TestCase) + + def check_unicode(self, algorithm_name): + # Unicode objects are not allowed as input. +- expected = hashlib.new(algorithm_name, str(u'spam')).hexdigest() ++ expected = hashlib.new(algorithm_name, str(u'spam'), ++ usedforsecurity=False).hexdigest() + self.check(algorithm_name, u'spam', expected) + + def test_unicode(self): +@@ -354,6 +335,70 @@ class HashLibTestCase(unittest.TestCase) + self.assertEqual(expected_hash, hasher.hexdigest()) + + ++ def test_issue9146(self): ++ # Ensure that various ways to use "MD5" from "hashlib" don't segfault: ++ m = hashlib.md5(usedforsecurity=False) ++ m.update(b'abc\n') ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = hashlib.new('md5', usedforsecurity=False) ++ m.update(b'abc\n') ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = hashlib.md5(b'abc\n', usedforsecurity=False) ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = hashlib.new('md5', b'abc\n', usedforsecurity=False) ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ def assertRaisesUnknownCipher(self, callable_obj=None, *args, **kwargs): ++ try: ++ callable_obj(*args, **kwargs) ++ except ValueError, e: ++ if not e.args[0].endswith('unknown cipher'): ++ self.fail('Incorrect exception raised') ++ else: ++ self.fail('Exception was not raised') ++ ++ @unittest.skipUnless(OPENSSL_ENFORCES_FIPS, ++ 'FIPS enforcement required for this test.') ++ def test_hashlib_fips_mode(self): ++ # Ensure that we raise a ValueError on vanilla attempts to use MD5 ++ # in hashlib in a FIPS-enforced setting: ++ self.assertRaisesUnknownCipher(hashlib.md5) ++ self.assertRaisesUnknownCipher(hashlib.new, 'md5') ++ ++ @unittest.skipUnless(OPENSSL_ENFORCES_FIPS, ++ 'FIPS enforcement required for this test.') ++ def test_hashopenssl_fips_mode(self): ++ # Verify the _hashlib module's handling of md5: ++ import _hashlib ++ ++ assert hasattr(_hashlib, 'openssl_md5') ++ ++ # Ensure that _hashlib raises a ValueError on vanilla attempts to ++ # use MD5 in a FIPS-enforced setting: ++ self.assertRaisesUnknownCipher(_hashlib.openssl_md5) ++ self.assertRaisesUnknownCipher(_hashlib.new, 'md5') ++ ++ # Ensure that in such a setting we can whitelist a callsite with ++ # usedforsecurity=False and have it succeed: ++ m = _hashlib.openssl_md5(usedforsecurity=False) ++ m.update('abc\n') ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = _hashlib.new('md5', usedforsecurity=False) ++ m.update('abc\n') ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = _hashlib.openssl_md5('abc\n', usedforsecurity=False) ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = _hashlib.new('md5', 'abc\n', usedforsecurity=False) ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ ++ + class KDFTests(unittest.TestCase): + pbkdf2_test_vectors = [ + (b'password', b'salt', 1, None), +diff -up Python-2.7.2/Modules/Setup.dist.hashlib-fips Python-2.7.2/Modules/Setup.dist +--- Python-2.7.2/Modules/Setup.dist.hashlib-fips 2011-09-14 00:21:26.163252001 -0400 ++++ Python-2.7.2/Modules/Setup.dist 2011-09-14 00:21:26.201252001 -0400 +@@ -248,14 +248,14 @@ imageop imageop.c # Operations on images + # Message-Digest Algorithm, described in RFC 1321. The necessary files + # md5.c and md5.h are included here. + +-_md5 md5module.c md5.c ++#_md5 md5module.c md5.c + + + # The _sha module implements the SHA checksum algorithms. + # (NIST's Secure Hash Algorithms.) +-_sha shamodule.c +-_sha256 sha256module.c +-_sha512 sha512module.c ++#_sha shamodule.c ++#_sha256 sha256module.c ++#_sha512 sha512module.c + + + # SGI IRIX specific modules -- off by default. +diff -up Python-2.7.2/setup.py.hashlib-fips Python-2.7.2/setup.py +--- Python-2.7.2/setup.py.hashlib-fips 2011-09-14 00:21:25.722252001 -0400 ++++ Python-2.7.2/setup.py 2011-09-14 00:21:26.203252001 -0400 +@@ -768,21 +768,6 @@ class PyBuildExt(build_ext): + print ("warning: openssl 0x%08x is too old for _hashlib" % + openssl_ver) + missing.append('_hashlib') +- if COMPILED_WITH_PYDEBUG or not have_usable_openssl: +- # The _sha module implements the SHA1 hash algorithm. +- exts.append( Extension('_sha', ['shamodule.c']) ) +- # The _md5 module implements the RSA Data Security, Inc. MD5 +- # Message-Digest Algorithm, described in RFC 1321. The +- # necessary files md5.c and md5.h are included here. +- exts.append( Extension('_md5', +- sources = ['md5module.c', 'md5.c'], +- depends = ['md5.h']) ) +- +- min_sha2_openssl_ver = 0x00908000 +- if COMPILED_WITH_PYDEBUG or openssl_ver < min_sha2_openssl_ver: +- # OpenSSL doesn't do these until 0.9.8 so we'll bring our own hash +- exts.append( Extension('_sha256', ['sha256module.c']) ) +- exts.append( Extension('_sha512', ['sha512module.c']) ) + + # Modules that provide persistent dictionary-like semantics. You will + # probably want to arrange for at least one of them to be available on +--- Python-2.7.8/Modules/_hashopenssl.c.orig 2014-06-30 04:05:41.000000000 +0200 ++++ Python-2.7.8/Modules/_hashopenssl.c 2014-07-14 14:21:59.546386572 +0200 +@@ -36,6 +36,8 @@ + #endif + + /* EVP is the preferred interface to hashing in OpenSSL */ ++#include ++#include + #include + #include + #include +@@ -67,11 +69,19 @@ + + static PyTypeObject EVPtype; + ++/* Struct to hold all the cached information we need on a specific algorithm. ++ We have one of these per algorithm */ ++typedef struct { ++ PyObject *name_obj; ++ EVP_MD_CTX ctxs[2]; ++ /* ctx_ptrs will point to ctxs unless an error occurred, when it will ++ be NULL: */ ++ EVP_MD_CTX *ctx_ptrs[2]; ++ PyObject *error_msgs[2]; ++} EVPCachedInfo; + +-#define DEFINE_CONSTS_FOR_NEW(Name) \ +- static PyObject *CONST_ ## Name ## _name_obj = NULL; \ +- static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \ +- static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL; ++#define DEFINE_CONSTS_FOR_NEW(Name) \ ++ static EVPCachedInfo cached_info_ ##Name; + + DEFINE_CONSTS_FOR_NEW(md5) + DEFINE_CONSTS_FOR_NEW(sha1) +@@ -117,6 +127,48 @@ + } + } + ++static void ++mc_ctx_init(EVP_MD_CTX *ctx, int usedforsecurity) ++{ ++ EVP_MD_CTX_init(ctx); ++ ++ /* ++ If the user has declared that this digest is being used in a ++ non-security role (e.g. indexing into a data structure), set ++ the exception flag for openssl to allow it ++ */ ++ if (!usedforsecurity) { ++#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW ++ EVP_MD_CTX_set_flags(ctx, ++ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); ++#endif ++ } ++} ++ ++/* Get an error msg for the last error as a PyObject */ ++static PyObject * ++error_msg_for_last_error(void) ++{ ++ char *errstr; ++ ++ errstr = ERR_error_string(ERR_peek_last_error(), NULL); ++ ERR_clear_error(); ++ ++ return PyString_FromString(errstr); /* Can be NULL */ ++} ++ ++static void ++set_evp_exception(void) ++{ ++ char *errstr; ++ ++ errstr = ERR_error_string(ERR_peek_last_error(), NULL); ++ ERR_clear_error(); ++ ++ PyErr_SetString(PyExc_ValueError, errstr); ++} ++ ++ + /* Internal methods for a hash object */ + + static void +@@ -315,14 +367,15 @@ + static int + EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds) + { +- static char *kwlist[] = {"name", "string", NULL}; ++ static char *kwlist[] = {"name", "string", "usedforsecurity", NULL}; + PyObject *name_obj = NULL; ++ int usedforsecurity = 1; + Py_buffer view = { 0 }; + char *nameStr; + const EVP_MD *digest; + +- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s*:HASH", kwlist, +- &name_obj, &view)) { ++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s*i:HASH", kwlist, ++ &name_obj, &view, &usedforsecurity)) { + return -1; + } + +@@ -338,7 +391,12 @@ + PyBuffer_Release(&view); + return -1; + } +- EVP_DigestInit(&self->ctx, digest); ++ mc_ctx_init(&self->ctx, usedforsecurity); ++ if (!EVP_DigestInit_ex(&self->ctx, digest, NULL)) { ++ set_evp_exception(); ++ PyBuffer_Release(&view); ++ return -1; ++ } + + self->name = name_obj; + Py_INCREF(self->name); +@@ -422,7 +480,8 @@ + static PyObject * + EVPnew(PyObject *name_obj, + const EVP_MD *digest, const EVP_MD_CTX *initial_ctx, +- const unsigned char *cp, Py_ssize_t len) ++ const unsigned char *cp, Py_ssize_t len, ++ int usedforsecurity) + { + EVPobject *self; + +@@ -437,7 +496,12 @@ + if (initial_ctx) { + EVP_MD_CTX_copy(&self->ctx, initial_ctx); + } else { +- EVP_DigestInit(&self->ctx, digest); ++ mc_ctx_init(&self->ctx, usedforsecurity); ++ if (!EVP_DigestInit_ex(&self->ctx, digest, NULL)) { ++ set_evp_exception(); ++ Py_DECREF(self); ++ return NULL; ++ } + } + + if (cp && len) { +@@ -461,20 +525,28 @@ + An optional string argument may be provided and will be\n\ + automatically hashed.\n\ + \n\ +-The MD5 and SHA1 algorithms are always supported.\n"); ++The MD5 and SHA1 algorithms are always supported.\n\ ++\n\ ++An optional \"usedforsecurity=True\" keyword argument is provided for use in\n\ ++environments that enforce FIPS-based restrictions. Some implementations of\n\ ++OpenSSL can be configured to prevent the usage of non-secure algorithms (such\n\ ++as MD5). If you have a non-security use for these algorithms (e.g. a hash\n\ ++table), you can override this argument by marking the callsite as\n\ ++\"usedforsecurity=False\"."); + + static PyObject * + EVP_new(PyObject *self, PyObject *args, PyObject *kwdict) + { +- static char *kwlist[] = {"name", "string", NULL}; ++ static char *kwlist[] = {"name", "string", "usedforsecurity", NULL}; + PyObject *name_obj = NULL; + Py_buffer view = { 0 }; + PyObject *ret_obj; + char *name; + const EVP_MD *digest; ++ int usedforsecurity = 1; + +- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|s*:new", kwlist, +- &name_obj, &view)) { ++ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|s*i:new", kwlist, ++ &name_obj, &view, &usedforsecurity)) { + return NULL; + } + +@@ -487,7 +559,7 @@ + digest = EVP_get_digestbyname(name); + + ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, +- view.len); ++ view.len, usedforsecurity); + PyBuffer_Release(&view); + + return ret_obj; +@@ -713,51 +785,111 @@ + + + /* +- * This macro generates constructor function definitions for specific +- * hash algorithms. These constructors are much faster than calling +- * the generic one passing it a python string and are noticably +- * faster than calling a python new() wrapper. Thats important for ++ * This macro and function generates a family of constructor function ++ * definitions for specific hash algorithms. These constructors are much ++ * faster than calling the generic one passing it a python string and are ++ * noticably faster than calling a python new() wrapper. That's important for + * code that wants to make hashes of a bunch of small strings. + */ + #define GEN_CONSTRUCTOR(NAME) \ + static PyObject * \ +- EVP_new_ ## NAME (PyObject *self, PyObject *args) \ ++ EVP_new_ ## NAME (PyObject *self, PyObject *args, PyObject *kwdict) \ + { \ +- Py_buffer view = { 0 }; \ +- PyObject *ret_obj; \ +- \ +- if (!PyArg_ParseTuple(args, "|s*:" #NAME , &view)) { \ +- return NULL; \ +- } \ +- \ +- ret_obj = EVPnew( \ +- CONST_ ## NAME ## _name_obj, \ +- NULL, \ +- CONST_new_ ## NAME ## _ctx_p, \ +- (unsigned char*)view.buf, view.len); \ +- PyBuffer_Release(&view); \ +- return ret_obj; \ ++ return implement_specific_EVP_new(self, args, kwdict, \ ++ "|s*i:" #NAME, \ ++ &cached_info_ ## NAME ); \ + } + ++static PyObject * ++implement_specific_EVP_new(PyObject *self, PyObject *args, PyObject *kwdict, ++ const char *format, ++ EVPCachedInfo *cached_info) ++{ ++ static char *kwlist[] = {"string", "usedforsecurity", NULL}; ++ Py_buffer view = { 0 }; ++ int usedforsecurity = 1; ++ int idx; ++ PyObject *ret_obj = NULL; ++ ++ assert(cached_info); ++ ++ if (!PyArg_ParseTupleAndKeywords(args, kwdict, format, kwlist, ++ &view, &usedforsecurity)) { ++ return NULL; ++ } ++ ++ idx = usedforsecurity ? 1 : 0; ++ ++ /* ++ * If an error occurred during creation of the global content, the ctx_ptr ++ * will be NULL, and the error_msg will hopefully be non-NULL: ++ */ ++ if (cached_info->ctx_ptrs[idx]) { ++ /* We successfully initialized this context; copy it: */ ++ ret_obj = EVPnew(cached_info->name_obj, ++ NULL, ++ cached_info->ctx_ptrs[idx], ++ (unsigned char*)view.buf, view.len, ++ usedforsecurity); ++ } else { ++ /* Some kind of error happened initializing the global context for ++ this (digest, usedforsecurity) pair. ++ Raise an exception with the saved error message: */ ++ if (cached_info->error_msgs[idx]) { ++ PyErr_SetObject(PyExc_ValueError, cached_info->error_msgs[idx]); ++ } else { ++ PyErr_SetString(PyExc_ValueError, "Error initializing hash"); ++ } ++ } ++ ++ PyBuffer_Release(&view); ++ ++ return ret_obj; ++} ++ + /* a PyMethodDef structure for the constructor */ + #define CONSTRUCTOR_METH_DEF(NAME) \ +- {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \ ++ {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, \ ++ METH_VARARGS |METH_KEYWORDS, \ + PyDoc_STR("Returns a " #NAME \ + " hash object; optionally initialized with a string") \ + } + +-/* used in the init function to setup a constructor: initialize OpenSSL +- constructor constants if they haven't been initialized already. */ +-#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \ +- if (CONST_ ## NAME ## _name_obj == NULL) { \ +- CONST_ ## NAME ## _name_obj = PyString_FromString(#NAME); \ +- if (EVP_get_digestbyname(#NAME)) { \ +- CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \ +- EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \ +- } \ +- } \ ++/* ++ Macro/function pair to set up the constructors. ++ ++ Try to initialize a context for each hash twice, once with ++ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW and once without. ++ ++ Any that have errors during initialization will end up wit a NULL ctx_ptrs ++ entry, and err_msgs will be set (unless we're very low on memory) ++*/ ++#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \ ++ init_constructor_constant(&cached_info_ ## NAME, #NAME); \ + } while (0); + ++static void ++init_constructor_constant(EVPCachedInfo *cached_info, const char *name) ++{ ++ assert(cached_info); ++ cached_info->name_obj = PyString_FromString(name); ++ if (EVP_get_digestbyname(name)) { ++ int i; ++ for (i=0; i<2; i++) { ++ mc_ctx_init(&cached_info->ctxs[i], i); ++ if (EVP_DigestInit_ex(&cached_info->ctxs[i], ++ EVP_get_digestbyname(name), NULL)) { ++ /* Success: */ ++ cached_info->ctx_ptrs[i] = &cached_info->ctxs[i]; ++ } else { ++ /* Failure: */ ++ cached_info->ctx_ptrs[i] = NULL; ++ cached_info->error_msgs[i] = error_msg_for_last_error(); ++ } ++ } ++ } ++} ++ + GEN_CONSTRUCTOR(md5) + GEN_CONSTRUCTOR(sha1) + #ifdef _OPENSSL_SUPPORTS_SHA2 +@@ -794,14 +926,11 @@ + { + PyObject *m, *openssl_md_meth_names; + ++ SSL_load_error_strings(); ++ SSL_library_init(); + OpenSSL_add_all_digests(); + ERR_load_crypto_strings(); + +- /* TODO build EVP_functions openssl_* entries dynamically based +- * on what hashes are supported rather than listing many +- * but having some be unsupported. Only init appropriate +- * constants. */ +- + Py_TYPE(&EVPtype) = &PyType_Type; + if (PyType_Ready(&EVPtype) < 0) + return; diff --git a/SOURCES/00147-add-debug-malloc-stats.patch b/SOURCES/00147-add-debug-malloc-stats.patch new file mode 100644 index 0000000..6c7d3f1 --- /dev/null +++ b/SOURCES/00147-add-debug-malloc-stats.patch @@ -0,0 +1,761 @@ +diff --git a/Include/dictobject.h b/Include/dictobject.h +index 5a1e9fe..da89cec 100644 +--- a/Include/dictobject.h ++++ b/Include/dictobject.h +@@ -154,6 +154,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); + ++PyAPI_FUNC(void) _PyDict_DebugMallocStats(FILE *out); ++ + #ifdef __cplusplus + } + #endif +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); + ++PyAPI_FUNC(void) _PyFloat_DebugMallocStats(FILE* out); + + + #ifdef __cplusplus +diff --git a/Include/frameobject.h b/Include/frameobject.h +index 3460379..db89a4a 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); + ++PyAPI_FUNC(void) _PyFrame_DebugMallocStats(FILE *out); ++ + /* Return the line of code the frame is currently executing. */ + PyAPI_FUNC(int) PyFrame_GetLineNumber(PyFrameObject *); + +diff --git a/Include/intobject.h b/Include/intobject.h +index d198574..60cb9e0 100644 +--- a/Include/intobject.h ++++ b/Include/intobject.h +@@ -78,6 +78,8 @@ PyAPI_FUNC(PyObject *) _PyInt_FormatAdvanced(PyObject *obj, + char *format_spec, + Py_ssize_t format_spec_len); + ++PyAPI_FUNC(void) _PyInt_DebugMallocStats(FILE *out); ++ + #ifdef __cplusplus + } + #endif +diff --git a/Include/listobject.h b/Include/listobject.h +index f19b1c5..7fccb47 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) + ++PyAPI_FUNC(void) _PyList_DebugMallocStats(FILE *out); ++ + #ifdef __cplusplus + } + #endif +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); + ++PyAPI_FUNC(void) _PyCFunction_DebugMallocStats(FILE *out); ++PyAPI_FUNC(void) _PyMethod_DebugMallocStats(FILE *out); ++ ++ + #ifdef __cplusplus + } + #endif +diff --git a/Include/object.h b/Include/object.h +index 807b241..a9d2079 100644 +--- a/Include/object.h ++++ b/Include/object.h +@@ -1040,6 +1040,13 @@ PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(void); + _PyTrash_thread_deposit_object((PyObject*)op); \ + } while (0); + ++PyAPI_FUNC(void) ++_PyDebugAllocatorStats(FILE *out, const char *block_name, int num_blocks, ++ size_t sizeof_block); ++ ++PyAPI_FUNC(void) ++_PyObject_DebugTypeStats(FILE *out); ++ + #ifdef __cplusplus + } + #endif +diff --git a/Include/objimpl.h b/Include/objimpl.h +index cbf6bc3..8c14ab8 100644 +--- a/Include/objimpl.h ++++ b/Include/objimpl.h +@@ -101,13 +101,13 @@ PyAPI_FUNC(void) PyObject_Free(void *); + + /* Macros */ + #ifdef WITH_PYMALLOC ++PyAPI_FUNC(void) _PyObject_DebugMallocStats(FILE *out); + #ifdef PYMALLOC_DEBUG /* WITH_PYMALLOC && PYMALLOC_DEBUG */ + PyAPI_FUNC(void *) _PyObject_DebugMalloc(size_t nbytes); + PyAPI_FUNC(void *) _PyObject_DebugRealloc(void *p, size_t nbytes); + PyAPI_FUNC(void) _PyObject_DebugFree(void *p); + PyAPI_FUNC(void) _PyObject_DebugDumpAddress(const void *p); + PyAPI_FUNC(void) _PyObject_DebugCheckAddress(const void *p); +-PyAPI_FUNC(void) _PyObject_DebugMallocStats(void); + 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 --git a/Include/setobject.h b/Include/setobject.h +index 52b07d5..73a37b6 100644 +--- a/Include/setobject.h ++++ b/Include/setobject.h +@@ -92,6 +92,7 @@ PyAPI_FUNC(int) _PySet_Next(PyObject *set, Py_ssize_t *pos, PyObject **key); + PyAPI_FUNC(int) _PySet_NextEntry(PyObject *set, Py_ssize_t *pos, PyObject **key, long *hash); + 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 + } +diff --git a/Include/stringobject.h b/Include/stringobject.h +index 12cc093..0a5fbd1 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); + ++PyAPI_FUNC(void) _PyString_DebugMallocStats(FILE *out); ++ + #ifdef __cplusplus + } + #endif +diff --git a/Include/tupleobject.h b/Include/tupleobject.h +index a5ab733..27e6ca6 100644 +--- a/Include/tupleobject.h ++++ b/Include/tupleobject.h +@@ -54,6 +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 + } +diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h +index 7781f96..321bd20 100644 +--- a/Include/unicodeobject.h ++++ b/Include/unicodeobject.h +@@ -1406,6 +1406,8 @@ PyAPI_FUNC(int) _PyUnicode_IsAlpha( + Py_UNICODE ch /* Unicode character */ + ); + ++PyAPI_FUNC(void) _PyUnicode_DebugMallocStats(FILE *out); ++ + #ifdef __cplusplus + } + #endif +diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py +index 9342716..8eeb5ab 100644 +--- a/Lib/test/test_sys.py ++++ b/Lib/test/test_sys.py +@@ -487,6 +487,32 @@ class SysModuleTest(unittest.TestCase): + p.wait() + self.assertIn(executable, ["''", repr(sys.executable)]) + ++ def test_debugmallocstats(self): ++ # Test sys._debugmallocstats() ++ ++ import subprocess ++ ++ # Verify the default of writing to stderr: ++ p = subprocess.Popen([sys.executable, ++ '-c', 'import sys; sys._debugmallocstats()'], ++ stderr=subprocess.PIPE) ++ 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: ++ sys._debugmallocstats(out) ++ result = open('mallocstats.txt').read() ++ self.assertIn("arenas allocated current", result) ++ os.unlink('mallocstats.txt') ++ ++ # Verify that the destination must be a file: ++ with self.assertRaises(TypeError): ++ sys._debugmallocstats(42) ++ ++ + @test.test_support.cpython_only + class SizeofTest(unittest.TestCase): + +diff --git a/Objects/classobject.c b/Objects/classobject.c +index 02d7cfd..1c44a47 100644 +--- a/Objects/classobject.c ++++ b/Objects/classobject.c +@@ -2691,3 +2691,12 @@ PyMethod_Fini(void) + { + (void)PyMethod_ClearFreeList(); + } ++ ++/* Print summary info about the state of the optimized allocator */ ++void ++_PyMethod_DebugMallocStats(FILE *out) ++{ ++ _PyDebugAllocatorStats(out, ++ "free PyMethodObject", ++ numfree, sizeof(PyMethodObject)); ++} +diff --git a/Objects/dictobject.c b/Objects/dictobject.c +index c544ecd..89ca39c 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; + ++/* Print summary info about the state of the optimized allocator */ ++void ++_PyDict_DebugMallocStats(FILE *out) ++{ ++ _PyDebugAllocatorStats(out, ++ "free PyDictObject", numfree, sizeof(PyDictObject)); ++} ++ ++ + void + PyDict_Fini(void) + { +diff --git a/Objects/floatobject.c b/Objects/floatobject.c +index 5954d39..02acc8c 100644 +--- a/Objects/floatobject.c ++++ b/Objects/floatobject.c +@@ -34,6 +34,22 @@ typedef struct _floatblock PyFloatBlock; + static PyFloatBlock *block_list = NULL; + static PyFloatObject *free_list = NULL; + ++/* Print summary info about the state of the optimized allocator */ ++void ++_PyFloat_DebugMallocStats(FILE *out) ++{ ++ int num_blocks = 0; ++ PyFloatBlock *block; ++ ++ /* Walk the block list, counting */ ++ for (block = block_list; block ; block = block->next) { ++ num_blocks++; ++ } ++ ++ _PyDebugAllocatorStats(out, ++ "PyFloatBlock", num_blocks, sizeof(PyFloatBlock)); ++} ++ + static PyFloatObject * + fill_free_list(void) + { +diff --git a/Objects/frameobject.c b/Objects/frameobject.c +index 4c91dd0..03a66dc 100644 +--- a/Objects/frameobject.c ++++ b/Objects/frameobject.c +@@ -1019,3 +1019,13 @@ PyFrame_Fini(void) + Py_XDECREF(builtin_object); + builtin_object = NULL; + } ++ ++/* Print summary info about the state of the optimized allocator */ ++void ++_PyFrame_DebugMallocStats(FILE *out) ++{ ++ _PyDebugAllocatorStats(out, ++ "free PyFrameObject", ++ numfree, sizeof(PyFrameObject)); ++} ++ +diff --git a/Objects/intobject.c b/Objects/intobject.c +index 9b27c35..703fa5a 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; + ++ ++/* Print summary info about the state of the optimized allocator */ ++void ++_PyInt_DebugMallocStats(FILE *out) ++{ ++ int num_blocks = 0; ++ PyIntBlock *block; ++ ++ /* Walk the block list, counting */ ++ for (block = block_list; block ; block = block->next) { ++ num_blocks++; ++ } ++ ++ _PyDebugAllocatorStats(out, ++ "PyIntBlock", num_blocks, sizeof(PyIntBlock)); ++} ++ + static PyIntObject * + fill_free_list(void) + { +diff --git a/Objects/listobject.c b/Objects/listobject.c +index 24eff76..38848bd 100644 +--- a/Objects/listobject.c ++++ b/Objects/listobject.c +@@ -109,6 +109,15 @@ PyList_Fini(void) + } + } + ++/* Print summary info about the state of the optimized allocator */ ++void ++_PyList_DebugMallocStats(FILE *out) ++{ ++ _PyDebugAllocatorStats(out, ++ "free PyListObject", ++ numfree, sizeof(PyListObject)); ++} ++ + PyObject * + PyList_New(Py_ssize_t size) + { +diff --git a/Objects/methodobject.c b/Objects/methodobject.c +index c1a99ab..ea5df77 100644 +--- a/Objects/methodobject.c ++++ b/Objects/methodobject.c +@@ -412,6 +412,15 @@ PyCFunction_Fini(void) + (void)PyCFunction_ClearFreeList(); + } + ++/* Print summary info about the state of the optimized allocator */ ++void ++_PyCFunction_DebugMallocStats(FILE *out) ++{ ++ _PyDebugAllocatorStats(out, ++ "free PyCFunction", ++ numfree, sizeof(PyCFunction)); ++} ++ + /* 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 --git a/Objects/object.c b/Objects/object.c +index 65366b0..acef3ce 100644 +--- a/Objects/object.c ++++ b/Objects/object.c +@@ -2360,6 +2360,23 @@ PyMem_Free(void *p) + PyMem_FREE(p); + } + ++void ++_PyObject_DebugTypeStats(FILE *out) ++{ ++ _PyString_DebugMallocStats(out); ++ _PyCFunction_DebugMallocStats(out); ++ _PyDict_DebugMallocStats(out); ++ _PyFloat_DebugMallocStats(out); ++ _PyFrame_DebugMallocStats(out); ++ _PyInt_DebugMallocStats(out); ++ _PyList_DebugMallocStats(out); ++ _PyMethod_DebugMallocStats(out); ++ _PySet_DebugMallocStats(out); ++ _PyTuple_DebugMallocStats(out); ++#if Py_USING_UNICODE ++ _PyUnicode_DebugMallocStats(out); ++#endif ++} + + /* These methods are used to control infinite recursion in repr, str, print, + etc. Container objects that may recursively contain themselves, +diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c +index 0778c85..f049f5c 100644 +--- a/Objects/obmalloc.c ++++ b/Objects/obmalloc.c +@@ -541,12 +541,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; + +-#ifdef PYMALLOC_DEBUG + /* Total number of times malloc() called to allocate an arena. */ + static size_t ntimes_arena_allocated = 0; + /* High water mark (max value ever seen) for narenas_currently_allocated. */ + static size_t narenas_highwater = 0; +-#endif + + /* Allocate a new arena. If we run out of memory, return NULL. Else + * allocate a new arena, and return the address of an arena_object +@@ -563,7 +561,7 @@ new_arena(void) + + #ifdef PYMALLOC_DEBUG + if (Py_GETENV("PYTHONMALLOCSTATS")) +- _PyObject_DebugMallocStats(); ++ _PyObject_DebugMallocStats(stderr); + #endif + if (unused_arena_objects == NULL) { + uint i; +@@ -631,11 +629,9 @@ new_arena(void) + arenaobj->address = (uptr)address; + + ++narenas_currently_allocated; +-#ifdef PYMALLOC_DEBUG + ++ntimes_arena_allocated; + if (narenas_currently_allocated > narenas_highwater) + narenas_highwater = narenas_currently_allocated; +-#endif + arenaobj->freepools = NULL; + /* pool_address <- first pool-aligned address in the arena + nfreepools <- number of whole pools that fit after alignment */ +@@ -1796,17 +1792,19 @@ _PyObject_DebugDumpAddress(const void *p) + } + } + ++#endif /* PYMALLOC_DEBUG */ ++ + static size_t +-printone(const char* msg, size_t value) ++printone(FILE *out, const char* msg, size_t value) + { + int i, k; + char buf[100]; + size_t origvalue = value; + +- fputs(msg, stderr); ++ fputs(msg, out); + for (i = (int)strlen(msg); i < 35; ++i) +- fputc(' ', stderr); +- fputc('=', stderr); ++ fputc(' ', out); ++ fputc('=', out); + + /* Write the value with commas. */ + i = 22; +@@ -1827,17 +1825,32 @@ printone(const char* msg, size_t value) + + while (i >= 0) + buf[i--] = ' '; +- fputs(buf, stderr); ++ fputs(buf, out); + + return origvalue; + } + +-/* Print summary info to stderr about the state of pymalloc's structures. ++void ++_PyDebugAllocatorStats(FILE *out, ++ const char *block_name, int num_blocks, size_t sizeof_block) ++{ ++ char buf1[128]; ++ char buf2[128]; ++ PyOS_snprintf(buf1, sizeof(buf1), ++ "%d %ss * %zd bytes each", ++ num_blocks, block_name, sizeof_block); ++ PyOS_snprintf(buf2, sizeof(buf2), ++ "%48s ", buf1); ++ (void)printone(out, buf2, num_blocks * sizeof_block); ++} ++ ++ ++/* Print summary info to "out" about the state of pymalloc's structures. + * In Py_DEBUG mode, also perform some expensive internal consistency + * checks. + */ + void +-_PyObject_DebugMallocStats(void) ++_PyObject_DebugMallocStats(FILE *out) + { + uint i; + const uint numclasses = SMALL_REQUEST_THRESHOLD >> ALIGNMENT_SHIFT; +@@ -1866,7 +1879,7 @@ _PyObject_DebugMallocStats(void) + size_t total; + char buf[128]; + +- fprintf(stderr, "Small block threshold = %d, in %u size classes.\n", ++ fprintf(out, "Small block threshold = %d, in %u size classes.\n", + SMALL_REQUEST_THRESHOLD, numclasses); + + for (i = 0; i < numclasses; ++i) +@@ -1920,10 +1933,10 @@ _PyObject_DebugMallocStats(void) + } + assert(narenas == narenas_currently_allocated); + +- fputc('\n', stderr); ++ fputc('\n', out); + fputs("class size num pools blocks in use avail blocks\n" + "----- ---- --------- ------------- ------------\n", +- stderr); ++ out); + + for (i = 0; i < numclasses; ++i) { + size_t p = numpools[i]; +@@ -1934,7 +1947,7 @@ _PyObject_DebugMallocStats(void) + assert(b == 0 && f == 0); + continue; + } +- fprintf(stderr, "%5u %6u " ++ fprintf(out, "%5u %6u " + "%11" PY_FORMAT_SIZE_T "u " + "%15" PY_FORMAT_SIZE_T "u " + "%13" PY_FORMAT_SIZE_T "u\n", +@@ -1944,36 +1957,35 @@ _PyObject_DebugMallocStats(void) + pool_header_bytes += p * POOL_OVERHEAD; + quantization += p * ((POOL_SIZE - POOL_OVERHEAD) % size); + } +- fputc('\n', stderr); +- (void)printone("# times object malloc called", serialno); +- +- (void)printone("# arenas allocated total", ntimes_arena_allocated); +- (void)printone("# arenas reclaimed", ntimes_arena_allocated - narenas); +- (void)printone("# arenas highwater mark", narenas_highwater); +- (void)printone("# arenas allocated current", narenas); ++ fputc('\n', out); ++#ifdef PYMALLOC_DEBUG ++ (void)printone(out, "# times object malloc called", serialno); ++#endif ++ (void)printone(out, "# arenas allocated total", ntimes_arena_allocated); ++ (void)printone(out, "# arenas reclaimed", ntimes_arena_allocated - narenas); ++ (void)printone(out, "# arenas highwater mark", narenas_highwater); ++ (void)printone(out, "# arenas allocated current", narenas); + + PyOS_snprintf(buf, sizeof(buf), + "%" PY_FORMAT_SIZE_T "u arenas * %d bytes/arena", + narenas, ARENA_SIZE); +- (void)printone(buf, narenas * ARENA_SIZE); ++ (void)printone(out, buf, narenas * ARENA_SIZE); + +- fputc('\n', stderr); ++ fputc('\n', out); + +- total = printone("# bytes in allocated blocks", allocated_bytes); +- total += printone("# bytes in available blocks", available_bytes); ++ total = printone(out, "# bytes in allocated blocks", allocated_bytes); ++ total += printone(out, "# bytes in available blocks", available_bytes); + + PyOS_snprintf(buf, sizeof(buf), + "%u unused pools * %d bytes", numfreepools, POOL_SIZE); +- total += printone(buf, (size_t)numfreepools * POOL_SIZE); ++ total += printone(out, buf, (size_t)numfreepools * POOL_SIZE); + +- total += printone("# bytes lost to pool headers", pool_header_bytes); +- total += printone("# bytes lost to quantization", quantization); +- total += printone("# bytes lost to arena alignment", arena_alignment); +- (void)printone("Total", total); ++ total += printone(out, "# bytes lost to pool headers", pool_header_bytes); ++ total += printone(out, "# bytes lost to quantization", quantization); ++ total += printone(out, "# bytes lost to arena alignment", arena_alignment); ++ (void)printone(out, "Total", total); + } + +-#endif /* PYMALLOC_DEBUG */ +- + #ifdef Py_USING_MEMORY_DEBUGGER + /* Make this function last so gcc won't inline it since the definition is + * after the reference. +diff --git a/Objects/setobject.c b/Objects/setobject.c +index 31da3db..da086ab 100644 +--- a/Objects/setobject.c ++++ b/Objects/setobject.c +@@ -1087,6 +1087,16 @@ PySet_Fini(void) + Py_CLEAR(emptyfrozenset); + } + ++/* Print summary info about the state of the optimized allocator */ ++void ++_PySet_DebugMallocStats(FILE *out) ++{ ++ _PyDebugAllocatorStats(out, ++ "free PySetObject", ++ numfree, sizeof(PySetObject)); ++} ++ ++ + static PyObject * + set_new(PyTypeObject *type, PyObject *args, PyObject *kwds) + { +diff --git a/Objects/stringobject.c b/Objects/stringobject.c +index c47d32f..b1ffa24 100644 +--- a/Objects/stringobject.c ++++ b/Objects/stringobject.c +@@ -4880,3 +4880,43 @@ void _Py_ReleaseInternedStrings(void) + PyDict_Clear(interned); + Py_CLEAR(interned); + } ++ ++void _PyString_DebugMallocStats(FILE *out) ++{ ++ ssize_t i; ++ int num_immortal = 0, num_mortal = 0; ++ ssize_t immortal_size = 0, mortal_size = 0; ++ ++ if (interned == NULL || !PyDict_Check(interned)) ++ return; ++ ++ for (i = 0; i <= ((PyDictObject*)interned)->ma_mask; i++) { ++ PyDictEntry *ep = ((PyDictObject*)interned)->ma_table + i; ++ PyObject *pvalue = ep->me_value; ++ if (pvalue != NULL) { ++ PyStringObject *s = (PyStringObject *)ep->me_key; ++ ++ switch (s->ob_sstate) { ++ case SSTATE_NOT_INTERNED: ++ /* XXX Shouldn't happen */ ++ break; ++ case SSTATE_INTERNED_IMMORTAL: ++ num_immortal ++; ++ immortal_size += s->ob_size; ++ break; ++ case SSTATE_INTERNED_MORTAL: ++ num_mortal ++; ++ mortal_size += s->ob_size; ++ break; ++ default: ++ Py_FatalError("Inconsistent interned string state."); ++ } ++ } ++ } ++ ++ fprintf(out, "%d mortal interned strings\n", num_mortal); ++ fprintf(out, "%d immortal interned strings\n", num_immortal); ++ fprintf(out, "total size of all interned strings: " ++ "%zi/%zi " ++ "mortal/immortal\n", mortal_size, immortal_size); ++} +diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c +index 6f4b18c..e8e4490 100644 +--- a/Objects/tupleobject.c ++++ b/Objects/tupleobject.c +@@ -44,6 +44,22 @@ show_track(void) + } + #endif + ++/* Print summary info about the state of the optimized allocator */ ++void ++_PyTuple_DebugMallocStats(FILE *out) ++{ ++#if PyTuple_MAXSAVESIZE > 0 ++ int i; ++ char buf[128]; ++ for (i = 1; i < PyTuple_MAXSAVESIZE; i++) { ++ PyOS_snprintf(buf, sizeof(buf), ++ "free %d-sized PyTupleObject", i); ++ _PyDebugAllocatorStats(out, ++ buf, ++ numfree[i], _PyObject_VAR_SIZE(&PyTuple_Type, i)); ++ } ++#endif ++} + + PyObject * + PyTuple_New(register Py_ssize_t size) +diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c +index a859fa0..b6ff83e 100644 +--- a/Objects/unicodeobject.c ++++ b/Objects/unicodeobject.c +@@ -9018,6 +9018,12 @@ _PyUnicode_Fini(void) + (void)PyUnicode_ClearFreeList(); + } + ++void _PyUnicode_DebugMallocStats(FILE *out) ++{ ++ _PyDebugAllocatorStats(out, "free PyUnicodeObject", numfree, ++ sizeof(PyUnicodeObject)); ++} ++ + #ifdef __cplusplus + } + #endif +diff --git a/Python/pythonrun.c b/Python/pythonrun.c +index b686317..c3b3e17 100644 +--- a/Python/pythonrun.c ++++ b/Python/pythonrun.c +@@ -605,7 +605,7 @@ Py_Finalize(void) + #endif /* Py_TRACE_REFS */ + #ifdef PYMALLOC_DEBUG + if (Py_GETENV("PYTHONMALLOCSTATS")) +- _PyObject_DebugMallocStats(); ++ _PyObject_DebugMallocStats(stderr); + #endif + + call_ll_exitfuncs(); +diff --git a/Python/sysmodule.c b/Python/sysmodule.c +index 22238ba..60624f2 100644 +--- a/Python/sysmodule.c ++++ b/Python/sysmodule.c +@@ -890,6 +890,57 @@ a 11-tuple where the entries in the tuple are counts of:\n\ + extern "C" { + #endif + ++static PyObject * ++sys_debugmallocstats(PyObject *self, PyObject *args) ++{ ++ PyObject *file = NULL; ++ FILE *fp; ++ ++ if (!PyArg_ParseTuple(args, "|O!", ++ &PyFile_Type, &file)) { ++ return NULL; ++ } ++ if (!file) { ++ /* Default to sys.stderr: */ ++ file = PySys_GetObject("stderr"); ++ if (!file) { ++ PyErr_SetString(PyExc_ValueError, "sys.stderr not set"); ++ return NULL; ++ } ++ if (!PyFile_Check(file)) { ++ PyErr_SetString(PyExc_TypeError, "sys.stderr is not a file"); ++ return NULL; ++ } ++ } ++ ++ Py_INCREF(file); ++ /* OK, we now own a ref on non-NULL "file" */ ++ ++ fp = PyFile_AsFile(file); ++ if (!fp) { ++ PyErr_SetString(PyExc_ValueError, "file is closed"); ++ Py_DECREF(file); ++ return NULL; ++ } ++ ++ _PyObject_DebugMallocStats(fp); ++ fputc('\n', fp); ++ _PyObject_DebugTypeStats(fp); ++ ++ Py_DECREF(file); ++ ++ Py_RETURN_NONE; ++} ++PyDoc_STRVAR(debugmallocstats_doc, ++"_debugmallocstats([file])\n\ ++\n\ ++Print summary info to the given file (or sys.stderr) about the state of\n\ ++pymalloc's structures.\n\ ++\n\ ++In Py_DEBUG mode, also perform some expensive internal consistency\n\ ++checks.\n\ ++"); ++ + #ifdef Py_TRACE_REFS + /* Defined in objects.c because it uses static globals if that file */ + extern PyObject *_Py_GetObjects(PyObject *, PyObject *); +@@ -988,6 +1039,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}, ++ {"_debugmallocstats", sys_debugmallocstats, METH_VARARGS, ++ debugmallocstats_doc}, + {NULL, NULL} /* sentinel */ + }; + diff --git a/SOURCES/00155-avoid-ctypes-thunks.patch b/SOURCES/00155-avoid-ctypes-thunks.patch new file mode 100644 index 0000000..92dd668 --- /dev/null +++ b/SOURCES/00155-avoid-ctypes-thunks.patch @@ -0,0 +1,15 @@ +diff -up Python-2.7.3/Lib/ctypes/__init__.py.rhbz814391 Python-2.7.3/Lib/ctypes/__init__.py +--- Python-2.7.3/Lib/ctypes/__init__.py.rhbz814391 2012-04-20 14:51:19.390990244 -0400 ++++ Python-2.7.3/Lib/ctypes/__init__.py 2012-04-20 14:51:45.141668316 -0400 +@@ -272,11 +272,6 @@ def _reset_cache(): + # _SimpleCData.c_char_p_from_param + POINTER(c_char).from_param = c_char_p.from_param + _pointer_type_cache[None] = c_void_p +- # XXX for whatever reasons, creating the first instance of a callback +- # function is needed for the unittests on Win64 to succeed. This MAY +- # be a compiler bug, since the problem occurs only when _ctypes is +- # compiled with the MS SDK compiler. Or an uninitialized variable? +- CFUNCTYPE(c_int)(lambda: None) + + try: + from _ctypes import set_conversion_mode diff --git a/SOURCES/00156-gdb-autoload-safepath.patch b/SOURCES/00156-gdb-autoload-safepath.patch new file mode 100644 index 0000000..a16fe8d --- /dev/null +++ b/SOURCES/00156-gdb-autoload-safepath.patch @@ -0,0 +1,57 @@ +diff -up Python-2.7.3/Lib/test/test_gdb.py.gdb-autoload-safepath Python-2.7.3/Lib/test/test_gdb.py +--- Python-2.7.3/Lib/test/test_gdb.py.gdb-autoload-safepath 2012-04-30 15:53:57.254045220 -0400 ++++ Python-2.7.3/Lib/test/test_gdb.py 2012-04-30 16:19:19.569941124 -0400 +@@ -54,6 +54,19 @@ def gdb_has_frame_select(): + + HAS_PYUP_PYDOWN = gdb_has_frame_select() + ++def gdb_has_autoload_safepath(): ++ # Recent GDBs will only auto-load scripts from certain safe ++ # locations, so we will need to turn off this protection. ++ # However, if the GDB doesn't have it, then the following ++ # command will generate noise on stderr (rhbz#817072): ++ cmd = "--eval-command=set auto-load safe-path /" ++ p = subprocess.Popen(["gdb", "--batch", cmd], ++ stderr=subprocess.PIPE) ++ _, stderr = p.communicate() ++ return '"on" or "off" expected.' not in stderr ++ ++HAS_AUTOLOAD_SAFEPATH = gdb_has_autoload_safepath() ++ + class DebuggerTests(unittest.TestCase): + + """Test that the debugger can debug Python.""" +diff -up Python-2.7.10/Lib/test/test_gdb.py.ms Python-2.7.10/Lib/test/test_gdb.py +--- Python-2.7.10/Lib/test/test_gdb.py.ms 2015-05-25 17:00:25.028462615 +0200 ++++ Python-2.7.10/Lib/test/test_gdb.py 2015-05-25 17:01:53.166359822 +0200 +@@ -153,6 +153,17 @@ class DebuggerTests(unittest.TestCase): + + 'run'] + ++ if HAS_AUTOLOAD_SAFEPATH: ++ # Recent GDBs will only auto-load scripts from certain safe ++ # locations. ++ # Where necessary, turn off this protection to ensure that ++ # our -gdb.py script can be loaded - but not on earlier gdb builds ++ # as this would generate noise on stderr (rhbz#817072): ++ init_commands = ['set auto-load safe-path /'] ++ else: ++ init_commands = [] ++ ++ + # GDB as of 7.4 onwards can distinguish between the + # value of a variable at entry vs current value: + # http://sourceware.org/gdb/onlinedocs/gdb/Variables.html +@@ -167,10 +178,11 @@ class DebuggerTests(unittest.TestCase): + else: + commands += ['backtrace'] + +- # print commands ++ # print init_commands + + # Use "commands" to generate the arguments with which to invoke "gdb": + args = ["gdb", "--batch", "-nx"] ++ args += ['--init-eval-command=%s' % cmd for cmd in init_commands] + args += ['--eval-command=%s' % cmd for cmd in commands] + args += ["--args", + sys.executable] diff --git a/SOURCES/00165-crypt-module-salt-backport.patch b/SOURCES/00165-crypt-module-salt-backport.patch new file mode 100644 index 0000000..0040aae --- /dev/null +++ b/SOURCES/00165-crypt-module-salt-backport.patch @@ -0,0 +1,292 @@ +diff --git a/Doc/library/crypt.rst b/Doc/library/crypt.rst +index 91464ef..6ee64d6 100644 +--- a/Doc/library/crypt.rst ++++ b/Doc/library/crypt.rst +@@ -16,9 +16,9 @@ + + This module implements an interface to the :manpage:`crypt(3)` routine, which is + a one-way hash function based upon a modified DES algorithm; see the Unix man +-page for further details. Possible uses include allowing Python scripts to +-accept typed passwords from the user, or attempting to crack Unix passwords with +-a dictionary. ++page for further details. Possible uses include storing hashed passwords ++so you can check passwords without storing the actual password, or attempting ++to crack Unix passwords with a dictionary. + + .. index:: single: crypt(3) + +@@ -27,15 +27,81 @@ the :manpage:`crypt(3)` routine in the running system. Therefore, any + extensions available on the current implementation will also be available on + this module. + ++Hashing Methods ++--------------- + +-.. function:: crypt(word, salt) ++The :mod:`crypt` module defines the list of hashing methods (not all methods ++are available on all platforms): ++ ++.. data:: METHOD_SHA512 ++ ++ A Modular Crypt Format method with 16 character salt and 86 character ++ hash. This is the strongest method. ++ ++.. versionadded:: 3.3 ++ ++.. data:: METHOD_SHA256 ++ ++ Another Modular Crypt Format method with 16 character salt and 43 ++ character hash. ++ ++.. versionadded:: 3.3 ++ ++.. data:: METHOD_MD5 ++ ++ Another Modular Crypt Format method with 8 character salt and 22 ++ character hash. ++ ++.. versionadded:: 3.3 ++ ++.. data:: METHOD_CRYPT ++ ++ The traditional method with a 2 character salt and 13 characters of ++ hash. This is the weakest method. ++ ++.. versionadded:: 3.3 ++ ++ ++Module Attributes ++----------------- ++ ++ ++.. attribute:: methods ++ ++ A list of available password hashing algorithms, as ++ ``crypt.METHOD_*`` objects. This list is sorted from strongest to ++ weakest, and is guaranteed to have at least ``crypt.METHOD_CRYPT``. ++ ++.. versionadded:: 3.3 ++ ++ ++Module Functions ++---------------- ++ ++The :mod:`crypt` module defines the following functions: ++ ++.. function:: crypt(word, salt=None) + + *word* will usually be a user's password as typed at a prompt or in a graphical +- interface. *salt* is usually a random two-character string which will be used +- to perturb the DES algorithm in one of 4096 ways. The characters in *salt* must +- be in the set ``[./a-zA-Z0-9]``. Returns the hashed password as a string, which +- will be composed of characters from the same alphabet as the salt (the first two +- characters represent the salt itself). ++ interface. The optional *salt* is either a string as returned from ++ :func:`mksalt`, one of the ``crypt.METHOD_*`` values (though not all ++ may be available on all platforms), or a full encrypted password ++ including salt, as returned by this function. If *salt* is not ++ provided, the strongest method will be used (as returned by ++ :func:`methods`. ++ ++ Checking a password is usually done by passing the plain-text password ++ as *word* and the full results of a previous :func:`crypt` call, ++ which should be the same as the results of this call. ++ ++ *salt* (either a random 2 or 16 character string, possibly prefixed with ++ ``$digit$`` to indicate the method) which will be used to perturb the ++ encryption algorithm. The characters in *salt* must be in the set ++ ``[./a-zA-Z0-9]``, with the exception of Modular Crypt Format which ++ prefixes a ``$digit$``. ++ ++ Returns the hashed password as a string, which will be composed of ++ characters from the same alphabet as the salt. + + .. index:: single: crypt(3) + +@@ -43,6 +109,27 @@ this module. + different sizes in the *salt*, it is recommended to use the full crypted + password as salt when checking for a password. + ++.. versionchanged:: 3.3 ++ Before version 3.3, *salt* must be specified as a string and cannot ++ accept ``crypt.METHOD_*`` values (which don't exist anyway). ++ ++ ++.. function:: mksalt(method=None) ++ ++ Return a randomly generated salt of the specified method. If no ++ *method* is given, the strongest method available as returned by ++ :func:`methods` is used. ++ ++ The return value is a string either of 2 characters in length for ++ ``crypt.METHOD_CRYPT``, or 19 characters starting with ``$digit$`` and ++ 16 random characters from the set ``[./a-zA-Z0-9]``, suitable for ++ passing as the *salt* argument to :func:`crypt`. ++ ++.. versionadded:: 3.3 ++ ++Examples ++-------- ++ + A simple example illustrating typical use:: + + import crypt, getpass, pwd +@@ -59,3 +146,11 @@ A simple example illustrating typical use:: + else: + return 1 + ++To generate a hash of a password using the strongest available method and ++check it against the original:: ++ ++ import crypt ++ ++ hashed = crypt.crypt(plaintext) ++ if hashed != crypt.crypt(plaintext, hashed): ++ raise "Hashed version doesn't validate against original" +diff --git a/Lib/crypt.py b/Lib/crypt.py +new file mode 100644 +index 0000000..bf0a416 +--- /dev/null ++++ b/Lib/crypt.py +@@ -0,0 +1,71 @@ ++"""Wrapper to the POSIX crypt library call and associated functionality. ++ ++Note that the ``methods`` and ``METHOD_*`` attributes are non-standard ++extensions to Python 2.7, backported from 3.3""" ++ ++import _crypt ++import string as _string ++from random import SystemRandom as _SystemRandom ++from collections import namedtuple as _namedtuple ++ ++ ++_saltchars = _string.ascii_letters + _string.digits + './' ++_sr = _SystemRandom() ++ ++ ++class _Method(_namedtuple('_Method', 'name ident salt_chars total_size')): ++ ++ """Class representing a salt method per the Modular Crypt Format or the ++ legacy 2-character crypt method.""" ++ ++ def __repr__(self): ++ return '' % self.name ++ ++ ++def mksalt(method=None): ++ """Generate a salt for the specified method. ++ ++ If not specified, the strongest available method will be used. ++ ++ This is a non-standard extension to Python 2.7, backported from 3.3 ++ """ ++ if method is None: ++ method = methods[0] ++ s = '$%s$' % method.ident if method.ident else '' ++ s += ''.join(_sr.sample(_saltchars, method.salt_chars)) ++ return s ++ ++ ++def crypt(word, salt=None): ++ """Return a string representing the one-way hash of a password, with a salt ++ prepended. ++ ++ If ``salt`` is not specified or is ``None``, the strongest ++ available method will be selected and a salt generated. Otherwise, ++ ``salt`` may be one of the ``crypt.METHOD_*`` values, or a string as ++ returned by ``crypt.mksalt()``. ++ ++ Note that these are non-standard extensions to Python 2.7's crypt.crypt() ++ entrypoint, backported from 3.3: the standard Python 2.7 crypt.crypt() ++ entrypoint requires two strings as the parameters, and does not support ++ keyword arguments. ++ """ ++ if salt is None or isinstance(salt, _Method): ++ salt = mksalt(salt) ++ return _crypt.crypt(word, salt) ++ ++ ++# available salting/crypto methods ++METHOD_CRYPT = _Method('CRYPT', None, 2, 13) ++METHOD_MD5 = _Method('MD5', '1', 8, 34) ++METHOD_SHA256 = _Method('SHA256', '5', 16, 63) ++METHOD_SHA512 = _Method('SHA512', '6', 16, 106) ++ ++methods = [] ++for _method in (METHOD_SHA512, METHOD_SHA256, METHOD_MD5): ++ _result = crypt('', _method) ++ if _result and len(_result) == _method.total_size: ++ methods.append(_method) ++methods.append(METHOD_CRYPT) ++del _result, _method ++ +diff --git a/Lib/test/test_crypt.py b/Lib/test/test_crypt.py +index 7cd9c71..b061a55 100644 +--- a/Lib/test/test_crypt.py ++++ b/Lib/test/test_crypt.py +@@ -16,6 +16,25 @@ class CryptTestCase(unittest.TestCase): + self.assertEqual(cr2, cr) + + ++ def test_salt(self): ++ self.assertEqual(len(crypt._saltchars), 64) ++ for method in crypt.methods: ++ salt = crypt.mksalt(method) ++ self.assertEqual(len(salt), ++ method.salt_chars + (3 if method.ident else 0)) ++ ++ def test_saltedcrypt(self): ++ for method in crypt.methods: ++ pw = crypt.crypt('assword', method) ++ self.assertEqual(len(pw), method.total_size) ++ pw = crypt.crypt('assword', crypt.mksalt(method)) ++ self.assertEqual(len(pw), method.total_size) ++ ++ def test_methods(self): ++ # Gurantee that METHOD_CRYPT is the last method in crypt.methods. ++ self.assertTrue(len(crypt.methods) >= 1) ++ self.assertEqual(crypt.METHOD_CRYPT, crypt.methods[-1]) ++ + def test_main(): + test_support.run_unittest(CryptTestCase) + +diff --git a/Modules/Setup.dist b/Modules/Setup.dist +index 2712f06..3ea4f0c 100644 +--- a/Modules/Setup.dist ++++ b/Modules/Setup.dist +@@ -225,7 +225,7 @@ _ssl _ssl.c \ + # + # First, look at Setup.config; configure may have set this for you. + +-crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems ++_crypt _cryptmodule.c -lcrypt # crypt(3); needs -lcrypt on some systems + + + # Some more UNIX dependent modules -- off by default, since these +diff --git a/Modules/cryptmodule.c b/Modules/cryptmodule.c +index 76de54f..7c69ca6 100644 +--- a/Modules/cryptmodule.c ++++ b/Modules/cryptmodule.c +@@ -43,7 +43,7 @@ static PyMethodDef crypt_methods[] = { + }; + + PyMODINIT_FUNC +-initcrypt(void) ++init_crypt(void) + { +- Py_InitModule("crypt", crypt_methods); ++ Py_InitModule("_crypt", crypt_methods); + } +diff --git a/setup.py b/setup.py +index b787487..c60ac35 100644 +--- a/setup.py ++++ b/setup.py +@@ -798,7 +798,7 @@ class PyBuildExt(build_ext): + libs = ['crypt'] + else: + libs = [] +- exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) ) ++ exts.append( Extension('_crypt', ['_cryptmodule.c'], libraries=libs) ) + + # CSV files + exts.append( Extension('_csv', ['_csv.c']) ) diff --git a/SOURCES/00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch b/SOURCES/00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch new file mode 100644 index 0000000..9807883 --- /dev/null +++ b/SOURCES/00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch @@ -0,0 +1,47 @@ +diff --git a/Lib/test/test_gdb.py b/Lib/test/test_gdb.py +index 3354b34..10ba0e5 100644 +--- a/Lib/test/test_gdb.py ++++ b/Lib/test/test_gdb.py +@@ -725,11 +725,10 @@ class PyListTests(DebuggerTests): + ' 2 \n' + ' 3 def foo(a, b, c):\n', + bt) +- ++@unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") ++@unittest.skipIf(python_is_optimized(), ++ "Python was compiled with optimizations") + class StackNavigationTests(DebuggerTests): +- @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") +- @unittest.skipIf(python_is_optimized(), +- "Python was compiled with optimizations") + def test_pyup_command(self): + 'Verify that the "py-up" command works' + bt = self.get_stack_trace(script=self.get_sample_script(), +@@ -740,7 +739,6 @@ class StackNavigationTests(DebuggerTests): + baz\(a, b, c\) + $''') + +- @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") + def test_down_at_bottom(self): + 'Verify handling of "py-down" at the bottom of the stack' + bt = self.get_stack_trace(script=self.get_sample_script(), +@@ -748,9 +746,6 @@ $''') + self.assertEndsWith(bt, + 'Unable to find a newer python frame\n') + +- @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") +- @unittest.skipIf(python_is_optimized(), +- "Python was compiled with optimizations") + def test_up_at_top(self): + 'Verify handling of "py-up" at the top of the stack' + bt = self.get_stack_trace(script=self.get_sample_script(), +@@ -758,9 +753,6 @@ $''') + self.assertEndsWith(bt, + 'Unable to find an older python frame\n') + +- @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") +- @unittest.skipIf(python_is_optimized(), +- "Python was compiled with optimizations") + def test_up_then_down(self): + 'Verify "py-up" followed by "py-down"' + bt = self.get_stack_trace(script=self.get_sample_script(), diff --git a/SOURCES/00169-avoid-implicit-usage-of-md5-in-multiprocessing.patch b/SOURCES/00169-avoid-implicit-usage-of-md5-in-multiprocessing.patch new file mode 100644 index 0000000..debf92f --- /dev/null +++ b/SOURCES/00169-avoid-implicit-usage-of-md5-in-multiprocessing.patch @@ -0,0 +1,41 @@ +diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py +--- a/Lib/multiprocessing/connection.py ++++ b/Lib/multiprocessing/connection.py +@@ -41,6 +41,10 @@ + # A very generous timeout when it comes to local connections... + CONNECTION_TIMEOUT = 20. + ++# The hmac module implicitly defaults to using MD5. ++# Support using a stronger algorithm for the challenge/response code: ++HMAC_DIGEST_NAME='sha256' ++ + _mmap_counter = itertools.count() + + default_family = 'AF_INET' +@@ -700,12 +704,16 @@ + WELCOME = b'#WELCOME#' + FAILURE = b'#FAILURE#' + ++def get_digestmod_for_hmac(): ++ import hashlib ++ return getattr(hashlib, HMAC_DIGEST_NAME) ++ + def deliver_challenge(connection, authkey): + import hmac + assert isinstance(authkey, bytes) + message = os.urandom(MESSAGE_LENGTH) + connection.send_bytes(CHALLENGE + message) +- digest = hmac.new(authkey, message).digest() ++ digest = hmac.new(authkey, message, get_digestmod_for_hmac()).digest() + response = connection.recv_bytes(256) # reject large message + if response == digest: + connection.send_bytes(WELCOME) +@@ -719,7 +727,7 @@ + message = connection.recv_bytes(256) # reject large message + assert message[:len(CHALLENGE)] == CHALLENGE, 'message = %r' % message + message = message[len(CHALLENGE):] +- digest = hmac.new(authkey, message).digest() ++ digest = hmac.new(authkey, message, get_digestmod_for_hmac()).digest() + connection.send_bytes(digest) + response = connection.recv_bytes(256) # reject large message + if response != WELCOME: diff --git a/SOURCES/00170-gc-assertions.patch b/SOURCES/00170-gc-assertions.patch new file mode 100644 index 0000000..9ade298 --- /dev/null +++ b/SOURCES/00170-gc-assertions.patch @@ -0,0 +1,279 @@ +diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py +index 7e47b2d..12a210d 100644 +--- a/Lib/test/test_gc.py ++++ b/Lib/test/test_gc.py +@@ -1,7 +1,8 @@ + import unittest + from test.support import (verbose, run_unittest, start_threads, +- requires_type_collecting) ++ requires_type_collecting, import_module) + import sys ++import sysconfig + import time + import gc + import weakref +@@ -39,6 +40,8 @@ class GC_Detector(object): + self.wr = weakref.ref(C1055820(666), it_happened) + + ++BUILT_WITH_NDEBUG = ('-DNDEBUG' in sysconfig.get_config_vars()['PY_CFLAGS']) ++ + ### Tests + ############################################################################### + +@@ -537,6 +540,49 @@ class GCTests(unittest.TestCase): + # would be damaged, with an empty __dict__. + self.assertEqual(x, None) + ++ @unittest.skipIf(BUILT_WITH_NDEBUG, ++ 'built with -NDEBUG') ++ def test_refcount_errors(self): ++ # Verify the "handling" of objects with broken refcounts ++ ++ import_module("ctypes") #skip if not supported ++ ++ import subprocess ++ code = '''if 1: ++ a = [] ++ b = [a] ++ ++ # Simulate the refcount of "a" being too low (compared to the ++ # references held on it by live data), but keeping it above zero ++ # (to avoid deallocating it): ++ import ctypes ++ ctypes.pythonapi.Py_DecRef(ctypes.py_object(a)) ++ ++ # The garbage collector should now have a fatal error when it reaches ++ # the broken object: ++ import gc ++ gc.collect() ++ ''' ++ p = subprocess.Popen([sys.executable, "-c", code], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE) ++ stdout, stderr = p.communicate() ++ p.stdout.close() ++ p.stderr.close() ++ # Verify that stderr has a useful error message: ++ self.assertRegexpMatches(stderr, ++ b'Modules/gcmodule.c:[0-9]+: visit_decref: Assertion "gc->gc.gc_refs != 0" failed.') ++ self.assertRegexpMatches(stderr, ++ b'refcount was too small') ++ self.assertRegexpMatches(stderr, ++ b'object : \[\]') ++ self.assertRegexpMatches(stderr, ++ b'type : list') ++ self.assertRegexpMatches(stderr, ++ b'refcount: 1') ++ self.assertRegexpMatches(stderr, ++ b'address : 0x[0-9a-f]+') ++ + class GCTogglingTests(unittest.TestCase): + def setUp(self): + gc.enable() +diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c +index 916e481..0233ce2 100644 +--- a/Modules/gcmodule.c ++++ b/Modules/gcmodule.c +@@ -21,6 +21,73 @@ + #include "Python.h" + #include "frameobject.h" /* for PyFrame_ClearFreeList */ + ++/* ++ Define a pair of assertion macros. ++ ++ These work like the regular C assert(), in that they will abort the ++ process with a message on stderr if the given condition fails to hold, ++ but compile away to nothing if NDEBUG is defined. ++ ++ However, before aborting, Python will also try to call _PyObject_Dump() on ++ the given object. This may be of use when investigating bugs in which a ++ particular object is corrupt (e.g. buggy a tp_visit method in an extension ++ module breaking the garbage collector), to help locate the broken objects. ++ ++ The WITH_MSG variant allows you to supply an additional message that Python ++ will attempt to print to stderr, after the object dump. ++*/ ++#ifdef NDEBUG ++/* No debugging: compile away the assertions: */ ++#define PyObject_ASSERT_WITH_MSG(obj, expr, msg) ((void)0) ++#else ++/* With debugging: generate checks: */ ++#define PyObject_ASSERT_WITH_MSG(obj, expr, msg) \ ++ ((expr) \ ++ ? (void)(0) \ ++ : _PyObject_AssertFailed((obj), \ ++ (msg), \ ++ (__STRING(expr)), \ ++ (__FILE__), \ ++ (__LINE__), \ ++ (__PRETTY_FUNCTION__))) ++#endif ++ ++#define PyObject_ASSERT(obj, expr) \ ++ PyObject_ASSERT_WITH_MSG(obj, expr, NULL) ++ ++static void _PyObject_AssertFailed(PyObject *, const char *, ++ const char *, const char *, int, ++ const char *); ++ ++static void ++_PyObject_AssertFailed(PyObject *obj, const char *msg, const char *expr, ++ const char *file, int line, const char *function) ++{ ++ fprintf(stderr, ++ "%s:%d: %s: Assertion \"%s\" failed.\n", ++ file, line, function, expr); ++ if (msg) { ++ fprintf(stderr, "%s\n", msg); ++ } ++ ++ fflush(stderr); ++ ++ if (obj) { ++ /* This might succeed or fail, but we're about to abort, so at least ++ try to provide any extra info we can: */ ++ _PyObject_Dump(obj); ++ } ++ else { ++ fprintf(stderr, "NULL object\n"); ++ } ++ ++ fflush(stdout); ++ fflush(stderr); ++ ++ /* Terminate the process: */ ++ abort(); ++} ++ + /* Get an object's GC head */ + #define AS_GC(o) ((PyGC_Head *)(o)-1) + +@@ -328,7 +395,8 @@ update_refs(PyGC_Head *containers) + { + PyGC_Head *gc = containers->gc.gc_next; + for (; gc != containers; gc = gc->gc.gc_next) { +- assert(gc->gc.gc_refs == GC_REACHABLE); ++ PyObject_ASSERT(FROM_GC(gc), ++ gc->gc.gc_refs == GC_REACHABLE); + gc->gc.gc_refs = Py_REFCNT(FROM_GC(gc)); + /* Python's cyclic gc should never see an incoming refcount + * of 0: if something decref'ed to 0, it should have been +@@ -348,7 +416,8 @@ update_refs(PyGC_Head *containers) + * so serious that maybe this should be a release-build + * check instead of an assert? + */ +- assert(gc->gc.gc_refs != 0); ++ PyObject_ASSERT(FROM_GC(gc), ++ gc->gc.gc_refs != 0); + } + } + +@@ -363,7 +432,9 @@ visit_decref(PyObject *op, void *data) + * generation being collected, which can be recognized + * because only they have positive gc_refs. + */ +- assert(gc->gc.gc_refs != 0); /* else refcount was too small */ ++ PyObject_ASSERT_WITH_MSG(FROM_GC(gc), ++ gc->gc.gc_refs != 0, ++ "refcount was too small"); + if (gc->gc.gc_refs > 0) + gc->gc.gc_refs--; + } +@@ -423,9 +494,10 @@ visit_reachable(PyObject *op, PyGC_Head *reachable) + * If gc_refs == GC_UNTRACKED, it must be ignored. + */ + else { +- assert(gc_refs > 0 +- || gc_refs == GC_REACHABLE +- || gc_refs == GC_UNTRACKED); ++ PyObject_ASSERT(FROM_GC(gc), ++ gc_refs > 0 ++ || gc_refs == GC_REACHABLE ++ || gc_refs == GC_UNTRACKED); + } + } + return 0; +@@ -467,7 +539,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) + */ + PyObject *op = FROM_GC(gc); + traverseproc traverse = Py_TYPE(op)->tp_traverse; +- assert(gc->gc.gc_refs > 0); ++ PyObject_ASSERT(op, gc->gc.gc_refs > 0); + gc->gc.gc_refs = GC_REACHABLE; + (void) traverse(op, + (visitproc)visit_reachable, +@@ -545,7 +617,8 @@ move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) + for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) { + PyObject *op = FROM_GC(gc); + +- assert(IS_TENTATIVELY_UNREACHABLE(op)); ++ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op)); ++ + next = gc->gc.gc_next; + + if (has_finalizer(op)) { +@@ -621,7 +694,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) + PyWeakReference **wrlist; + + op = FROM_GC(gc); +- assert(IS_TENTATIVELY_UNREACHABLE(op)); ++ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op)); + next = gc->gc.gc_next; + + if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) +@@ -642,9 +715,9 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) + * the callback pointer intact. Obscure: it also + * changes *wrlist. + */ +- assert(wr->wr_object == op); ++ PyObject_ASSERT(wr->wr_object, wr->wr_object == op); + _PyWeakref_ClearRef(wr); +- assert(wr->wr_object == Py_None); ++ PyObject_ASSERT(wr->wr_object, wr->wr_object == Py_None); + if (wr->wr_callback == NULL) + continue; /* no callback */ + +@@ -678,7 +751,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) + */ + if (IS_TENTATIVELY_UNREACHABLE(wr)) + continue; +- assert(IS_REACHABLE(wr)); ++ PyObject_ASSERT(op, IS_REACHABLE(wr)); + + /* Create a new reference so that wr can't go away + * before we can process it again. +@@ -687,7 +760,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) + + /* Move wr to wrcb_to_call, for the next pass. */ + wrasgc = AS_GC(wr); +- assert(wrasgc != next); /* wrasgc is reachable, but ++ PyObject_ASSERT(op, wrasgc != next); ++ /* wrasgc is reachable, but + next isn't, so they can't + be the same */ + gc_list_move(wrasgc, &wrcb_to_call); +@@ -703,11 +777,11 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) + + gc = wrcb_to_call.gc.gc_next; + op = FROM_GC(gc); +- assert(IS_REACHABLE(op)); +- assert(PyWeakref_Check(op)); ++ PyObject_ASSERT(op, IS_REACHABLE(op)); ++ PyObject_ASSERT(op, PyWeakref_Check(op)); + wr = (PyWeakReference *)op; + callback = wr->wr_callback; +- assert(callback != NULL); ++ PyObject_ASSERT(op, callback != NULL); + + /* copy-paste of weakrefobject.c's handle_callback() */ + temp = PyObject_CallFunctionObjArgs(callback, wr, NULL); +@@ -810,7 +884,7 @@ delete_garbage(PyGC_Head *collectable, PyGC_Head *old) + PyGC_Head *gc = collectable->gc.gc_next; + PyObject *op = FROM_GC(gc); + +- assert(IS_TENTATIVELY_UNREACHABLE(op)); ++ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op)); + if (debug & DEBUG_SAVEALL) { + PyList_Append(garbage, op); + } diff --git a/SOURCES/00174-fix-for-usr-move.patch b/SOURCES/00174-fix-for-usr-move.patch new file mode 100644 index 0000000..b48dc5c --- /dev/null +++ b/SOURCES/00174-fix-for-usr-move.patch @@ -0,0 +1,28 @@ +diff -up Python-2.7.3/Modules/getpath.c.fix-for-usr-move Python-2.7.3/Modules/getpath.c +--- Python-2.7.3/Modules/getpath.c.fix-for-usr-move 2013-03-06 14:25:32.801828698 -0500 ++++ Python-2.7.3/Modules/getpath.c 2013-03-06 15:59:30.872443168 -0500 +@@ -510,6 +510,24 @@ calculate_path(void) + MAXPATHLEN bytes long. + */ + ++ /* ++ Workaround for rhbz#817554, where an empty argv0_path erroneously ++ locates "prefix" as "/lib[64]/python2.7" due to it finding ++ "/lib[64]/python2.7/os.py" via the /lib -> /usr/lib symlink for ++ https://fedoraproject.org/wiki/Features/UsrMove ++ */ ++ if (argv0_path[0] == '\0' && 0 == strcmp(prog, "cmpi_swig")) { ++ /* ++ We have an empty argv0_path, presumably because prog aka ++ Py_GetProgramName() was not found on $PATH. ++ ++ Set argv0_path to "/usr/" so that search_for_prefix() and ++ search_for_exec_prefix() don't erroneously pick up ++ on /lib/ via the UsrMove symlink: ++ */ ++ strcpy(argv0_path, "/usr/"); ++ } ++ + if (!(pfound = search_for_prefix(argv0_path, home))) { + if (!Py_FrozenFlag) + fprintf(stderr, diff --git a/SOURCES/00180-python-add-support-for-ppc64p7.patch b/SOURCES/00180-python-add-support-for-ppc64p7.patch new file mode 100644 index 0000000..ef94c86 --- /dev/null +++ b/SOURCES/00180-python-add-support-for-ppc64p7.patch @@ -0,0 +1,13 @@ +diff --git a/config.sub b/config.sub +index 3478c1f..e422173 100755 +--- a/config.sub ++++ b/config.sub +@@ -1040,7 +1040,7 @@ case $basic_machine in + ;; + ppc64) basic_machine=powerpc64-unknown + ;; +- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ++ ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown diff --git a/SOURCES/00181-allow-arbitrary-timeout-in-condition-wait.patch b/SOURCES/00181-allow-arbitrary-timeout-in-condition-wait.patch new file mode 100644 index 0000000..757c7dd --- /dev/null +++ b/SOURCES/00181-allow-arbitrary-timeout-in-condition-wait.patch @@ -0,0 +1,70 @@ +diff --git a/Lib/threading.py b/Lib/threading.py +index cb49c4a..c9795a5 100644 +--- a/Lib/threading.py ++++ b/Lib/threading.py +@@ -305,7 +305,7 @@ class _Condition(_Verbose): + else: + return True + +- def wait(self, timeout=None): ++ def wait(self, timeout=None, balancing=True): + """Wait until notified or until a timeout occurs. + + If the calling thread has not acquired the lock when this method is +@@ -354,7 +354,10 @@ class _Condition(_Verbose): + remaining = endtime - _time() + if remaining <= 0: + break +- delay = min(delay * 2, remaining, .05) ++ if balancing: ++ delay = min(delay * 2, remaining, 0.05) ++ else: ++ delay = remaining + _sleep(delay) + if not gotit: + if __debug__: +@@ -599,7 +602,7 @@ class _Event(_Verbose): + with self.__cond: + self.__flag = False + +- def wait(self, timeout=None): ++ def wait(self, timeout=None, balancing=True): + """Block until the internal flag is true. + + If the internal flag is true on entry, return immediately. Otherwise, +@@ -617,7 +620,7 @@ class _Event(_Verbose): + """ + with self.__cond: + if not self.__flag: +- self.__cond.wait(timeout) ++ self.__cond.wait(timeout, balancing) + return self.__flag + + # Helper to generate new thread names +@@ -908,7 +911,7 @@ class Thread(_Verbose): + if 'dummy_threading' not in _sys.modules: + raise + +- def join(self, timeout=None): ++ def join(self, timeout=None, balancing=True): + """Wait until the thread terminates. + + This blocks the calling thread until the thread whose join() method is +@@ -957,7 +960,7 @@ class Thread(_Verbose): + if __debug__: + self._note("%s.join(): timed out", self) + break +- self.__block.wait(delay) ++ self.__block.wait(delay, balancing) + else: + if __debug__: + self._note("%s.join(): thread stopped", self) +@@ -1143,7 +1146,7 @@ class _DummyThread(Thread): + def _set_daemon(self): + return True + +- def join(self, timeout=None): ++ def join(self, timeout=None, balancing=True): + assert False, "cannot join a dummy thread" + + diff --git a/SOURCES/00185-urllib2-honors-noproxy-for-ftp.patch b/SOURCES/00185-urllib2-honors-noproxy-for-ftp.patch new file mode 100644 index 0000000..b26c4d4 --- /dev/null +++ b/SOURCES/00185-urllib2-honors-noproxy-for-ftp.patch @@ -0,0 +1,12 @@ +diff -up Python-2.7.5/Lib/urllib2.py.orig Python-2.7.5/Lib/urllib2.py +--- Python-2.7.5/Lib/urllib2.py.orig 2013-07-17 12:22:58.595525622 +0200 ++++ Python-2.7.5/Lib/urllib2.py 2013-07-17 12:19:59.875898030 +0200 +@@ -728,6 +728,8 @@ class ProxyHandler(BaseHandler): + if proxy_type is None: + proxy_type = orig_type + ++ req.get_host() ++ + if req.host and proxy_bypass(req.host): + return None + diff --git a/SOURCES/00187-add-RPATH-to-pyexpat.patch b/SOURCES/00187-add-RPATH-to-pyexpat.patch new file mode 100644 index 0000000..0ac5227 --- /dev/null +++ b/SOURCES/00187-add-RPATH-to-pyexpat.patch @@ -0,0 +1,25 @@ +diff -r e8b8279ca118 setup.py +--- a/setup.py Sun Jul 21 21:57:52 2013 -0400 ++++ b/setup.py Tue Aug 20 09:45:31 2013 +0200 +@@ -1480,12 +1480,21 @@ + 'expat/xmltok_impl.h' + ] + ++ # Add an explicit RPATH to pyexpat.so pointing at the directory ++ # containing the system expat (which has the extra XML_SetHashSalt ++ # symbol), to avoid an ImportError with a link error if there's an ++ # LD_LIBRARY_PATH containing a "vanilla" build of expat (without the ++ # symbol) (rhbz#833271): ++ EXPAT_RPATH = '/usr/lib64' if sys.maxint == 0x7fffffffffffffff else '/usr/lib' ++ ++ + exts.append(Extension('pyexpat', + define_macros = define_macros, + include_dirs = expat_inc, + libraries = expat_lib, + sources = ['pyexpat.c'] + expat_sources, + depends = expat_depends, ++ extra_link_args = ['-Wl,-rpath,%s' % EXPAT_RPATH] + )) + + # Fredrik Lundh's cElementTree module. Note that this also diff --git a/SOURCES/00191-disable-NOOP.patch b/SOURCES/00191-disable-NOOP.patch new file mode 100644 index 0000000..2d4189a --- /dev/null +++ b/SOURCES/00191-disable-NOOP.patch @@ -0,0 +1,12 @@ +diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py +index 1bb6690..28ed25d 100644 +--- a/Lib/test/test_smtplib.py ++++ b/Lib/test/test_smtplib.py +@@ -182,6 +182,7 @@ class DebuggingServerTests(unittest.TestCase): + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) + smtp.quit() + ++ @unittest._skipInRpmBuild("Does not work in network-free environment") + def testNOOP(self): + smtp = smtplib.SMTP(HOST, self.port, local_hostname='localhost', timeout=15) + expected = (250, 'Ok') diff --git a/SOURCES/00193-enable-loading-sqlite-extensions.patch b/SOURCES/00193-enable-loading-sqlite-extensions.patch new file mode 100644 index 0000000..36d053a --- /dev/null +++ b/SOURCES/00193-enable-loading-sqlite-extensions.patch @@ -0,0 +1,11 @@ +--- Python-2.7.5/setup.py.orig 2013-05-11 20:32:54.000000000 -0700 ++++ Python-2.7.5/setup.py 2014-02-18 14:16:07.999004901 -0800 +@@ -1168,7 +1168,7 @@ class PyBuildExt(build_ext): + sqlite_defines.append(('MODULE_NAME', '\\"sqlite3\\"')) + + # Comment this out if you want the sqlite3 module to be able to load extensions. +- sqlite_defines.append(("SQLITE_OMIT_LOAD_EXTENSION", "1")) ++ #sqlite_defines.append(("SQLITE_OMIT_LOAD_EXTENSION", "1")) + + if host_platform == 'darwin': + # In every directory on the search path search for a dynamic diff --git a/SOURCES/00198-add-rewheel-module.patch b/SOURCES/00198-add-rewheel-module.patch new file mode 100644 index 0000000..b39f9f3 --- /dev/null +++ b/SOURCES/00198-add-rewheel-module.patch @@ -0,0 +1,249 @@ +diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py +index 5021ebf..63c763a 100644 +--- a/Lib/ensurepip/__init__.py ++++ b/Lib/ensurepip/__init__.py +@@ -7,6 +7,7 @@ import pkgutil + import shutil + import sys + import tempfile ++from ensurepip import rewheel + + + __all__ = ["version", "bootstrap"] +@@ -29,6 +30,8 @@ def _run_pip(args, additional_paths=None): + + # Install the bundled software + import pip._internal ++ if args[0] in ["install", "list", "wheel"]: ++ args.append('--pre') + return pip._internal.main(args) + + +@@ -93,21 +96,40 @@ def _bootstrap(root=None, upgrade=False, user=False, + # omit pip and easy_install + os.environ["ENSUREPIP_OPTIONS"] = "install" + ++ whls = [] ++ rewheel_dir = None ++ # try to see if we have system-wide versions of _PROJECTS ++ dep_records = rewheel.find_system_records([p[0] for p in _PROJECTS]) ++ # TODO: check if system-wide versions are the newest ones ++ # if --upgrade is used? ++ if all(dep_records): ++ # if we have all _PROJECTS installed system-wide, we'll recreate ++ # wheels from them and install those ++ rewheel_dir = tempfile.mkdtemp() ++ for dr in dep_records: ++ new_whl = rewheel.rewheel_from_record(dr, rewheel_dir) ++ whls.append(os.path.join(rewheel_dir, new_whl)) ++ else: ++ # if we don't have all the _PROJECTS installed system-wide, ++ # let's just fall back to bundled wheels ++ for project, version in _PROJECTS: ++ whl = os.path.join( ++ os.path.dirname(__file__), ++ "_bundled", ++ "{}-{}-py2.py3-none-any.whl".format(project, version) ++ ) ++ whls.append(whl) ++ + tmpdir = tempfile.mkdtemp() + try: + # Put our bundled wheels into a temporary directory and construct the + # additional paths that need added to sys.path + additional_paths = [] +- for project, version in _PROJECTS: +- wheel_name = "{}-{}-py2.py3-none-any.whl".format(project, version) +- whl = pkgutil.get_data( +- "ensurepip", +- "_bundled/{}".format(wheel_name), +- ) +- with open(os.path.join(tmpdir, wheel_name), "wb") as fp: +- fp.write(whl) +- +- additional_paths.append(os.path.join(tmpdir, wheel_name)) ++ for whl in whls: ++ shutil.copy(whl, tmpdir) ++ additional_paths.append(os.path.join(tmpdir, os.path.basename(whl))) ++ if rewheel_dir: ++ shutil.rmtree(rewheel_dir) + + # Construct the arguments to be passed to the pip command + args = ["install", "--no-index", "--find-links", tmpdir] +diff --git a/Lib/ensurepip/rewheel/__init__.py b/Lib/ensurepip/rewheel/__init__.py +new file mode 100644 +index 0000000..75c2094 +--- /dev/null ++++ b/Lib/ensurepip/rewheel/__init__.py +@@ -0,0 +1,158 @@ ++import argparse ++import codecs ++import csv ++import email.parser ++import os ++import io ++import re ++import site ++import subprocess ++import sys ++import zipfile ++ ++def run(): ++ parser = argparse.ArgumentParser(description='Recreate wheel of package with given RECORD.') ++ parser.add_argument('record_path', ++ help='Path to RECORD file') ++ parser.add_argument('-o', '--output-dir', ++ help='Dir where to place the wheel, defaults to current working dir.', ++ dest='outdir', ++ default=os.path.curdir) ++ ++ ns = parser.parse_args() ++ retcode = 0 ++ try: ++ print(rewheel_from_record(**vars(ns))) ++ except BaseException as e: ++ print('Failed: {}'.format(e)) ++ retcode = 1 ++ sys.exit(1) ++ ++def find_system_records(projects): ++ """Return list of paths to RECORD files for system-installed projects. ++ ++ If a project is not installed, the resulting list contains None instead ++ of a path to its RECORD ++ """ ++ records = [] ++ # get system site-packages dirs ++ if hasattr(sys, 'real_prefix'): ++ #we are in python2 virtualenv and sys.real_prefix is the original sys.prefix ++ _orig_prefixes = site.PREFIXES ++ setattr(site, 'PREFIXES', [sys.real_prefix]*2) ++ sys_sitepack = site.getsitepackages() ++ setattr(site, 'PREFIXES', _orig_prefixes) ++ elif hasattr(sys, 'base_prefix'): # python3 venv doesn't inject real_prefix to sys ++ # we are on python3 and base(_exec)_prefix is unchanged in venv ++ sys_sitepack = site.getsitepackages([sys.base_prefix, sys.base_exec_prefix]) ++ else: ++ # we are in python2 without virtualenv ++ sys_sitepack = site.getsitepackages() ++ ++ sys_sitepack = [sp for sp in sys_sitepack if os.path.exists(sp)] ++ # try to find all projects in all system site-packages ++ for project in projects: ++ path = None ++ for sp in sys_sitepack: ++ dist_info_re = os.path.join(sp, project) + '-[^\{0}]+\.dist-info'.format(os.sep) ++ candidates = [os.path.join(sp, p) for p in os.listdir(sp)] ++ # filter out candidate dirs based on the above regexp ++ filtered = [c for c in candidates if re.match(dist_info_re, c)] ++ # if we have 0 or 2 or more dirs, something is wrong... ++ if len(filtered) == 1: ++ path = filtered[0] ++ if path is not None: ++ records.append(os.path.join(path, 'RECORD')) ++ else: ++ records.append(None) ++ return records ++ ++def rewheel_from_record(record_path, outdir): ++ """Recreates a whee of package with given record_path and returns path ++ to the newly created wheel.""" ++ site_dir = os.path.dirname(os.path.dirname(record_path)) ++ record_relpath = record_path[len(site_dir):].strip(os.path.sep) ++ to_write, to_omit = get_records_to_pack(site_dir, record_relpath) ++ new_wheel_name = get_wheel_name(record_path) ++ new_wheel_path = os.path.join(outdir, new_wheel_name + '.whl') ++ ++ new_wheel = zipfile.ZipFile(new_wheel_path, mode='w', compression=zipfile.ZIP_DEFLATED) ++ # we need to write a new record with just the files that we will write, ++ # e.g. not binaries and *.pyc/*.pyo files ++ if sys.version_info[0] < 3: ++ new_record = io.BytesIO() ++ else: ++ new_record = io.StringIO() ++ writer = csv.writer(new_record) ++ ++ # handle files that we can write straight away ++ for f, sha_hash, size in to_write: ++ new_wheel.write(os.path.join(site_dir, f), arcname=f) ++ writer.writerow([f, sha_hash,size]) ++ ++ # rewrite the old wheel file with a new computed one ++ writer.writerow([record_relpath, '', '']) ++ new_wheel.writestr(record_relpath, new_record.getvalue()) ++ ++ new_wheel.close() ++ ++ return new_wheel.filename ++ ++def get_wheel_name(record_path): ++ """Return proper name of the wheel, without .whl.""" ++ ++ wheel_info_path = os.path.join(os.path.dirname(record_path), 'WHEEL') ++ with codecs.open(wheel_info_path, encoding='utf-8') as wheel_info_file: ++ wheel_info = email.parser.Parser().parsestr(wheel_info_file.read().encode('utf-8')) ++ ++ metadata_path = os.path.join(os.path.dirname(record_path), 'METADATA') ++ with codecs.open(metadata_path, encoding='utf-8') as metadata_file: ++ metadata = email.parser.Parser().parsestr(metadata_file.read().encode('utf-8')) ++ ++ # construct name parts according to wheel spec ++ distribution = metadata.get('Name') ++ version = metadata.get('Version') ++ build_tag = '' # nothing for now ++ lang_tag = [] ++ for t in wheel_info.get_all('Tag'): ++ lang_tag.append(t.split('-')[0]) ++ lang_tag = '.'.join(lang_tag) ++ abi_tag, plat_tag = wheel_info.get('Tag').split('-')[1:3] ++ # leave out build tag, if it is empty ++ to_join = filter(None, [distribution, version, build_tag, lang_tag, abi_tag, plat_tag]) ++ return '-'.join(list(to_join)) ++ ++def get_records_to_pack(site_dir, record_relpath): ++ """Accepts path of sitedir and path of RECORD file relative to it. ++ Returns two lists: ++ - list of files that can be written to new RECORD straight away ++ - list of files that shouldn't be written or need some processing ++ (pyc and pyo files, scripts) ++ """ ++ record_file_path = os.path.join(site_dir, record_relpath) ++ with codecs.open(record_file_path, encoding='utf-8') as record_file: ++ record_contents = record_file.read() ++ # temporary fix for https://github.com/pypa/pip/issues/1376 ++ # we need to ignore files under ".data" directory ++ data_dir = os.path.dirname(record_relpath).strip(os.path.sep) ++ data_dir = data_dir[:-len('dist-info')] + 'data' ++ ++ to_write = [] ++ to_omit = [] ++ for l in record_contents.splitlines(): ++ spl = l.split(',') ++ if len(spl) == 3: ++ # new record will omit (or write differently): ++ # - abs paths, paths with ".." (entry points), ++ # - pyc+pyo files ++ # - the old RECORD file ++ # TODO: is there any better way to recognize an entry point? ++ if os.path.isabs(spl[0]) or spl[0].startswith('..') or \ ++ spl[0].endswith('.pyc') or spl[0].endswith('.pyo') or \ ++ spl[0] == record_relpath or spl[0].startswith(data_dir): ++ to_omit.append(spl) ++ else: ++ to_write.append(spl) ++ else: ++ pass # bad RECORD or empty line ++ return to_write, to_omit +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 877698c..2c43611 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -1065,7 +1065,7 @@ LIBSUBDIRS= lib-tk lib-tk/test lib-tk/test/test_tkinter \ + test/tracedmodules \ + encodings compiler hotshot \ + email email/mime email/test email/test/data \ +- ensurepip ensurepip/_bundled \ ++ ensurepip ensurepip/_bundled ensurepip/rewheel\ + json json/tests \ + sqlite3 sqlite3/test \ + logging bsddb bsddb/test csv importlib wsgiref \ 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/00288-disable-python2.patch b/SOURCES/00288-disable-python2.patch new file mode 100644 index 0000000..84a9e9f --- /dev/null +++ b/SOURCES/00288-disable-python2.patch @@ -0,0 +1,52 @@ +--- Python-2.7.15-orig/Python/pythonrun.c ++++ Python-2.7.15/Python/pythonrun.c +@@ -180,6 +182,49 @@ + char buf[128]; + #endif + extern void _Py_ReadyTypes(void); ++ char *py2_allow_flag = getenv("RHEL_ALLOW_PYTHON2_FOR_BUILD"); ++ ++ // Fail unless a specific workaround is applied ++ if ((!py2_allow_flag || strcmp(py2_allow_flag, "1") != 0) ++ && (strstr(Py_GetProgramName(), "for-tests") == NULL) ++ ) { ++ fprintf(stderr, ++ "\n" ++ "ERROR: Python 2 is disabled in RHEL8.\n" ++ "\n" ++ "- For guidance on porting to Python 3, see the\n" ++ " Conservative Python3 Porting Guide:\n" ++ " http://portingguide.readthedocs.io/\n" ++ "\n" ++ "- If you need Python 2 at runtime:\n" ++ " - Use the python27 module\n" ++ "\n" ++ "- If you do not have access to BZ#1533919:\n" ++ " - Use the python27 module\n" ++ "\n" ++ "- If you need to use Python 2 only at RPM build time:\n" ++ " - File a bug blocking BZ#1533919:\n" ++ " https://bugzilla.redhat.com/show_bug.cgi?id=1533919\n" ++ " - Set the environment variable RHEL_ALLOW_PYTHON2_FOR_BUILD=1\n" ++ " (Note that if you do not file the bug as above,\n" ++ " this workaround will break without warning in the future.)\n" ++ "\n" ++ "- If you need to use Python 2 only for tests:\n" ++ " - File a bug blocking BZ#1533919:\n" ++ " https://bugzilla.redhat.com/show_bug.cgi?id=1533919\n" ++ " (If your test tool does not have a Bugzilla component,\n" ++ " feel free to use `python2`.)\n" ++ " - Use /usr/bin/python2-for-tests instead of python2 to run\n" ++ " your tests.\n" ++ " (Note that if you do not file the bug as above,\n" ++ " this workaround will break without warning in the future.)\n" ++ "\n" ++ "For details, see https://hurl.corp.redhat.com/rhel8-py2\n" ++ "\n" ++ ); ++ fflush(stderr); ++ Py_FatalError("Python 2 is disabled"); ++ } + + if (initialized) + return; diff --git a/SOURCES/00289-disable-nis-detection.patch b/SOURCES/00289-disable-nis-detection.patch new file mode 100644 index 0000000..4e185bb --- /dev/null +++ b/SOURCES/00289-disable-nis-detection.patch @@ -0,0 +1,69 @@ +diff --git a/setup.py b/setup.py +index 585e380..9993f11 100644 +--- a/setup.py ++++ b/setup.py +@@ -1346,11 +1346,7 @@ class PyBuildExt(build_ext): + else: + missing.append('resource') + +- nis = self._detect_nis(inc_dirs, lib_dirs) +- if nis is not None: +- exts.append(nis) +- else: +- missing.append('nis') ++ # nis (Sun yellow pages) is handled in Setup.dist + + # Curses support, requiring the System V version of curses, often + # provided by the ncurses library. +@@ -2162,51 +2158,6 @@ class PyBuildExt(build_ext): + # for dlopen, see bpo-32647 + ext.libraries.append('dl') + +- def _detect_nis(self, inc_dirs, lib_dirs): +- if host_platform in {'win32', 'cygwin', 'qnx6'}: +- return None +- +- libs = [] +- library_dirs = [] +- includes_dirs = [] +- +- # bpo-32521: glibc has deprecated Sun RPC for some time. Fedora 28 +- # moved headers and libraries to libtirpc and libnsl. The headers +- # are in tircp and nsl sub directories. +- rpcsvc_inc = find_file( +- 'rpcsvc/yp_prot.h', inc_dirs, +- [os.path.join(inc_dir, 'nsl') for inc_dir in inc_dirs] +- ) +- rpc_inc = find_file( +- 'rpc/rpc.h', inc_dirs, +- [os.path.join(inc_dir, 'tirpc') for inc_dir in inc_dirs] +- ) +- if rpcsvc_inc is None or rpc_inc is None: +- # not found +- return None +- includes_dirs.extend(rpcsvc_inc) +- includes_dirs.extend(rpc_inc) +- +- if self.compiler.find_library_file(lib_dirs, 'nsl'): +- libs.append('nsl') +- else: +- # libnsl-devel: check for libnsl in nsl/ subdirectory +- nsl_dirs = [os.path.join(lib_dir, 'nsl') for lib_dir in lib_dirs] +- libnsl = self.compiler.find_library_file(nsl_dirs, 'nsl') +- if libnsl is not None: +- library_dirs.append(os.path.dirname(libnsl)) +- libs.append('nsl') +- +- if self.compiler.find_library_file(lib_dirs, 'tirpc'): +- libs.append('tirpc') +- +- return Extension( +- 'nis', ['nismodule.c'], +- libraries=libs, +- library_dirs=library_dirs, +- include_dirs=includes_dirs +- ) +- + + class PyBuildInstall(install): + # Suppress the warning about installation into the lib_dynload diff --git a/SOURCES/04000-modularity-disable-tk.patch b/SOURCES/04000-modularity-disable-tk.patch new file mode 100644 index 0000000..a90f5a1 --- /dev/null +++ b/SOURCES/04000-modularity-disable-tk.patch @@ -0,0 +1,21 @@ +diff -urN Python-2.7.13/Modules/Setup.dist Python-2.7.13_modul/Modules/Setup.dist +--- Python-2.7.13/Modules/Setup.dist 2017-04-21 14:57:13.767444374 +0200 ++++ Python-2.7.13_modul/Modules/Setup.dist 2017-04-21 14:56:49.658953833 +0200 +@@ -326,7 +326,7 @@ + # every system. + + # *** Always uncomment this (leave the leading underscore in!): +-_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ ++#_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ + # *** Uncomment and edit to reflect where your Tcl/Tk libraries are: + # -L/usr/local/lib \ + # *** Uncomment and edit to reflect where your Tcl/Tk headers are: +@@ -345,7 +345,7 @@ + # *** Uncomment and edit for TOGL extension only: + # -DWITH_TOGL togl.c \ + # *** Uncomment and edit to reflect your Tcl/Tk versions: +- -ltk -ltcl \ ++# -ltk -ltcl \ + # *** Uncomment and edit to reflect where your X11 libraries are: + # -L/usr/X11R6/lib \ + # *** Or uncomment this for Solaris: diff --git a/SOURCES/05000-autotool-intermediates.patch b/SOURCES/05000-autotool-intermediates.patch new file mode 100644 index 0000000..dfe0257 --- /dev/null +++ b/SOURCES/05000-autotool-intermediates.patch @@ -0,0 +1,207 @@ +diff -up ./configure.autotool-intermediates ./configure +--- ./configure.autotool-intermediates 2013-04-09 11:24:01.024185796 +0200 ++++ ./configure 2013-04-09 11:24:01.780183954 +0200 +@@ -639,6 +639,8 @@ TRUE + MACHDEP_OBJS + DYNLOADFILE + DLINCLDIR ++DTRACEHDRS ++DTRACEOBJS + THREADOBJ + LDLAST + USE_THREAD_MODULE +@@ -659,6 +661,8 @@ OTHER_LIBTOOL_OPT + UNIVERSAL_ARCH_FLAGS + BASECFLAGS + OPT ++DEBUG_SUFFIX ++DEBUG_EXT + LN + MKDIR_P + INSTALL_DATA +@@ -795,8 +799,11 @@ with_pth + enable_ipv6 + with_doc_strings + with_tsc ++with_count_allocs ++with_call_profile + with_pymalloc + with_valgrind ++with_dtrace + with_wctype_functions + with_fpectl + with_libm +@@ -1472,8 +1479,11 @@ Optional Packages: + --with-pth use GNU pth threading libraries + --with(out)-doc-strings disable/enable documentation strings + --with(out)-tsc enable/disable timestamp counter profile ++ --with(out)count-allocs enable/disable per-type instance accounting ++ --with(out)-call-profile enable/disable statistics on function call invocation + --with(out)-pymalloc disable/enable specialized mallocs + --with-valgrind Enable Valgrind support ++ --with(out)-dtrace disable/enable dtrace support + --with-wctype-functions use wctype.h functions + --with-fpectl enable SIGFPE catching + --with-libm=STRING math library +@@ -5343,8 +5353,8 @@ $as_echo "#define Py_ENABLE_SHARED 1" >> + INSTSONAME="$LDLIBRARY".$SOVERSION + ;; + Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*) +- LDLIBRARY='libpython$(VERSION).so' +- BLDLIBRARY='-L. -lpython$(VERSION)' ++ LDLIBRARY='libpython$(VERSION)$(DEBUG_EXT).so' ++ BLDLIBRARY='-L. -lpython$(VERSION)$(DEBUG_EXT)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + case $ac_sys_system in + FreeBSD*) +@@ -5367,7 +5377,7 @@ $as_echo "#define Py_ENABLE_SHARED 1" >> + ;; + OSF*) + LDLIBRARY='libpython$(VERSION).so' +- BLDLIBRARY='-rpath $(LIBDIR) -L. -lpython$(VERSION)' ++ BLDLIBRARY='-L. -lpython$(VERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + ;; + atheos*) +@@ -5894,6 +5904,14 @@ $as_echo "no" >&6; } + fi + + ++if test "$Py_DEBUG" = 'true' ++then ++ DEBUG_EXT=_d ++ DEBUG_SUFFIX=-debug ++fi ++ ++ ++ + # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be + # merged with this chunk of code? + +@@ -9958,6 +9976,50 @@ $as_echo "no" >&6; } + fi + + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-count-allocs" >&5 ++$as_echo_n "checking for --with-count-allocs... " >&6; } ++ ++# Check whether --with-count-allocs was given. ++if test "${with_count_allocs+set}" = set; then : ++ withval=$with_count_allocs; ++if test "$withval" != no ++then ++ ++$as_echo "#define COUNT_ALLOCS 1" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-call-profile" >&5 ++$as_echo_n "checking for --with-call-profile... " >&6; } ++ ++# Check whether --with-call-profile was given. ++if test "${with_call_profile+set}" = set; then : ++ withval=$with_call_profile; ++if test "$withval" != no ++then ++ ++$as_echo "#define CALL_PROFILE 1" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ + # Check for Python-specific malloc support + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-pymalloc" >&5 + $as_echo_n "checking for --with-pymalloc... " >&6; } +@@ -10007,6 +10069,46 @@ fi + + fi + ++# Check for dtrace support ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-dtrace" >&5 ++$as_echo_n "checking for --with-dtrace... " >&6; } ++ ++# Check whether --with-dtrace was given. ++if test "${with_dtrace+set}" = set; then : ++ withval=$with_dtrace; ++fi ++ ++ ++if test ! -z "$with_dtrace" ++then ++ if dtrace -G -o /dev/null -s $srcdir/Include/pydtrace.d 2>/dev/null ++ then ++ ++$as_echo "#define WITH_DTRACE 1" >>confdefs.h ++ ++ with_dtrace="Sun" ++ DTRACEOBJS="Python/dtrace.o" ++ DTRADEHDRS="" ++ elif dtrace -h -o /dev/null -s $srcdir/Include/pydtrace.d ++ then ++ ++$as_echo "#define WITH_DTRACE 1" >>confdefs.h ++ ++ with_dtrace="Apple" ++ DTRACEOBJS="" ++ DTRADEHDRS="pydtrace.h" ++ else ++ with_dtrace="no" ++ fi ++else ++ with_dtrace="no" ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_dtrace" >&5 ++$as_echo "$with_dtrace" >&6; } ++ ++ ++ + # Check for --with-wctype-functions + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-wctype-functions" >&5 + $as_echo_n "checking for --with-wctype-functions... " >&6; } +diff -up ./pyconfig.h.in.autotool-intermediates ./pyconfig.h.in +--- ./pyconfig.h.in.autotool-intermediates 2013-04-09 11:24:01.020185806 +0200 ++++ ./pyconfig.h.in 2013-04-09 11:24:02.088183204 +0200 +@@ -18,6 +18,12 @@ + /* Define this if you have BeOS threads. */ + #undef BEOS_THREADS + ++/* Define to keep records on function call invocation */ ++#undef CALL_PROFILE ++ ++/* Define to keep records of the number of instances of each type */ ++#undef COUNT_ALLOCS ++ + /* Define if you have the Mach cthreads package */ + #undef C_THREADS + +@@ -1119,12 +1125,6 @@ + /* Define to profile with the Pentium timestamp counter */ + #undef WITH_TSC + +-/* Define to keep records of the number of instances of each type */ +-#undef COUNT_ALLOCS +- +-/* Define to keep records on function call invocation */ +-#undef CALL_PROFILE +- + /* Define if you want pymalloc to be disabled when running under valgrind */ + #undef WITH_VALGRIND + diff --git a/SOURCES/get-source.sh b/SOURCES/get-source.sh new file mode 100755 index 0000000..f07df6b --- /dev/null +++ b/SOURCES/get-source.sh @@ -0,0 +1,28 @@ +#! /bin/bash -ex + +# Download a release of Python (if missing) and remove .exe files from it + +version=$1 + +if [ -z "${version}" ]; then + echo "Usage: $0 VERSION" >& 2 + echo "" >& 2 + echo "example: $0 2.7.15" >& 2 + exit 1 +fi + +versionedname=Python-${version} +orig_archive=${versionedname}.tar.xz +new_archive=${versionedname}-noexe.tar.xz + +if [ ! -e ${orig_archive} ]; then + wget -N https://www.python.org/ftp/python/${version}/${orig_archive} +fi + +deleted_names=$(tar --list -Jf ${orig_archive} | grep '\.exe$') + +# tar --delete does not operate on compressed archives, so do +# xz compression/decompression explicitly +xz --decompress --stdout ${orig_archive} | \ + tar --delete -v ${deleted_names} | \ + xz --compress --stdout -3 -T0 > ${new_archive} diff --git a/SOURCES/libpython.stp b/SOURCES/libpython.stp new file mode 100644 index 0000000..56cf2fb --- /dev/null +++ b/SOURCES/libpython.stp @@ -0,0 +1,17 @@ +/* Systemtap tapset to make it easier to trace Python */ + +/* + Define python.function.entry/return: +*/ +probe python.function.entry = process("python").library("LIBRARY_PATH").mark("function__entry") +{ + filename = user_string($arg1); + funcname = user_string($arg2); + lineno = $arg3; +} +probe python.function.return = process("python").library("LIBRARY_PATH").mark("function__return") +{ + filename = user_string($arg1); + funcname = user_string($arg2); + lineno = $arg3; +} diff --git a/SOURCES/pyfuntop.stp b/SOURCES/pyfuntop.stp new file mode 100644 index 0000000..f235a23 --- /dev/null +++ b/SOURCES/pyfuntop.stp @@ -0,0 +1,21 @@ +#!/usr/bin/stap + +global fn_calls; + +probe python.function.entry +{ + fn_calls[pid(), filename, funcname, lineno] += 1; +} + +probe timer.ms(1000) { + printf("\033[2J\033[1;1H") /* clear screen */ + printf("%6s %80s %6s %30s %6s\n", + "PID", "FILENAME", "LINE", "FUNCTION", "CALLS") + foreach ([pid, filename, funcname, lineno] in fn_calls- limit 20) { + printf("%6d %80s %6d %30s %6d\n", + pid, filename, lineno, funcname, + fn_calls[pid, filename, funcname, lineno]); + } + + delete fn_calls; +} diff --git a/SOURCES/pynche b/SOURCES/pynche new file mode 100644 index 0000000..4032e41 --- /dev/null +++ b/SOURCES/pynche @@ -0,0 +1,2 @@ +#!/bin/bash +exec `python2 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific = True))"`/pynche/pynche diff --git a/SOURCES/python-2.5-cflags.patch b/SOURCES/python-2.5-cflags.patch new file mode 100644 index 0000000..32243bf --- /dev/null +++ b/SOURCES/python-2.5-cflags.patch @@ -0,0 +1,11 @@ +--- Python-2.5c1/Makefile.pre.in.cflags 2006-08-18 11:05:40.000000000 -0400 ++++ Python-2.5c1/Makefile.pre.in 2006-08-18 11:09:26.000000000 -0400 +@@ -334,7 +334,7 @@ + + # Build the interpreter + $(BUILDPYTHON): Modules/python.o $(LIBRARY) $(LDLIBRARY) +- $(LINKCC) $(LDFLAGS) $(LINKFORSHARED) -o $@ \ ++ $(LINKCC) $(CFLAGS) $(LDFLAGS) $(LINKFORSHARED) -o $@ \ + Modules/python.o \ + $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) + diff --git a/SOURCES/python-2.5.1-plural-fix.patch b/SOURCES/python-2.5.1-plural-fix.patch new file mode 100644 index 0000000..5002cb2 --- /dev/null +++ b/SOURCES/python-2.5.1-plural-fix.patch @@ -0,0 +1,12 @@ +diff -up Python-2.5.1/Lib/gettext.py.plural Python-2.5.1/Lib/gettext.py +--- Python-2.5.1/Lib/gettext.py.plural 2007-09-10 11:38:57.000000000 -0400 ++++ Python-2.5.1/Lib/gettext.py 2007-09-10 11:39:00.000000000 -0400 +@@ -299,6 +299,8 @@ class GNUTranslations(NullTranslations): + item = item.strip() + if not item: + continue ++ if item.startswith("#"): ++ continue + k = v = None + if ':' in item: + k, v = item.split(':', 1) diff --git a/SOURCES/python-2.5.1-sqlite-encoding.patch b/SOURCES/python-2.5.1-sqlite-encoding.patch new file mode 100644 index 0000000..ff2a3f8 --- /dev/null +++ b/SOURCES/python-2.5.1-sqlite-encoding.patch @@ -0,0 +1,24 @@ +diff -up Python-2.5.1/Lib/sqlite3/dbapi2.py.encoding Python-2.5.1/Lib/sqlite3/dbapi2.py +--- Python-2.5.1/Lib/sqlite3/dbapi2.py.encoding 2007-09-14 10:41:50.000000000 -0400 ++++ Python-2.5.1/Lib/sqlite3/dbapi2.py 2007-09-14 10:42:00.000000000 -0400 +@@ -1,7 +1,6 @@ +-# -*- coding: iso-8859-1 -*- + # pysqlite2/dbapi2.py: the DB-API 2.0 interface + # +-# Copyright (C) 2004-2005 Gerhard H�ring ++# Copyright (C) 2004-2005 Gerhard Haering + # + # This file is part of pysqlite. + # +diff -up Python-2.5.1/Lib/sqlite3/__init__.py.encoding Python-2.5.1/Lib/sqlite3/__init__.py +--- Python-2.5.1/Lib/sqlite3/__init__.py.encoding 2007-09-14 10:41:47.000000000 -0400 ++++ Python-2.5.1/Lib/sqlite3/__init__.py 2007-09-14 10:42:06.000000000 -0400 +@@ -1,7 +1,6 @@ +-#-*- coding: ISO-8859-1 -*- + # pysqlite2/__init__.py: the pysqlite2 package. + # +-# Copyright (C) 2005 Gerhard H�ring ++# Copyright (C) 2005 Gerhard Haering + # + # This file is part of pysqlite. + # diff --git a/SOURCES/python-2.6-rpath.patch b/SOURCES/python-2.6-rpath.patch new file mode 100644 index 0000000..33d7cf6 --- /dev/null +++ b/SOURCES/python-2.6-rpath.patch @@ -0,0 +1,12 @@ +diff -up Python-2.6/configure.ac.rpath Python-2.6/configure.ac +--- Python-2.6/configure.ac.rpath 2008-11-24 02:51:06.000000000 -0500 ++++ Python-2.6/configure.ac 2008-11-24 02:51:21.000000000 -0500 +@@ -729,7 +729,7 @@ if test $enable_shared = "yes"; then + ;; + OSF*) + LDLIBRARY='libpython$(VERSION).so' +- BLDLIBRARY='-rpath $(LIBDIR) -L. -lpython$(VERSION)' ++ BLDLIBRARY='-L. -lpython$(VERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} + ;; + atheos*) diff --git a/SOURCES/python-2.6.4-distutils-rpath.patch b/SOURCES/python-2.6.4-distutils-rpath.patch new file mode 100644 index 0000000..f156507 --- /dev/null +++ b/SOURCES/python-2.6.4-distutils-rpath.patch @@ -0,0 +1,20 @@ +diff -up Python-2.6.4/Lib/distutils/unixccompiler.py.distutils-rpath Python-2.6.4/Lib/distutils/unixccompiler.py +--- Python-2.6.4/Lib/distutils/unixccompiler.py.distutils-rpath 2009-09-09 04:34:06.000000000 -0400 ++++ Python-2.6.4/Lib/distutils/unixccompiler.py 2010-03-15 21:33:25.000000000 -0400 +@@ -142,6 +142,16 @@ class UnixCCompiler(CCompiler): + if sys.platform == "cygwin": + exe_extension = ".exe" + ++ def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs): ++ """Remove standard library path from rpath""" ++ libraries, library_dirs, runtime_library_dirs = \ ++ CCompiler._fix_lib_args(self, libraries, library_dirs, ++ runtime_library_dirs) ++ libdir = sysconfig.get_config_var('LIBDIR') ++ if runtime_library_dirs and (libdir in runtime_library_dirs): ++ runtime_library_dirs.remove(libdir) ++ return libraries, library_dirs, runtime_library_dirs ++ + def preprocess(self, source, + output_file=None, macros=None, include_dirs=None, + extra_preargs=None, extra_postargs=None): diff --git a/SOURCES/python-2.7-lib64-sysconfig.patch b/SOURCES/python-2.7-lib64-sysconfig.patch new file mode 100644 index 0000000..0cef361 --- /dev/null +++ b/SOURCES/python-2.7-lib64-sysconfig.patch @@ -0,0 +1,44 @@ +diff -up Python-2.7/Lib/sysconfig.py.lib64-sysconfig Python-2.7/Lib/sysconfig.py +--- Python-2.7/Lib/sysconfig.py.lib64-sysconfig 2010-07-08 14:18:41.386898476 -0400 ++++ Python-2.7/Lib/sysconfig.py 2010-07-08 14:22:02.837896461 -0400 +@@ -7,20 +7,20 @@ from os.path import pardir, realpath + + _INSTALL_SCHEMES = { + 'posix_prefix': { +- 'stdlib': '{base}/lib/python{py_version_short}', +- 'platstdlib': '{platbase}/lib/python{py_version_short}', ++ 'stdlib': '{base}/lib64/python{py_version_short}', ++ 'platstdlib': '{platbase}/lib64/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', +- 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', ++ 'platlib': '{platbase}/lib64/python{py_version_short}/site-packages', + 'include': '{base}/include/python{py_version_short}', + 'platinclude': '{platbase}/include/python{py_version_short}', + 'scripts': '{base}/bin', + 'data': '{base}', + }, + 'posix_home': { +- 'stdlib': '{base}/lib/python', +- 'platstdlib': '{base}/lib/python', ++ 'stdlib': '{base}/lib64/python', ++ 'platstdlib': '{base}/lib64/python', + 'purelib': '{base}/lib/python', +- 'platlib': '{base}/lib/python', ++ 'platlib': '{base}/lib64/python', + 'include': '{base}/include/python', + 'platinclude': '{base}/include/python', + 'scripts': '{base}/bin', +@@ -65,10 +65,10 @@ _INSTALL_SCHEMES = { + 'data' : '{userbase}', + }, + 'posix_user': { +- 'stdlib': '{userbase}/lib/python{py_version_short}', +- 'platstdlib': '{userbase}/lib/python{py_version_short}', ++ 'stdlib': '{userbase}/lib64/python{py_version_short}', ++ 'platstdlib': '{userbase}/lib64/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', +- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', ++ 'platlib': '{userbase}/lib64/python{py_version_short}/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data' : '{userbase}', diff --git a/SOURCES/python-2.7.1-config.patch b/SOURCES/python-2.7.1-config.patch new file mode 100644 index 0000000..4b076db --- /dev/null +++ b/SOURCES/python-2.7.1-config.patch @@ -0,0 +1,284 @@ +diff --git a/Modules/Setup.dist b/Modules/Setup.dist +index bbc9222..2cf35a9 100644 +--- a/Modules/Setup.dist ++++ b/Modules/Setup.dist +@@ -153,7 +153,7 @@ GLHACK=-Dclear=__GLclear + # modules are to be built as shared libraries (see above for more + # detail; also note that *static* reverses this effect): + +-#*shared* ++*shared* + + # GNU readline. Unlike previous Python incarnations, GNU readline is + # now incorporated in an optional module, configured in the Setup file +@@ -163,33 +163,33 @@ GLHACK=-Dclear=__GLclear + # it, depending on your system -- see the GNU readline instructions. + # It's okay for this to be a shared library, too. + +-#readline readline.c -lreadline -ltermcap ++readline readline.c -lreadline -ltermcap + + + # Modules that should always be present (non UNIX dependent): + +-#array arraymodule.c # array objects +-#cmath cmathmodule.c _math.c # -lm # complex math library functions +-#math mathmodule.c _math.c # -lm # math library functions, e.g. sin() +-#_struct _struct.c # binary structure packing/unpacking +-#time timemodule.c # -lm # time operations and variables +-#operator operator.c # operator.add() and similar goodies +-#_testcapi _testcapimodule.c # Python C API test module +-#_random _randommodule.c # Random number generator +-#_collections _collectionsmodule.c # Container types ++array arraymodule.c # array objects ++cmath cmathmodule.c _math.c # -lm # complex math library functions ++math mathmodule.c _math.c # -lm # math library functions, e.g. sin() ++_struct _struct.c # binary structure packing/unpacking ++time timemodule.c # -lm # time operations and variables ++operator operator.c # operator.add() and similar goodies ++_testcapi _testcapimodule.c # Python C API test module ++_random _randommodule.c # Random number generator ++_collections _collectionsmodule.c # Container types + #_heapq _heapqmodule.c # Heapq type +-#itertools itertoolsmodule.c # Functions creating iterators for efficient looping +-#strop stropmodule.c # String manipulations +-#_functools _functoolsmodule.c # Tools for working with functions and callable objects ++itertools itertoolsmodule.c # Functions creating iterators for efficient looping ++strop stropmodule.c # String manipulations ++_functools _functoolsmodule.c # Tools for working with functions and callable objects + #_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator + #_pickle _pickle.c # pickle accelerator + #datetime datetimemodule.c # date/time type +-#_bisect _bisectmodule.c # Bisection algorithms ++_bisect _bisectmodule.c # Bisection algorithms + +-#unicodedata unicodedata.c # static Unicode character database ++unicodedata unicodedata.c # static Unicode character database + + # access to ISO C locale support +-#_locale _localemodule.c # -lintl ++_locale _localemodule.c # -lintl + + # Standard I/O baseline + #_io -I$(srcdir)/Modules/_io _io/bufferedio.c _io/bytesio.c _io/fileio.c _io/iobase.c _io/_iomodule.c _io/stringio.c _io/textio.c +@@ -199,41 +199,41 @@ GLHACK=-Dclear=__GLclear + # (If you have a really backward UNIX, select and socket may not be + # supported...) + +-#fcntl fcntlmodule.c # fcntl(2) and ioctl(2) +-#spwd spwdmodule.c # spwd(3) +-#grp grpmodule.c # grp(3) +-#select selectmodule.c # select(2); not on ancient System V ++fcntl fcntlmodule.c # fcntl(2) and ioctl(2) ++spwd spwdmodule.c # spwd(3) ++grp grpmodule.c # grp(3) ++select selectmodule.c # select(2); not on ancient System V + + # Memory-mapped files (also works on Win32). +-#mmap mmapmodule.c ++mmap mmapmodule.c + + # CSV file helper +-#_csv _csv.c ++_csv _csv.c + + # Socket module helper for socket(2) +-#_socket socketmodule.c timemodule.c ++_socket socketmodule.c timemodule.c + + # Socket module helper for SSL support; you must comment out the other + # socket line above, and possibly edit the SSL variable: + #SSL=/usr/local/ssl +-#_ssl _ssl.c \ +-# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ +-# -L$(SSL)/lib -lssl -lcrypto ++_ssl _ssl.c \ ++ -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ ++ -L$(SSL)/lib -lssl -lcrypto + + # The crypt module is now disabled by default because it breaks builds + # on many systems (where -lcrypt is needed), e.g. Linux (I believe). + # + # First, look at Setup.config; configure may have set this for you. + +-#crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems ++crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems + + + # Some more UNIX dependent modules -- off by default, since these + # are not supported by all UNIX systems: + +-#nis nismodule.c -lnsl # Sun yellow pages -- not everywhere +-#termios termios.c # Steen Lumholt's termios module +-#resource resource.c # Jeremy Hylton's rlimit interface ++nis nismodule.c -lnsl -ltirpc -I/usr/include/tirpc -I/usr/include/nsl -L/usr/lib/nsl ++termios termios.c # Steen Lumholt's termios module ++resource resource.c # Jeremy Hylton's rlimit interface + + + # Multimedia modules -- off by default. +@@ -241,8 +241,8 @@ GLHACK=-Dclear=__GLclear + # #993173 says audioop works on 64-bit platforms, though. + # These represent audio samples or images as strings: + +-#audioop audioop.c # Operations on audio samples +-#imageop imageop.c # Operations on images ++audioop audioop.c # Operations on audio samples ++imageop imageop.c # Operations on images + + + # Note that the _md5 and _sha modules are normally only built if the +@@ -252,14 +252,14 @@ GLHACK=-Dclear=__GLclear + # Message-Digest Algorithm, described in RFC 1321. The necessary files + # md5.c and md5.h are included here. + +-#_md5 md5module.c md5.c ++_md5 md5module.c md5.c + + + # The _sha module implements the SHA checksum algorithms. + # (NIST's Secure Hash Algorithms.) +-#_sha shamodule.c +-#_sha256 sha256module.c +-#_sha512 sha512module.c ++_sha shamodule.c ++_sha256 sha256module.c ++_sha512 sha512module.c + + + # SGI IRIX specific modules -- off by default. +@@ -306,12 +306,12 @@ GLHACK=-Dclear=__GLclear + # A Linux specific module -- off by default; this may also work on + # some *BSDs. + +-#linuxaudiodev linuxaudiodev.c ++linuxaudiodev linuxaudiodev.c + + + # George Neville-Neil's timing module: + +-#timing timingmodule.c ++timing timingmodule.c + + + # The _tkinter module. +@@ -326,7 +326,7 @@ GLHACK=-Dclear=__GLclear + # every system. + + # *** Always uncomment this (leave the leading underscore in!): +-# _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ ++_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ + # *** Uncomment and edit to reflect where your Tcl/Tk libraries are: + # -L/usr/local/lib \ + # *** Uncomment and edit to reflect where your Tcl/Tk headers are: +@@ -336,7 +336,7 @@ GLHACK=-Dclear=__GLclear + # *** Or uncomment this for Solaris: + # -I/usr/openwin/include \ + # *** Uncomment and edit for Tix extension only: +-# -DWITH_TIX -ltix8.1.8.2 \ ++ -DWITH_TIX -ltix \ + # *** Uncomment and edit for BLT extension only: + # -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \ + # *** Uncomment and edit for PIL (TkImaging) extension only: +@@ -345,7 +345,7 @@ GLHACK=-Dclear=__GLclear + # *** Uncomment and edit for TOGL extension only: + # -DWITH_TOGL togl.c \ + # *** Uncomment and edit to reflect your Tcl/Tk versions: +-# -ltk8.2 -ltcl8.2 \ ++ -ltk -ltcl \ + # *** Uncomment and edit to reflect where your X11 libraries are: + # -L/usr/X11R6/lib \ + # *** Or uncomment this for Solaris: +@@ -355,7 +355,7 @@ GLHACK=-Dclear=__GLclear + # *** Uncomment for AIX: + # -lld \ + # *** Always uncomment this; X11 libraries to link with: +-# -lX11 ++ -lX11 + + # Lance Ellinghaus's syslog module + #syslog syslogmodule.c # syslog daemon interface +@@ -377,7 +377,7 @@ GLHACK=-Dclear=__GLclear + # it is a highly experimental and dangerous device for calling + # *arbitrary* C functions in *arbitrary* shared libraries: + +-#dl dlmodule.c ++dl dlmodule.c + + + # Modules that provide persistent dictionary-like semantics. You will +@@ -400,7 +400,7 @@ GLHACK=-Dclear=__GLclear + # + # First, look at Setup.config; configure may have set this for you. + +-#gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm ++gdbm gdbmmodule.c -lgdbm + + + # Sleepycat Berkeley DB interface. +@@ -415,11 +415,9 @@ GLHACK=-Dclear=__GLclear + # + # Edit the variables DB and DBLIBVERto point to the db top directory + # and the subdirectory of PORT where you built it. +-#DB=/usr/local/BerkeleyDB.4.0 +-#DBLIBVER=4.0 +-#DBINC=$(DB)/include +-#DBLIB=$(DB)/lib +-#_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER) ++DBINC=/usr/include/libdb ++DBLIB=/usr/lib ++_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb + + # Historical Berkeley DB 1.85 + # +@@ -434,14 +432,14 @@ GLHACK=-Dclear=__GLclear + + + # Helper module for various ascii-encoders +-#binascii binascii.c ++binascii binascii.c + + # Fred Drake's interface to the Python parser +-#parser parsermodule.c ++parser parsermodule.c + + # cStringIO and cPickle +-#cStringIO cStringIO.c +-#cPickle cPickle.c ++cStringIO cStringIO.c ++cPickle cPickle.c + + + # Lee Busby's SIGFPE modules. +@@ -464,7 +462,7 @@ GLHACK=-Dclear=__GLclear + # Andrew Kuchling's zlib module. + # This require zlib 1.1.3 (or later). + # See http://www.gzip.org/zlib/ +-#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz ++zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz + + # Interface to the Expat XML parser + # More information on Expat can be found at www.libexpat.org. +@@ -475,14 +473,14 @@ GLHACK=-Dclear=__GLclear + # Hye-Shik Chang's CJKCodecs + + # multibytecodec is required for all the other CJK codec modules +-#_multibytecodec cjkcodecs/multibytecodec.c +- +-#_codecs_cn cjkcodecs/_codecs_cn.c +-#_codecs_hk cjkcodecs/_codecs_hk.c +-#_codecs_iso2022 cjkcodecs/_codecs_iso2022.c +-#_codecs_jp cjkcodecs/_codecs_jp.c +-#_codecs_kr cjkcodecs/_codecs_kr.c +-#_codecs_tw cjkcodecs/_codecs_tw.c ++_multibytecodec cjkcodecs/multibytecodec.c ++ ++_codecs_cn cjkcodecs/_codecs_cn.c ++_codecs_hk cjkcodecs/_codecs_hk.c ++_codecs_iso2022 cjkcodecs/_codecs_iso2022.c ++_codecs_jp cjkcodecs/_codecs_jp.c ++_codecs_kr cjkcodecs/_codecs_kr.c ++_codecs_tw cjkcodecs/_codecs_tw.c + + # Example -- included for reference only: + # xx xxmodule.c diff --git a/SOURCES/python-2.7.1-fix_test_abc_with_COUNT_ALLOCS.patch b/SOURCES/python-2.7.1-fix_test_abc_with_COUNT_ALLOCS.patch new file mode 100644 index 0000000..bb38281 --- /dev/null +++ b/SOURCES/python-2.7.1-fix_test_abc_with_COUNT_ALLOCS.patch @@ -0,0 +1,27 @@ +diff -up Python-2.7.1/Lib/test/test_abc.py.cache_leak Python-2.7.1/Lib/test/test_abc.py +--- Python-2.7.1/Lib/test/test_abc.py.cache_leak 2010-12-28 18:06:35.551938356 -0500 ++++ Python-2.7.1/Lib/test/test_abc.py 2010-12-28 18:09:09.021059202 -0500 +@@ -3,6 +3,8 @@ + + """Unit tests for abc.py.""" + ++import sys ++ + import unittest, weakref + from test import test_support + +@@ -229,8 +231,12 @@ class TestABC(unittest.TestCase): + # Trigger cache. + C().f() + del C +- test_support.gc_collect() +- self.assertEqual(r(), None) ++ # This doesn't work in our debug build, presumably due to its use ++ # of COUNT_ALLOCS, which makes heap-allocated types immortal (once ++ # they've ever had an instance): ++ if not hasattr(sys, 'getcounts'): ++ test_support.gc_collect() ++ self.assertEqual(r(), None) + + def test_main(): + test_support.run_unittest(TestABC) diff --git a/SOURCES/python-2.7.2-add-extension-suffix-to-python-config.patch b/SOURCES/python-2.7.2-add-extension-suffix-to-python-config.patch new file mode 100644 index 0000000..d1ff052 --- /dev/null +++ b/SOURCES/python-2.7.2-add-extension-suffix-to-python-config.patch @@ -0,0 +1,18 @@ +diff -up Python-2.7.2/Misc/python-config.in.add-extension-suffix-to-python-config Python-2.7.2/Misc/python-config.in +--- Python-2.7.2/Misc/python-config.in.add-extension-suffix-to-python-config 2011-08-23 18:15:41.832497124 -0400 ++++ Python-2.7.2/Misc/python-config.in 2011-08-23 18:17:25.854490011 -0400 +@@ -6,7 +6,7 @@ import getopt + from distutils import sysconfig + + valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags', +- 'ldflags', 'help'] ++ 'ldflags', 'extension-suffix', 'help'] + + def exit_with_usage(code=1): + print >>sys.stderr, "Usage: %s [%s]" % (sys.argv[0], +@@ -54,3 +54,5 @@ for opt in opt_flags: + libs.extend(getvar('LINKFORSHARED').split()) + print ' '.join(libs) + ++ elif opt == '--extension-suffix': ++ print (sys.pydebug and "_d" or "") + sysconfig.get_config_var('SO') diff --git a/SOURCES/python-2.7rc1-socketmodule-constants.patch b/SOURCES/python-2.7rc1-socketmodule-constants.patch new file mode 100644 index 0000000..c32e103 --- /dev/null +++ b/SOURCES/python-2.7rc1-socketmodule-constants.patch @@ -0,0 +1,64 @@ +--- Python-2.7rc1/Modules/socketmodule.c.socketmodule 2010-05-09 10:46:46.000000000 -0400 ++++ Python-2.7rc1/Modules/socketmodule.c 2010-06-07 23:04:19.374234780 -0400 +@@ -4783,6 +4783,61 @@ init_socket(void) + PyModule_AddIntConstant(m, "SO_SETFIB", SO_SETFIB); + #endif + ++#ifdef SO_SNDBUFFORCE ++ PyModule_AddIntConstant(m, "SO_SNDBUFFORCE", SO_SNDBUFFORCE); ++#endif ++#ifdef SO_RCVBUFFORCE ++ PyModule_AddIntConstant(m, "SO_RCVBUFFORCE", SO_RCVBUFFORCE); ++#endif ++#ifdef SO_NO_CHECK ++ PyModule_AddIntConstant(m, "SO_NO_CHECK", SO_NO_CHECK); ++#endif ++#ifdef SO_PRIORITY ++ PyModule_AddIntConstant(m, "SO_PRIORITY", SO_PRIORITY); ++#endif ++#ifdef SO_BSDCOMPAT ++ PyModule_AddIntConstant(m, "SO_BSDCOMPAT", SO_BSDCOMPAT); ++#endif ++#ifdef SO_PASSCRED ++ PyModule_AddIntConstant(m, "SO_PASSCRED", SO_PASSCRED); ++#endif ++#ifdef SO_PEERCRED ++ PyModule_AddIntConstant(m, "SO_PEERCRED", SO_PEERCRED); ++#endif ++#ifdef SO_SECURITY_AUTHENTICATION ++ PyModule_AddIntConstant(m, "SO_SECURITY_AUTHENTICATION", SO_SECURITY_AUTHENTICATION); ++#endif ++#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT ++ PyModule_AddIntConstant(m, "SO_SECURITY_ENCRYPTION_TRANSPORT", SO_SECURITY_ENCRYPTION_TRANSPORT); ++#endif ++#ifdef SO_SECURITY_ENCRYPTION_NETWORK ++ PyModule_AddIntConstant(m, "SO_SECURITY_ENCRYPTION_NETWORK", SO_SECURITY_ENCRYPTION_NETWORK); ++#endif ++#ifdef SO_BINDTODEVICE ++ PyModule_AddIntConstant(m, "SO_BINDTODEVICE", SO_BINDTODEVICE); ++#endif ++#ifdef SO_ATTACH_FILTER ++ PyModule_AddIntConstant(m, "SO_ATTACH_FILTER", SO_ATTACH_FILTER); ++#endif ++#ifdef SO_DETACH_FILTER ++ PyModule_AddIntConstant(m, "SO_DETACH_FILTER", SO_DETACH_FILTER); ++#endif ++#ifdef SO_PEERNAME ++ PyModule_AddIntConstant(m, "SO_PEERNAME", SO_PEERNAME); ++#endif ++#ifdef SO_TIMESTAMP ++ PyModule_AddIntConstant(m, "SO_TIMESTAMP", SO_TIMESTAMP); ++#endif ++#ifdef SO_PEERSEC ++ PyModule_AddIntConstant(m, "SO_PEERSEC", SO_PEERSEC); ++#endif ++#ifdef SO_PASSSEC ++ PyModule_AddIntConstant(m, "SO_PASSSEC", SO_PASSSEC); ++#endif ++#ifdef SO_TIMESTAMPNS ++ PyModule_AddIntConstant(m, "SO_TIMESTAMPNS", SO_TIMESTAMPNS); ++#endif ++ + /* Maximum number of connections for "listen" */ + #ifdef SOMAXCONN + PyModule_AddIntConstant(m, "SOMAXCONN", SOMAXCONN); diff --git a/SOURCES/python-2.7rc1-socketmodule-constants2.patch b/SOURCES/python-2.7rc1-socketmodule-constants2.patch new file mode 100644 index 0000000..896ac88 --- /dev/null +++ b/SOURCES/python-2.7rc1-socketmodule-constants2.patch @@ -0,0 +1,19 @@ +diff -up Python-2.7rc1/Modules/socketmodule.c.socketmodule2 Python-2.7rc1/Modules/socketmodule.c +--- Python-2.7rc1/Modules/socketmodule.c.socketmodule2 2010-06-07 23:06:59.133498087 -0400 ++++ Python-2.7rc1/Modules/socketmodule.c 2010-06-07 23:11:51.249520087 -0400 +@@ -5253,6 +5253,15 @@ init_socket(void) + #ifdef TCP_QUICKACK + PyModule_AddIntConstant(m, "TCP_QUICKACK", TCP_QUICKACK); + #endif ++#ifdef TCP_CONGESTION ++ PyModule_AddIntConstant(m, "TCP_CONGESTION", TCP_CONGESTION); ++#endif ++#ifdef TCP_MD5SIG ++ PyModule_AddIntConstant(m, "TCP_MD5SIG", TCP_MD5SIG); ++#endif ++#ifdef TCP_MD5SIG_MAXKEYLEN ++ PyModule_AddIntConstant(m, "TCP_MD5SIG_MAXKEYLEN", TCP_MD5SIG_MAXKEYLEN); ++#endif + + + /* IPX options */ diff --git a/SOURCES/pythondeps.sh b/SOURCES/pythondeps.sh new file mode 100755 index 0000000..10a060a --- /dev/null +++ b/SOURCES/pythondeps.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +[ $# -ge 1 ] || { + cat > /dev/null + exit 0 +} + +case $1 in +-P|--provides) + shift + # Match buildroot/payload paths of the form + # /PATH/OF/BUILDROOT/usr/bin/pythonMAJOR.MINOR + # generating a line of the form + # python(abi) = MAJOR.MINOR + # (Don't match against -config tools e.g. /usr/bin/python2.6-config) + grep "/usr/bin/python.\..$" \ + | sed -e "s|.*/usr/bin/python\(.\..\)|python(abi) = \1|" + ;; +-R|--requires) + shift + # Match buildroot paths of the form + # /PATH/OF/BUILDROOT/usr/lib/pythonMAJOR.MINOR/ and + # /PATH/OF/BUILDROOT/usr/lib64/pythonMAJOR.MINOR/ + # generating (uniqely) lines of the form: + # python(abi) = MAJOR.MINOR + grep "/usr/lib[^/]*/python.\../.*" \ + | sed -e "s|.*/usr/lib[^/]*/python\(.\..\)/.*|python(abi) = \1|g" \ + | sort | uniq + ;; +esac + +exit 0 diff --git a/SOURCES/systemtap-example.stp b/SOURCES/systemtap-example.stp new file mode 100644 index 0000000..164333a --- /dev/null +++ b/SOURCES/systemtap-example.stp @@ -0,0 +1,19 @@ +/* + Example usage of the Python systemtap tapset to show a nested view of all + Python function calls (and returns) across the whole system. + + Run this using + stap systemtap-example.stp + to instrument all Python processes on the system, or (for example) using + stap systemtap-example.stp -c COMMAND + to instrument a specific program (implemented in Python) +*/ +probe python.function.entry +{ + printf("%s => %s in %s:%d\n", thread_indent(1), funcname, filename, lineno); +} + +probe python.function.return +{ + printf("%s <= %s in %s:%d\n", thread_indent(-1), funcname, filename, lineno); +} diff --git a/SPECS/python2.spec b/SPECS/python2.spec new file mode 100644 index 0000000..f6a68ea --- /dev/null +++ b/SPECS/python2.spec @@ -0,0 +1,3792 @@ +# ====================================================== +# Conditionals and other variables controlling the build +# ====================================================== + +# Note that the bcond macros are named for the CLI option they create. +# "%%bcond_without" means "ENABLE by default and create a --without option" + +# Ability to reuse RPM-installed pip using rewheel +%bcond_with rewheel + +# Extra build for debugging the interpreter or C-API extensions +# (the -debug subpackages) +%bcond_with debug_build + +# Remove extra packages +%bcond_with tk_and_tools + +%global unicode ucs4 + +%global python python2 + +%global pybasever 2.7 +%global pylibdir %{_libdir}/python%{pybasever} +%global tools_dir %{pylibdir}/Tools +%global demo_dir %{pylibdir}/Demo +%global doc_tools_dir %{pylibdir}/Doc/tools +%global dynload_dir %{pylibdir}/lib-dynload +%global site_packages %{pylibdir}/site-packages + +# Python's configure script defines SOVERSION, and this is used in the Makefile +# to determine INSTSONAME, the name of the libpython DSO: +# LDLIBRARY='libpython$(VERSION).so' +# INSTSONAME="$LDLIBRARY".$SOVERSION +# We mirror this here in order to make it easier to add the -gdb.py hooks. +# (if these get out of sync, the payload of the libs subpackage will fail +# and halt the build) +%global py_SOVERSION 1.0 +%global py_INSTSONAME_optimized libpython%{pybasever}.so.%{py_SOVERSION} +%global py_INSTSONAME_debug libpython%{pybasever}_d.so.%{py_SOVERSION} + +# Disabled for now: +%global with_huntrleaks 0 + +%global with_gdb_hooks 1 + +%global with_systemtap 1 + +# some arches don't have valgrind so we need to disable its support on them +%ifarch %{valgrind_arches} +%global with_valgrind 1 +%else +%global with_valgrind 0 +%endif + +%global with_gdbm 1 + +%if 0%{?_module_build} +%global with_valgrind 0 +%global with_systemtap 0 + +# (Don't) Run the test suite in %%check +%bcond_with tests +%else +# Run the test suite in %%check +%bcond_without tests +%endif + +# Disable automatic bytecompilation. The python2.7 binary is not yet +# available in /usr/bin when Python is built. Also, the bytecompilation fails +# on files that test invalid syntax. +%undefine __brp_python_bytecompile +# The above is broken now +# https://bugzilla.redhat.com/show_bug.cgi?id=1597664 +# This is an older non-standard way to disable the brp script, as a workaround +%undefine py_auto_byte_compile + +# We need to get a newer configure generated out of configure.in for the following +# patches: +# patch 4 (CFLAGS) +# patch 52 (valgrind) +# patch 55 (systemtap) +# patch 145 (linux2) +# +# For patch 55 (systemtap), we need to get a new header for configure to use +# +# configure.in requires autoconf-2.65, but the version in Fedora is currently +# autoconf-2.66 +# +# For now, we'll generate a patch to the generated configure script and +# pyconfig.h.in on a machine that has a local copy of autoconf 2.65 +# +# Instructions on obtaining such a copy can be seen at +# http://bugs.python.org/issue7997 +# +# To make it easy to regenerate the patch, this specfile can be run in two +# ways: +# (i) regenerate_autotooling_patch 0 : the normal approach: prep the +# source tree using a pre-generated patch to the "configure" script, and do a +# full build +# (ii) regenerate_autotooling_patch 1 : intended to be run on a developer's +# workstation: prep the source tree without patching configure, then rerun a +# local copy of autoconf-2.65, regenerate the patch, then exit, without doing +# the rest of the build +%global regenerate_autotooling_patch 0 + + +# ================== +# Top-level metadata +# ================== +Summary: An interpreted, interactive, object-oriented programming language +Name: %{python} +# Remember to also rebase python2-docs when changing this: +Version: 2.7.17 +Release: 1%{?dist} +License: Python +Group: Development/Languages +Requires: %{python}-libs%{?_isa} = %{version}-%{release} +Requires: %{python}-for-tests%{?_isa} = %{version}-%{release} +Provides: python(abi) = %{pybasever} + + +# ======================= +# Build-time requirements +# ======================= + +# (keep this list alphabetized) + +BuildRequires: autoconf +%if ! 0%{?_module_build} +BuildRequires: bluez-libs-devel +%endif +BuildRequires: bzip2 +BuildRequires: bzip2-devel +BuildRequires: glibc-devel +BuildRequires: gmp-devel +BuildRequires: libdb-devel +BuildRequires: libffi-devel +BuildRequires: ncurses-devel +BuildRequires: openssl-devel +BuildRequires: pkgconfig +BuildRequires: readline-devel +BuildRequires: sqlite-devel +%if %{with tk_and_tools} +BuildRequires: tcl-devel +%endif + +# For the nis module +BuildRequires: libnsl2-devel +BuildRequires: libtirpc-devel + +# expat 2.1.0 added the symbol XML_SetHashSalt without bumping SONAME. We use +# it (in pyexpat) in order to enable the fix in Python-2.7.3 for CVE-2012-0876: +BuildRequires: expat-devel >= 2.1.0 + +BuildRequires: findutils +BuildRequires: gcc-c++ +%if %{with_gdbm} +# ABI change without soname bump, reverted +BuildRequires: gdbm-devel >= 1:1.13 +%endif +%if %{with tk_and_tools} +BuildRequires: libGL-devel +BuildRequires: libX11-devel +%endif #{with tk_and_tools} + +%if 0%{?with_systemtap} +BuildRequires: systemtap-sdt-devel +# (this introduces a circular dependency, in that systemtap-sdt-devel's +# /usr/bin/dtrace is a python script) +%global tapsetdir /usr/share/systemtap/tapset +%endif # with_systemtap + +BuildRequires: tar +%if %{with tk_and_tools} +BuildRequires: tix-devel +BuildRequires: tk-devel +%endif #{with tk_and_tools} + +%if 0%{?with_valgrind} +BuildRequires: valgrind-devel +%endif + +BuildRequires: zlib-devel + +%if %{with rewheel} +BuildRequires: python2-setuptools +Requires: python2-setuptools + +%if ! 0%{?_module_build} +BuildRequires: python2-pip +Requires: python2-pip +%endif # !module_build +%endif # rewheel + + + +# ======================= +# Source code and patches +# ======================= + +# The upstream tarball includes questionable executable files for Windows, +# which we should not ship even in the SRPM. +# Run the "get-source.sh" with the version as argument to download the upstream +# tarball and generate a version with the .exe files removed. For example: +# $ ./get-source.sh 2.7.15 + +Source: Python-%{version}-noexe.tar.xz + +# A script to remove .exe files from the source distribution +Source1: get-source.sh + +# Work around bug 562906 until it's fixed in rpm-build by providing a fixed +# version of pythondeps.sh: +Source2: pythondeps.sh +%global __python_requires %{SOURCE2} + +# Systemtap tapset to make it easier to use the systemtap static probes +# (actually a template; LIBRARY_PATH will get fixed up during install) +# Written by dmalcolm; not yet sent upstream +Source3: libpython.stp + + +# Example systemtap script using the tapset +# Written by wcohen, mjw, dmalcolm; not yet sent upstream +Source4: systemtap-example.stp + +# Another example systemtap script that uses the tapset +# Written by dmalcolm; not yet sent upstream +Source5: pyfuntop.stp + +Source7: pynche + +# Modules/Setup.dist is ultimately used by the "makesetup" script to construct +# the Makefile and config.c +# +# Upstream leaves many things disabled by default, to try to make it easy as +# possible to build the code on as many platforms as possible. +# +# TODO: many modules can also now be built by setup.py after the python binary +# has been built; need to assess if we should instead build things there +# +# We patch it downstream as follows: +# - various modules are built by default by upstream as static libraries; +# we built them as shared libraries +# - build the "readline" module (appears to also be handled by setup.py now) +# - build the nis module (which needs the tirpc library since glibc 2.26) +# - enable the build of the following modules: +# - array arraymodule.c # array objects +# - cmath cmathmodule.c # -lm # complex math library functions +# - math mathmodule.c # -lm # math library functions, e.g. sin() +# - _struct _struct.c # binary structure packing/unpacking +# - time timemodule.c # -lm # time operations and variables +# - operator operator.c # operator.add() and similar goodies +# - _weakref _weakref.c # basic weak reference support +# - _testcapi _testcapimodule.c # Python C API test module +# - _random _randommodule.c # Random number generator +# - _collections _collectionsmodule.c # Container types +# - itertools itertoolsmodule.c +# - strop stropmodule.c +# - _functools _functoolsmodule.c +# - _bisect _bisectmodule.c # Bisection algorithms +# - unicodedata unicodedata.c # static Unicode character database +# - _locale _localemodule.c +# - fcntl fcntlmodule.c # fcntl(2) and ioctl(2) +# - spwd spwdmodule.c # spwd(3) +# - grp grpmodule.c # grp(3) +# - select selectmodule.c # select(2); not on ancient System V +# - mmap mmapmodule.c # Memory-mapped files +# - _csv _csv.c # CSV file helper +# - _socket socketmodule.c # Socket module helper for socket(2) +# - _ssl _ssl.c +# - crypt cryptmodule.c -lcrypt # crypt(3) +# - termios termios.c # Steen Lumholt's termios module +# - resource resource.c # Jeremy Hylton's rlimit interface +# - audioop audioop.c # Operations on audio samples +# - imageop imageop.c # Operations on images +# - _md5 md5module.c md5.c +# - _sha shamodule.c +# - _sha256 sha256module.c +# - _sha512 sha512module.c +# - linuxaudiodev linuxaudiodev.c +# - timing timingmodule.c +# - _tkinter _tkinter.c tkappinit.c +# - dl dlmodule.c +# - gdbm gdbmmodule.c +# - _bsddb _bsddb.c +# - binascii binascii.c +# - parser parsermodule.c +# - cStringIO cStringIO.c +# - cPickle cPickle.c +# - zlib zlibmodule.c +# - _multibytecodec cjkcodecs/multibytecodec.c +# - _codecs_cn cjkcodecs/_codecs_cn.c +# - _codecs_hk cjkcodecs/_codecs_hk.c +# - _codecs_iso2022 cjkcodecs/_codecs_iso2022.c +# - _codecs_jp cjkcodecs/_codecs_jp.c +# - _codecs_kr cjkcodecs/_codecs_kr.c +# - _codecs_tw cjkcodecs/_codecs_tw.c +Patch0: python-2.7.1-config.patch + +# Removes the "-g" option from "pydoc", for some reason; I believe +# (dmalcolm 2010-01-29) that this was introduced in this change: +# - fix pydoc (#68082) +# in 2.2.1-12 as a response to the -g option needing TkInter installed +# (Red Hat Linux 8) +# Not upstream +Patch1: 00001-pydocnogui.patch + +# Add $(CFLAGS) to the linker arguments when linking the "python" binary +# since some architectures (sparc64) need this (rhbz:199373). +# Not yet filed upstream +Patch4: python-2.5-cflags.patch + +# Work around a bug in Python' gettext module relating to the "Plural-Forms" +# header (rhbz:252136) +# Related to upstream issues: +# http://bugs.python.org/issue1448060 and http://bugs.python.org/issue1475523 +# though the proposed upstream patches are, alas, different +Patch6: python-2.5.1-plural-fix.patch + +# This patch was listed in the changelog as: +# * Fri Sep 14 2007 Jeremy Katz - 2.5.1-11 +# - fix encoding of sqlite .py files to work around weird encoding problem +# in Turkish (#283331) +# A traceback attached to rhbz 244016 shows the problem most clearly: a +# traceback on attempting to import the sqlite module, with: +# "SyntaxError: encoding problem: with BOM (__init__.py, line 1)" +# This seems to come from Parser/tokenizer.c:check_coding_spec +# Our patch changes two source files within sqlite3, removing the +# "coding: ISO-8859-1" specs and character E4 = U+00E4 = +# LATIN SMALL LETTER A WITH DIAERESIS from in ghaering's surname. +# +# It may be that the conversion of "ISO-8859-1" to "iso-8859-1" is thwarted +# by the implementation of "tolower" in the Turkish locale; see: +# https://bugzilla.redhat.com/show_bug.cgi?id=191096#c9 +# +# TODO: Not yet sent upstream, and appears to me (dmalcolm 2010-01-29) that +# it may be papering over a symptom +Patch7: python-2.5.1-sqlite-encoding.patch + +# FIXME: Lib/ctypes/util.py posix implementation defines a function +# _get_soname(f). Upstreams's implementation of this uses objdump to read the +# SONAME from a library; we avoid this, apparently to minimize space +# requirements on the live CD: +# (rhbz:307221) +Patch10: 00010-2.7.13-binutils-no-dep.patch + +# Upstream as of Python 2.7.3: +# Patch11: python-2.7rc1-codec-ascii-tolower.patch + +# Add various constants to the socketmodule (rhbz#436560): +# TODO: these patches were added in 2.5.1-22 and 2.5.1-24 but appear not to +# have been sent upstream yet: +Patch13: python-2.7rc1-socketmodule-constants.patch +Patch14: python-2.7rc1-socketmodule-constants2.patch + +# Remove an "-rpath $(LIBDIR)" argument from the linkage args in configure.in: +# FIXME: is this for OSF, not Linux? +Patch16: python-2.6-rpath.patch + +# Fixup distutils/unixccompiler.py to remove standard library path from rpath: +# Adapted from Patch0 in ivazquez' python3000 specfile, removing usage of +# super() as it's an old-style class +Patch17: python-2.6.4-distutils-rpath.patch + +# 00055 # +# Systemtap support: add statically-defined probe points +# Patch based on upstream bug: http://bugs.python.org/issue4111 +# fixed up by mjw and wcohen for 2.6.2, then fixed up by dmalcolm for 2.6.4 +# then rewritten by mjw (attachment 390110 of rhbz 545179), then reformatted +# for 2.7rc1 by dmalcolm: +Patch55: 00055-systemtap.patch + +# Only used when "%%{_lib}" == "lib64" +# Fixup various paths throughout the build and in distutils from "lib" to "lib64", +# and add the /usr/lib64/pythonMAJOR.MINOR/site-packages to sitedirs, in front of +# /usr/lib/pythonMAJOR.MINOR/site-packages +# Not upstream +Patch102: 00102-2.7.13-lib64.patch + +# Python 2.7 split out much of the path-handling from distutils/sysconfig.py to +# a new sysconfig.py (in r77704). +# We need to make equivalent changes to that new file to ensure that the stdlib +# and platform-specific code go to /usr/lib64 not /usr/lib, on 64-bit archs: +Patch103: python-2.7-lib64-sysconfig.patch + +# 00104 # +# Only used when "%%{_lib}" == "lib64" +# Another lib64 fix, for distutils/tests/test_install.py; not upstream: +Patch104: 00104-lib64-fix-for-test_install.patch + +# 00111 # +# Patch the Makefile.pre.in so that the generated Makefile doesn't try to build +# a libpythonMAJOR.MINOR.a (bug 550692): +# Downstream only: not appropriate for upstream +Patch111: 00111-no-static-lib.patch + +# 00112 # +# Patch to support building both optimized vs debug stacks DSO ABIs, sharing +# the same .py and .pyc files, using "_d.so" to signify a debug build of an +# extension module. +# +# Based on Debian's patch for the same, +# http://patch-tracker.debian.org/patch/series/view/python2.6/2.6.5-2/debug-build.dpatch +# +# (which was itself based on the upstream Windows build), but with some +# changes: +# +# * Debian's patch to dynload_shlib.c looks for module_d.so, then module.so, +# but this can potentially find a module built against the wrong DSO ABI. We +# instead search for just module_d.so in a debug build +# +# * We remove this change from configure.in's build of the Makefile: +# SO=$DEBUG_EXT.so +# so that sysconfig.py:customize_compiler stays with shared_lib_extension='.so' +# on debug builds, so that UnixCCompiler.find_library_file can find system +# libraries (otherwise "make sharedlibs" fails to find system libraries, +# erroneously looking e.g. for "libffi_d.so" rather than "libffi.so") +# +# * We change Lib/distutils/command/build_ext.py:build_ext.get_ext_filename +# to add the _d there, when building an extension. This way, "make sharedlibs" +# can build ctypes, by finding the sysmtem libffi.so (rather than failing to +# find "libffi_d.so"), and builds the module as _ctypes_d.so +# +# * Similarly, update build_ext:get_libraries handling of Py_ENABLE_SHARED by +# appending "_d" to the python library's name for the debug configuration +# +# * We modify Modules/makesetup to add the "_d" to the generated Makefile +# rules for the various Modules/*.so targets +# +# This may introduce issues when building an extension that links directly +# against another extension (e.g. users of NumPy?), but seems more robust when +# searching for external libraries +# +# * We don't change Lib/distutils/command/build.py: build.build_purelib to +# embed plat_specifier, leaving it as is, as pure python builds should be +# unaffected by these differences (we'll be sharing the .py and .pyc files) +# +# * We introduce DEBUG_SUFFIX as well as DEBUG_EXT: +# - DEBUG_EXT is used by ELF files (names and SONAMEs); it will be "_d" for +# a debug build +# - DEBUG_SUFFIX is used by filesystem paths; it will be "-debug" for a +# debug build +# +# Both will be empty in an optimized build. "_d" contains characters that +# are valid ELF metadata, but this leads to various ugly filesystem paths (such +# as the include path), and DEBUG_SUFFIX allows these paths to have more natural +# names. Changing this requires changes elsewhere in the distutils code. +# +# * We add DEBUG_SUFFIX to PYTHON in the Makefile, so that the two +# configurations build parallel-installable binaries with different names +# ("python-debug" vs "python"). +# +# * Similarly, we add DEBUG_SUFFIX within python-config and +# python$(VERSION)-config, so that the two configuration get different paths +# for these. +# +# See also patch 130 below +# +Patch112: 00112-2.7.13-debug-build.patch + + +# 00113 # +# Add configure-time support for the COUNT_ALLOCS and CALL_PROFILE options +# described at http://svn.python.org/projects/python/trunk/Misc/SpecialBuilds.txt +# so that if they are enabled, they will be in that build's pyconfig.h, so that +# extension modules will reliably use them +# Not yet sent upstream +Patch113: 00113-more-configuration-flags.patch + +# 00114 # +# Add flags for statvfs.f_flag to the constant list in posixmodule (i.e. "os") +# (rhbz:553020); partially upstream as http://bugs.python.org/issue7647 +# Not yet sent upstream +Patch114: 00114-statvfs-f_flag-constants.patch + +# Upstream r79310 removed the "Modules" directory from sys.path when Python is +# running from the build directory on POSIX to fix a unit test (issue #8205). +# This seems to have broken the compileall.py done in "make install": it cannot +# find shared library extension modules at this point in the build (sys.path +# does not contain DESTDIR/usr/lib(64)/python-2.7/lib-dynload for some reason), +# leading to the build failing with: +# Traceback (most recent call last): +# File "/home/david/rpmbuild/BUILDROOT/python-2.7-0.1.rc2.fc14.x86_64/usr/lib64/python2.7/compileall.py", line 17, in +# import struct +# File "/home/david/rpmbuild/BUILDROOT/python-2.7-0.1.rc2.fc14.x86_64/usr/lib64/python2.7/struct.py", line 1, in +# from _struct import * +# ImportError: No module named _struct +# This patch adds the build Modules directory to build path. +Patch121: 00121-add-Modules-to-build-path.patch + +# 2.7.1 (in r84230) added a test to test_abc which fails if python is +# configured with COUNT_ALLOCS, which is the case for our debug build +# (the COUNT_ALLOCS instrumentation keeps "C" alive). +# Not yet sent upstream +Patch128: python-2.7.1-fix_test_abc_with_COUNT_ALLOCS.patch + +# 00130 # +# Add "--extension-suffix" option to python-config and python-debug-config +# (rhbz#732808) +# +# This is adapted from 3.2's PEP-3149 support. +# +# Fedora's debug build has some non-standard features (see also patch 112 +# above), though largely shared with Debian/Ubuntu and Windows +# +# In particular, SO in the Makefile is currently always just ".so" for our +# python 2 optimized builds, but for python 2 debug it should be '_d.so', to +# distinguish the debug vs optimized ABI, following the pattern in the above +# patch. +# +# Not yet sent upstream +Patch130: python-2.7.2-add-extension-suffix-to-python-config.patch + +# 00131 # +# The four tests in test_io built on top of check_interrupted_write_retry +# fail when built in Koji, for ppc and ppc64; for some reason, the SIGALRM +# handlers are never called, and the call to write runs to completion +# (rhbz#732998) +Patch131: 00131-disable-tests-in-test_io.patch + +# 00132 # +# Add non-standard hooks to unittest for use in the "check" phase below, when +# running selftests within the build: +# @unittest._skipInRpmBuild(reason) +# for tests that hang or fail intermittently within the build environment, and: +# @unittest._expectedFailureInRpmBuild +# for tests that always fail within the build environment +# +# The hooks only take effect if WITHIN_PYTHON_RPM_BUILD is set in the +# environment, which we set manually in the appropriate portion of the "check" +# phase below (and which potentially other python-* rpms could set, to reuse +# these unittest hooks in their own "check" phases) +Patch132: 00132-add-rpmbuild-hooks-to-unittest.patch + +# 00133 # +# "dl" is deprecated, and test_dl doesn't work on 64-bit builds: +Patch133: 00133-skip-test_dl.patch + +# 00136 # +# Some tests try to seek on sys.stdin, but don't work as expected when run +# within Koji/mock; skip them within the rpm build: +Patch136: 00136-skip-tests-of-seeking-stdin-in-rpmbuild.patch + +# 00137 # +# Some tests within distutils fail when run in an rpmbuild: +Patch137: 00137-skip-distutils-tests-that-fail-in-rpmbuild.patch + +# 00138 # +# Fixup some tests within distutils to work with how debug builds are set up: +Patch138: 00138-fix-distutils-tests-in-debug-build.patch + +# 00139 # +# ARM-specific: skip known failure in test_float: +# http://bugs.python.org/issue8265 (rhbz#706253) +Patch139: 00139-skip-test_float-known-failure-on-arm.patch + +# 00140 # +# Sparc-specific: skip known failure in test_ctypes: +# http://bugs.python.org/issue8314 (rhbz#711584) +# which appears to be a libffi bug +Patch140: 00140-skip-test_ctypes-known-failure-on-sparc.patch + +# 00142 # +# Some pty tests fail when run in mock (rhbz#714627): +Patch142: 00142-skip-failing-pty-tests-in-rpmbuild.patch + +# 00143 # +# Fix the --with-tsc option on ppc64, and rework it on 32-bit ppc to avoid +# aliasing violations (rhbz#698726) +# Sent upstream as http://bugs.python.org/issue12872 +Patch143: 00143-tsc-on-ppc.patch + +# 00144 # +# (Optionally) disable the gdbm module: +Patch144: 00144-no-gdbm.patch + +# 00146 # +# Support OpenSSL FIPS mode (e.g. when OPENSSL_FORCE_FIPS_MODE=1 is set) +# - handle failures from OpenSSL (e.g. on attempts to use MD5 in a +# FIPS-enforcing environment) +# - add a new "usedforsecurity" keyword argument to the various digest +# algorithms in hashlib so that you can whitelist a callsite with +# "usedforsecurity=False" +# (sent upstream for python 3 as http://bugs.python.org/issue9216; this is a +# backport to python 2.7; see RHEL6 patch 119) +# - enforce usage of the _hashlib implementation: don't fall back to the _md5 +# and _sha* modules (leading to clearer error messages if fips selftests +# fail) +# - don't build the _md5 and _sha* modules; rely on the _hashlib implementation +# of hashlib (for example, md5.py will use _hashlib's implementation of MD5, +# if permitted by the FIPS setting) +# (rhbz#563986) +Patch146: 00146-hashlib-fips.patch + +# 00147 # +# Add a sys._debugmallocstats() function +# Based on patch 202 from RHEL 5's python.spec, with updates from rhbz#737198 +# Sent upstream as http://bugs.python.org/issue14785 +Patch147: 00147-add-debug-malloc-stats.patch + +# 00155 # +# Avoid allocating thunks in ctypes unless absolutely necessary, to avoid +# generating SELinux denials on "import ctypes" and "import uuid" when +# embedding Python within httpd (rhbz#814391) +Patch155: 00155-avoid-ctypes-thunks.patch + +# 00156 # +# Recent builds of gdb will only auto-load scripts from certain safe +# locations. Turn off this protection when running test_gdb in the selftest +# suite to ensure that it can load our -gdb.py script (rhbz#817072): +# Not yet sent upstream +Patch156: 00156-gdb-autoload-safepath.patch + +# 00165 # +# Backport to Python 2 from Python 3.3 of improvements to the "crypt" module +# adding precanned ways of salting a password (rhbz#835021) +# Based on r88500 patch to py3k from Python 3.3 +# plus 6482dd1c11ed, 0586c699d467, 62994662676a, 74a1110a3b50, plus edits +# to docstrings to note that this additional functionality is not standard +# within 2.7 +Patch165: 00165-crypt-module-salt-backport.patch + +# 00167 # +# Don't run any of the stack navigation tests in test_gdb when Python is +# optimized, since there appear to be many different ways in which gdb can +# fail to read the PyFrameObject* for arbitrary places in the callstack, +# presumably due to compiler optimization (rhbz#912025) +# +# Not yet sent upstream +Patch167: 00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch + +# 00169 # +# Use SHA-256 rather than implicitly using MD5 within the challenge handling +# in multiprocessing.connection +# +# Sent upstream as http://bugs.python.org/issue17258 +# (rhbz#879695) +Patch169: 00169-avoid-implicit-usage-of-md5-in-multiprocessing.patch + +# 00170 # +# In debug builds, try to print repr() when a C-level assert fails in the +# garbage collector (typically indicating a reference-counting error +# somewhere else e.g in an extension module) +# Backported to 2.7 from a patch I sent upstream for py3k +# http://bugs.python.org/issue9263 (rhbz#614680) +# hiding the proposed new macros/functions within gcmodule.c to avoid exposing +# them within the extension API. +# (rhbz#850013) +Patch170: 00170-gc-assertions.patch + +# 00174 # +# Workaround for failure to set up prefix/exec_prefix when running +# an embededed libpython that sets Py_SetProgramName() to a name not +# on $PATH when run from the root directory due to +# https://fedoraproject.org/wiki/Features/UsrMove +# e.g. cmpi-bindings under systemd (rhbz#817554): +Patch174: 00174-fix-for-usr-move.patch + +# 00180 # +# Enable building on ppc64p7 +# Not appropriate for upstream, Fedora-specific naming +Patch180: 00180-python-add-support-for-ppc64p7.patch + +# 00181 # +# Allow arbitrary timeout for Condition.wait, as reported in +# https://bugzilla.redhat.com/show_bug.cgi?id=917709 +# Upstream doesn't want this: http://bugs.python.org/issue17748 +# But we have no better solution downstream yet, and since there is +# no API breakage, we apply this patch. +# Doesn't apply to Python 3, where this is fixed otherwise and works. +Patch181: 00181-allow-arbitrary-timeout-in-condition-wait.patch + +# 00185 # +# Makes urllib2 honor "no_proxy" enviroment variable for "ftp:" URLs +# when ftp_proxy is set +Patch185: 00185-urllib2-honors-noproxy-for-ftp.patch + +# 00187 # +# Add an explicit RPATH to pyexpat.so pointing at the directory +# containing the system expat (which has the extra XML_SetHashSalt +# symbol), to avoid an ImportError with a link error if there's an +# LD_LIBRARY_PATH containing a "vanilla" build of expat (without the +# symbol) +Patch187: 00187-add-RPATH-to-pyexpat.patch + +# 00191 # +# Disabling NOOP test as it fails without internet connection +Patch191: 00191-disable-NOOP.patch + +# 00193 # +# Enable loading sqlite extensions. This patch isn't needed for +# python3.spec, since Python 3 has a configuration option for this. +# rhbz#1066708 +# Patch provided by John C. Peterson +Patch193: 00193-enable-loading-sqlite-extensions.patch + +# 00198 # +Patch198: 00198-add-rewheel-module.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#1565560 +# DOWNSTREAM ONLY PATCH +Patch257: 00257-threading-wait-clamp-remaining-time.patch + +# 00288 # +# Adds a warning when /usr/bin/python is invoked during rpmbuild +# See https://fedoraproject.org/wiki/Changes/Avoid_usr_bin_python_in_RPM_Build +Patch288: 00288-disable-python2.patch + +# 00289 # +# Disable automatic detection for the nis module +# (we handle it it in Setup.dist, see Patch0) +Patch289: 00289-disable-nis-detection.patch + +# (New patches go here ^^^) +# +# When adding new patches to "python2" and "python3" in Fedora, EL, etc., +# please try to keep the patch numbers in-sync between all specfiles. +# +# More information, and a patch number catalog, is at: +# +# https://fedoraproject.org/wiki/SIGs/Python/PythonPatches + +# This is the generated patch to "configure"; see the description of +# %%{regenerate_autotooling_patch} +# above: + +# Disable tk for modularity builds to break up build dependencies +Patch04000: 04000-modularity-disable-tk.patch + +Patch5000: 05000-autotool-intermediates.patch + +# ====================================================== +# Additional metadata, and subpackages +# ====================================================== + +# Providing python27 as now multiple interpreters exist in Fedora +# alongside the system one e.g. python26, python33 etc +Provides: python27 = %{version}-%{release} + + +URL: https://www.python.org/ + +%description +Python 2 is an old version of the language that is incompatible with the 3.x +line of releases. The language is mostly the same, but many details, especially +how built-in objects like dictionaries and strings work, have changed +considerably, and a lot of deprecated features have finally been removed in the +3.x line. + +Note that documentation for Python 2 is provided in the python2-docs +package. + +This package provides the "python2" executable; most of the actual +implementation is within the "python2-libs" package. + +%package for-tests +Summary: The python2-for-tests-command +Requires: %{python}-libs%{?_isa} = %{version}-%{release} + +%description for-tests +This package provides the "python2-for-tests" executable, a working +Python 2 interpreter intended for use only in test harnesses that +were not ported to Python 3 yet. + +Install this package, but not "python2", to approximate a system that +lacks Python 2 entirely. + + +%package libs +Summary: Runtime libraries for Python 2 +Group: Applications/System + +# Needed for ctypes, to load libraries, worked around for Live CDs size +# Requires: binutils + +# expat 2.1.0 added the symbol XML_SetHashSalt without bumping SONAME. We use +# this symbol (in pyexpat), so we must explicitly state this dependency to +# prevent "import pyexpat" from failing with a linker error if someone hasn't +# yet upgraded expat: +Requires: expat >= 2.1.0 + +# Python built with glibc >= 2.24.90-26 needs to require it (rhbz#1410644). +Requires: glibc%{?_isa} >= 2.24.90-26 + +%if %{with_gdbm} +# ABI change without soname bump, reverted +Requires: gdbm%{?_isa} >= 1:1.13 +%endif + +Provides: python-libs = %{version}-%{release} +Provides: python-libs%{?_isa} = %{version}-%{release} + +%description libs +This package contains files used to embed Python 2 into applications. + +%package devel +Summary: Libraries and header files needed for Python 2 development +Group: Development/Libraries +Requires: %{python}%{?_isa} = %{version}-%{release} +Requires: python-rpm-macros +Requires: python2-rpm-macros +Requires: python3-rpm-generators +Requires: pkgconfig + +# https://bugzilla.redhat.com/show_bug.cgi?id=1217376 +# https://bugzilla.redhat.com/show_bug.cgi?id=1496757 +# https://bugzilla.redhat.com/show_bug.cgi?id=1218294 +# TODO change to a specific subpackage once available (#1218294) +Requires: redhat-rpm-config + +# Needed here because of the migration of Makefile from -devel to the main +# package +Conflicts: %{python} < %{version}-%{release} + +Provides: python-devel = %{version}-%{release} +Provides: python-devel%{?_isa} = %{version}-%{release} + +%description devel +This package contains libraries and header files used to build applications +with and native libraries for Python 2 + +%if %{with tk_and_tools} +%package tools +Summary: A collection of development tools included with Python 2 +Group: Development/Tools +Requires: %{name} = %{version}-%{release} +Requires: %{python}-tkinter = %{version}-%{release} + +Provides: python-tools = %{version}-%{release} +Provides: python-tools%{?_isa} = %{version}-%{release} + +%description tools +This package includes several tools to help with the development of Python 2 +programs, including IDLE (an IDE with editing and debugging facilities), a +color editor (pynche), and a python gettext program (pygettext.py). + +%package tkinter +Summary: A graphical user interface for the Python 2 scripting language +Group: Development/Languages +Requires: %{name} = %{version}-%{release} + +Provides: tkinter = %{version}-%{release} +Provides: tkinter%{?_isa} = %{version}-%{release} +Provides: tkinter2 = %{version}-%{release} +Provides: tkinter2%{?_isa} = %{version}-%{release} +Provides: python-tkinter = %{version}-%{release} +Provides: python-tkinter%{?_isa} = %{version}-%{release} + +%description tkinter + +The Tkinter (Tk interface) program is an graphical user interface for +the Python 2 scripting language. + +You should install the python2tkinter package if you'd like to use a graphical +user interface for Python 2 programming. +%endif %{with tk_and_tools} + +%package test +Summary: The test modules from the main python2 package +Group: Development/Languages +Requires: %{name} = %{version}-%{release} + +Provides: python-test = %{version}-%{release} +Provides: python-test%{?_isa} = %{version}-%{release} + +%description test + +The test modules from the main python2 package: %{name} +These have been removed to save space, as they are never or almost +never used in production. + +You might want to install the python2-test package if you're developing python 2 +code that uses more than just unittest and/or test.support. + +%if %{with debug_build} +%package debug +Summary: Debug version of the Python 2 runtime +Group: Applications/System + +# The debug build is an all-in-one package version of the regular build, and +# shares the same .py/.pyc files and directories as the regular build. Hence +# we depend on all of the subpackages of the regular build: +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-devel%{?_isa} = %{version}-%{release} +Requires: %{name}-test%{?_isa} = %{version}-%{release} +%if %{with tk_and_tools} +Requires: %{python}-tkinter%{?_isa} = %{version}-%{release} +Requires: %{name}-tools%{?_isa} = %{version}-%{release} +%endif #{with tk_and_tools} + +Provides: python-debug = %{version}-%{release} +Provides: python-debug%{?_isa} = %{version}-%{release} + +%description debug +python2-debug provides a version of the Python 2 runtime with numerous debugging +features enabled, aimed at advanced Python users, such as developers of Python +extension modules. + +This version uses more memory and will be slower than the regular Python 2 build, +but is useful for tracking down reference-counting issues, and other bugs. + +The bytecodes are unchanged, so that .pyc files are compatible between the two +version of Python 2, but the debugging features mean that C/C++ extension modules +are ABI-incompatible with those built for the standard runtime. + +It shares installation directories with the standard Python 2 runtime, so that +.py and .pyc files can be shared. All compiled extension modules gain a "_d" +suffix ("foo_d.so" rather than "foo.so") so that each Python 2 implementation can +load its own extensions. +%endif # with debug_build + + +# ====================================================== +# The prep phase of the build: +# ====================================================== + +%prep +%setup -q -n Python-%{version} + +%if 0%{?with_systemtap} +# Provide an example of usage of the tapset: +cp -a %{SOURCE4} . +cp -a %{SOURCE5} . +%endif # with_systemtap + +# Ensure that we're using the system copy of various libraries, rather than +# copies shipped by upstream in the tarball: +# Remove embedded copy of expat: +rm -r Modules/expat || exit 1 + +# Remove embedded copy of libffi: +for SUBDIR in darwin libffi libffi_arm_wince libffi_msvc libffi_osx ; do + rm -r Modules/_ctypes/$SUBDIR || exit 1 ; +done + +# Remove embedded copy of zlib: +rm -r Modules/zlib || exit 1 + +## Disabling hashlib patch for now as it needs to be reimplemented +## for OpenSSL 1.1.0. +# Don't build upstream Python's implementation of these crypto algorithms; +# instead rely on _hashlib and OpenSSL. +# +# For example, in our builds md5.py uses always uses hashlib.md5 (rather than +# falling back to _md5 when hashlib.md5 is not available); hashlib.md5 is +# implemented within _hashlib via OpenSSL (and thus respects FIPS mode) +#for f in md5module.c md5.c shamodule.c sha256module.c sha512module.c; do +# rm Modules/$f +#done + +# +# Apply patches: +# +%patch0 -p1 -b .rhconfig +%patch1 -p1 -b .no_gui +%patch4 -p1 -b .cflags +%patch6 -p1 -b .plural +%patch7 -p1 + +%if "%{_lib}" == "lib64" +%patch102 -p1 -b .lib64 +%patch103 -p1 -b .lib64-sysconfig +%patch104 -p1 +%endif + +%patch10 -p1 -b .binutils-no-dep +%patch13 -p1 -b .socketmodule +%patch14 -p1 -b .socketmodule2 +%patch16 -p1 -b .rpath +%patch17 -p1 -b .distutils-rpath + +%if 0%{?with_systemtap} +%patch55 -p1 -b .systemtap +%endif + +%patch111 -p1 -b .no-static-lib + +%patch112 -p1 -b .debug-build + +%patch113 -p1 -b .more-configuration-flags + +%patch114 -p1 -b .statvfs-f-flag-constants + + +%patch121 -p1 +%patch128 -p1 + +%patch130 -p1 + +%ifarch ppc %{power64} +%patch131 -p1 +%endif + +%patch132 -p1 +%patch133 -p1 +%patch136 -p1 -b .stdin-test +%patch137 -p1 +%patch138 -p1 +%ifarch %{arm} +%patch139 -p1 +%endif +%ifarch %{sparc} +%patch140 -p1 +%endif +%patch142 -p1 -b .tty-fail +%patch143 -p1 -b .tsc-on-ppc +%if !%{with_gdbm} +%patch144 -p1 +%endif +#patch146 -p1 +%patch147 -p1 +%patch155 -p1 +%patch156 -p1 +%patch165 -p1 +mv Modules/cryptmodule.c Modules/_cryptmodule.c +%patch167 -p1 +%patch169 -p1 +%patch170 -p1 +%patch174 -p1 -b .fix-for-usr-move +%patch180 -p1 +%patch181 -p1 +%patch185 -p1 +%patch187 -p1 +%patch191 -p1 +%patch193 -p1 +%if %{with rewheel} +%patch198 -p1 +%endif +%patch257 -p1 +%patch288 -p1 +%patch289 -p1 + +%if ! %{with tk_and_tools} +%patch4000 -p1 +%endif + +# This shouldn't be necesarry, but is right now (2.2a3) +find -name "*~" |xargs rm -f + +%if ! 0%{regenerate_autotooling_patch} +# Normally we apply the patch to "configure" +# We don't apply the patch if we're working towards regenerating it +%patch5000 -p0 -b .autotool-intermediates +%endif + + +# ====================================================== +# Configuring and building the code: +# ====================================================== + +%build +export RHEL_ALLOW_PYTHON2_FOR_BUILD=1 +topdir=$(pwd) +export CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC -fwrapv" +export CXXFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC -fwrapv" +export CPPFLAGS="$(pkg-config --cflags-only-I libffi)" +export OPT="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC -fwrapv" +export LINKCC="gcc" +export LDFLAGS="$RPM_LD_FLAGS" +if pkg-config openssl ; then + export CFLAGS="$CFLAGS $(pkg-config --cflags openssl)" + export LDFLAGS="$LDFLAGS $(pkg-config --libs-only-L openssl)" +fi +# Force CC +export CC=gcc + +%if 0%{regenerate_autotooling_patch} +# If enabled, this code regenerates the patch to "configure", using a +# local copy of autoconf-2.65, then exits the build +# +# The following assumes that the copy is installed to ~/autoconf-2.65/bin +# as per these instructions: +# http://bugs.python.org/issue7997 + +for f in pyconfig.h.in configure ; do + cp $f $f.autotool-intermediates ; +done + +# Rerun the autotools: +PATH=~/autoconf-2.65/bin:$PATH autoconf +autoheader + +# Regenerate the patch: +gendiff . .autotool-intermediates > %{PATCH5000} + + +# Exit the build +exit 1 +%endif + +# Define a function, for how to perform a "build" of python for a given +# configuration: +BuildPython() { + ConfName=$1 + BinaryName=$2 + SymlinkName=$3 + ExtraConfigArgs=$4 + PathFixWithThisBinary=$5 + + ConfDir=build/$ConfName + + echo STARTING: BUILD OF PYTHON FOR CONFIGURATION: $ConfName - %{_bindir}/$BinaryName + mkdir -p $ConfDir + + pushd $ConfDir + + # Use the freshly created "configure" script, but in the directory two above: + %global _configure $topdir/configure + +%configure \ + --enable-ipv6 \ + --enable-shared \ + --enable-unicode=%{unicode} \ + --with-dbmliborder=gdbm:ndbm:bdb \ + --with-system-expat \ + --with-system-ffi \ +%if 0%{?with_systemtap} + --with-dtrace \ + --with-tapset-install-dir=%{tapsetdir} \ +%endif +%if 0%{?with_valgrind} + --with-valgrind \ +%endif + $ExtraConfigArgs \ + %{nil} + +make EXTRA_CFLAGS="$CFLAGS" %{?_smp_mflags} + +# We need to fix shebang lines across the full source tree. +# +# We do this using the pathfix.py script, which requires one of the +# freshly-built Python binaries. +# +# We use the optimized python binary, and make the shebangs point at that same +# optimized python binary: +if $PathFixWithThisBinary +then + # pathfix.py currently only works with files matching ^[a-zA-Z0-9_]+\.py$ + # when crawling through directories, so we handle the special cases manually + LD_LIBRARY_PATH="$topdir/$ConfDir" ./$BinaryName \ + $topdir/Tools/scripts/pathfix.py \ + -i "%{_bindir}/python%{pybasever}" \ + $topdir \ + $topdir/Tools/pynche/pynche \ + $topdir/Demo/pdist/{rcvs,rcsbump,rrcs} \ + $topdir/Demo/scripts/find-uname.py \ + $topdir/Tools/scripts/reindent-rst.py +fi + +# Rebuild with new python +# We need a link to a versioned python in the build directory +ln -s $BinaryName $SymlinkName +LD_LIBRARY_PATH="$topdir/$ConfDir" PATH=$PATH:$topdir/$ConfDir make -s EXTRA_CFLAGS="$CFLAGS" %{?_smp_mflags} + + popd + echo FINISHED: BUILD OF PYTHON FOR CONFIGURATION: $ConfDir +} + +# Use "BuildPython" to support building with different configurations: + +%if %{with debug_build} +BuildPython debug \ + python-debug \ + python%{pybasever}-debug \ +%ifarch %{ix86} x86_64 ppc %{power64} + "--with-pydebug --with-tsc --with-count-allocs --with-call-profile" \ +%else + "--with-pydebug --with-count-allocs --with-call-profile" \ +%endif + false +%endif # with debug_build + +BuildPython optimized \ + python \ + python%{pybasever} \ +%ifarch %{ix86} x86_64 + "" \ +%else + "" \ +%endif + true + + +# ====================================================== +# Installing the built code: +# ====================================================== + +%install +export RHEL_ALLOW_PYTHON2_FOR_BUILD=1 +topdir=$(pwd) +rm -rf %{buildroot} +mkdir -p %{buildroot}%{_prefix} %{buildroot}%{_mandir} + +# Clean up patched .py files that are saved as .lib64 +for f in distutils/command/install distutils/sysconfig; do + rm -f Lib/$f.py.lib64 +done + +InstallPython() { + + ConfName=$1 + BinaryName=$2 + PyInstSoName=$3 + + ConfDir=build/$ConfName + + echo STARTING: INSTALL OF PYTHON FOR CONFIGURATION: $ConfName - %{_bindir}/$BinaryName + mkdir -p $ConfDir + + pushd $ConfDir + +make install DESTDIR=%{buildroot} + +# We install a collection of hooks for gdb that make it easier to debug +# executables linked against libpython (such as /usr/lib/python itself) +# +# These hooks are implemented in Python itself +# +# gdb-archer looks for them in the same path as the ELF file, with a -gdb.py suffix. +# We put them in the debuginfo package by installing them to e.g.: +# /usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py +# (note that the debug path is /usr/lib/debug for both 32/64 bit) +# +# See https://fedoraproject.org/wiki/Features/EasierPythonDebugging for more +# information +# +# Initially I tried: +# /usr/lib/libpython2.6.so.1.0-gdb.py +# but doing so generated noise when ldconfig was rerun (rhbz:562980) +# +%if 0%{?with_gdb_hooks} +DirHoldingGdbPy=%{_prefix}/lib/debug/%{_libdir} +PathOfGdbPy=$DirHoldingGdbPy/$PyInstSoName.debug-gdb.py + +mkdir -p %{buildroot}$DirHoldingGdbPy +cp $topdir/Tools/gdb/libpython.py %{buildroot}$PathOfGdbPy + +# Manually byte-compile the file, in case find-debuginfo.sh is run before +# brp-python-bytecompile, so that the .pyc/.pyo files are properly listed in +# the debuginfo manifest: +LD_LIBRARY_PATH="$topdir/$ConfDir" $topdir/$ConfDir/$BinaryName \ + -c "import compileall; import sys; compileall.compile_dir('%{buildroot}$DirHoldingGdbPy', ddir='$DirHoldingGdbPy')" + +LD_LIBRARY_PATH="$topdir/$ConfDir" $topdir/$ConfDir/$BinaryName -O \ + -c "import compileall; import sys; compileall.compile_dir('%{buildroot}$DirHoldingGdbPy', ddir='$DirHoldingGdbPy')" +%endif # with_gdb_hooks + + popd + + echo FINISHED: INSTALL OF PYTHON FOR CONFIGURATION: $ConfName +} + +# Use "InstallPython" to support building with different configurations: + +# Install the "debug" build first, so that we can move some files aside +%if %{with debug_build} +InstallPython debug \ + python%{pybasever}-debug \ + %{py_INSTSONAME_debug} +%endif # with debug_build + +# Now the optimized build: +InstallPython optimized \ + python%{pybasever} \ + %{py_INSTSONAME_optimized} + + +# Fix the interpreter path in binaries installed by distutils +# (which changes them by itself) +# Make sure we preserve the file permissions +for fixed in %{buildroot}%{_bindir}/pydoc; do + sed 's,#!.*/python$,#!/usr/bin/env python%{pybasever},' $fixed > $fixed- \ + && cat $fixed- > $fixed && rm -f $fixed- +done + +# Junk, no point in putting in -test sub-pkg +rm -f %{buildroot}/%{pylibdir}/idlelib/testcode.py* + +# don't include tests that are run at build time in the package +# This is documented, and used: rhbz#387401 +if /bin/false; then + # Move this to -test subpackage. +mkdir save_bits_of_test +for i in test_support.py __init__.py; do + cp -a %{buildroot}/%{pylibdir}/test/$i save_bits_of_test +done +rm -rf %{buildroot}/%{pylibdir}/test +mkdir %{buildroot}/%{pylibdir}/test +cp -a save_bits_of_test/* %{buildroot}/%{pylibdir}/test +fi + +# tools + +mkdir -p ${RPM_BUILD_ROOT}%{site_packages} + +#pynche +install -p -m755 %{SOURCE7} ${RPM_BUILD_ROOT}%{_bindir}/pynche +chmod 755 ${RPM_BUILD_ROOT}%{_bindir}/pynche +rm -f Tools/pynche/*.pyw +cp -rp Tools/pynche \ + ${RPM_BUILD_ROOT}%{site_packages}/ + +mv Tools/pynche/README Tools/pynche/README.pynche + +#gettext +install -m755 Tools/i18n/pygettext.py %{buildroot}%{_bindir}/ +install -m755 Tools/i18n/msgfmt.py %{buildroot}%{_bindir}/ + +# Useful development tools +install -m755 -d %{buildroot}%{tools_dir}/scripts +install Tools/README %{buildroot}%{tools_dir}/ +install Tools/scripts/*py %{buildroot}%{tools_dir}/scripts/ + +# Documentation tools +install -m755 -d %{buildroot}%{doc_tools_dir} +#install -m755 Doc/tools/mkhowto %{buildroot}%{doc_tools_dir} + +# Useful demo scripts +install -m755 -d %{buildroot}%{demo_dir} +cp -ar Demo/* %{buildroot}%{demo_dir} + +# Get rid of crap +find %{buildroot}/ -name "*~"|xargs rm -f +find %{buildroot}/ -name ".cvsignore"|xargs rm -f +find %{buildroot}/ -name "*.bat"|xargs rm -f +find . -name "*~"|xargs rm -f +find . -name ".cvsignore"|xargs rm -f +#zero length +rm -f %{buildroot}%{pylibdir}/LICENSE.txt + + +# Provide binaries in the form of bin2 and bin2.7, thus implementing +# (and expanding) the recommendations of PEP 394. +mv %{buildroot}%{_bindir}/idle %{buildroot}%{_bindir}/idle%{pybasever} +ln -s ./idle%{pybasever} %{buildroot}%{_bindir}/idle2 +ln -s ./idle2 %{buildroot}%{_bindir}/idle + +mv %{buildroot}%{_bindir}/pynche %{buildroot}%{_bindir}/pynche%{pybasever} +ln -s ./pynche%{pybasever} %{buildroot}%{_bindir}/pynche2 +ln -s ./pynche2 %{buildroot}%{_bindir}/pynche + +mv %{buildroot}%{_bindir}/pydoc %{buildroot}%{_bindir}/pydoc%{pybasever} +ln -s ./pydoc%{pybasever} %{buildroot}%{_bindir}/pydoc2 +ln -s ./pydoc2 %{buildroot}%{_bindir}/pydoc + +mv %{buildroot}%{_bindir}/pygettext.py %{buildroot}%{_bindir}/pygettext%{pybasever}.py +ln -s ./pygettext%{pybasever}.py %{buildroot}%{_bindir}/pygettext2.py +ln -s ./pygettext2.py %{buildroot}%{_bindir}/pygettext.py + +mv %{buildroot}%{_bindir}/msgfmt.py %{buildroot}%{_bindir}/msgfmt%{pybasever}.py +ln -s ./msgfmt%{pybasever}.py %{buildroot}%{_bindir}/msgfmt2.py +ln -s ./msgfmt2.py %{buildroot}%{_bindir}/msgfmt.py + +mv %{buildroot}%{_bindir}/smtpd.py %{buildroot}%{_bindir}/smtpd%{pybasever}.py +ln -s ./smtpd%{pybasever}.py %{buildroot}%{_bindir}/smtpd2.py +ln -s ./smtpd2.py %{buildroot}%{_bindir}/smtpd.py + +# Fix bug #143667: python should own /usr/lib/python2.x on 64-bit machines +%if "%{_lib}" == "lib64" +install -d %{buildroot}/%{_prefix}/lib/python%{pybasever}/site-packages +%endif + +# Make python-devel multilib-ready (bug #192747, #139911) +%global _pyconfig32_h pyconfig-32.h +%global _pyconfig64_h pyconfig-64.h + +%ifarch %{power64} s390x x86_64 ia64 alpha sparc64 aarch64 %{mips64} riscv64 +%global _pyconfig_h %{_pyconfig64_h} +%else +%global _pyconfig_h %{_pyconfig32_h} +%endif + +%if %{with debug_build} +%global PyIncludeDirs python%{pybasever} python%{pybasever}-debug +%else +%global PyIncludeDirs python%{pybasever} +%endif + +for PyIncludeDir in %{PyIncludeDirs} ; do + mv %{buildroot}%{_includedir}/$PyIncludeDir/pyconfig.h \ + %{buildroot}%{_includedir}/$PyIncludeDir/%{_pyconfig_h} + cat > %{buildroot}%{_includedir}/$PyIncludeDir/pyconfig.h << EOF +#include + +#if __WORDSIZE == 32 +#include "%{_pyconfig32_h}" +#elif __WORDSIZE == 64 +#include "%{_pyconfig64_h}" +#else +#error "Unknown word size" +#endif +EOF +done +ln -s ../../libpython%{pybasever}.so %{buildroot}%{pylibdir}/config/libpython%{pybasever}.so + +# Fix for bug 201434: make sure distutils looks at the right pyconfig.h file +# Similar for sysconfig: sysconfig.get_config_h_filename tries to locate +# pyconfig.h so it can be parsed, and needs to do this at runtime in site.py +# when python starts up. +# +# Split this out so it goes directly to the pyconfig-32.h/pyconfig-64.h +# variants: +sed -i -e "s/'pyconfig.h'/'%{_pyconfig_h}'/" \ + %{buildroot}%{pylibdir}/distutils/sysconfig.py \ + %{buildroot}%{pylibdir}/sysconfig.py + +# Ensure that the curses module was linked against libncursesw.so, rather than +# libncurses.so (bug 539917) +ldd %{buildroot}/%{dynload_dir}/_curses*.so \ + | grep curses \ + | grep libncurses.so && (echo "_curses.so linked against libncurses.so" ; exit 1) + +# Ensure that the debug modules are linked against the debug libpython, and +# likewise for the optimized modules and libpython: +for Module in %{buildroot}/%{dynload_dir}/*.so ; do + case $Module in + *_d.so) + ldd $Module | grep %{py_INSTSONAME_optimized} && + (echo Debug module $Module linked against optimized %{py_INSTSONAME_optimized} ; exit 1) + + ;; + *) + ldd $Module | grep %{py_INSTSONAME_debug} && + (echo Optimized module $Module linked against debug %{py_INSTSONAME_optimized} ; exit 1) + ;; + esac +done + +# +# Systemtap hooks: +# +%if 0%{?with_systemtap} +# Install a tapset for this libpython into tapsetdir, fixing up the path to the +# library: +mkdir -p %{buildroot}%{tapsetdir} +%ifarch %{power64} s390x x86_64 ia64 alpha sparc64 aarch64 %{mips64} +%global libpython_stp_optimized libpython%{pybasever}-64.stp +%global libpython_stp_debug libpython%{pybasever}-debug-64.stp +%else +%global libpython_stp_optimized libpython%{pybasever}-32.stp +%global libpython_stp_debug libpython%{pybasever}-debug-32.stp +%endif + +sed \ + -e "s|LIBRARY_PATH|%{_libdir}/%{py_INSTSONAME_optimized}|" \ + %{SOURCE3} \ + > %{buildroot}%{tapsetdir}/%{libpython_stp_optimized} + +%if %{with debug_build} +sed \ + -e "s|LIBRARY_PATH|%{_libdir}/%{py_INSTSONAME_debug}|" \ + %{SOURCE3} \ + > %{buildroot}%{tapsetdir}/%{libpython_stp_debug} +%endif # with debug_build +%endif # with_systemtap + +# Do bytecompilation with the newly installed interpreter. +# compile *.pyo +find %{buildroot} -type f -a -name "*.py" -print0 | \ + LD_LIBRARY_PATH="%{buildroot}%{dynload_dir}/:%{buildroot}%{_libdir}" \ + PYTHONPATH="%{buildroot}%{_libdir}/python%{pybasever} %{buildroot}%{_libdir}/python%{pybasever}/site-packages" \ + xargs -0 %{buildroot}%{_bindir}/python%{pybasever} -O -c 'import py_compile, sys; [py_compile.compile(f, dfile=f.partition("%{buildroot}")[2]) for f in sys.argv[1:]]' || : +# compile *.pyc +find %{buildroot} -type f -a -name "*.py" -print0 | \ + LD_LIBRARY_PATH="%{buildroot}%{dynload_dir}/:%{buildroot}%{_libdir}" \ + PYTHONPATH="%{buildroot}%{_libdir}/python%{pybasever} %{buildroot}%{_libdir}/python%{pybasever}/site-packages" \ + xargs -0 %{buildroot}%{_bindir}/python%{pybasever} -c 'import py_compile, sys; [py_compile.compile(f, dfile=f.partition("%{buildroot}")[2]) for f in sys.argv[1:]]' || : + + +# Make library-files user writable +/usr/bin/chmod 755 %{buildroot}%{dynload_dir}/*.so +/usr/bin/chmod 755 %{buildroot}%{_libdir}/libpython%{pybasever}.so.1.0 +%if %{with debug_build} +/usr/bin/chmod 755 %{buildroot}%{_libdir}/libpython%{pybasever}_d.so.1.0 +%endif # with debug_build + +# Add an executable for tests +cp %{buildroot}%{_bindir}/python%{pybasever} %{buildroot}%{_bindir}/python2-for-tests +# Remove unversioned executables +rm %{buildroot}%{_bindir}/python +rm %{buildroot}%{_bindir}/idle +rm %{buildroot}%{_bindir}/pydoc +rm %{buildroot}%{_bindir}/pynche +rm %{buildroot}%{_bindir}/smtpd.py +rm %{buildroot}%{_bindir}/python-config +# Remove unversioned manpage +rm %{buildroot}%{_mandir}/man1/python.* + + +# ====================================================== +# Running the upstream test suite +# ====================================================== + +%check +export RHEL_ALLOW_PYTHON2_FOR_BUILD=1 +topdir=$(pwd) +CheckPython() { + ConfName=$1 + BinaryName=$2 + ConfDir=$(pwd)/build/$ConfName + + export OPENSSL_CONF=/non-existing-file + + echo STARTING: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName + + # Note that we're running the tests using the version of the code in the + # builddir, not in the buildroot. + + pushd $ConfDir + + EXTRATESTOPTS="--verbose" + +%ifarch s390 s390x %{power64} %{arm} aarch64 %{mips} + EXTRATESTOPTS="$EXTRATESTOPTS -x test_gdb" +%endif +%ifarch %{mips64} + EXTRATESTOPTS="$EXTRATESTOPTS -x test_ctypes" +%endif + +%if 0%{?with_huntrleaks} + # Try to detect reference leaks on debug builds. By default this means + # running every test 10 times (6 to stabilize, then 4 to watch): + if [ "$ConfName" = "debug" ] ; then + EXTRATESTOPTS="$EXTRATESTOPTS --huntrleaks : " + fi +%endif + + # Run the upstream test suite, setting "WITHIN_PYTHON_RPM_BUILD" so that the + # our non-standard decorators take effect on the relevant tests: + # @unittest._skipInRpmBuild(reason) + # @unittest._expectedFailureInRpmBuild + WITHIN_PYTHON_RPM_BUILD= EXTRATESTOPTS="$EXTRATESTOPTS -x test_distutils" make test + + popd + + echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName + +} + +%if %{with tests} + +# no locale coercion in python2 +# test_ssl:test_load_dh_params shutil.copies into unicode filename +export LC_ALL=C.utf-8 + +# Check each of the configurations: +%if %{with debug_build} +CheckPython \ + debug \ + python%{pybasever}-debug +%endif # with debug_build +CheckPython \ + optimized \ + python%{pybasever} + +%endif # with tests + + +# ====================================================== +# Cleaning up +# ====================================================== + + +%files +%defattr(-, root, root, -) +%{!?_licensedir:%global license %%doc} +%license LICENSE +%doc README +%{_bindir}/pydoc* +%{_bindir}/%{python} +%{_bindir}/python%{pybasever} +%{_mandir}/*/* + +%files for-tests +%license LICENSE +%{_bindir}/python2-for-tests + +%files libs +%defattr(-,root,root,-) +%{!?_licensedir:%global license %%doc} +%license LICENSE +%doc README +%dir %{pylibdir} +%dir %{dynload_dir} + +%{dynload_dir}/_md5module.so +%{dynload_dir}/_sha256module.so +%{dynload_dir}/_sha512module.so +%{dynload_dir}/_shamodule.so + +%{dynload_dir}/Python-%{version}-py%{pybasever}.egg-info +%{dynload_dir}/_bisectmodule.so +%{dynload_dir}/_bsddb.so +%{dynload_dir}/_codecs_cn.so +%{dynload_dir}/_codecs_hk.so +%{dynload_dir}/_codecs_iso2022.so +%{dynload_dir}/_codecs_jp.so +%{dynload_dir}/_codecs_kr.so +%{dynload_dir}/_codecs_tw.so +%{dynload_dir}/_collectionsmodule.so +%{dynload_dir}/_csv.so +%{dynload_dir}/_ctypes.so +%{dynload_dir}/_curses.so +%{dynload_dir}/_curses_panel.so +%{dynload_dir}/_elementtree.so +%{dynload_dir}/_functoolsmodule.so +%{dynload_dir}/_hashlib.so +%{dynload_dir}/_heapq.so +%{dynload_dir}/_hotshot.so +%{dynload_dir}/_io.so +%{dynload_dir}/_json.so +%{dynload_dir}/_localemodule.so +%{dynload_dir}/_lsprof.so +%{dynload_dir}/_multibytecodecmodule.so +%{dynload_dir}/_multiprocessing.so +%{dynload_dir}/_randommodule.so +%{dynload_dir}/_socketmodule.so +%{dynload_dir}/_sqlite3.so +%{dynload_dir}/_ssl.so +%{dynload_dir}/_struct.so +%{dynload_dir}/arraymodule.so +%{dynload_dir}/audioop.so +%{dynload_dir}/binascii.so +%{dynload_dir}/bz2.so +%{dynload_dir}/cPickle.so +%{dynload_dir}/cStringIO.so +%{dynload_dir}/cmathmodule.so +%{dynload_dir}/_cryptmodule.so +%{dynload_dir}/datetime.so +%{dynload_dir}/dbm.so +%{dynload_dir}/dlmodule.so +%{dynload_dir}/fcntlmodule.so +%{dynload_dir}/future_builtins.so +%if %{with_gdbm} +%{dynload_dir}/gdbmmodule.so +%endif +%{dynload_dir}/grpmodule.so +%{dynload_dir}/imageop.so +%{dynload_dir}/itertoolsmodule.so +%{dynload_dir}/linuxaudiodev.so +%{dynload_dir}/math.so +%{dynload_dir}/mmapmodule.so +%{dynload_dir}/nismodule.so +%{dynload_dir}/operator.so +%{dynload_dir}/ossaudiodev.so +%{dynload_dir}/parsermodule.so +%{dynload_dir}/pyexpat.so +%{dynload_dir}/readline.so +%{dynload_dir}/resource.so +%{dynload_dir}/selectmodule.so +%{dynload_dir}/spwdmodule.so +%{dynload_dir}/stropmodule.so +%{dynload_dir}/syslog.so +%{dynload_dir}/termios.so +%{dynload_dir}/timemodule.so +%{dynload_dir}/timingmodule.so +%{dynload_dir}/unicodedata.so +%{dynload_dir}/xxsubtype.so +%{dynload_dir}/zlibmodule.so + +%dir %{site_packages} +%{site_packages}/README +%{pylibdir}/*.py* +%{pylibdir}/*.doc +%{pylibdir}/wsgiref.egg-info +%dir %{pylibdir}/bsddb +%{pylibdir}/bsddb/*.py* +%{pylibdir}/compiler +%dir %{pylibdir}/ctypes +%{pylibdir}/ctypes/*.py* +%{pylibdir}/ctypes/macholib +%{pylibdir}/curses +%dir %{pylibdir}/distutils +%{pylibdir}/distutils/*.py* +%{pylibdir}/distutils/README +%{pylibdir}/distutils/command +%exclude %{pylibdir}/distutils/command/wininst-*.exe +%dir %{pylibdir}/email +%{pylibdir}/email/*.py* +%{pylibdir}/email/mime +%{pylibdir}/encodings +%{pylibdir}/hotshot +%{pylibdir}/idlelib +%{pylibdir}/importlib +%dir %{pylibdir}/json +%{pylibdir}/json/*.py* +%{pylibdir}/lib2to3 +%exclude %{pylibdir}/lib2to3/tests +%{pylibdir}/logging +%{pylibdir}/multiprocessing +%{pylibdir}/plat-linux2 +%{pylibdir}/pydoc_data +%dir %{pylibdir}/sqlite3 +%{pylibdir}/sqlite3/*.py* + +# Some bits of test are used for actual testing of stuff, not just python itself: +# See also https://bugzilla.redhat.com/show_bug.cgi?id=1528899 +%dir %{pylibdir}/test +%{pylibdir}/test/__init__.py* +%{pylibdir}/test/support/ +%{pylibdir}/test/script_helper.py* +%{pylibdir}/test/test_support.py* + +%{pylibdir}/unittest +%{pylibdir}/wsgiref +%{pylibdir}/xml +%if "%{_lib}" == "lib64" +%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever} +%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever}/site-packages +%endif + +# "Makefile" and the config-32/64.h file are needed by +# distutils/sysconfig.py:_init_posix(), so we include them in the libs +# package, along with their parent directories (bug 531901): +%dir %{pylibdir}/config +%{pylibdir}/config/Makefile +%dir %{_includedir}/python%{pybasever} +%{_includedir}/python%{pybasever}/%{_pyconfig_h} + +%{_libdir}/%{py_INSTSONAME_optimized} +%if 0%{?with_systemtap} +%dir %(dirname %{tapsetdir}) +%dir %{tapsetdir} +%{tapsetdir}/%{libpython_stp_optimized} +%doc systemtap-example.stp pyfuntop.stp +%endif + +%dir %{pylibdir}/ensurepip/ +%{pylibdir}/ensurepip/*.py* +%exclude %{pylibdir}/ensurepip/_bundled + +%if %{with rewheel} +%dir %{pylibdir}/ensurepip/rewheel/ +%{pylibdir}/ensurepip/rewheel/*.py* +%endif + + +%files devel +%defattr(-,root,root,-) +%{_libdir}/pkgconfig/python-%{pybasever}.pc +%{_libdir}/pkgconfig/python.pc +%{_libdir}/pkgconfig/python2.pc +%{pylibdir}/config/* +%exclude %{pylibdir}/config/Makefile +%exclude %{pylibdir}/distutils/command/wininst-*.exe +%{_includedir}/python%{pybasever}/*.h +%exclude %{_includedir}/python%{pybasever}/%{_pyconfig_h} +%doc Misc/README.valgrind Misc/valgrind-python.supp Misc/gdbinit +%{_bindir}/python2-config +%{_bindir}/python%{pybasever}-config +%{_libdir}/libpython%{pybasever}.so + +%if %{with tk_and_tools} +%files tools +%defattr(-,root,root,755) +%doc Tools/pynche/README.pynche +%{site_packages}/pynche +%{_bindir}/smtpd*.py* + +# https://bugzilla.redhat.com/show_bug.cgi?id=1111275 +%exclude %{_bindir}/2to3* + +%{_bindir}/idle* +%{_bindir}/pynche* +%{_bindir}/pygettext*.py* +%{_bindir}/msgfmt*.py* +%{tools_dir} +%{demo_dir} +%{pylibdir}/Doc + +%files tkinter +%defattr(-,root,root,755) +%{pylibdir}/lib-tk +%{dynload_dir}/_tkinter.so + +%else #{with tk_and_tools} + +%exclude %{site_packages}/pynche +%exclude %{_bindir}/smtpd*.py* + +# https://bugzilla.redhat.com/show_bug.cgi?id=1111275 +%exclude %{_bindir}/2to3* + +%exclude %{_bindir}/idle* +%exclude %{_bindir}/pynche* +%exclude %{_bindir}/pygettext*.py* +%exclude %{_bindir}/msgfmt*.py* +%exclude %{tools_dir} +%exclude %{demo_dir} +%exclude %{pylibdir}/Doc + +%exclude %{pylibdir}/lib-tk +%exclude %{dynload_dir}/_tkinter.so + +%endif + +%files test +%defattr(-, root, root, -) +%{pylibdir}/bsddb/test +%{pylibdir}/ctypes/test +%{pylibdir}/distutils/tests +%{pylibdir}/email/test +%{pylibdir}/json/tests +%{pylibdir}/lib2to3/tests +%{pylibdir}/sqlite3/test +%{pylibdir}/test/* + +# Some bits of test are used for actual testing of stuff, not just python itself: +# See also https://bugzilla.redhat.com/show_bug.cgi?id=1528899 +%exclude %{pylibdir}/test/__init__.py* +%exclude %{pylibdir}/test/support/ +%exclude %{pylibdir}/test/script_helper.py* +%exclude %{pylibdir}/test/test_support.py* + +%{dynload_dir}/_ctypes_test.so +%{dynload_dir}/_testcapimodule.so + + +# We don't bother splitting the debug build out into further subpackages: +# if you need it, you're probably a developer. + +# Hence the manifest is the combination of analogous files in the manifests of +# all of the other subpackages + +%if %{with debug_build} +%files debug +%defattr(-,root,root,-) + +# Analog of the core subpackage's files: +%{_bindir}/python-debug +%{_bindir}/%{python}-debug +%{_bindir}/python%{pybasever}-debug + +# Analog of the -libs subpackage's files, with debug builds of the built-in +# "extension" modules: + +%{dynload_dir}/_md5module_d.so +%{dynload_dir}/_sha256module_d.so +%{dynload_dir}/_sha512module_d.so +%{dynload_dir}/_shamodule_d.so + +%{dynload_dir}/_bisectmodule_d.so +%{dynload_dir}/_bsddb_d.so +%{dynload_dir}/_codecs_cn_d.so +%{dynload_dir}/_codecs_hk_d.so +%{dynload_dir}/_codecs_iso2022_d.so +%{dynload_dir}/_codecs_jp_d.so +%{dynload_dir}/_codecs_kr_d.so +%{dynload_dir}/_codecs_tw_d.so +%{dynload_dir}/_collectionsmodule_d.so +%{dynload_dir}/_csv_d.so +%{dynload_dir}/_ctypes_d.so +%{dynload_dir}/_curses_d.so +%{dynload_dir}/_curses_panel_d.so +%{dynload_dir}/_elementtree_d.so +%{dynload_dir}/_functoolsmodule_d.so +%{dynload_dir}/_hashlib_d.so +%{dynload_dir}/_heapq_d.so +%{dynload_dir}/_hotshot_d.so +%{dynload_dir}/_io_d.so +%{dynload_dir}/_json_d.so +%{dynload_dir}/_localemodule_d.so +%{dynload_dir}/_lsprof_d.so +%{dynload_dir}/_multibytecodecmodule_d.so +%{dynload_dir}/_multiprocessing_d.so +%{dynload_dir}/_randommodule_d.so +%{dynload_dir}/_socketmodule_d.so +%{dynload_dir}/_sqlite3_d.so +%{dynload_dir}/_ssl_d.so +%{dynload_dir}/_struct_d.so +%{dynload_dir}/arraymodule_d.so +%{dynload_dir}/audioop_d.so +%{dynload_dir}/binascii_d.so +%{dynload_dir}/bz2_d.so +%{dynload_dir}/cPickle_d.so +%{dynload_dir}/cStringIO_d.so +%{dynload_dir}/cmathmodule_d.so +%{dynload_dir}/_cryptmodule_d.so +%{dynload_dir}/datetime_d.so +%{dynload_dir}/dbm_d.so +%{dynload_dir}/dlmodule_d.so +%{dynload_dir}/fcntlmodule_d.so +%{dynload_dir}/future_builtins_d.so +%if %{with_gdbm} +%{dynload_dir}/gdbmmodule_d.so +%endif +%{dynload_dir}/grpmodule_d.so +%{dynload_dir}/imageop_d.so +%{dynload_dir}/itertoolsmodule_d.so +%{dynload_dir}/linuxaudiodev_d.so +%{dynload_dir}/math_d.so +%{dynload_dir}/mmapmodule_d.so +%{dynload_dir}/nismodule_d.so +%{dynload_dir}/operator_d.so +%{dynload_dir}/ossaudiodev_d.so +%{dynload_dir}/parsermodule_d.so +%{dynload_dir}/pyexpat_d.so +%{dynload_dir}/readline_d.so +%{dynload_dir}/resource_d.so +%{dynload_dir}/selectmodule_d.so +%{dynload_dir}/spwdmodule_d.so +%{dynload_dir}/stropmodule_d.so +%{dynload_dir}/syslog_d.so +%{dynload_dir}/termios_d.so +%{dynload_dir}/timemodule_d.so +%{dynload_dir}/timingmodule_d.so +%{dynload_dir}/unicodedata_d.so +%{dynload_dir}/xxsubtype_d.so +%{dynload_dir}/zlibmodule_d.so + +# No need to split things out the "Makefile" and the config-32/64.h file as we +# do for the regular build above (bug 531901), since they're all in one package +# now; they're listed below, under "-devel": + +%{_libdir}/%{py_INSTSONAME_debug} +%if 0%{?with_systemtap} +%dir %(dirname %{tapsetdir}) +%dir %{tapsetdir} +%{tapsetdir}/%{libpython_stp_debug} +%endif + +# Analog of the -devel subpackage's files: +%dir %{pylibdir}/config-debug +%{_libdir}/pkgconfig/python-%{pybasever}-debug.pc +%{_libdir}/pkgconfig/python-debug.pc +%{_libdir}/pkgconfig/python2-debug.pc +%{pylibdir}/config-debug/* +%{_includedir}/python%{pybasever}-debug/*.h +%{_bindir}/python-debug-config +%{_bindir}/python2-debug-config +%{_bindir}/python%{pybasever}-debug-config +%{_libdir}/libpython%{pybasever}_d.so + +# Analog of the -tools subpackage's files: +# None for now; we could build precanned versions that have the appropriate +# shebang if needed + +%if ! 0%{?_module_build} +# Analog of the tkinter subpackage's files: +%{dynload_dir}/_tkinter_d.so +%endif + +# Analog of the -test subpackage's files: +%{dynload_dir}/_ctypes_test_d.so +%{dynload_dir}/_testcapimodule_d.so + +%endif # with debug_build + +# We put the debug-gdb.py file inside /usr/lib/debug to avoid noise from +# ldconfig (rhbz:562980). +# +# The /usr/lib/rpm/redhat/macros defines the __debug_package macro to use +# debugfiles.list, and it appears that everything below /usr/lib/debug and +# (/usr/src/debug) gets added to this file (via LISTFILES) in +# /usr/lib/rpm/find-debuginfo.sh +# +# Hence by installing it below /usr/lib/debug we ensure it is added to the +# -debuginfo subpackage +# (if it doesn't, then the rpmbuild ought to fail since the debug-gdb.py +# payload file would be unpackaged) + +# Workaround for rhbz#1476593 +%undefine _debuginfo_subpackages + +# ====================================================== +# Finally, the changelog: +# ====================================================== + +%changelog +* Wed Oct 23 2019 Charalampos Stratakis - 2.7.17-1 +- Update to 2.7.17 +Resolves: rhbz#1759946 + +* Tue Jun 11 2019 Charalampos Stratakis - 2.7.16-8 +- Fix urlparse.urlsplit() error message for Unicode URL +Resolves: rhbz#1689328 + +* Fri Jun 07 2019 Charalampos Stratakis - 2.7.16-7 +- Security fix for CVE-2019-10160 +Resolves: rhbz#1689328 + +* Thu May 30 2019 Charalampos Stratakis - 2.7.16-6 +- Security fix for CVE-2019-9948 +Resolves: rhbz#1704177 + +* Thu May 30 2019 Charalampos Stratakis - 2.7.16-5 +- Disallow control chars in http URLs +- Fixes CVE-2019-9740 and CVE-2019-9947 +Resolves: rhbz#1704369 and rhbz#1703537 + +* Fri May 03 2019 Charalampos Stratakis - 2.7.16-4 +- Updated fix for CVE-2019-9636 +Resolves: rhbz#1689328 + +* Fri Apr 12 2019 Charalampos Stratakis - 2.7.16-3 +- Fix coverity scan static analysis issues +Resolves: rhbz#1602667 + +* Wed Apr 3 2019 Charalampos Stratakis - 2.7.16-2 +- Security fix for CVE-2019-9636 (rhbz#1689328) + +* Mon Apr 1 2019 Charalampos Stratakis - 2.7.16-1 +- Update to 2.7.16 +Resolves: rhbz#1680964 + +* Thu Nov 29 2018 Tomas Orsava - 2.7.15-16 +- Bump NVR to redo CI gating tests, because the "update test" was + malfunctioning and had to be fixed +Resolves: rhbz#1565560 + +* Wed Nov 28 2018 Charalampos Stratakis - 2.7.15-15 +- Workaround Python's threading library issue with non returning wait, for signals with timeout +Resolves: rhbz#1565560 + +* Tue Nov 13 2018 Charalampos Stratakis - 2.7.15-14 +- Add choices for sort option of cProfile for better output +Resolves: rhbz#1565101 + +* Wed Nov 07 2018 Lumír Balhar - 2.7.15-13 +- Bring audiotest.au back to package. It's not copyrighted anymore. +- Resolves: rhbz#1643970 + +* Fri Oct 12 2018 Petr Viktorin - 2.7.15-12 +- Remove Windows binaries from the source archive +- Resolves: rhbz#1633220 + +* Fri Oct 12 2018 Charalampos Stratakis - 2.7.15-11 +- Fix test_dbm_gnu for gdbm 1.15 which fails on ppc64le +Resolves: rhbz#1638710 + +* Mon Sep 24 2018 Miro Hrončok - 2.7.15-10 +- Security fix for CVE-2018-14647 +Resolves: rhbz#1632095 + +* Sat Aug 04 2018 Petr Viktorin - 2.7.15-9 +- Disable Python 2 at the C level + +* Fri Aug 3 2018 Florian Weimer - 2.7.15-8 +- Honor %%{valgrind_arches} + +* Thu Aug 02 2018 Charalampos Stratakis - 2.7.15-7 +- Disable optimizations +- Disable ssl related tests for now + +* Wed Jul 25 2018 Petr Kubat - 2.7.15-6 +- Rebuilt for gdbm + +* Mon Jul 09 2018 Petr Viktorin - 2.7.15-5 +- Don't build the tkinter and tools subpackages + +* Thu Jun 28 2018 Petr Viktorin - 2.7.15-4 +- Disable Python 2 +- Exclude the unversioned commands in /usr/bin +- Exclude the unversioned man page +- No longer Provide unversioned "python" + +* Tue Jun 26 2018 Petr Viktorin - 2.7.15-3 +- Bump release + +* Fri Jun 22 2018 Petr Viktorin - 2.7.15-2 +- Provide the python2-for-tests package +- Disable rewheel & ensurepip +- Disable the debug build + +* Tue May 01 2018 Miro Hrončok - 2.7.15-1 +- Update to version 2.7.15 + +* Wed Apr 25 2018 Tomas Orsava - 2.7.14-17 +- Change shebangs to the proper versioned binary +- Bytecompile files manually, disbale brp-python-bytecompile +Resolves: rhbz#1572171 + +* Fri Apr 13 2018 Miro Hrončok - 2.7.14-16 +- Remove Obsoletes tag from when python was renamed to python2 (Fedora 25 was last) + +* Wed Mar 14 2018 Miro Hrončok - 2.7.14-15 +- Fix broken SSL module +Resolves: rhbz#1555081 + +* Tue Mar 13 2018 Charalampos Stratakis - 2.7.14-14 +- Do not send IP addresses in SNI TLS extension + +* Mon Feb 26 2018 Petr Viktorin - 2.7.14-13 +- Fix -Wint-in-bool-context warnings +Resolves: rhbz#1473425 + +* Sat Feb 24 2018 Florian Weimer - 2.7.14-12 +- Rebuild with new LDFLAGS from redhat-rpm-config + +* Thu Feb 15 2018 Miro Hrončok - 2.7.14-11 +- Move test.support and test.script_helper to python2-libs +Resolves: rhbz#1528899 + +* Fri Feb 09 2018 Fedora Release Engineering - 2.7.14-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Tue Jan 30 2018 Petr Viktorin - 2.7.14-9 +- Add patch 288: warn/fail if Python 2 is called as /usr/bin/python and + PYTHON_DISALLOW_AMBIGUOUS_VERSION is set +- Add patch 289: Fix for over-aligned GC info + +* Sat Jan 20 2018 Björn Esser - 2.7.14-8 +- Rebuilt for switch to libxcrypt + +* Wed Jan 17 2018 Petr Viktorin - 2.7.14-7 +- Build the nis module with tirpc + +* Tue Jan 16 2018 Miro Hrončok - 2.7.14-6 +- Rebuild for reverted gdbm 1.13 on Fedora 27 + +* Thu Jan 11 2018 Charalampos Stratakis - 2.7.14-5 +- Rebuild for gdbm 1.14 + +* Mon Dec 11 2017 Charalampos Stratakis - 2.7.14-4 +- Fix hanging of all threads when trying to access an inaccessible NFS server. + +* Thu Nov 09 2017 Miro Hrončok - 2.7.14-3 +- Make the -devel package require redhat-rpm-config +Resolves: rhbz#1496757 + +* Thu Nov 02 2017 Charalampos Stratakis - 2.7.14-2 +- Add a new PYTHONSHOWREFCOUNT environment variable for printing the reference + count in debug builds. +- Fix nondeterministic read in test_pty. + +* Mon Oct 09 2017 Iryna Shcherbina - 2.7.14-1 +- Update to version 2.7.14 + +* Thu Aug 31 2017 Tomas Orsava - 2.7.13-18 +- Switch some macros into bconds to facilitate modularity + +* Wed Aug 16 2017 Miro Hrončok - 2.7.13-17 +- Exclude /usr/bin/2to3 (rhbz#1111275) + +* Mon Aug 14 2017 David "Sanqui" Labský - 2.7.13-16 +- Do not generate debuginfo subpackages (#1476593) + +* Wed Aug 09 2017 Michal Cyprian - 2.7.13-15 +- Revert "Add --executable option to install.py command" + This enhancement is currently not needed and it can possibly + collide with `pip --editable`option + +* Thu Aug 03 2017 Fedora Release Engineering - 2.7.13-14 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 2.7.13-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon Jun 26 2017 Charalampos Stratakis - 2.7.13-11 +- Fix test_alpn_protocols from test_ssl + +* Wed May 31 2017 Miro Hrončok - 2.7.13-11 +- Change fixed Obsoletes version with a dynamic one (rhbz#1457336) + +* Thu May 18 2017 Karsten Hopp - 2.7.13-10 +- revert logic for modularity patch and enable gdbm for modularity + +* Tue May 16 2017 Tomas Orsava - 2.7.13-9 +- Added a dependency to the devel subpackage on python3-rpm-generators which + have been excised out of rpm-build +- There is no Python 2 package containing Python RPM generators, therefore + Python 3 is needed when Python 2 package is to be built, but this was + decided not to be a problem due to nearing EOL of Python 2 +- Involves: rhbz#1410631, rhbz#1444925 + +* Wed May 10 2017 Charalampos Stratakis - 2.7.13-8 +- Enable profile guided optimizations for x86_64 and i686 architectures +- Update description to reflect that Python 2 is not the default Python + +* Tue Apr 25 2017 Karsten Hopp - 2.7.13-7 +- apply modularity patch only during module builds + +* Sun Apr 23 2017 Karsten Hopp - 2.7.13-6 +- add missing patch + +* Fri Apr 21 2017 Karsten Hopp - 2.7.13-5 +- drop a couple of dependencies for Modularity builds + +* Tue Feb 21 2017 Michal Cyprian - 2.7.13-5 +- Add --executable option to install.py command + +* Fri Feb 17 2017 Charalampos Stratakis - 2.7.13-4 +- Fix the upgrade path to F26 due to renaming the package to python2 (rhbz#1420332) + +* Sat Feb 11 2017 Fedora Release Engineering - 2.7.13-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 12 2017 Igor Gnatenko - 2.7.13-2 +- Rebuild for readline 7.x + +* Wed Jan 11 2017 Charalampos Stratakis - 2.7.13-1 +- Update to 2.7.13 +- Don't blow up on EL7 kernel (random generator) (rhbz#1410175, rhbz#1410187) +- Require glibc >= 2.24.90-26 (rhbz#1410644) + +* Thu Oct 27 2016 Charalampos Stratakis - 2.7.12-9 +- Rename package to python2 and also rename the subpackages accordingly +- Provide and obsolete python and the respective subpackages to ensure a clean +upgrade path +- Remove old provides for packages that got into stdlib +- Implement PEP 394 + +* Wed Oct 12 2016 Charalampos Stratakis - 2.7.12-8 +- Port ssl and hashlib modules to OpenSSL 1.1.0 +- Drop hashlib patch for now +- Add riscv64 arch to 64bit and no-valgrind arches + +* Thu Sep 29 2016 Miro Hrončok - 2.7.12-7 +- Provide python27 + +* Fri Sep 02 2016 Charalampos Stratakis - 2.7.12-6 +- Remove unversioned Obsoletes + +* Thu Sep 01 2016 Charalampos Stratakis - 2.7.12-5 +- Rebase rewheel patch so it applies properly (rhbz#1372183) + +* Tue Aug 09 2016 Charalampos Stratakis - 2.7.12-4 +- SPEC file cleanup +- Removal of unapplied patches + +* Tue Aug 09 2016 Charalampos Stratakis - 2.7.12-3 +- Fix for CVE-2016-1000110 HTTPoxy attack +- SPEC file cleanup + +* Mon Aug 01 2016 Michal Toman - 2.7.12-2 +- Build properly on MIPS + +* Fri Jul 15 2016 Charalampos Stratakis - 2.7.12-1 +- Update to 2.7.12 +- Refactored patches: 10, 102, 112, 134, 153 +- Dropped patches: 166, 209, 210 + +* Fri Jul 08 2016 Charalampos Stratakis - 2.7.11-8 +- Refactor patch for properly fixing CVE-2016-5636 + +* Fri Jul 08 2016 Charalampos Stratakis - 2.7.11-7 +- Fix test_pyexpat failure with Expat version of 2.2.0 + +* Thu Jun 16 2016 Tomas Orsava - 2.7.11-6 +- Fix for: CVE-2016-0772 python: smtplib StartTLS stripping attack +- Raise an error when STARTTLS fails +- rhbz#1303647: https://bugzilla.redhat.com/show_bug.cgi?id=1303647 +- rhbz#1346344: https://bugzilla.redhat.com/show_bug.cgi?id=1346344 +- Fixed upstream: https://hg.python.org/cpython/rev/b3ce713fb9be + +* Mon Jun 13 2016 Charalampos Stratakis - 2.7.11-5 +- Added patch for fixing possible integer overflow and heap corruption in zipimporter.get_data() + +* Thu Feb 04 2016 Fedora Release Engineering - 2.7.11-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jan 13 2016 Orion Poplawski - 2.7.11-3 +- Drop macros, require python/python2-rpm-macros + +* Wed Dec 30 2015 Orion Poplawski - 2.7.11-2 +- Get ready for separate python-macros package + +* Tue Dec 15 2015 Robert Kuska - 2.7.11-1 +- Update to 2.7.11 + +* Thu Oct 15 2015 Thomas Spura - 2.7.10-11 +- provide/obsolete _isa packages in python_provide (#1271776) + +* Wed Sep 23 2015 Robert Kuska - 2.7.10-10 +- Revert the moving modules to python-tools because distutils uses lib2to3 + +* Tue Sep 22 2015 Robert Kuska - 2.7.10-9 +- Move idlelib and lib2to3 modules to pythont-tools + +* Thu Sep 3 2015 Orion Poplawski - 2.7.10-8 +- Fix quoting in %%python_provide macro + +* Thu Sep 3 2015 Orion Poplawski - 2.7.10-7 +- Add obsoletes to %%python_provide macro to fix upgrade path +- Fix python2- provides for python- packages in %%python_provide + +* Thu Jul 23 2015 Thomas Spura - 2.7.10-6 +- python-macros: remove R on python (#1246036) + +* Wed Jul 22 2015 Thomas Spura - 2.7.10-5 +- Include epoch in the python_provide macro fpc#534 (Slavek Kabrda) + +* Mon Jun 29 2015 Thomas Spura - 2.7.10-4 +- correct python_provide macro to include version only when emiting provides + +* Thu Jun 25 2015 Thomas Spura - 2.7.10-3 +- Add unversioned python-macros from fpc#281 and fpc#534 + and require it from python-devel +- Make python-macros noarch + +* Wed Jun 17 2015 Matej Stuchlik - 2.7.10-2 +- Make relocating Python by changing _prefix actually work +Resolves: rhbz#1231801 + +* Mon May 25 2015 Matej Stuchlik - 2.7.10-1 +- Update to 2.7.10 + +* Tue May 5 2015 Peter Robinson 2.7.9-11 +- Disable test_gdb on aarch64 (rhbz#1196181), it joins all other non x86 arches + +* Wed Apr 15 2015 Robert Kuska - 2.7.9-10 +- Remove provides/obsolates for unittest2 +- Skip test_gdb on arm until rhbz#1196181 is resolved + +* Thu Mar 05 2015 Matej Stuchlik - 2.7.9-9 +- Add proper rewheel Requires + +* Sat Feb 21 2015 Till Maas - 2.7.9-8 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + +* Sat Feb 21 2015 Till Maas - 2.7.9-7 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + +* Tue Feb 17 2015 Ville Skyttä - 2.7.9-6 +- Own systemtap dirs (#710733) + +* Fri Feb 06 2015 Karsten Hopp 2.7.9-5 +- disable test_gdb on ppc64* until rhbz#1132488 is really resolved + +* Tue Jan 20 2015 Slavek Kabrda - 2.7.9-4 +- We need to provide both arch specific and noarch Provide for python2-devel +in order not to break noarch builds. + +* Tue Jan 20 2015 Slavek Kabrda - 2.7.9-3 +- Make python2-devel provide arch specific. +Resolves: rhbz#1183530 + +* Mon Jan 12 2015 Dan Horák - 2.7.9-2 +- build with valgrind on ppc64le +- disable test_gdb on s390(x) until rhbz#1181034 is resolved + +* Thu Dec 11 2014 Matej Stuchlik - 2.7.9-1 +- Update to 2.7.9 +- Refreshed patches: #55, #137, #146, #153, #156, #198 +- Dropped patches: #196, #197 +- New patch: #199 +- Added the rewheel module + +* Mon Nov 24 2014 Matej Stuchlik - 2.7.8-10 +- Improve python2_version macros + +* Thu Nov 13 2014 Matej Stuchlik - 2.7.8-9 +- Add python2_version_nodots macro + +* Mon Nov 10 2014 Slavek Kabrda - 2.7.8-8 +- Revert previous change, see rhbz#1161166#c6. + +* Fri Nov 07 2014 Slavek Kabrda - 2.7.8-7 +- Provide importable unittest2 +Resolves: rhbz#1161166 + +* Thu Aug 21 2014 Robert Kuska - 2.7.8-6 +- Update patch 196 (ssl backport) + +* Tue Aug 19 2014 Robert Kuska - 2.7.8-5 +- Backport ssl module from python3 + +* Sun Aug 17 2014 Fedora Release Engineering - 2.7.8-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Thu Jul 31 2014 Tom Callaway - 2.7.8-3 +- fix license handling + +* Fri Jul 18 2014 Robert Kuska - 2.7.8-2 +- Enable SSLv2 and SSLv3 when SSLv23_method is used in ssl + +* Mon Jul 14 2014 Robert Kuska - 2.7.8-1 +- Update to 2.7.8 + +* Fri Jul 11 2014 Dan Horák - 2.7.7-3 +- rebuilt for updated libffi ABI on ppc64le + +* Sat Jun 7 2014 Peter Robinson 2.7.7-2 +- aarch64 has valgrind, just list those that don't support it + +* Wed Jun 04 2014 Matej Stuchlik - 2.7.7-1 +- Update to 2.7.7 +- Refreshed patches: #16, #112, #138, #147, #157, #166, #173, #5000 +- Dropped patches: #190, #192, #194 + +* Tue Jun 03 2014 Dan Horák - 2.7.6-9 +- update the arch list where valgrind exists - %%power64 includes also + ppc64le which is not supported yet + +* Wed May 21 2014 Jaroslav Škarvada - 2.7.6-8 +- Rebuilt for https://fedoraproject.org/wiki/Changes/f21tcl86 + +* Fri May 09 2014 Tomas Radej - 2.7.6-7 +- Fixed obsoletes on ordereddict (bz #1095434) + +* Mon Apr 14 2014 Tomas Radej - 2.7.6-6 +- Obsoletes python-ordereddict (bz #1085593, not precisely 1:1 replacement) + +* Mon Apr 07 2014 Bohuslav Kabrda - 2.7.6-5 +- Fix test failure with SQLite > 3.8.4. +- Obsolete/Provide python-unittest2 +Related: rhbz#1060426 + +* Wed Feb 19 2014 Bohuslav Kabrda - 2.7.6-4 +- Enable loading sqlite extensions. +Resolves: rhbz#1066708 + +* Mon Feb 10 2014 Tomas Radej - 2.7.6-3 +- Fixed buffer overflow (upstream patch) +Resolves: rhbz#1062375 + +* Tue Feb 04 2014 Bohuslav Kabrda - 2.7.6-2 +- Install macros in _rpmconfigdir. + +* Wed Jan 29 2014 Tomas Radej - 2.7.6-1 +- Updated to v2.7.6 +- Freshened patches 102, 111, 112, 136, and 142 +- Dropped patches 186, 188 (both fixed upstream) + +* Wed Jan 15 2014 Matej Stuchlik - 2.7.5-11 +- Make library-files user writable to get rid of + Permission Denied in buildlog from debuginfo-packaging + +* Tue Jan 14 2014 Dennis Gilmore - 2.7.5-10 +- enable valgrind support on 32 bit arm + +* Tue Nov 12 2013 Tomas Radej - 2.7.5-9 +- Import get_python_version in bdist_rpm +Resolves: rhbz#1029082 + +* Tue Oct 08 2013 Bohuslav Kabrda - 2.7.5-8 +- Fix processing gdb py-bt command in eval calls. +Resolves: rhbz#1008154 + +* Tue Sep 03 2013 Bohuslav Kabrda - 2.7.5-7 +- Removed ancient Obsolete: python-sqlite2. + +* Mon Aug 26 2013 Bohuslav Kabrda - 2.7.5-6 +- Sync back/renumber patches to stay consistent with rhel. + +* Mon Aug 19 2013 Matej Stuchlik - 2.7.5-5 +- Added fix for CVE-2013-4238 (rhbz#998430) + +* Sun Aug 04 2013 Fedora Release Engineering - 2.7.5-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Mon Jul 08 2013 Bohuslav Kabrda - 2.7.5-3 +- Fix build with libffi containing multilib wrapper for ffi.h (rhbz#979696). + +* Mon Jul 08 2013 Bohuslav Kabrda - 2.7.5-2 +- Obsolete PyXML as requested in rhbz#981137. + +* Thu May 16 2013 Bohuslav Kabrda - 2.7.5-1 +- Updated to Python 2.7.5. +- Refreshed patches: 0 (config), 102 (lib64), 121 (add Modules to build path), +153 (gdb test noise) +- Dropped patches: 126, 127 (big endian issues, both fixed upstream), +175 (configure -Wformat, fixed upstream) +- Synced patch numbers with python3.spec. + +* Tue May 14 2013 David Malcolm - 2.7.4-5 +- fix multilib issue in python-tools due to /usr/bin/pynche (source 7; +rhbz#831437) + +* Thu May 02 2013 Bohuslav Kabrda - 2.7.4-4 +- Add patch that enables building on ppc64p7. + +* Mon Apr 22 2013 Bohuslav Kabrda - 2.7.4-3 +- Allow arbitrary timeout in Condition.wait (rhbz#917709). + +* Thu Apr 11 2013 Kalev Lember - 2.7.4-2 +- Build with libdb 5.3 instead of libdb4 +- Refreshed patches: 0 (config), 102 (lib64) +- Dropped patches: 54 (db4 version), 159 (db4 include path adjustment) + +* Mon Apr 08 2013 Bohuslav Kabrda - 2.7.4-1 +- Updated to Python 2.7.4. +- Refreshed patches: 0 (config), 7 (sqlite encoding), 16 (rpath in config), +55 (systemtap), 111 (no static lib), 112 (debug build), 113 (more +configuration flags), 130 (add extension to python config), 134 (fix +COUNT_ALLOCS in test_sys), 146 (haslib FIPS), 147 (add debug malloc stats), +153 (fix gdb test noise), 157 (uid, gid overflow - fixed upstream, just +keeping few more downstream tests), 165 (crypt module salt backport), +175 (fix configure Wformat), 5000 (regenerated autotooling patch) +- Dropped patches: 101 (lib64 regex; merged upstream), 171 (exception on +missing /dev/urandom; merged upstream), 172 (poll for multiprocessing socket +connection; merged upstream) + +* Mon Mar 25 2013 David Malcolm - 2.7.3-35 +- fix gcc 4.8 incompatibility (rhbz#927358); regenerate autotool intermediates + +* Wed Mar 6 2013 David Malcolm - 2.7.3-34 +- restrict scope of workaround for cmpi-bindings issue to avoid breaking +in-tree running of test_sys and test_subprocess (rhbz#817554) + +* Wed Mar 6 2013 David Malcolm - 2.7.3-33 +- add workaround for cmpi-bindings issue (rhbz#817554) + +* Mon Mar 4 2013 David Malcolm - 2.7.3-32 +- add workaround for ENOPROTOOPT seen running selftests in Koji +(rhbz#913732) + +* Mon Mar 4 2013 David Malcolm - 2.7.3-31 +- remove config flag from /etc/rpm/macros.python2 + +* Fri Feb 22 2013 David Malcolm - 2.7.3-30 +- remove __debug_package macro from comment + +* Fri Feb 22 2013 David Malcolm - 2.7.3-29 +- drop -b from application of patch 157 (uid/gid overflows) + +* Fri Feb 22 2013 David Malcolm - 2.7.3-28 +- fix bogus dates in changelog + +* Thu Feb 21 2013 David Malcolm - 2.7.3-27 +- port _multiprocessing.Connection.poll() to use the "poll" syscall, rather +than "select", allowing large numbers of subprocesses (patch 172; +rhbz#849992) + +* Thu Feb 21 2013 David Malcolm - 2.7.3-26 +- raise correct exception in os.urandom() when /dev/urandom is missing +(patch 171; rhbz#907383) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-25 +- in debug builds, try to print repr() when a C-level assert fails in the +garbage collector (typically indicating a reference-counting error somewhere +else e.g in an extension module) (patch 170; rhbz#850013) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-24 +- move lib2to3/tests from python-libs to python-test (rhbz#850056) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-23 +- use SHA-256 rather than implicitly using MD5 within the challenge handling +in multiprocessing.connection (patch 169; rhbz#879695) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-22 +- fix a problem with distutils.sysconfig when CFLAGS is defined in the +environment (patch 168; rhbz#849994) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-21 +- don't run any stack navigation tests in test_gdb for optimized builds +(patch 167; rhbz#912025) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-20 +- s/cryptmodule/_cryptmodule/ in package payload (rhbz#835021) + +* Tue Feb 19 2013 David Malcolm - 2.7.3-19 +- bulletproof the gdb debugging hooks against a failure seen in ARM builds +(patch 166; rhbz#912025) +- re-enable make check on ARM (rhbz#912025) + +* Tue Feb 19 2013 David Malcolm - 2.7.3-18 +- backport pre-canned ways of salting a password to the "crypt" module from 3.3 +(rhbz#835021) + +* Tue Feb 19 2013 David Malcolm - 2.7.3-17 +- remove "_default_patch_fuzz" directive to avoid patches being silently +misapplied (refresh patch 1, patch 101, patch 102, patch 111, patch 121, +patch 158; rename patch 1, patch 101, patch 121; apply patch 54 before the +lib64 patches to avoid fuzz problems caused by the conditional application +of the lib64 patches) + +* Mon Feb 18 2013 Peter Robinson 2.7.3-16 +- disable make check on ARM for the moment until 912025 is fixed + +* Mon Feb 11 2013 David Malcolm - 2.7.3-15 +- add aarch64 (rhbz#909783) + +* Thu Nov 29 2012 David Malcolm - 2.7.3-14 +- add BR on bluez-libs-devel (rhbz#879720) + +* Thu Aug 9 2012 David Malcolm - 2.7.3-13 +- remove f18 conditional from patch 159 + +* Fri Jul 27 2012 Fedora Release Engineering - 2.7.3-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 17 2012 Bohuslav Kabrda - 2.7.3-11 +- fix memory leak in module _hashlib (patch 158, rhbz#836285) +- fix db4 include path for libdb4 package (f18 and above) (patch 159) + +* Tue Jun 26 2012 David Malcolm - 2.7.3-10 +- fix missing include in uid/gid handling patch (patch 157; rhbz#830405) + +* Fri Jun 22 2012 David Malcolm - 2.7.3-9 +- use rpm macro for power64 (rhbz#834653) + +* Tue May 15 2012 David Malcolm - 2.7.3-8 +- update uid/gid handling to avoid int overflows seen with uid/gid +values >= 2^31 on 32-bit architectures (patch 157; rhbz#697470) + +* Fri May 4 2012 David Malcolm - 2.7.3-7 +- renumber autotools patch from 300 to 5000 +- specfile cleanups + +* Mon Apr 30 2012 David Malcolm - 2.7.3-6 +- try again to fix test_gdb.py (patch 156; rhbz#817072) + +* Mon Apr 30 2012 David Malcolm - 2.7.3-5 +- fix test_gdb.py (patch 156; rhbz#817072) + +* Fri Apr 20 2012 David Malcolm - 2.7.3-4 +- avoid allocating thunks in ctypes unless absolutely necessary, to avoid +generating SELinux denials on "import ctypes" and "import uuid" when embedding +Python within httpd (patch 155; rhbz#814391) + +* Thu Apr 19 2012 David Malcolm - 2.7.3-3 +- add explicit version requirements on expat to avoid linkage problems with +XML_SetHashSalt + +* Wed Apr 18 2012 David Malcolm - 2.7.3-2 +- fix -config symlinks (patch 112; rhbz#813836) + +* Wed Apr 11 2012 David Malcolm - 2.7.3-1 +- 2.7.3: refresh patch 102 (lib64); drop upstream patches 11 (ascii-to-lower), +115 (pydoc robustness), 145 (linux2), 148 (gdbm magic values), 151 (deadlock +in fork); refresh patch 112 (debug build); revise patch 127 +(test_structmember); fix test_gdb (patch 153); refresh patch 137 (distutils +tests); add python2.pc to python-devel; regenerate the autotool intermediates +patch (patch 300) + +* Sat Feb 25 2012 Thomas Spura - 2.7.2-20 +- fix deadlock issue (#787712) + +* Fri Feb 17 2012 Toshio Kuratomi - 2.7.2-19 +- Obsolete python-sqlite2 + +* Thu Nov 24 2011 Ville Skyttä - 2.7.2-18 +- Build with $RPM_LD_FLAGS (#756862). +- Use xz-compressed source tarball. + +* Wed Oct 26 2011 Fedora Release Engineering - 2.7.2-17 +- Rebuilt for glibc bug#747377 + +* Fri Sep 30 2011 David Malcolm - 2.7.2-16 +- re-enable gdbm (patch 148; rhbz#742242) + +* Fri Sep 16 2011 David Malcolm - 2.7.2-15 +- add a sys._debugmallocstats() function (patch 147) + +* Wed Sep 14 2011 David Malcolm - 2.7.2-14 +- support OpenSSL FIPS mode in _hashlib and hashlib; don't build the _md5 and +_sha* modules, relying on _hashlib in hashlib, and thus within md5 etc +(rhbz#563986; patch 146) + +* Wed Sep 14 2011 David Malcolm - 2.7.2-13 +- force sys.platform to be "linux2" (patch 145) + +* Tue Sep 13 2011 David Malcolm - 2.7.2-12 +- disable gdbm module to prepare for gdbm soname bump + +* Mon Sep 12 2011 David Malcolm - 2.7.2-11 +- rename and renumber patches for consistency with python3.spec (55, 111, 113, +114, 125, 131, 129 to 143) + +* Sat Sep 10 2011 David Malcolm - 2.7.2-10 +- rewrite of "check", introducing downstream-only hooks for skipping specific +cases in an rpmbuild (patch 132), and fixing/skipping failing tests in a more +fine-grained manner than before (patches 104, 133-142) + +* Thu Sep 1 2011 David Malcolm - 2.7.2-9 +- run selftests with "--verbose" +- disable parts of test_io on ppc (rhbz#732998) + +* Tue Aug 23 2011 David Malcolm - 2.7.2-8 +- add --extension-suffix option to python-config (patch 130; rhbz#732808) + +* Tue Aug 23 2011 David Malcolm - 2.7.2-7 +- re-enable and fix the --with-tsc option on ppc64, and rework it on 32-bit +ppc to avoid aliasing violations (patch 129; rhbz#698726) + +* Tue Aug 23 2011 David Malcolm - 2.7.2-6 +- don't use --with-tsc on ppc64 debug builds (rhbz#698726) + +* Thu Aug 18 2011 David Malcolm - 2.7.2-5 +- add rpm macros file (rhbz#731800) + +* Fri Jul 8 2011 David Malcolm - 2.7.2-4 +- cleanup of BuildRequires; add comment headings to specfile sections + +* Wed Jun 22 2011 David Malcolm - 2.7.2-3 +- reorganize test exclusions (test_openpty and test_pty seem to be failing on +every arch, not just the explicitly-listed ones) + +* Mon Jun 13 2011 Dan Horák - 2.7.2-2 +- add s390(x) excluded tests + +* Mon Jun 13 2011 David Malcolm - 2.7.2-1 +- 2.7.2; drop upstreamed patches: patch 122 (parallel make fix), patch 124 +(test_commands and SELinux), patch 130 (ppc preprocessor macro in debug +build); patch 131 (decimal in Turkish locale); regenerate the autotool +intermediates patch (patch 300) + +* Tue Jun 07 2011 Dennis Gilmore - 2.7.1-9 +- fix sparc building by excluding failing tests RHBZ#711584 + +* Mon May 23 2011 Peter Robinson - 2.7.1-8 +- fix compile on ARM by excluding failing tests on arm - RHBZ #706253 + +* Tue Apr 12 2011 David Malcolm - 2.7.1-7 +- fix "import decimal" in the Turkish locale (patch 131; rhbz#694928) + +* Wed Feb 09 2011 Fedora Release Engineering - 2.7.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Jan 21 2011 Toshio Kuratomi - 2.7.1-5 +- Switch from setting OPT to setting EXTRA_CFLAGS so we don't overwrite the + DNDEBUG flag + +* Fri Jan 7 2011 David Malcolm - 2.7.1-4 +- for now, drop "obsoletes" of python-argparse, since it interracts badly with +multilib (rhbz#667984) + +* Fri Jan 7 2011 Thomas Spura - 2.7.1-3 +- obsolete/provide python-argparse (new in 2.7) + +* Thu Jan 6 2011 David Malcolm - 2.7.1-2 +- fix the ppc build of the debug configuration (patch 130; rhbz#661510) + +* Thu Dec 23 2010 David Malcolm - 2.7.1-1 +- 2.7.1, reworking patch 0 (config), patch 102 (lib64); drop upstream +patch 56 (cfgparse), patch 110 (ctypes/SELinux/noexecmem), patch 119 (expat +compat), patch 123 (2to3 on "from itertools import *") +- fix test_abc's test_cache_leak in the debug build (patch 128) +- drop _weakref.so from manifest (_weakref became a core module in r84230) + +* Wed Sep 29 2010 jkeating - 2.7-13 +- Rebuilt for gcc bug 634757 + +* Mon Sep 27 2010 David Malcolm - 2.7-12 +- fix test_structmember on 64bit-bigendian (patch 127) + +* Fri Sep 24 2010 David Malcolm - 2.7-11 +- fix dbm_contains on 64bit-bigendian (patch 126; rhbz#626756) + +* Thu Sep 16 2010 Toshio Kuratomi - 2.7-10 +- backport a patch to fix a change in behaviour in configparse. + +* Thu Sep 9 2010 David Malcolm - 2.7-9 +- move most of the payload of the core package to the libs subpackage, given +that the libs aren't meaningfully usable without the standard libraries + +* Wed Aug 18 2010 David Malcolm - 2.7-8 +- add %%check section +- update lib64 patch (patch 102) to fix expected output in test_site.py on +64-bit systems +- patch test_commands.py to work with SELinux (patch 124) +- patch the debug build's usage of COUNT_ALLOCS to be less verbose (patch 125) + +* Mon Jul 26 2010 David Malcolm - 2.7-7 +- fixup missing -lcrypt to "crypt" module in config patch (patch 0) + +* Mon Jul 26 2010 David Malcolm - 2.7-6 +- re-enable systemtap +- cherrypick upstream patch to 2to3 for "from itertools import *" +traceback (patch 123) + +* Thu Jul 22 2010 David Malcolm - 2.7-5 +- disable systemtap for now (dtrace is failing on startup due to the bug +mentioned in 2.7-4) +- provide relative path to python binary when running pathfix.py +- fix parallel make (patch 122) + +* Thu Jul 22 2010 David Malcolm - 2.7-4 +- fix reference to pyconfig.h in sysconfig that led to failure on startup if +python-devel was not installed + +* Thu Jul 8 2010 David Malcolm - 2.7-3 +- add patch to fixup the new sysconfig.py for our multilib support on +64-bit (patch 103) + +* Thu Jul 8 2010 David Malcolm - 2.7-2 +- add machinery for regenerating the "configure" script in the face of +mismatching autoconf versions (patch 300) + +* Tue Jul 6 2010 David Malcolm - 2.7-1 +- 2.7 final; drop alphatag +- drop patch 117 (upstream), patch 120 (upstreamed) +- fix the commented-out __python_ver from 26 to 27 + +* Tue Jun 22 2010 David Malcolm - 2.7-0.1.rc2 +- 2.7rc2 +- revert r79310 (patch 121) +- remove modulator: upstream removed it in r78338 +- rename mathmodule(_d).so to math(_d).so in manifests (appears to be changed +by r76861) +- _bytesio(_d).so and _filesio(_d).so were consolidated into _io(_d).so in +r73394 (upstream issue 6215) +- use the gdb hooks from the upstream tarball, rather than keeping our own +copy. The upstream version has some whitespace changes, a new write_repr for +unicode objects, and various bulletproofings for being run on older gdbs + +* Tue Jun 22 2010 David Malcolm - 2.7-0.1.rc1 +- 2.7rc1: + - rework patches to apply against 2.7 (which among other changes has had a +whitespace cleanup of the .c code): .rhconfig (patch0), .binutils-no-dep +(patch10), .ascii-tolower (patch11), .socketmodule (patch13), .socketmodule2 +(patch14), .systemtap (patch55), .lib64 (patch102), .selinux (patch110), +.no-static-lib (patch111), .debug-build (patch112), .statvfs-f-flag-constants +(patch114), ..CVE-2010-2089 (patch117) + - drop upstream patches: .expat (patch3), .brprpm (patch51), .valgrind +(patch52), .db48 (patch53), .CVE-2010-1634 (patch 116), .CVE-2008-5983 (patch +118) + +* Tue Jun 22 2010 David Malcolm - 2.6.5-17 +- Stop python bailing out with an assertion failure when UnicodeDecodeErrors +occur on very large buffers (patch 120, upstream issue 9058) + +* Mon Jun 21 2010 David Malcolm - 2.6.5-16 +- Fix an incompatibility between pyexpat and the system expat-2.0.1 that led to +a segfault running test_pyexpat.py (patch 119; upstream issue 9054) + +* Tue Jun 8 2010 David Malcolm - 2.6.5-15 +- add a flag to make it easy to turn off the debug build when troubleshooting +the rpm build + +* Sat Jun 5 2010 Dan Horák - 2.6.5-14 +- reading the timestamp counter is available only on some arches (see Python/ceval.c) +- disable --with-valgrind on s390(x) arches + +* Fri Jun 4 2010 David Malcolm - 2.6.5-13 +- ensure that the compiler is invoked with "-fwrapv" (rhbz#594819) +- CVE-2010-1634: fix various integer overflow checks in the audioop +module (patch 116) +- CVE-2010-2089: further checks within the audioop module (patch 117) +- CVE-2008-5983: the new PySys_SetArgvEx entry point from r81399 (patch 118) + +* Thu May 27 2010 David Malcolm - 2.6.5-12 +- make "pydoc -k" more robust in the face of broken modules (rhbz:461419, patch115) + +* Wed May 26 2010 David Malcolm - 2.6.5-11 +- add flags for statvfs.f_flag to the constant list in posixmodule (i.e. "os") +(patch 114) + +* Tue May 25 2010 David Malcolm - 2.6.5-10 +- add configure-time support for COUNT_ALLOCS and CALL_PROFILE debug options +(patch 113); enable them and the WITH_TSC option within the debug build + +* Tue May 18 2010 David Malcolm - 2.6.5-9 +- build and install two different configurations of Python: debug and standard, +packaging the debug build in a new "python-debug" subpackage (patch 112) + +* Tue May 4 2010 David Malcolm - 2.6.5-8 +- don't delete wsgiref.egg-info (rhbz:588426) + +* Mon Apr 26 2010 David Malcolm - 2.6.5-7 +- disable --with-valgrind on sparc arches + +* Mon Apr 12 2010 David Malcolm - 2.6.5-6 +- move the "bdist_wininst" command's template .exe files from the core package +to the devel subpackage, to save space (rhbz:525469) +- fix stray doublelisting of config directory wildcard in devel subpackage + +* Wed Mar 31 2010 David Malcolm - 2.6.5-5 +- update python-gdb.py from v4 to v5 (improving performance and stability, +adding commands) + +* Thu Mar 25 2010 David Malcolm - 2.6.5-4 +- update python-gdb.py from v3 to v4 (fixing infinite recursion on reference +cycles and tracebacks on bytes 0x80-0xff in strings, adding handlers for sets +and exceptions) + +* Wed Mar 24 2010 David Malcolm - 2.6.5-3 +- refresh gdb hooks to v3 (reworking how they are packaged) + +* Mon Mar 22 2010 David Malcolm - 2.6.5-2 +- remove unnecessary arch-conditionality for patch 101 + +* Fri Mar 19 2010 David Malcolm - 2.6.5-1 +- update to 2.6.5: http://www.python.org/download/releases/2.6.5/ +- replace our patch to compile against db4.8 with a patch from +upstream (patch 53, from r78974); update patch 54 since part of it is now in +that upstream patch +- update patch 110 so that it still applies in the face of upstream r78380 + +* Tue Mar 16 2010 David Malcolm - 2.6.4-23 +- fixup distutils/unixccompiler.py to remove standard library path from +rpath (patch 17) +- delete DOS batch files + +* Fri Mar 12 2010 David Malcolm - 2.6.4-22 +- add pyfuntop.stp; allow systemtap support to be disabled +- remove trailing period from tkinter summary +- don't own /usr/bin/python-config if you're not the main python + +* Thu Mar 11 2010 Marcela Mašláňová - 2.6.4-21 +- rebuild with new gdbm + +* Thu Feb 11 2010 David Malcolm - 2.6.4-20 +- avoid having the "test" subdirectory and the files within it that are in the +core subpackage also be owned by the test subpackage (rhbz:467588) + +* Wed Feb 10 2010 David Malcolm - 2.6.4-19 +- revise the systemtap patch (patch 55:python-2.6.4-dtrace.patch) to the +new version by mjw in attachment 390110 of rhbz:545179, as this should +eliminate the performance penalty for the case where the probes aren't in +use, and eliminate all architecture-specific code (rhbz:563541; except on +sparc) + +* Tue Feb 9 2010 David Malcolm - 2.6.4-18 +- add a systemtap tapset defining "python.function.entry" and +"python.function.return" to make it easy to use the static probepoint within +Python; add an example of using the tapset to the docs + +* Tue Feb 9 2010 David Malcolm - 2.6.4-17 +- add systemtap static probes (wcohen; patch 55; rh bug #545179) +- update some comments in specfile relating to gdb work +- manually byte-compile the gdb.py file with the freshly-built python to ensure +that .pyx and .pyo files make it into the debuginfo manifest if they are later +byte-compiled after find-debuginfo.sh is run + +* Mon Feb 8 2010 David Malcolm - 2.6.4-16 +- move the -gdb.py file from %%{_libdir}/INSTSONAME-gdb.py to +%%{_prefix}/lib/debug/%%{_libdir}/INSTSONAME.debug-gdb.py to avoid noise from +ldconfig (bug 562980), and which should also ensure it becomes part of the +debuginfo subpackage, rather than the libs subpackage +- introduce %%{py_SOVERSION} and %%{py_INSTSONAME} to reflect the upstream +configure script, and to avoid fragile scripts that try to figure this out +dynamically (e.g. for the -gdb.py change) + +* Mon Feb 8 2010 David Malcolm - 2.6.4-15 +- work around bug 562906 by supplying a fixed version of pythondeps.sh +- set %%{_python_bytecompile_errors_terminate_build} to 0 to prevent the broken +test files from killing the build on buildroots where python is installed + +* Fri Feb 5 2010 David Malcolm - 2.6.4-14 +- add gdb hooks for easier debugging + +* Fri Jan 29 2010 David Malcolm - 2.6.4-13 +- document all patches, and remove the commented-out ones + +* Tue Jan 26 2010 David Malcolm - 2.6.4-12 +- Address some of the issues identified in package review (bug 226342): + - update libs requirement on base package to use %%{name} for consistency's +sake + - convert from backticks to $() syntax throughout + - wrap value of LD_LIBRARY_PATH in quotes + - convert "/usr/bin/find" requirement to "findutils" + - remove trailing periods from summaries of -devel and -tools subpackages + - fix spelling mistake in description of -test subpackage + - convert usage of $$RPM_BUILD_ROOT to %%{buildroot} throughout, for +stylistic consistency + - supply dirmode arguments to defattr directives + +* Mon Jan 25 2010 David Malcolm - 2.6.4-11 +- update python-2.6.2-config.patch to remove downstream customization of build +of pyexpat and elementtree modules +- add patch adapted from upstream (patch 3) to add support for building against +system expat; add --with-system-expat to "configure" invocation +- remove embedded copy of expat from source tree during "prep" + +* Mon Jan 25 2010 David Malcolm - 2.6.4-10 +- introduce macros for 3 directories, replacing expanded references throughout: +%%{pylibdir}, %%{dynload_dir}, %%{site_packages} +- explicitly list all lib-dynload files, rather than dynamically gathering the +payload into a temporary text file, so that we can be sure what we are +shipping; remove now-redundant testing for presence of certain .so files +- remove embedded copy of zlib from source tree before building + +* Mon Jan 25 2010 David Malcolm - 2.6.4-9 +- change python-2.6.2-config.patch to remove our downstream change to curses +configuration in Modules/Setup.dist, so that the curses modules are built using +setup.py with the downstream default (linking against libncursesw.so, rather +than libncurses.so), rather than within the Makefile; add a test to %%install +to verify the dso files that the curses module is linked against the correct +DSO (bug 539917; changes _cursesmodule.so -> _curses.so) + +* Fri Jan 22 2010 David Malcolm - 2.6.4-8 +- rebuild (bug 556975) + +* Wed Jan 20 2010 David Malcolm - 2.6.4-7 +- move lib2to3 from -tools subpackage to main package (bug 556667) + +* Mon Jan 18 2010 David Malcolm - 2.6.4-6 +- patch Makefile.pre.in to avoid building static library (patch111, bug 556092) +- split up the "configure" invocation flags onto individual lines + +* Fri Jan 15 2010 David Malcolm - 2.6.4-5 +- replace usage of %%define with %%global +- use the %%{_isa} macro to ensure that the python-devel dependency on python +is for the correct multilib arch (#555943) +- delete bundled copy of libffi to make sure we use the system one +- replace references to /usr with %%{_prefix}; replace references to +/usr/include with %%{_includedir} + +* Wed Dec 16 2009 David Malcolm - 2.6.4-4 +- automatically disable arena allocator when run under valgrind (upstream +issue 2422; patch 52) +- add patch from Josh Boyer containing diff against upstream PyBSDDB to make +the bsddb module compile against db-4.8 (patch 53, #544275); bump the necessary +version of db4-devel to 4.8 +- patch setup.py so that it searches for db-4.8, and enable debug output for +said search; make Setup.dist use db-4.8 (patch 54) + +* Thu Nov 12 2009 David Malcolm - 2.6.4-3 +- fixup the build when __python_ver is set (Zach Sadecki; bug 533989); use +pybasever in the files section + +* Thu Oct 29 2009 David Malcolm - 2.6.4-2 +- "Makefile" and the config-32/64.h file are needed by distutils/sysconfig.py +_init_posix(), so we include them in the core package, along with their parent +directories (bug 531901) + +* Mon Oct 26 2009 David Malcolm - 2.6.4-1 +- Update to 2.6.4 + +* Fri Aug 21 2009 Tomas Mraz - 2.6.2-2 +- rebuilt with new openssl + +* Mon Jul 27 2009 James Antill - 2.6.2-1 +- Update to 2.6.2 + +* Sun Jul 26 2009 Fedora Release Engineering - 2.6-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Sat Jul 4 2009 Jonathan Steffan - 2.6-10 +- Move python-config to devel subpackage (#506153) +- Update BuildRoot for new standard + +* Sun Jun 28 2009 Jonathan Steffan - 2.6-9 +- Update python-tools description (#448940) + +* Wed Apr 15 2009 Ignacio Vazquez-Abrams 2.6-8 +- Replace python-hashlib and python-uuid (#484715) + +* Tue Mar 17 2009 James Antill - 2.6-7 +- Use system libffi +- Resolves: bug#490573 +- Fix SELinux execmem problems +- Resolves: bug#488396 + +* Thu Feb 26 2009 Fedora Release Engineering - 2.6-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Jan 16 2009 Tomas Mraz - 2.6-4 +- rebuild with new openssl + +* Tue Jan 6 2009 James Antill - 2.6-3 +- Fix distutils generated rpms. +- Resolves: bug#236535 + +* Wed Dec 10 2008 Ignacio Vazquez-Abrams - 2.6-2 +- Enable -lcrypt for cryptmodule + +* Fri Nov 28 2008 Ignacio Vazquez-Abrams - 2.6-1 +- Update to 2.6 + +* Tue Sep 30 2008 James Antill - 2.5.2-1 +- Move to 2.5.2 +- Fix CVE-2008-2316 hashlib overflow. + +* Thu Jul 17 2008 Jeremy Katz - 2.5.1-30 +- Fix up the build for new rpm +- And actually build against db4-4.7 (#455170) + +* Thu Jul 10 2008 Tom "spot" Callaway - 2.5.1-27 +- fix license tag +- enable support for db4-4.7 + +* Sun Jun 15 2008 James Antill - 2.5.1-26 +- Fix sporadic listdir problem +- Resolves: bug#451494 + +* Mon Apr 7 2008 James Antill - 2.5.1-25 +- Rebuild to re-gen autoconf file due to glibc change. +- Resolves: bug#441003 + +* Tue Mar 25 2008 James Antill - 2.5.1-24 +- Add more constants to socketmodule + +* Sat Mar 8 2008 James Antill - 2.5.1-22 +- Add constants to socketmodule +- Resolves: bug#436560 + +* Tue Feb 19 2008 Fedora Release Engineering - 2.5.1-22 +- Autorebuild for GCC 4.3 + +* Sun Jan 13 2008 Tom "spot" Callaway - 2.5.1-21 +- rebuild for new tk in rawhide + +* Mon Jan 7 2008 James Antill - 2.5.1-20 +- Add valgrind support files, as doc, to python-devel +- Relates: rhbz#418621 +- Add new API from 2.6, set_wakeup_fd ... use at own risk, presumably won't +- change but I have no control to guarantee that. +- Resolves: rhbz#427794 +- Add gdbinit support file, as doc, to python-devel + +* Fri Jan 4 2008 Tom "spot" Callaway - 2.5.1-19 +- rebuild for new tcl/tk in rawhide + +* Fri Dec 7 2007 James Antill - 2.5.1-18 +- Create a python-test sub-module, over 3MB of stuff noone wants. +- Don't remove egginfo files, try this see what happens ... may revert. +- Resolves: rhbz#414711 + +* Mon Dec 3 2007 Jeremy Katz - 2.5.1-17 +- rebuild for new libssl + +* Fri Nov 30 2007 James Antill - 2.5.1-16 +- Fix pyconfig.h comment typo. +- Add back test_support.py and the __init__.py file. +- Resolves: rhbz#387401 + +* Tue Oct 30 2007 James Antill - 2.5.1-15 +- Do codec lowercase in C Locale. +- Resolves: 207134 191096 +- Fix stupid namespacing in pysqlite, minimal upgrade to 2.3.3 pysqlite +- Resolves: 263221 + +* Wed Oct 24 2007 James Antill - 2.5.1-14 +- Remove bintuils dep. for live CD ... add work around for ctypes + +* Mon Oct 22 2007 James Antill - 2.5.1-13 +- Add tix buildprereq +- Add tkinter patch +- Resolves: #281751 +- Fix ctypes loading of libraries, add requires on binutils +- Resolves: #307221 +- Possible fix for CVE-2007-4965 possible exploitable integer overflow +- Resolves: #295971 + +* Tue Oct 16 2007 Mike Bonnet - 2.5.1-12 +- fix marshalling of objects in xmlrpclib (python bug #1739842) + +* Fri Sep 14 2007 Jeremy Katz - 2.5.1-11 +- fix encoding of sqlite .py files to work around weird encoding problem + in Turkish (#283331) + +* Mon Sep 10 2007 Jeremy Katz - 2.5.1-10 +- work around problems with multi-line plural specification (#252136) + +* Tue Aug 28 2007 Jeremy Katz - 2.5.1-9 +- rebuild against new expat + +* Tue Aug 14 2007 Jeremy Katz - 2.5.1-8 +- build against db4.6 + +* Tue Aug 14 2007 Dennis Gilmore - 2.5.1-7 +- add sparc64 to the list of archs for _pyconfig64_h + +* Fri Aug 10 2007 Jeremy Katz - 2.5.1-6 +- fix ctypes again on some arches (Hans de Goede, #251637) + +* Fri Jul 6 2007 Jeremy Katz - 2.5.1-5 +- link curses modules with ncursesw (#246385) + +* Wed Jun 27 2007 Jeremy Katz - 2.5.1-4 +- fix _elementtree.so build (#245703) +- ensure that extension modules we expect are actually built rather than + having them silently fall out of the package + +* Tue Jun 26 2007 Jeremy Katz - 2.5.1-3 +- link with system expat (#245703) + +* Thu Jun 21 2007 Jeremy Katz - 2.5.1-2 +- rebuild to take advantage of hardlinking between identical pyc/pyo files + +* Thu May 31 2007 Jeremy Katz - 2.5.1-1 +- update to python 2.5.1 + +* Mon Mar 19 2007 Jeremy Katz - 2.5.3-12 +- fix alpha build (#231961) + +* Tue Feb 13 2007 Jeremy Katz - 2.5.3-11 +- tcl/tk was reverted; rebuild again + +* Thu Feb 1 2007 Jeremy Katz - 2.5.3-10 +- rebuild for new tcl/tk + +* Tue Jan 16 2007 Miroslav Lichvar - 2.5.3-9 +- link with ncurses + +* Sat Jan 6 2007 Jeremy Katz - 2.5.3-8 +- fix extensions to use shared libpython (#219564) +- all 64bit platforms need the regex fix (#122304) + +* Wed Jan 3 2007 Jeremy Katz - 2.5.3-7 +- fix ctypes to not require execstack (#220669) + +* Fri Dec 15 2006 Jeremy Katz - 2.5.3-6 +- don't link against compat-db (Robert Scheck) + +* Wed Dec 13 2006 Jarod Wilson - 2.5.3-5 +- fix invalid assert in debug mode (upstream changeset 52622) + +* Tue Dec 12 2006 Jeremy Katz - 2.5.3-4 +- obsolete/provide python-ctypes (#219256) + +* Mon Dec 11 2006 Jeremy Katz - 2.5.3-3 +- fix atexit traceback with failed syslog logger (#218214) +- split libpython into python-libs subpackage for multilib apps + embedding python interpreters + +* Wed Dec 6 2006 Jeremy Katz - 2.5.3-2 +- disable installation of .egg-info files for now + +* Tue Dec 5 2006 Jeremy Katz +- support db 4.5 +- obsolete python-elementtree; since it requires some code tweaks, don't + provide it +- obsolete old python-sqlite; provide the version that's actually included + +* Mon Oct 30 2006 Jeremy Katz +- fix _md5 and _sha modules (Robert Sheck) +- no longer provide optik compat; it's been a couple of years now +- no longer provide the old shm module; if this is still needed, let's + build it separately +- no longer provide japanese codecs; should be a separate package + +* Mon Oct 23 2006 Jeremy Katz - 2.5-0 +- update to 2.5.0 final + +* Fri Aug 18 2006 Mihai Ibanescu - 2.4.99.c1 +- Updated to 2.5c1. Merged fixes from FC6 too: +- Fixed bug #199373 (on some platforms CFLAGS is needed when linking) +- Fixed bug #198971 (case conversion not locale safe in logging library) +- Verified bug #201434 (distutils.sysconfig is confused by the change to make + python-devel multilib friendly) is fixed upstream + +* Sun Jul 16 2006 Mihai Ibanescu - 2.4.99.b2 +- Updated to 2.5b2 (which for comparison reasons is re-labeled 2.4.99.b2) + +* Fri Jun 23 2006 Mihai Ibanescu - 2.4.99.b1 +- Updated to 2.5b1 (which for comparison reasons is re-labeled 2.4.99.b1) + +* Tue Jun 13 2006 Jeremy Katz - 2.4.3-11.FC6 +- and fix it for real + +* Tue Jun 13 2006 Jeremy Katz - 2.4.3-10.FC6 +- fix python-devel on ia64 + +* Tue Jun 13 2006 Mihai Ibanescu - 2.4.3-9 +- Fixed python-devel to be multilib friendly (bug #192747, #139911) + +* Tue Jun 13 2006 Mihai Ibanescu - 2.4.3-8 +- Only copying mkhowto from the Docs - we don't need perl dependencies from + python-tools. + +* Mon Jun 12 2006 Mihai Ibanescu - 2.4.3-7 +- Fixed bug #121198 (webbrowser.py should use the user's preferences first) + +* Mon Jun 12 2006 Mihai Ibanescu - 2.4.3-6 +- Fixed bug #192592 (too aggressive assertion fails) - SF#1257960 +- Fixed bug #167468 (Doc/tools not included) - added in the python-tools package + +* Thu Jun 8 2006 Mihai Ibanescu - 2.4.3-5 +- Fixed bug #193484 (added pydoc in the main package) + +* Mon Jun 5 2006 Mihai Ibanescu - 2.4.3-4 +- Added dist in the release + +* Mon May 15 2006 Mihai Ibanescu - 2.4.3-3 +- rebuilt to fix broken libX11 dependency + +* Wed Apr 12 2006 Jeremy Katz - 2.4.3-2 +- rebuild with new gcc to fix #188649 + +* Thu Apr 6 2006 Mihai Ibanescu - 2.4.3-1 +- Updated to 2.4.3 + +* Fri Feb 10 2006 Jesse Keating - 2.4.2-3.2.1 +- bump again for double-long bug on ppc(64) + +* Fri Feb 10 2006 Mihai Ibanescu - 2.4.3-3.2 +- rebuilt for newer tix + +* Tue Feb 07 2006 Jesse Keating - 2.4.2-3.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Fri Jan 20 2006 Mihai Ibanescu 2.4.2-3 +- fixed #136654 for another instance of audiotest.au + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Sat Nov 19 2005 Bill Nottingham 2.4.2-2 +- fix build for modular X, remove X11R6 path references + +* Tue Nov 15 2005 Mihai Ibanescu 2.4.2-1 +- Upgraded to 2.4.2 +- BuildRequires autoconf + +* Wed Nov 9 2005 Mihai Ibanescu 2.4.1-16 +- Rebuilding against newer openssl. +- XFree86-devel no longer exists + +* Mon Sep 26 2005 Peter Jones 2.4.1-14 +- Once more -- this time, to fix -EPERM when you run it in a directory + you can't read from. + +* Mon Sep 26 2005 Peter Jones 2.4.1-13 +- So, 5 or 6 people have said it works for them with this patch... + +* Sun Sep 25 2005 Peter Jones 2.4.1-12 +- Fixed bug #169159 (check for argc>0 and argv[0] == NULL, not just + argv[0][0]='\0') + Reworked the patch from -8 a bit more. + +* Fri Sep 23 2005 Mihai Ibanescu 2.4.1-10 +- Fixed bug #169159 (don't let python core dump if no arguments are passed in) + Reworked the patch from -8 a bit more. + +* Thu Sep 22 2005 Peter Jones 2.4.1-8 +- Fix bug #169046 more correctly. + +* Thu Sep 22 2005 Mihai Ibanescu 2.4.1-7 +- Fixed bug #169046 (realpath is unsafe); thanks to + Peter Jones and Arjan van de Ven for + diagnosing and the patch. + +* Tue Sep 20 2005 Mihai Ibanescu 2.4.1-4 +- Fixed bug #168655 (fixes for building as python24) + +* Tue Jul 26 2005 Mihai Ibanescu 2.4.1-3 +- Fixed bug #163435 (pynche doesn't start)) + +* Wed Apr 20 2005 Mihai Ibanescu 2.4.1-2 +- Fixed bug #143667 (python should own /usr/lib/python* on 64-bit systems, for + noarch packages) +- Fixed bug #143419 (BuildRequires db4 is not versioned) + +* Wed Apr 6 2005 Mihai Ibanescu 2.4.1-1 +- updated to 2.4.1 + +* Mon Mar 14 2005 Mihai Ibanescu 2.4-6 +- building the docs from a different source rpm, to decouple bootstrapping + python from having tetex installed + +* Fri Mar 11 2005 Dan Williams 2.4-5 +- Rebuild to pick up new libssl.so.5 + +* Wed Feb 2 2005 Mihai Ibanescu 2.4-4 +- Fixed security issue in SimpleXMLRPCServer.py (#146647) + +* Wed Jan 12 2005 Tim Waugh 2.4-3 +- Rebuilt for new readline. + +* Mon Dec 6 2004 Jeff Johnson 2.4-2 +- db-4.3.21 returns DB_BUFFER_SMALL rather than ENOMEM (#141994). +- add Provide: python(abi) = 2.4 +- include msgfmt/pygettext *.pyc and *.pyo from brp-python-bytecompile. + +* Fri Dec 3 2004 Mihai Ibanescu 2.4-1 +- Python-2.4.tar.bz2 (final) + +* Fri Nov 19 2004 Mihai Ibanescu 2.4-0.c1.1 +- Python-2.4c1.tar.bz2 (release candidate 1) + +* Thu Nov 11 2004 Jeff Johnson 2.4-0.b2.4 +- rebuild against db-4.3.21. + +* Mon Nov 8 2004 Jeremy Katz - 2.4-0.b2.3 +- fix the lib64 patch so that 64bit arches still look in /usr/lib/python... + +* Mon Nov 8 2004 Jeremy Katz - 2.4-0.b2.2 +- cryptmodule still needs -lcrypt (again) + +* Thu Nov 4 2004 Mihai Ibanescu 2.4-0.b2.1 +- Updated to python 2.4b2 (and labeled it 2.4-0.b2.1 to avoid breaking rpm's + version comparison) + +* Thu Nov 4 2004 Mihai Ibanescu 2.3.4-13 +- Fixed bug #138112 (python overflows stack buffer) - SF bug 105470 + +* Tue Nov 2 2004 Mihai Ibanescu 2.3.4-12 +- Fixed bugs #131439 #136023 #137863 (.pyc/.pyo files had the buildroot added) + +* Tue Oct 26 2004 Mihai Ibanescu 2.3.4-11 +- Fixed bug #136654 (python has sketchy audio clip) + +* Tue Aug 31 2004 Mihai Ibanescu 2.3.4-10 +- Fixed bug #77418 (Demo dir not packaged) +- More tweaking on #19347 (Moved Tools/ under /usr/lib/python2.3/Tools) + +* Fri Aug 13 2004 Mihai Ibanescu 2.3.4-8 +- Fixed bug #129769: Makefile in new python conflicts with older version found + in old python-devel +- Reorganized the spec file to get rid of the aspython2 define; __python_ver + is more powerful. + +* Tue Aug 3 2004 Mihai Ibanescu 2.3.4-7 +- Including html documentation for non-i386 arches +- Fixed #125362 (python-doc html files have japanese character encoding) +- Fixed #128923 (missing dependency between python and python-devel) + +* Fri Jul 30 2004 Mihai Ibanescu 2.3.4-6 +- Fixed #128030 (help() not printing anything) +- Fixed #125472 (distutils.sysconfig.get_python_lib() not returning the right + path on 64-bit systems) +- Fixed #127357 (building python as a shared library) +- Fixed #19347 (including the contents of Tools/scripts/ in python-tools) + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Tue Jun 8 2004 Mihai Ibanescu 2.3.4-3 +- Added an optik.py that provides the same interface from optparse for + backward compatibility; obsoleting python-optik + +* Mon Jun 7 2004 Mihai Ibanescu 2.3.4-2 +- Patched bdist_rpm to allow for builds of multiple binary rpms (bug #123598) + +* Fri Jun 4 2004 Mihai Ibanescu 2.3.4-1 +- Updated to 2.3.4-1 with Robert Scheck's help (bug #124764) +- Added BuildRequires: tix-devel (bug #124918) + +* Fri May 7 2004 Mihai Ibanescu 2.3.3-6 +- Correct fix for #122304 from upstream: + http://sourceforge.net/tracker/?func=detail&atid=105470&aid=931848&group_id=5470 + +* Thu May 6 2004 Mihai Ibanescu 2.3.3-4 +- Fix for bug #122304 : splitting the domain name fails on 64-bit arches +- Fix for bug #120879 : including Makefile into the main package + +- Requires XFree86-devel instead of -libs (see bug #118442) + +* Tue Mar 16 2004 Mihai Ibanescu 2.3.3-3 +- Requires XFree86-devel instead of -libs (see bug #118442) + +* Tue Mar 02 2004 Elliot Lee +- rebuilt + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Fri Dec 19 2003 Jeff Johnson 2.3.3-1 +- upgrade to 2.3.3. + +* Sat Dec 13 2003 Jeff Johnson 2.3.2-9 +- rebuild against db-4.2.52. + +* Fri Dec 12 2003 Jeremy Katz 2.3.2-8 +- more rebuilding for new tcl/tk + +* Wed Dec 3 2003 Jeff Johnson 2.3.2-7.1 +- rebuild against db-4.2.42. + +* Fri Nov 28 2003 Mihai Ibanescu 2.3.2-7 +- rebuilt against newer tcl/tk + +* Mon Nov 24 2003 Mihai Ibanescu 2.3.2-6 +- added a Provides: python-abi + +* Wed Nov 12 2003 Mihai Ibanescu 2.3.2-5 +- force CC (#109268) + +* Sun Nov 9 2003 Jeremy Katz 2.3.2-4 +- cryptmodule still needs -lcrypt + +* Wed Nov 5 2003 Mihai Ibanescu 2.3.2-2 +- Added patch for missing mkhowto + +* Thu Oct 16 2003 Mihai Ibanescu 2.3.2-1 +- Updated to 2.3.2 + +* Thu Sep 25 2003 Mihai Ibanescu 2.3.1-1 +- 2.3.1 final + +* Tue Sep 23 2003 Mihai Ibanescu 2.3.1-0.8.RC1 +- Building the python 2.3.1 release candidate +- Updated the lib64 patch + +* Wed Jul 30 2003 Mihai Ibanescu 2.3-0.2 +- Building python 2.3 +- Added more BuildRequires +- Updated the startup files for modulator and pynche; idle installs its own + now. + +* Thu Jul 3 2003 Mihai Ibanescu 2.2.3-4 +- Rebuilt against newer db4 packages (bug #98539) + +* Mon Jun 9 2003 Elliot Lee 2.2.3-3 +- rebuilt + +* Sat Jun 7 2003 Mihai Ibanescu 2.2.3-2 +- Rebuilt + +* Fri Jun 6 2003 Mihai Ibanescu 2.2.3-1 +- Upgraded to 2.2.3 + +* Wed Apr 2 2003 Mihai Ibanescu 2.2.2-28 +- Rebuilt + +* Wed Apr 2 2003 Mihai Ibanescu 2.2.2-27 +- Modified the ftpuri patch conforming to http://ietf.org/rfc/rfc1738.txt + +* Mon Feb 24 2003 Elliot Lee +- rebuilt + +* Mon Feb 24 2003 Mihai Ibanescu 2.2.2-25 +- Fixed bug #84886: pydoc dies when run w/o arguments +- Fixed bug #84205: add python shm module back (used to be shipped with 1.5.2) +- Fixed bug #84966: path in byte-compiled code still wrong + +* Thu Feb 20 2003 Jeremy Katz 2.2.2-23 +- ftp uri's should be able to specify being rooted at the root instead of + where you login via ftp (#84692) + +* Mon Feb 10 2003 Mihai Ibanescu 2.2.2-22 +- Using newer Japanese codecs (1.4.9). Thanks to + Peter Bowen for pointing this out. + +* Thu Feb 6 2003 Mihai Ibanescu 2.2.2-21 +- Rebuild + +* Wed Feb 5 2003 Mihai Ibanescu 2.2.2-20 +- Release number bumped really high: turning on UCS4 (ABI compatibility + breakage) + +* Fri Jan 31 2003 Mihai Ibanescu 2.2.2-13 +- Attempt to look both in /usr/lib64 and /usr/lib/python2.2/site-packages/: + some work on python-2.2.2-lib64.patch + +* Thu Jan 30 2003 Mihai Ibanescu 2.2.2-12 +- Rebuild to incorporate the removal of .lib64 and - files. + +* Thu Jan 30 2003 Mihai Ibanescu 2.2.2-11.7.3 +- Fixed bug #82544: Errata removes most tools +- Fixed bug #82435: Python 2.2.2 errata breaks redhat-config-users +- Removed .lib64 and - files that get installed after we fix the multilib + .py files. + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Wed Jan 15 2003 Jens Petersen 2.2.2-10 +- rebuild to update tkinter's tcltk deps +- convert changelog to utf-8 + +* Tue Jan 7 2003 Nalin Dahyabhai 2.2.2-9 +- rebuild + +* Fri Jan 3 2003 Nalin Dahyabhai +- pick up OpenSSL cflags and ldflags from pkgconfig if available + +* Thu Jan 2 2003 Jeremy Katz 2.2.2-8 +- urllib2 didn't support non-anonymous ftp. add support based on how + urllib did it (#80676, #78168) + +* Mon Dec 16 2002 Mihai Ibanescu 2.2.2-7 +- Fix bug #79647 (Rebuild of SRPM fails if python isn't installed) +- Added a bunch of missing BuildRequires found while fixing the + above-mentioned bug + +* Tue Dec 10 2002 Tim Powers 2.2.2-6 +- rebuild to fix broken tcltk deps for tkinter + +* Fri Nov 22 2002 Mihai Ibanescu +2.2.2-3.7.3 +- Recompiled for 7.3 (to fix the -lcrypt bug) +- Fix for the spurious error message at the end of the build (build-requires + gets confused by executable files starting with """"): make the tests + non-executable. + +* Wed Nov 20 2002 Mihai Ibanescu +2.2.2-5 +- Fixed configuration patch to add -lcrypt when compiling cryptmodule.c + +2.2.2-4 +- Spec file change from Matt Wilson to disable linking + with the C++ compiler. + +* Mon Nov 11 2002 Mihai Ibanescu +2.2.2-3.* +- Merged patch from Karsten Hopp from 2.2.1-17hammer to + use %%{_libdir} +- Added XFree86-libs as BuildRequires (because of tkinter) +- Fixed duplicate listing of plat-linux2 +- Fixed exclusion of lib-dynload/japanese +- Added lib64 patch for the japanese codecs +- Use setup magic instead of using tar directly on JapaneseCodecs + +* Tue Nov 5 2002 Mihai Ibanescu +2.2.2-2 +- Fix #76912 (python-tools contains idle, which uses tkinter, but there is no + requirement of tkinter from python-tools). +- Fix #74013 (rpm is missing the /usr/lib/python2.2/test directory) + +* Mon Nov 4 2002 Mihai Ibanescu +- builds as python2 require a different libdb +- changed the buildroot name of python to match python2 builds + +* Fri Nov 1 2002 Mihai Ibanescu +- updated python to 2.2.2 and adjusted the patches accordingly + +* Mon Oct 21 2002 Mihai Ibanescu +- Fix #53930 (Python-2.2.1-buildroot-bytecode.patch) +- Added BuildPrereq dependency on gcc-c++ + +* Fri Aug 30 2002 Trond Eivind Glomsrød 2.2.1-17 +- security fix for _execvpe + +* Tue Aug 13 2002 Trond Eivind Glomsrød 2.2.1-16 +- Fix #71011,#71134, #58157 + +* Wed Aug 7 2002 Trond Eivind Glomsrød 2.2.1-15 +- Resurrect tkinter +- Fix for distutils (#67671) +- Fix #69962 + +* Thu Jul 25 2002 Trond Eivind Glomsrød 2.2.1-14 +- Obsolete tkinter/tkinter2 (#69838) + +* Tue Jul 23 2002 Trond Eivind Glomsrød 2.2.1-13 +- Doc fixes (#53951) - not on alpha at the momemt + +* Mon Jul 8 2002 Trond Eivind Glomsrød 2.2.1-12 +- fix pydoc (#68082) + +* Mon Jul 8 2002 Trond Eivind Glomsrød 2.2.1-11 +- Add db4-devel as a BuildPrereq + +* Fri Jun 21 2002 Tim Powers 2.2.1-10 +- automated rebuild + +* Mon Jun 17 2002 Trond Eivind Glomsrød 2.2.1-9 +- Add Japanese codecs (#66352) + +* Tue Jun 11 2002 Trond Eivind Glomsrød 2.2.1-8 +- No more tkinter... + +* Wed May 29 2002 Trond Eivind Glomsrød 2.2.1-7 +- Rebuild + +* Tue May 21 2002 Trond Eivind Glomsrød 2.2.1-6 +- Add the email subcomponent (#65301) + +* Fri May 10 2002 Trond Eivind Glomsrød 2.2.1-5 +- Rebuild + +* Thu May 02 2002 Than Ngo 2.2.1-4 +- rebuild i new enviroment + +* Tue Apr 23 2002 Trond Eivind Glomsrød +- Use ucs2, not ucs4, to avoid breaking tkinter (#63965) + +* Mon Apr 22 2002 Trond Eivind Glomsrød 2.2.1-2 +- Make it use db4 + +* Fri Apr 12 2002 Trond Eivind Glomsrød 2.2.1-1 +- 2.2.1 - a bugfix-only release + +* Fri Apr 12 2002 Trond Eivind Glomsrød 2.2-16 +- the same, but in builddirs - this will remove them from the + docs package, which doesn't look in the buildroot for files. + +* Fri Apr 12 2002 Trond Eivind Glomsrød 2.2-15 +- Get rid of temporary files and .cvsignores included + in the tarball and make install + +* Fri Apr 5 2002 Trond Eivind Glomsrød 2.2-14 +- Don't own lib-tk in main package, only in tkinter (#62753) + +* Mon Mar 25 2002 Trond Eivind Glomsrød 2.2-13 +- rebuild + +* Mon Mar 25 2002 Trond Eivind Glomsrød 2.2-12 +- rebuild + +* Fri Mar 1 2002 Trond Eivind Glomsrød 2.2-11 +- Add a not to the Distutils obsoletes test (doh!) + +* Fri Mar 1 2002 Trond Eivind Glomsrød 2.2-10 +- Rebuild + +* Mon Feb 25 2002 Trond Eivind Glomsrød 2.2-9 +- Only obsolete Distutils when built as python + +* Thu Feb 21 2002 Trond Eivind Glomsrød 2.2-8 +- Make files in /usr/bin install side by side with python 1.5 when +- Drop explicit requirement of db4 + built as python2 + +* Thu Jan 31 2002 Elliot Lee 2.2-7 +- Use version and pybasever macros to make updating easy +- Use _smp_mflags macro + +* Tue Jan 29 2002 Trond Eivind Glomsrød 2.2-6 +- Add db4-devel to BuildPrereq + +* Fri Jan 25 2002 Nalin Dahyabhai 2.2-5 +- disable ndbm support, which is db2 in disguise (really interesting things + can happen when you mix db2 and db4 in a single application) + +* Thu Jan 24 2002 Trond Eivind Glomsrød 2.2-4 +- Obsolete subpackages if necesarry +- provide versioned python2 +- build with db4 + +* Wed Jan 16 2002 Trond Eivind Glomsrød 2.2-3 +- Alpha toolchain broken. Disable build on alpha. +- New openssl + +* Wed Dec 26 2001 Trond Eivind Glomsrød 2.2-1 +- 2.2 final + +* Fri Dec 14 2001 Trond Eivind Glomsrød 2.2-0.11c1 +- 2.2 RC 1 +- Don't include the _tkinter module in the main package - it's + already in the tkiter packace +- Turn off the mpzmodule, something broke in the buildroot + +* Wed Nov 28 2001 Trond Eivind Glomsrød 2.2-0.10b2 +- Use -fPIC for OPT as well, in lack of a proper libpython.so + +* Mon Nov 26 2001 Matt Wilson 2.2-0.9b2 +- changed DESTDIR to point to / so that distutils will install dynload + modules properly in the installroot + +* Fri Nov 16 2001 Matt Wilson 2.2-0.8b2 +- 2.2b2 + +* Fri Oct 26 2001 Matt Wilson 2.2-0.7b1 +- python2ify + +* Fri Oct 19 2001 Trond Eivind Glomsrød 2.2-0.5b1 +- 2.2b1 + +* Sun Sep 30 2001 Trond Eivind Glomsrød 2.2-0.4a4 +- 2.2a4 +- Enable UCS4 support +- Enable IPv6 +- Provide distutils +- Include msgfmt.py and pygettext.py + +* Fri Sep 14 2001 Trond Eivind Glomsrød 2.2-0.3a3 +- Obsolete Distutils, which is now part of the main package +- Obsolete python2 + +* Thu Sep 13 2001 Trond Eivind Glomsrød 2.2-0.2a3 +- Add docs, tools and tkinter subpackages, to match the 1.5 layout + +* Wed Sep 12 2001 Trond Eivind Glomsrød 2.2-0.1a3 +- 2.2a3 +- don't build tix and blt extensions + +* Mon Aug 13 2001 Trond Eivind Glomsrød +- Add tk and tix to build dependencies + +* Sat Jul 21 2001 Trond Eivind Glomsrød +- 2.1.1 bugfix release - with a GPL compatible license + +* Fri Jul 20 2001 Trond Eivind Glomsrød +- Add new build dependencies (#49753) + +* Tue Jun 26 2001 Nalin Dahyabhai +- build with -fPIC + +* Fri Jun 1 2001 Trond Eivind Glomsrød +- 2.1 +- reorganization of file includes + +* Wed Dec 20 2000 Trond Eivind Glomsrød +- fix the "requires" clause, it lacked a space causing problems +- use %%{_tmppath} +- don't define name, version etc +- add the available patches from the Python home page + +* Fri Dec 15 2000 Matt Wilson +- added devel subpackage + +* Fri Dec 15 2000 Matt Wilson +- modify all files to use "python2.0" as the intrepter +- don't build the Expat bindings +- build against db1 + +* Mon Oct 16 2000 Jeremy Hylton +- updated for 2.0 final + +* Mon Oct 9 2000 Jeremy Hylton +- updated for 2.0c1 +- build audioop, imageop, and rgbimg extension modules +- include xml.parsers subpackage +- add test.xml.out to files list + +* Thu Oct 5 2000 Jeremy Hylton +- added bin/python2.0 to files list (suggested by Martin v. L?) + +* Tue Sep 26 2000 Jeremy Hylton +- updated for release 1 of 2.0b2 +- use .bz2 version of Python source + +* Tue Sep 12 2000 Jeremy Hylton +- Version 2 of 2.0b1 +- Make the package relocatable. Thanks to Suchandra Thapa. +- Exclude Tkinter from main RPM. If it is in a separate RPM, it is + easier to track Tk releases.