]> git.ipfire.org Git - people/pmueller/ipfire-3.x.git/commitdiff
python: Update to 2.7.15
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 22 Feb 2019 22:04:48 +0000 (22:04 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 22 Feb 2019 22:04:48 +0000 (22:04 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
35 files changed:
python/patches/00001-pydocnogui.patch [new file with mode: 0644]
python/patches/00010-2.7.13-binutils-no-dep.patch [new file with mode: 0644]
python/patches/00101-lib64-regex.patch [deleted file]
python/patches/00111-no-static-lib.patch [deleted file]
python/patches/00112-2.7.13-debug-build.patch [new file with mode: 0644]
python/patches/00125-less-verbose-COUNT_ALLOCS.patch [deleted file]
python/patches/00132-add-rpmbuild-hooks-to-unittest.patch [new file with mode: 0644]
python/patches/00134-fix-COUNT_ALLOCS-failure-in-test_sys.patch [deleted file]
python/patches/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch [new file with mode: 0644]
python/patches/00138-fix-distutils-tests-in-debug-build.patch [new file with mode: 0644]
python/patches/00139-skip-test_float-known-failure-on-arm.patch [new file with mode: 0644]
python/patches/00140-skip-test_ctypes-known-failure-on-sparc.patch [new file with mode: 0644]
python/patches/00141-fix-test_gc_with_COUNT_ALLOCS.patch [deleted file]
python/patches/00142-skip-failing-pty-tests-in-rpmbuild.patch
python/patches/00143-tsc-on-ppc.patch [new file with mode: 0644]
python/patches/00147-add-debug-malloc-stats.patch [new file with mode: 0644]
python/patches/00156-gdb-autoload-safepath.patch [new file with mode: 0644]
python/patches/00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch [new file with mode: 0644]
python/patches/00170-gc-assertions.patch
python/patches/00173-workaround-ENOPROTOOPT-in-bind_port.patch [deleted file]
python/patches/00180-python-add-support-for-ppc64p7.patch [new file with mode: 0644]
python/patches/00181-allow-arbitrary-timeout-in-condition-wait.patch
python/patches/00184-ctypes-should-build-with-libffi-multilib-wrapper.patch [deleted file]
python/patches/00187-add-RPATH-to-pyexpat.patch [new file with mode: 0644]
python/patches/00189-use-rpm-wheels.patch [new file with mode: 0644]
python/patches/00190-gdb-py-bt-dont-raise-exception-from-eval.patch [new file with mode: 0644]
python/patches/00191-disable-NOOP.patch [new file with mode: 0644]
python/patches/00193-enable-loading-sqlite-extensions.patch [new file with mode: 0644]
python/patches/00289-disable-nis-detection.patch [new file with mode: 0644]
python/patches/00309-shutil-spawn-subprocess.patch [new file with mode: 0644]
python/patches/00310-use-xml-sethashsalt-in-elementtree.patch [new file with mode: 0644]
python/patches/python-2.5-cflags.patch
python/patches/python-2.7.1-config.patch
python/python-2.7.13-lib64.patch [moved from python/python-2.7.12-lib64.patch with 90% similarity]
python/python.nm

diff --git a/python/patches/00001-pydocnogui.patch b/python/patches/00001-pydocnogui.patch
new file mode 100644 (file)
index 0000000..0311f38
--- /dev/null
@@ -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 <name>" to write out the HTML documentation for a module
+ to a file named "<name>.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 <name> ...
+     Write out the HTML documentation for a module to a file in the current
+     directory.  If <name> 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/python/patches/00010-2.7.13-binutils-no-dep.patch b/python/patches/00010-2.7.13-binutils-no-dep.patch
new file mode 100644 (file)
index 0000000..d432623
--- /dev/null
@@ -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/python/patches/00101-lib64-regex.patch b/python/patches/00101-lib64-regex.patch
deleted file mode 100644 (file)
index e399390..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-diff -up Python-2.7.3/Lib/test/test_re.py.lib64-regex Python-2.7.3/Lib/test/test_re.py
---- Python-2.7.3/Lib/test/test_re.py.lib64-regex       2012-04-09 19:07:32.000000000 -0400
-+++ Python-2.7.3/Lib/test/test_re.py   2013-02-19 13:53:57.624033102 -0500
-@@ -757,6 +757,15 @@ class ReTests(unittest.TestCase):
-         self.assertRaises(TypeError, re.finditer, "a", {})
-         self.assertRaises(OverflowError, _sre.compile, "abc", 0, [long_overflow])
-+    def test_bug_931848(self):
-+        try:
-+            unicode
-+        except NameError:
-+            pass
-+        pattern = eval('u"[\u002E\u3002\uFF0E\uFF61]"')
-+        self.assertEqual(re.compile(pattern).split("a.b.c"),
-+                         ['a','b','c'])
-+
- def run_re_tests():
-     from test.re_tests import tests, SUCCEED, FAIL, SYNTAX_ERROR
-     if verbose:
diff --git a/python/patches/00111-no-static-lib.patch b/python/patches/00111-no-static-lib.patch
deleted file mode 100644 (file)
index f71117f..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-diff -up Python-2.7.3/Makefile.pre.in.no-static-lib Python-2.7.3/Makefile.pre.in
---- Python-2.7.3/Makefile.pre.in.no-static-lib 2013-02-19 14:03:40.801993224 -0500
-+++ Python-2.7.3/Makefile.pre.in       2013-02-19 14:04:44.070988898 -0500
-@@ -397,7 +397,7 @@ coverage:
- # Build the interpreter
--$(BUILDPYTHON):       Modules/python.o $(LIBRARY) $(LDLIBRARY)
-+$(BUILDPYTHON):       Modules/python.o $(LDLIBRARY)
-               $(LINKCC) $(LDFLAGS) $(LINKFORSHARED) -o $@ \
-                       Modules/python.o \
-                       $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST)
-@@ -413,18 +413,6 @@ sharedmods: $(BUILDPYTHON)
-       $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \
-               $(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); \
-@@ -1021,18 +1009,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/python/patches/00112-2.7.13-debug-build.patch b/python/patches/00112-2.7.13-debug-build.patch
new file mode 100644 (file)
index 0000000..463f4d8
--- /dev/null
@@ -0,0 +1,324 @@
+From 898f93aa206e577dfe854c59bc62d0cea09cd5ed Mon Sep 17 00:00:00 2001
+From: Tomas Orsava <torsava@redhat.com>
+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/python/patches/00125-less-verbose-COUNT_ALLOCS.patch b/python/patches/00125-less-verbose-COUNT_ALLOCS.patch
deleted file mode 100644 (file)
index 8cef015..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-diff -up Python-2.7/Python/pythonrun.c.less-verbose-COUNT_ALLOCS Python-2.7/Python/pythonrun.c
---- Python-2.7/Python/pythonrun.c.less-verbose-COUNT_ALLOCS    2010-08-17 14:49:33.321913909 -0400
-+++ Python-2.7/Python/pythonrun.c      2010-08-17 14:54:48.750910403 -0400
-@@ -470,7 +470,15 @@ Py_Finalize(void)
-     /* Debugging stuff */
- #ifdef COUNT_ALLOCS
--    dump_counts(stdout);
-+    /* This is a downstream Fedora modification.
-+       The upstream default with COUNT_ALLOCS is to always dump the counts to
-+       stdout on exit.  For our debug builds its useful to have the info from
-+       COUNT_ALLOCS available, but the stdout info here gets in the way, so
-+       we make it optional, wrapping it in an environment variable (modelled
-+       on the other PYTHONDUMP* env variables):
-+    */
-+    if (Py_GETENV("PYTHONDUMPCOUNTS"))
-+        dump_counts(stdout);
- #endif
-     PRINT_TOTAL_REFS();
diff --git a/python/patches/00132-add-rpmbuild-hooks-to-unittest.patch b/python/patches/00132-add-rpmbuild-hooks-to-unittest.patch
new file mode 100644 (file)
index 0000000..e63395f
--- /dev/null
@@ -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/python/patches/00134-fix-COUNT_ALLOCS-failure-in-test_sys.patch b/python/patches/00134-fix-COUNT_ALLOCS-failure-in-test_sys.patch
deleted file mode 100644 (file)
index 71e7f68..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
-index 0dd4258..d9b3267 100644
---- a/Lib/test/test_sys.py
-+++ b/Lib/test/test_sys.py
-@@ -769,6 +769,11 @@ class SizeofTest(unittest.TestCase):
-                   '10P'                 # PySequenceMethods
-                   '6P'                  # PyBufferProcs
-                   '2P')
-+
-+        # COUNT_ALLOCS adds further fields to the end of a PyTypeObject:
-+        if hasattr(sys, 'getcounts'):
-+            s += size('P')
-+
-         class newstyleclass(object):
-             pass
-         check(newstyleclass, s)
diff --git a/python/patches/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch b/python/patches/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch
new file mode 100644 (file)
index 0000000..7122a29
--- /dev/null
@@ -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/python/patches/00138-fix-distutils-tests-in-debug-build.patch b/python/patches/00138-fix-distutils-tests-in-debug-build.patch
new file mode 100644 (file)
index 0000000..1fd1091
--- /dev/null
@@ -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/python/patches/00139-skip-test_float-known-failure-on-arm.patch b/python/patches/00139-skip-test_float-known-failure-on-arm.patch
new file mode 100644 (file)
index 0000000..9d0bfad
--- /dev/null
@@ -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/python/patches/00140-skip-test_ctypes-known-failure-on-sparc.patch b/python/patches/00140-skip-test_ctypes-known-failure-on-sparc.patch
new file mode 100644 (file)
index 0000000..95aa41e
--- /dev/null
@@ -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/python/patches/00141-fix-test_gc_with_COUNT_ALLOCS.patch b/python/patches/00141-fix-test_gc_with_COUNT_ALLOCS.patch
deleted file mode 100644 (file)
index d5bf3c9..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-diff -up Python-2.7.2/Lib/test/test_gc.py.fix-test_gc_with_COUNT_ALLOCS Python-2.7.2/Lib/test/test_gc.py
---- Python-2.7.2/Lib/test/test_gc.py.fix-test_gc_with_COUNT_ALLOCS     2011-09-08 19:49:13.045924309 -0400
-+++ Python-2.7.2/Lib/test/test_gc.py   2011-09-08 19:50:07.035920617 -0400
-@@ -102,11 +102,17 @@ class GCTests(unittest.TestCase):
-         del a
-         self.assertNotEqual(gc.collect(), 0)
-         del B, C
--        self.assertNotEqual(gc.collect(), 0)
-+        if hasattr(sys, 'getcounts'):
-+            self.assertEqual(gc.collect(), 0)
-+        else:
-+            self.assertNotEqual(gc.collect(), 0)
-         A.a = A()
-         del A
--        self.assertNotEqual(gc.collect(), 0)
--        self.assertEqual(gc.collect(), 0)
-+        if hasattr(sys, 'getcounts'):
-+            self.assertEqual(gc.collect(), 0)
-+        else:
-+            self.assertNotEqual(gc.collect(), 0)
-+            self.assertEqual(gc.collect(), 0)
-     def test_method(self):
-         # Tricky: self.__init__ is a bound method, it references the instance.
index 414ffcd9ad6f5c128f6ae1e230fd1c979634dd3a..2f51165b14c4235fb4ee33bc5b8b5d35437ed07c 100644 (file)
@@ -1,6 +1,6 @@
-diff -up Python-2.7.2/Lib/test/test_openpty.py.skip-failing-pty-tests-in-rpmbuild Python-2.7.2/Lib/test/test_openpty.py
---- Python-2.7.2/Lib/test/test_openpty.py.skip-failing-pty-tests-in-rpmbuild   2011-09-09 05:09:28.698920379 -0400
-+++ Python-2.7.2/Lib/test/test_openpty.py      2011-09-09 05:10:54.805914490 -0400
+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"):
  
  
@@ -8,11 +8,11 @@ diff -up Python-2.7.2/Lib/test/test_openpty.py.skip-failing-pty-tests-in-rpmbuil
 +    @unittest._skipInRpmBuild('sometimes fails in Koji, possibly due to a mock issue (rhbz#714627)')
      def test(self):
          master, slave = os.openpty()
-         if not os.isatty(slave):
-diff -up Python-2.7.2/Lib/test/test_pty.py.skip-failing-pty-tests-in-rpmbuild Python-2.7.2/Lib/test/test_pty.py
---- Python-2.7.2/Lib/test/test_pty.py.skip-failing-pty-tests-in-rpmbuild       2011-09-09 05:09:36.781919825 -0400
-+++ Python-2.7.2/Lib/test/test_pty.py  2011-09-09 05:11:14.741913127 -0400
-@@ -109,6 +109,7 @@ class PtyTest(unittest.TestCase):
+         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)
  
  
diff --git a/python/patches/00143-tsc-on-ppc.patch b/python/patches/00143-tsc-on-ppc.patch
new file mode 100644 (file)
index 0000000..447c6e3
--- /dev/null
@@ -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/python/patches/00147-add-debug-malloc-stats.patch b/python/patches/00147-add-debug-malloc-stats.patch
new file mode 100644 (file)
index 0000000..0d783f5
--- /dev/null
@@ -0,0 +1,711 @@
+diff -up Python-2.7.2/Include/dictobject.h.add-debug-malloc-stats Python-2.7.2/Include/dictobject.h
+--- Python-2.7.2/Include/dictobject.h.add-debug-malloc-stats   2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/dictobject.h  2011-09-16 19:03:25.105821625 -0400
+@@ -150,6 +150,8 @@ PyAPI_FUNC(PyObject *) PyDict_GetItemStr
+ 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 -up Python-2.7.2/Include/floatobject.h.add-debug-malloc-stats Python-2.7.2/Include/floatobject.h
+--- Python-2.7.2/Include/floatobject.h.add-debug-malloc-stats  2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/floatobject.h 2011-09-16 19:03:25.106821625 -0400
+@@ -132,6 +132,7 @@ PyAPI_FUNC(PyObject *) _PyFloat_FormatAd
+    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 -up Python-2.7.2/Include/frameobject.h.add-debug-malloc-stats Python-2.7.2/Include/frameobject.h
+--- Python-2.7.2/Include/frameobject.h.add-debug-malloc-stats  2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/frameobject.h 2011-09-16 19:03:25.107821625 -0400
+@@ -80,6 +80,8 @@ PyAPI_FUNC(void) PyFrame_FastToLocals(Py
+ 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 -up Python-2.7.2/Include/intobject.h.add-debug-malloc-stats Python-2.7.2/Include/intobject.h
+--- Python-2.7.2/Include/intobject.h.add-debug-malloc-stats    2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/intobject.h   2011-09-16 19:03:25.107821625 -0400
+@@ -74,6 +74,8 @@ PyAPI_FUNC(PyObject *) _PyInt_FormatAdva
+                                            char *format_spec,
+                                            Py_ssize_t format_spec_len);
++PyAPI_FUNC(void) _PyInt_DebugMallocStats(FILE *out);
++
+ #ifdef __cplusplus
+ }
+ #endif
+diff -up Python-2.7.2/Include/listobject.h.add-debug-malloc-stats Python-2.7.2/Include/listobject.h
+--- Python-2.7.2/Include/listobject.h.add-debug-malloc-stats   2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/listobject.h  2011-09-16 19:03:25.107821625 -0400
+@@ -62,6 +62,8 @@ PyAPI_FUNC(PyObject *) _PyList_Extend(Py
+ #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 -up Python-2.7.2/Include/methodobject.h.add-debug-malloc-stats Python-2.7.2/Include/methodobject.h
+--- Python-2.7.2/Include/methodobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/methodobject.h        2011-09-16 19:03:25.108821625 -0400
+@@ -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 -up Python-2.7.2/Include/object.h.add-debug-malloc-stats Python-2.7.2/Include/object.h
+--- Python-2.7.2/Include/object.h.add-debug-malloc-stats       2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/object.h      2011-09-16 19:03:25.108821625 -0400
+@@ -980,6 +980,13 @@ PyAPI_DATA(PyObject *) _PyTrash_delete_l
+             _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 -up Python-2.7.2/Include/objimpl.h.add-debug-malloc-stats Python-2.7.2/Include/objimpl.h
+--- Python-2.7.2/Include/objimpl.h.add-debug-malloc-stats      2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/objimpl.h     2011-09-16 19:03:25.108821625 -0400
+@@ -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 -up Python-2.7.2/Include/stringobject.h.add-debug-malloc-stats Python-2.7.2/Include/stringobject.h
+--- Python-2.7.2/Include/stringobject.h.add-debug-malloc-stats 2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/stringobject.h        2011-09-16 19:03:25.109821625 -0400
+@@ -204,6 +204,8 @@ PyAPI_FUNC(PyObject *) _PyBytes_FormatAd
+                                              char *format_spec,
+                                              Py_ssize_t format_spec_len);
++PyAPI_FUNC(void) _PyString_DebugMallocStats(FILE *out);
++
+ #ifdef __cplusplus
+ }
+ #endif
+diff -up Python-2.7.2/Include/unicodeobject.h.add-debug-malloc-stats Python-2.7.2/Include/unicodeobject.h
+--- Python-2.7.2/Include/unicodeobject.h.add-debug-malloc-stats        2011-06-11 11:46:23.000000000 -0400
++++ Python-2.7.2/Include/unicodeobject.h       2011-09-16 19:03:25.109821625 -0400
+@@ -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 -up Python-2.7.2/Lib/test/test_sys.py.add-debug-malloc-stats Python-2.7.2/Lib/test/test_sys.py
+--- Python-2.7.2/Lib/test/test_sys.py.add-debug-malloc-stats   2011-09-16 19:03:25.048821626 -0400
++++ Python-2.7.2/Lib/test/test_sys.py  2011-09-16 19:03:25.110821625 -0400
+@@ -473,6 +473,32 @@ class SysModuleTest(unittest.TestCase):
+         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 -up Python-2.7.2/Objects/classobject.c.add-debug-malloc-stats Python-2.7.2/Objects/classobject.c
+--- Python-2.7.2/Objects/classobject.c.add-debug-malloc-stats  2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/classobject.c 2011-09-16 19:03:25.110821625 -0400
+@@ -2670,3 +2670,12 @@ PyMethod_Fini(void)
+ {
+     (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 -up Python-2.7.2/Objects/dictobject.c.add-debug-malloc-stats Python-2.7.2/Objects/dictobject.c
+--- Python-2.7.2/Objects/dictobject.c.add-debug-malloc-stats   2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/dictobject.c  2011-09-16 19:03:25.111821625 -0400
+@@ -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 -up Python-2.7.2/Objects/floatobject.c.add-debug-malloc-stats Python-2.7.2/Objects/floatobject.c
+--- Python-2.7.2/Objects/floatobject.c.add-debug-malloc-stats  2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/floatobject.c 2011-09-16 19:03:25.111821625 -0400
+@@ -35,6 +35,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 -up Python-2.7.2/Objects/frameobject.c.add-debug-malloc-stats Python-2.7.2/Objects/frameobject.c
+--- Python-2.7.2/Objects/frameobject.c.add-debug-malloc-stats  2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/frameobject.c 2011-09-16 19:03:25.112821625 -0400
+@@ -980,3 +980,13 @@ PyFrame_Fini(void)
+     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 -up Python-2.7.2/Objects/intobject.c.add-debug-malloc-stats Python-2.7.2/Objects/intobject.c
+--- Python-2.7.2/Objects/intobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/intobject.c   2011-09-16 19:03:25.112821625 -0400
+@@ -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 -up Python-2.7.2/Objects/listobject.c.add-debug-malloc-stats Python-2.7.2/Objects/listobject.c
+--- Python-2.7.2/Objects/listobject.c.add-debug-malloc-stats   2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/listobject.c  2011-09-16 19:03:25.113821625 -0400
+@@ -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 -up Python-2.7.2/Objects/methodobject.c.add-debug-malloc-stats Python-2.7.2/Objects/methodobject.c
+--- Python-2.7.2/Objects/methodobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/methodobject.c        2011-09-16 19:03:25.113821625 -0400
+@@ -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 -up Python-2.7.2/Objects/object.c.add-debug-malloc-stats Python-2.7.2/Objects/object.c
+--- Python-2.7.2/Objects/object.c.add-debug-malloc-stats       2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/object.c      2011-09-16 19:04:46.463820849 -0400
+@@ -2334,6 +2334,23 @@ PyMem_Free(void *p)
+     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 -up Python-2.7.2/Objects/obmalloc.c.add-debug-malloc-stats Python-2.7.2/Objects/obmalloc.c
+--- Python-2.7.2/Objects/obmalloc.c.add-debug-malloc-stats     2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/obmalloc.c    2011-09-16 19:03:25.114821625 -0400
+@@ -508,12 +508,10 @@ static struct arena_object* usable_arena
+ /* 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
+@@ -528,7 +526,7 @@ new_arena(void)
+ #ifdef PYMALLOC_DEBUG
+     if (Py_GETENV("PYTHONMALLOCSTATS"))
+-        _PyObject_DebugMallocStats();
++        _PyObject_DebugMallocStats(stderr);
+ #endif
+     if (unused_arena_objects == NULL) {
+         uint i;
+@@ -588,11 +586,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 */
+@@ -1694,17 +1690,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;
+@@ -1725,17 +1723,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;
+@@ -1764,7 +1777,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)
+@@ -1818,10 +1831,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];
+@@ -1832,7 +1845,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",
+@@ -1842,36 +1855,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 -up Python-2.7.2/Objects/setobject.c.add-debug-malloc-stats Python-2.7.2/Objects/setobject.c
+--- Python-2.7.2/Objects/setobject.c.add-debug-malloc-stats    2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/setobject.c   2011-09-16 19:03:25.115821625 -0400
+@@ -1088,6 +1088,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 -up Python-2.7.2/Objects/stringobject.c.add-debug-malloc-stats Python-2.7.2/Objects/stringobject.c
+--- Python-2.7.2/Objects/stringobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/stringobject.c        2011-09-16 19:03:25.116821625 -0400
+@@ -4822,3 +4822,43 @@ void _Py_ReleaseInternedStrings(void)
+     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 -up Python-2.7.2/Objects/tupleobject.c.add-debug-malloc-stats Python-2.7.2/Objects/tupleobject.c
+--- Python-2.7.2/Objects/tupleobject.c.add-debug-malloc-stats  2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/tupleobject.c 2011-09-16 19:03:25.116821625 -0400
+@@ -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 -up Python-2.7.2/Objects/unicodeobject.c.add-debug-malloc-stats Python-2.7.2/Objects/unicodeobject.c
+--- Python-2.7.2/Objects/unicodeobject.c.add-debug-malloc-stats        2011-06-11 11:46:27.000000000 -0400
++++ Python-2.7.2/Objects/unicodeobject.c       2011-09-16 19:03:25.118821625 -0400
+@@ -8883,6 +8883,12 @@ _PyUnicode_Fini(void)
+     (void)PyUnicode_ClearFreeList();
+ }
++void _PyUnicode_DebugMallocStats(FILE *out)
++{
++    _PyDebugAllocatorStats(out, "free PyUnicodeObject", numfree,
++                           sizeof(PyUnicodeObject));
++}
++
+ #ifdef __cplusplus
+ }
+ #endif
+diff -up Python-2.7.2/Python/pythonrun.c.add-debug-malloc-stats Python-2.7.2/Python/pythonrun.c
+--- Python-2.7.2/Python/pythonrun.c.add-debug-malloc-stats     2011-09-16 19:03:25.025821626 -0400
++++ Python-2.7.2/Python/pythonrun.c    2011-09-16 19:03:25.118821625 -0400
+@@ -549,7 +549,7 @@ Py_Finalize(void)
+ #endif /* Py_TRACE_REFS */
+ #ifdef PYMALLOC_DEBUG
+     if (Py_GETENV("PYTHONMALLOCSTATS"))
+-        _PyObject_DebugMallocStats();
++        _PyObject_DebugMallocStats(stderr);
+ #endif
+     call_ll_exitfuncs();
+diff -up Python-2.7.2/Python/sysmodule.c.add-debug-malloc-stats Python-2.7.2/Python/sysmodule.c
+--- Python-2.7.2/Python/sysmodule.c.add-debug-malloc-stats     2011-09-16 19:03:25.007821626 -0400
++++ Python-2.7.2/Python/sysmodule.c    2011-09-16 19:03:25.119821625 -0400
+@@ -872,6 +872,57 @@ a 11-tuple where the entries in the tupl
+ 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 *);
+@@ -970,6 +1021,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/python/patches/00156-gdb-autoload-safepath.patch b/python/patches/00156-gdb-autoload-safepath.patch
new file mode 100644 (file)
index 0000000..a16fe8d
--- /dev/null
@@ -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/python/patches/00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch b/python/patches/00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch
new file mode 100644 (file)
index 0000000..9807883
--- /dev/null
@@ -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(),
index f3a0838acdccf570c6e0d7a3cdec2033b50eea37..9ade298930c9494f4be82d7548e2be8cc7d47d55 100644 (file)
@@ -1,16 +1,18 @@
-diff -up Python-2.7.3/Lib/test/test_gc.py.gc-assertions Python-2.7.3/Lib/test/test_gc.py
---- Python-2.7.3/Lib/test/test_gc.py.gc-assertions     2013-02-20 16:28:20.890536607 -0500
-+++ Python-2.7.3/Lib/test/test_gc.py   2013-02-20 16:39:52.720489297 -0500
-@@ -1,6 +1,7 @@
+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.test_support import verbose, run_unittest, start_threads
-+from test.test_support import verbose, run_unittest, start_threads, import_module
+ 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
-@@ -32,6 +33,8 @@ class GC_Detector(object):
+@@ -39,6 +40,8 @@ class GC_Detector(object):
          self.wr = weakref.ref(C1055820(666), it_happened)
  
  
@@ -19,7 +21,7 @@ diff -up Python-2.7.3/Lib/test/test_gc.py.gc-assertions Python-2.7.3/Lib/test/te
  ### Tests
  ###############################################################################
  
-@@ -476,6 +479,49 @@ class GCTests(unittest.TestCase):
+@@ -537,6 +540,49 @@ class GCTests(unittest.TestCase):
              # would be damaged, with an empty __dict__.
              self.assertEqual(x, None)
  
@@ -69,9 +71,10 @@ diff -up Python-2.7.3/Lib/test/test_gc.py.gc-assertions Python-2.7.3/Lib/test/te
  class GCTogglingTests(unittest.TestCase):
      def setUp(self):
          gc.enable()
-diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmodule.c
---- Python-2.7.3/Modules/gcmodule.c.gc-assertions      2012-04-09 19:07:34.000000000 -0400
-+++ Python-2.7.3/Modules/gcmodule.c    2013-02-20 16:28:21.029536600 -0500
+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 */
@@ -146,7 +149,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
  /* Get an object's GC head */
  #define AS_GC(o) ((PyGC_Head *)(o)-1)
  
-@@ -288,7 +355,8 @@ update_refs(PyGC_Head *containers)
+@@ -328,7 +395,8 @@ update_refs(PyGC_Head *containers)
  {
      PyGC_Head *gc = containers->gc.gc_next;
      for (; gc != containers; gc = gc->gc.gc_next) {
@@ -156,7 +159,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
          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
-@@ -308,7 +376,8 @@ update_refs(PyGC_Head *containers)
+@@ -348,7 +416,8 @@ update_refs(PyGC_Head *containers)
           * so serious that maybe this should be a release-build
           * check instead of an assert?
           */
@@ -166,7 +169,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
      }
  }
  
-@@ -323,7 +392,9 @@ visit_decref(PyObject *op, void *data)
+@@ -363,7 +432,9 @@ visit_decref(PyObject *op, void *data)
           * generation being collected, which can be recognized
           * because only they have positive gc_refs.
           */
@@ -177,7 +180,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
          if (gc->gc.gc_refs > 0)
              gc->gc.gc_refs--;
      }
-@@ -383,9 +454,10 @@ visit_reachable(PyObject *op, PyGC_Head
+@@ -423,9 +494,10 @@ visit_reachable(PyObject *op, PyGC_Head *reachable)
           * If gc_refs == GC_UNTRACKED, it must be ignored.
           */
           else {
@@ -191,7 +194,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
           }
      }
      return 0;
-@@ -427,7 +499,7 @@ move_unreachable(PyGC_Head *young, PyGC_
+@@ -467,7 +539,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable)
               */
              PyObject *op = FROM_GC(gc);
              traverseproc traverse = Py_TYPE(op)->tp_traverse;
@@ -200,7 +203,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
              gc->gc.gc_refs = GC_REACHABLE;
              (void) traverse(op,
                              (visitproc)visit_reachable,
-@@ -494,7 +566,8 @@ move_finalizers(PyGC_Head *unreachable,
+@@ -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);
  
@@ -210,7 +213,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
          next = gc->gc.gc_next;
  
          if (has_finalizer(op)) {
-@@ -570,7 +643,7 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -621,7 +694,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
          PyWeakReference **wrlist;
  
          op = FROM_GC(gc);
@@ -219,7 +222,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
          next = gc->gc.gc_next;
  
          if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op)))
-@@ -591,9 +664,9 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -642,9 +715,9 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
               * the callback pointer intact.  Obscure:  it also
               * changes *wrlist.
               */
@@ -231,7 +234,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
              if (wr->wr_callback == NULL)
                  continue;                       /* no callback */
  
-@@ -627,7 +700,7 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -678,7 +751,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
       */
              if (IS_TENTATIVELY_UNREACHABLE(wr))
                  continue;
@@ -240,7 +243,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
  
              /* Create a new reference so that wr can't go away
               * before we can process it again.
-@@ -636,7 +709,8 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -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);
@@ -250,7 +253,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
                                         next isn't, so they can't
                                         be the same */
              gc_list_move(wrasgc, &wrcb_to_call);
-@@ -652,11 +726,11 @@ handle_weakrefs(PyGC_Head *unreachable,
+@@ -703,11 +777,11 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
  
          gc = wrcb_to_call.gc.gc_next;
          op = FROM_GC(gc);
@@ -265,7 +268,7 @@ diff -up Python-2.7.3/Modules/gcmodule.c.gc-assertions Python-2.7.3/Modules/gcmo
  
          /* copy-paste of weakrefobject.c's handle_callback() */
          temp = PyObject_CallFunctionObjArgs(callback, wr, NULL);
-@@ -759,7 +833,7 @@ delete_garbage(PyGC_Head *collectable, P
+@@ -810,7 +884,7 @@ delete_garbage(PyGC_Head *collectable, PyGC_Head *old)
          PyGC_Head *gc = collectable->gc.gc_next;
          PyObject *op = FROM_GC(gc);
  
diff --git a/python/patches/00173-workaround-ENOPROTOOPT-in-bind_port.patch b/python/patches/00173-workaround-ENOPROTOOPT-in-bind_port.patch
deleted file mode 100644 (file)
index 3e83d67..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-diff -up Python-2.7.3/Lib/test/test_support.py.rhbz913732 Python-2.7.3/Lib/test/test_support.py
---- Python-2.7.3/Lib/test/test_support.py.rhbz913732   2013-03-04 16:11:53.757315921 -0500
-+++ Python-2.7.3/Lib/test/test_support.py      2013-03-04 16:12:11.331314722 -0500
-@@ -304,7 +304,8 @@ def bind_port(sock, host=HOST):
-             if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) == 1:
-                 raise TestFailed("tests should never set the SO_REUSEADDR "   \
-                                  "socket option on TCP/IP sockets!")
--        if hasattr(socket, 'SO_REUSEPORT'):
-+        if hasattr(socket, 'SO_REUSEPORT') \
-+                and 'WITHIN_PYTHON_RPM_BUILD' not in os.environ: # rhbz#913732
-             try:
-                 if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 1:
-                     raise TestFailed("tests should never set the SO_REUSEPORT "   \
-                                      "socket option on TCP/IP sockets!")
diff --git a/python/patches/00180-python-add-support-for-ppc64p7.patch b/python/patches/00180-python-add-support-for-ppc64p7.patch
new file mode 100644 (file)
index 0000000..ef94c86
--- /dev/null
@@ -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
index 665965d0f593fa2254bfe211441c6cec384e22ba..757c7dd51973184be642f578f486c66ec15c9d63 100644 (file)
@@ -24,8 +24,8 @@ index cb49c4a..c9795a5 100644
                  if not gotit:
                      if __debug__:
 @@ -599,7 +602,7 @@ class _Event(_Verbose):
-         finally:
-             self.__cond.release()
+         with self.__cond:
+             self.__flag = False
  
 -    def wait(self, timeout=None):
 +    def wait(self, timeout=None, balancing=True):
@@ -33,14 +33,14 @@ index cb49c4a..c9795a5 100644
  
          If the internal flag is true on entry, return immediately. Otherwise,
 @@ -617,7 +620,7 @@ class _Event(_Verbose):
-         self.__cond.acquire()
-         try:
+         """
+         with self.__cond:
              if not self.__flag:
 -                self.__cond.wait(timeout)
 +                self.__cond.wait(timeout, balancing)
              return self.__flag
-         finally:
-             self.__cond.release()
+
+ # Helper to generate new thread names
 @@ -908,7 +911,7 @@ class Thread(_Verbose):
              if 'dummy_threading' not in _sys.modules:
                  raise
diff --git a/python/patches/00184-ctypes-should-build-with-libffi-multilib-wrapper.patch b/python/patches/00184-ctypes-should-build-with-libffi-multilib-wrapper.patch
deleted file mode 100644 (file)
index 53d9dae..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
---- Python-3.3.2/setup.py.orig 2013-07-01 15:23:24.377711044 +0200
-+++ Python-3.3.2/setup.py      2013-07-01 15:23:34.094676496 +0200
-@@ -1882,7 +1882,8 @@
-                 if not line:
-                     ffi_inc = None
-                     break
--                if line.startswith('#define LIBFFI_H'):
-+                if line.startswith('#define LIBFFI_H') or \
-+                   line.startswith('#define ffi_wrapper_h'):
-                     break
-         ffi_lib = None
-         if ffi_inc is not None:
diff --git a/python/patches/00187-add-RPATH-to-pyexpat.patch b/python/patches/00187-add-RPATH-to-pyexpat.patch
new file mode 100644 (file)
index 0000000..0ac5227
--- /dev/null
@@ -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/python/patches/00189-use-rpm-wheels.patch b/python/patches/00189-use-rpm-wheels.patch
new file mode 100644 (file)
index 0000000..d7428f8
--- /dev/null
@@ -0,0 +1,71 @@
+diff --git a/Lib/ensurepip/__init__.py b/Lib/ensurepip/__init__.py
+index 89ed1ef..8008222 100644
+--- a/Lib/ensurepip/__init__.py
++++ b/Lib/ensurepip/__init__.py
+@@ -1,9 +1,10 @@
+ #!/usr/bin/env python2
+ from __future__ import print_function
++import distutils.version
++import glob
+ import os
+ import os.path
+-import pkgutil
+ import shutil
+ import sys
+ import tempfile
+@@ -11,10 +12,20 @@ import tempfile
+ __all__ = ["version", "bootstrap"]
++_WHEEL_DIR = "/usr/share/python-wheels/"
+-_SETUPTOOLS_VERSION = "39.0.1"
+-_PIP_VERSION = "9.0.3"
++def _get_most_recent_wheel_version(pkg):
++    prefix = os.path.join(_WHEEL_DIR, "{}-".format(pkg))
++    suffix = "-py2.py3-none-any.whl"
++    pattern = "{}*{}".format(prefix, suffix)
++    versions = (p[len(prefix):-len(suffix)] for p in glob.glob(pattern))
++    return str(max(versions, key=distutils.version.LooseVersion))
++
++
++_SETUPTOOLS_VERSION = _get_most_recent_wheel_version("setuptools")
++
++_PIP_VERSION = _get_most_recent_wheel_version("pip")
+ _PROJECTS = [
+     ("setuptools", _SETUPTOOLS_VERSION),
+@@ -28,8 +39,13 @@ def _run_pip(args, additional_paths=None):
+         sys.path = additional_paths + sys.path
+     # Install the bundled software
+-    import pip
+-    return pip.main(args)
++    try:
++        # pip 10
++        from pip._internal import main
++    except ImportError:
++        # pip 9
++        from pip import main
++    return main(args)
+ def version():
+@@ -100,12 +116,9 @@ def _bootstrap(root=None, upgrade=False, user=False,
+         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)
++            with open(os.path.join(_WHEEL_DIR, wheel_name), "rb") as sfp:
++                with open(os.path.join(tmpdir, wheel_name), "wb") as fp:
++                    fp.write(sfp.read())
+             additional_paths.append(os.path.join(tmpdir, wheel_name))
diff --git a/python/patches/00190-gdb-py-bt-dont-raise-exception-from-eval.patch b/python/patches/00190-gdb-py-bt-dont-raise-exception-from-eval.patch
new file mode 100644 (file)
index 0000000..4ef2a5d
--- /dev/null
@@ -0,0 +1,11 @@
+--- Python-2.7.5-orig/Tools/gdb/libpython.py   2013-05-12 03:32:54.000000000 +0000
++++ Python-2.7.5-orig/Tools/gdb/libpython.py   2013-09-15 09:56:25.494000000 +0000
+@@ -887,6 +887,8 @@ 
+         newline character'''
+         if self.is_optimized_out():
+             return '(frame information optimized out)'
++        if self.filename() == '<string>':
++            return '(in an eval block)'
+         filename = self.filename()
+         try:
+             f = open(filename, 'r')
diff --git a/python/patches/00191-disable-NOOP.patch b/python/patches/00191-disable-NOOP.patch
new file mode 100644 (file)
index 0000000..2d4189a
--- /dev/null
@@ -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/python/patches/00193-enable-loading-sqlite-extensions.patch b/python/patches/00193-enable-loading-sqlite-extensions.patch
new file mode 100644 (file)
index 0000000..36d053a
--- /dev/null
@@ -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/python/patches/00289-disable-nis-detection.patch b/python/patches/00289-disable-nis-detection.patch
new file mode 100644 (file)
index 0000000..4e185bb
--- /dev/null
@@ -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/python/patches/00309-shutil-spawn-subprocess.patch b/python/patches/00309-shutil-spawn-subprocess.patch
new file mode 100644 (file)
index 0000000..adc56c4
--- /dev/null
@@ -0,0 +1,61 @@
+From add531a1e55b0a739b0f42582f1c9747e5649ace Mon Sep 17 00:00:00 2001
+From: Benjamin Peterson <benjamin@python.org>
+Date: Tue, 28 Aug 2018 22:12:56 -0700
+Subject: [PATCH] closes bpo-34540: Convert shutil._call_external_zip to use
+ subprocess rather than distutils.spawn.
+
+---
+ Lib/shutil.py                                    | 16 ++++++++++------
+ .../2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst     |  3 +++
+ 2 files changed, 13 insertions(+), 6 deletions(-)
+ create mode 100644 Misc/NEWS.d/next/Security/2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst
+
+diff --git a/Lib/shutil.py b/Lib/shutil.py
+index 3462f7c5e91c..0ab1a06f5260 100644
+--- a/Lib/shutil.py
++++ b/Lib/shutil.py
+@@ -413,17 +413,21 @@ def _set_uid_gid(tarinfo):
+     return archive_name
+-def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False):
++def _call_external_zip(base_dir, zip_filename, verbose, dry_run, logger):
+     # XXX see if we want to keep an external call here
+     if verbose:
+         zipoptions = "-r"
+     else:
+         zipoptions = "-rq"
+-    from distutils.errors import DistutilsExecError
+-    from distutils.spawn import spawn
++    cmd = ["zip", zipoptions, zip_filename, base_dir]
++    if logger is not None:
++        logger.info(' '.join(cmd))
++    if dry_run:
++        return
++    import subprocess
+     try:
+-        spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run)
+-    except DistutilsExecError:
++        subprocess.check_call(cmd)
++    except subprocess.CalledProcessError:
+         # XXX really should distinguish between "couldn't find
+         # external 'zip' command" and "zip failed".
+         raise ExecError, \
+@@ -458,7 +462,7 @@ def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None):
+         zipfile = None
+     if zipfile is None:
+-        _call_external_zip(base_dir, zip_filename, verbose, dry_run)
++        _call_external_zip(base_dir, zip_filename, verbose, dry_run, logger)
+     else:
+         if logger is not None:
+             logger.info("creating '%s' and adding '%s' to it",
+diff --git a/Misc/NEWS.d/next/Security/2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst b/Misc/NEWS.d/next/Security/2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst
+new file mode 100644
+index 000000000000..4f686962a87b
+--- /dev/null
++++ b/Misc/NEWS.d/next/Security/2018-08-28-22-11-54.bpo-34540.gfQ0TM.rst
+@@ -0,0 +1,3 @@
++When ``shutil.make_archive`` falls back to the external ``zip`` problem, it
++uses :mod:`subprocess` to invoke it rather than :mod:`distutils.spawn`. This
++closes a possible shell injection vector.
diff --git a/python/patches/00310-use-xml-sethashsalt-in-elementtree.patch b/python/patches/00310-use-xml-sethashsalt-in-elementtree.patch
new file mode 100644 (file)
index 0000000..27d8d1c
--- /dev/null
@@ -0,0 +1,85 @@
+From 554c48934c599b3fb04c73d740bba1a745b89b41 Mon Sep 17 00:00:00 2001
+From: Christian Heimes <christian@python.org>
+Date: Tue, 18 Sep 2018 14:38:58 +0200
+Subject: [PATCH] [2.7] bpo-34623: Use XML_SetHashSalt in _elementtree
+ (GH-9146)
+
+The C accelerated _elementtree module now initializes hash randomization
+salt from _Py_HashSecret instead of libexpat's default CPRNG.
+
+Signed-off-by: Christian Heimes <christian@python.org>
+
+https://bugs.python.org/issue34623.
+(cherry picked from commit cb5778f00ce48631c7140f33ba242496aaf7102b)
+
+Co-authored-by: Christian Heimes <christian@python.org>
+---
+ Include/pyexpat.h                                            | 4 +++-
+ .../next/Security/2018-09-10-16-05-39.bpo-34623.Ua9jMv.rst   | 2 ++
+ Modules/_elementtree.c                                       | 5 +++++
+ Modules/pyexpat.c                                            | 5 +++++
+ 4 files changed, 15 insertions(+), 1 deletion(-)
+ create mode 100644 Misc/NEWS.d/next/Security/2018-09-10-16-05-39.bpo-34623.Ua9jMv.rst
+
+diff --git a/Include/pyexpat.h b/Include/pyexpat.h
+index 5340ef5fa386..3fc5fa54da63 100644
+--- a/Include/pyexpat.h
++++ b/Include/pyexpat.h
+@@ -3,7 +3,7 @@
+ /* note: you must import expat.h before importing this module! */
+-#define PyExpat_CAPI_MAGIC  "pyexpat.expat_CAPI 1.0"
++#define PyExpat_CAPI_MAGIC  "pyexpat.expat_CAPI 1.1"
+ #define PyExpat_CAPSULE_NAME "pyexpat.expat_CAPI"
+ struct PyExpat_CAPI 
+@@ -43,6 +43,8 @@ struct PyExpat_CAPI
+         XML_Parser parser, XML_UnknownEncodingHandler handler,
+         void *encodingHandlerData);
+     void (*SetUserData)(XML_Parser parser, void *userData);
++    /* might be none for expat < 2.1.0 */
++    int (*SetHashSalt)(XML_Parser parser, unsigned long hash_salt);
+     /* always add new stuff to the end! */
+ };
+diff --git a/Misc/NEWS.d/next/Security/2018-09-10-16-05-39.bpo-34623.Ua9jMv.rst b/Misc/NEWS.d/next/Security/2018-09-10-16-05-39.bpo-34623.Ua9jMv.rst
+new file mode 100644
+index 000000000000..31ad92ef8582
+--- /dev/null
++++ b/Misc/NEWS.d/next/Security/2018-09-10-16-05-39.bpo-34623.Ua9jMv.rst
+@@ -0,0 +1,2 @@
++The C accelerated _elementtree module now initializes hash randomization
++salt from _Py_HashSecret instead of libexpat's default CSPRNG.
+diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
+index f7f992dd3a95..b38e0ab329c7 100644
+--- a/Modules/_elementtree.c
++++ b/Modules/_elementtree.c
+@@ -2574,6 +2574,11 @@ xmlparser(PyObject* self_, PyObject* args, PyObject* kw)
+         PyErr_NoMemory();
+         return NULL;
+     }
++    /* expat < 2.1.0 has no XML_SetHashSalt() */
++    if (EXPAT(SetHashSalt) != NULL) {
++        EXPAT(SetHashSalt)(self->parser,
++                           (unsigned long)_Py_HashSecret.prefix);
++    }
+     ALLOC(sizeof(XMLParserObject), "create expatparser");
+diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
+index 2b4d31293c64..1f8c0d70a559 100644
+--- a/Modules/pyexpat.c
++++ b/Modules/pyexpat.c
+@@ -2042,6 +2042,11 @@ MODULE_INITFUNC(void)
+     capi.SetProcessingInstructionHandler = XML_SetProcessingInstructionHandler;
+     capi.SetUnknownEncodingHandler = XML_SetUnknownEncodingHandler;
+     capi.SetUserData = XML_SetUserData;
++#if XML_COMBINED_VERSION >= 20100
++    capi.SetHashSalt = XML_SetHashSalt;
++#else
++    capi.SetHashSalt = NULL;
++#endif
+     /* export using capsule */
+     capi_object = PyCapsule_New(&capi, PyExpat_CAPSULE_NAME, NULL);
index 7d7459cf17905bc95ea354a8d565afb9a14f3b61..32243bf90a3b1e5c1cda19278e79040ea745eb5e 100644 (file)
@@ -3,7 +3,7 @@
 @@ -334,7 +334,7 @@
  
  # Build the interpreter
- $(BUILDPYTHON):       Modules/python.o $(LDLIBRARY)
+ $(BUILDPYTHON):       Modules/python.o $(LIBRARY) $(LDLIBRARY)
 -              $(LINKCC) $(LDFLAGS) $(LINKFORSHARED) -o $@ \
 +              $(LINKCC) $(CFLAGS) $(LDFLAGS) $(LINKFORSHARED) -o $@ \
                        Modules/python.o \
index a119dcf4583aee790377166aa87f4de20747e2ed..df9d4a6b63a8fb5c326784371528e833cb663719 100644 (file)
  # 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
++crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems
  
  
  # Some more UNIX dependent modules -- off by default, since these
 -#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 # Sun yellow pages -- not everywhere
++#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
  
  
  
  # The _tkinter module.
-@@ -333,7 +333,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:
 @@ -352,7 +352,7 @@ GLHACK=-Dclear=__GLclear
  # *** Uncomment for AIX:
  #     -lld \
similarity index 90%
rename from python/python-2.7.12-lib64.patch
rename to python/python-2.7.13-lib64.patch
index 00c835c81cce835633a9e48f314c65e6d4522ab7..b6d24ab334cf976b397376917853fb70f6065d97 100644 (file)
@@ -38,7 +38,7 @@ index 068d1ba..3e7f077 100644
              return libpython
          else:
 diff --git a/Lib/site.py b/Lib/site.py
-index e8433b4..e8e6b50 100644
+index c360802..868b7cb 100644
 --- a/Lib/site.py
 +++ b/Lib/site.py
 @@ -288,12 +288,16 @@ def getsitepackages():
@@ -56,16 +56,16 @@ index e8433b4..e8e6b50 100644
              sitepackages.append(prefix)
 +            sitepackages.append(os.path.join(prefix, "lib64", "site-packages"))
              sitepackages.append(os.path.join(prefix, "lib", "site-packages"))
-         if sys.platform == "darwin":
-             # for framework builds *only* we add the standard Apple
+     return sitepackages
 diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py
-index 78c4809..3b9e74d 100644
+index d9a9324..e411e5c 100644
 --- a/Lib/test/test_site.py
 +++ b/Lib/test/test_site.py
-@@ -246,17 +246,20 @@ class HelperFunctionsTests(unittest.TestCase):
-             self.assertEqual(dirs[2], wanted)
+@@ -235,17 +235,20 @@ class HelperFunctionsTests(unittest.TestCase):
+             self.assertEqual(dirs[0], wanted)
          elif os.sep == '/':
-             # OS X non-framwework builds, Linux, FreeBSD, etc
+             # 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)
@@ -88,7 +88,7 @@ index 78c4809..3b9e74d 100644
  
  class PthFile(object):
 diff --git a/Makefile.pre.in b/Makefile.pre.in
-index 5741a4c..0faa5c5 100644
+index adae76b..ecb27f3 100644
 --- a/Makefile.pre.in
 +++ b/Makefile.pre.in
 @@ -111,7 +111,7 @@ LIBDIR=            @libdir@
@@ -101,9 +101,18 @@ index 5741a4c..0faa5c5 100644
  # Detailed destination directories
  BINLIBDEST=   $(LIBDIR)/python$(VERSION)
 diff --git a/Modules/Setup.dist b/Modules/Setup.dist
-index c70a0d6..051fd41 100644
+index fbfa1c1..138fb33 100644
 --- a/Modules/Setup.dist
 +++ b/Modules/Setup.dist
+@@ -231,7 +231,7 @@
+ # 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.
@@ -123,7 +132,7 @@ index c70a0d6..051fd41 100644
  # Interface to the Expat XML parser
  #
 diff --git a/Modules/getpath.c b/Modules/getpath.c
-index 428684c..9ef6711 100644
+index fd33a01..c5c86fd 100644
 --- a/Modules/getpath.c
 +++ b/Modules/getpath.c
 @@ -108,7 +108,7 @@ static char prefix[MAXPATHLEN+1];
@@ -135,7 +144,7 @@ index 428684c..9ef6711 100644
  
  static void
  reduce(char *dir)
-@@ -550,7 +550,7 @@ calculate_path(void)
+@@ -548,7 +548,7 @@ calculate_path(void)
              fprintf(stderr,
                  "Could not find platform dependent libraries <exec_prefix>\n");
          strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
@@ -145,7 +154,7 @@ index 428684c..9ef6711 100644
      /* If we found EXEC_PREFIX do *not* reduce it!  (Yet.) */
  
 diff --git a/setup.py b/setup.py
-index 55c4f5d..19efe82 100644
+index 99ac359..859b6c4 100644
 --- a/setup.py
 +++ b/setup.py
 @@ -456,7 +456,7 @@ class PyBuildExt(build_ext):
index 5cba0a2f39481340f8bbc9e13e09e183388fe238..b312f8be6514d5885abf410834de86e43307725a 100644 (file)
@@ -5,8 +5,8 @@
 
 name       = python
 major_ver  = 2.7
-version    = %{major_ver}.12
-release    = 2
+version    = %{major_ver}.15
+release    = 1
 thisapp    = Python-%{version}
 
 groups     = Development/Languages
@@ -48,9 +48,11 @@ build
        export CFLAGS  += -D_GNU_SOURCE -fwrapv
        export CPPFLAGS = %(pkg-config --cflags-only-I libffi)
        export OPT      = %{CFLAGS}
+       export CC       = gcc
+       export LINKCC   = gcc
 
        if "%{lib}" == "lib64"
-               patches += %{DIR_SOURCE}/python-2.7.12-lib64.patch
+               patches += %{DIR_SOURCE}/python-2.7.13-lib64.patch
                patches += %{DIR_SOURCE}/python-2.7-lib64-sysconfig.patch
        end