diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9ca0244 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/Python-2.7.5.tar.xz diff --git a/.python.metadata b/.python.metadata new file mode 100644 index 0000000..a8fe566 --- /dev/null +++ b/.python.metadata @@ -0,0 +1 @@ +b7389791f789625c2ba9d897aa324008ff482daf SOURCES/Python-2.7.5.tar.xz diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/00001-pydocnogui.patch b/SOURCES/00001-pydocnogui.patch new file mode 100644 index 0000000..3b34842 --- /dev/null +++ b/SOURCES/00001-pydocnogui.patch @@ -0,0 +1,38 @@ +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. + Run "pydoc -p " to start an HTTP server on a given port on the + local machine to generate documentation web pages. + +-For platforms without a command line, "pydoc -g" starts the HTTP server +-and also pops up a little window for controlling it. +- + Run "pydoc -w " to write out the HTML documentation for a module + to a file named ".html". + +@@ -2290,9 +2287,6 @@ def cli(): + writing = 0 + + for opt, val in opts: +- if opt == '-g': +- gui() +- return + if opt == '-k': + apropos(val) + return +@@ -2346,13 +2340,10 @@ def cli(): + %s -p + Start an HTTP server on the given port on the local machine. + +-%s -g +- Pop up a graphical interface for finding and serving documentation. +- + %s -w ... + Write out the HTML documentation for a module to a file in the current + directory. If contains a '%s', it is treated as a filename; if + it names a directory, documentation is written for all the contents. +-""" % (cmd, os.sep, cmd, cmd, cmd, cmd, os.sep) ++""" % (cmd, os.sep, cmd, cmd, cmd, os.sep) + + if __name__ == '__main__': cli() diff --git a/SOURCES/00055-systemtap.patch b/SOURCES/00055-systemtap.patch new file mode 100644 index 0000000..67ec005 --- /dev/null +++ b/SOURCES/00055-systemtap.patch @@ -0,0 +1,198 @@ +diff -up Python-2.7rc1/configure.ac.systemtap Python-2.7rc1/configure.ac +--- Python-2.7rc1/configure.ac.systemtap 2010-06-06 10:53:15.514975012 -0400 ++++ Python-2.7rc1/configure.ac 2010-06-06 10:53:15.520974361 -0400 +@@ -2616,6 +2616,38 @@ if test "$with_valgrind" != no; then + ) + fi + ++# Check for dtrace support ++AC_MSG_CHECKING(for --with-dtrace) ++AC_ARG_WITH(dtrace, ++ AC_HELP_STRING(--with(out)-dtrace, disable/enable dtrace support)) ++ ++if test ! -z "$with_dtrace" ++then ++ if dtrace -G -o /dev/null -s $srcdir/Include/pydtrace.d 2>/dev/null ++ then ++ AC_DEFINE(WITH_DTRACE, 1, ++ [Define if you want to compile in Dtrace support]) ++ with_dtrace="Sun" ++ DTRACEOBJS="Python/dtrace.o" ++ DTRADEHDRS="" ++ elif dtrace -h -o /dev/null -s $srcdir/Include/pydtrace.d ++ then ++ AC_DEFINE(WITH_DTRACE, 1, ++ [Define if you want to compile in Dtrace support]) ++ with_dtrace="Apple" ++ DTRACEOBJS="" ++ DTRADEHDRS="pydtrace.h" ++ else ++ with_dtrace="no" ++ fi ++else ++ with_dtrace="no" ++fi ++ ++AC_MSG_RESULT($with_dtrace) ++AC_SUBST(DTRACEOBJS) ++AC_SUBST(DTRACEHDRS) ++ + # Check for --with-wctype-functions + AC_MSG_CHECKING(for --with-wctype-functions) + AC_ARG_WITH(wctype-functions, +diff -up Python-2.7rc1/Include/pydtrace.d.systemtap Python-2.7rc1/Include/pydtrace.d +--- Python-2.7rc1/Include/pydtrace.d.systemtap 2010-06-06 10:53:15.520974361 -0400 ++++ Python-2.7rc1/Include/pydtrace.d 2010-06-06 10:53:15.520974361 -0400 +@@ -0,0 +1,10 @@ ++provider python { ++ probe function__entry(const char *, const char *, int); ++ probe function__return(const char *, const char *, int); ++}; ++ ++#pragma D attributes Evolving/Evolving/Common provider python provider ++#pragma D attributes Private/Private/Common provider python module ++#pragma D attributes Private/Private/Common provider python function ++#pragma D attributes Evolving/Evolving/Common provider python name ++#pragma D attributes Evolving/Evolving/Common provider python args +diff -up Python-2.7rc1/Makefile.pre.in.systemtap Python-2.7rc1/Makefile.pre.in +--- Python-2.7rc1/Makefile.pre.in.systemtap 2010-06-06 10:53:15.488978775 -0400 ++++ Python-2.7rc1/Makefile.pre.in 2010-06-06 11:05:30.411100568 -0400 +@@ -298,6 +298,7 @@ PYTHON_OBJS= \ + Python/formatter_unicode.o \ + Python/formatter_string.o \ + Python/$(DYNLOADFILE) \ ++ @DTRACEOBJS@ \ + $(LIBOBJS) \ + $(MACHDEP_OBJS) \ + $(THREADOBJ) +@@ -599,6 +600,18 @@ Python/formatter_unicode.o: $(srcdir)/Py + Python/formatter_string.o: $(srcdir)/Python/formatter_string.c \ + $(STRINGLIB_HEADERS) + ++# Only needed with --with-dtrace ++buildinclude: ++ mkdir -p Include ++ ++Include/pydtrace.h: buildinclude $(srcdir)/Include/pydtrace.d ++ dtrace -o $@ $(DFLAGS) -C -h -s $(srcdir)/Include/pydtrace.d ++ ++Python/ceval.o: Include/pydtrace.h ++ ++Python/dtrace.o: buildinclude $(srcdir)/Include/pydtrace.d Python/ceval.o ++ dtrace -o $@ $(DFLAGS) -C -G -s $(srcdir)/Include/pydtrace.d Python/ceval.o ++ + ############################################################################ + # Header files + +@@ -1251,7 +1264,7 @@ Python/thread.o: @THREADHEADERS@ + .PHONY: frameworkinstall frameworkinstallframework frameworkinstallstructure + .PHONY: frameworkinstallmaclib frameworkinstallapps frameworkinstallunixtools + .PHONY: frameworkaltinstallunixtools recheck autoconf clean clobber distclean +-.PHONY: smelly funny patchcheck touch altmaninstall ++.PHONY: smelly funny patchcheck touch altmaninstall buildinclude + .PHONY: gdbhooks + + # IF YOU PUT ANYTHING HERE IT WILL GO AWAY +diff -up Python-2.7rc1/pyconfig.h.in.systemtap Python-2.7rc1/pyconfig.h.in +--- Python-2.7rc1/pyconfig.h.in.systemtap 2010-05-08 07:04:18.000000000 -0400 ++++ Python-2.7rc1/pyconfig.h.in 2010-06-06 10:53:15.521974070 -0400 +@@ -1074,6 +1074,9 @@ + /* Define if you want documentation strings in extension modules */ + #undef WITH_DOC_STRINGS + ++/* Define if you want to compile in Dtrace support */ ++#undef WITH_DTRACE ++ + /* Define if you want to use the new-style (Openstep, Rhapsody, MacOS) dynamic + linker (dyld) instead of the old-style (NextStep) dynamic linker (rld). + Dyld is necessary to support frameworks. */ +diff -up Python-2.7rc1/Python/ceval.c.systemtap Python-2.7rc1/Python/ceval.c +--- Python-2.7rc1/Python/ceval.c.systemtap 2010-05-09 10:46:46.000000000 -0400 ++++ Python-2.7rc1/Python/ceval.c 2010-06-06 11:08:40.683100500 -0400 +@@ -19,6 +19,10 @@ + + #include + ++#ifdef WITH_DTRACE ++#include "pydtrace.h" ++#endif ++ + #ifndef WITH_TSC + + #define READ_TIMESTAMP(var) +@@ -671,6 +675,55 @@ PyEval_EvalCode(PyCodeObject *co, PyObje + NULL); + } + ++#ifdef WITH_DTRACE ++static void ++dtrace_entry(PyFrameObject *f) ++{ ++ const char *filename; ++ const char *fname; ++ int lineno; ++ ++ filename = PyString_AsString(f->f_code->co_filename); ++ fname = PyString_AsString(f->f_code->co_name); ++ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); ++ ++ PYTHON_FUNCTION_ENTRY((char *)filename, (char *)fname, lineno); ++ ++ /* ++ * Currently a USDT tail-call will not receive the correct arguments. ++ * Disable the tail call here. ++ */ ++#if defined(__sparc) ++ asm("nop"); ++#endif ++} ++ ++static void ++dtrace_return(PyFrameObject *f) ++{ ++ const char *filename; ++ const char *fname; ++ int lineno; ++ ++ filename = PyString_AsString(f->f_code->co_filename); ++ fname = PyString_AsString(f->f_code->co_name); ++ lineno = PyCode_Addr2Line(f->f_code, f->f_lasti); ++ PYTHON_FUNCTION_RETURN((char *)filename, (char *)fname, lineno); ++ ++ /* ++ * Currently a USDT tail-call will not receive the correct arguments. ++ * Disable the tail call here. ++ */ ++#if defined(__sparc) ++ asm("nop"); ++#endif ++} ++#else ++#define PYTHON_FUNCTION_ENTRY_ENABLED() 0 ++#define PYTHON_FUNCTION_RETURN_ENABLED() 0 ++#define dtrace_entry(f) ++#define dtrace_return(f) ++#endif + + /* Interpreter main loop */ + +@@ -909,6 +962,9 @@ PyEval_EvalFrameEx(PyFrameObject *f, int + } + } + ++ if (PYTHON_FUNCTION_ENTRY_ENABLED()) ++ dtrace_entry(f); ++ + co = f->f_code; + names = co->co_names; + consts = co->co_consts; +@@ -3000,6 +3056,9 @@ fast_yield: + + /* pop frame */ + exit_eval_frame: ++ if (PYTHON_FUNCTION_RETURN_ENABLED()) ++ dtrace_return(f); ++ + Py_LeaveRecursiveCall(); + tstate->frame = f->f_back; + diff --git a/SOURCES/00104-lib64-fix-for-test_install.patch b/SOURCES/00104-lib64-fix-for-test_install.patch new file mode 100644 index 0000000..7852bf6 --- /dev/null +++ b/SOURCES/00104-lib64-fix-for-test_install.patch @@ -0,0 +1,13 @@ +--- Python-2.7.2/Lib/distutils/tests/test_install.py.lib64 2011-09-08 17:51:57.851405376 -0400 ++++ Python-2.7.2/Lib/distutils/tests/test_install.py 2011-09-08 18:40:46.754205096 -0400 +@@ -41,8 +41,9 @@ class InstallTestCase(support.TempdirMan + self.assertEqual(got, expected) + + libdir = os.path.join(destination, "lib", "python") ++ platlibdir = os.path.join(destination, "lib64", "python") + check_path(cmd.install_lib, libdir) +- check_path(cmd.install_platlib, libdir) ++ check_path(cmd.install_platlib, platlibdir) + check_path(cmd.install_purelib, libdir) + check_path(cmd.install_headers, + os.path.join(destination, "include", "python", "foopkg")) diff --git a/SOURCES/00111-no-static-lib.patch b/SOURCES/00111-no-static-lib.patch new file mode 100644 index 0000000..2f4fdd6 --- /dev/null +++ b/SOURCES/00111-no-static-lib.patch @@ -0,0 +1,50 @@ +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) $(CFLAGS) $(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/SOURCES/00113-more-configuration-flags.patch b/SOURCES/00113-more-configuration-flags.patch new file mode 100644 index 0000000..2d447b2 --- /dev/null +++ b/SOURCES/00113-more-configuration-flags.patch @@ -0,0 +1,50 @@ +diff -up Python-2.6.5/configure.ac.more-configuration-flags Python-2.6.5/configure.ac +--- Python-2.6.5/configure.ac.more-configuration-flags 2010-05-24 18:51:25.410111792 -0400 ++++ Python-2.6.5/configure.ac 2010-05-24 18:59:23.954986388 -0400 +@@ -2515,6 +2515,30 @@ else AC_MSG_RESULT(no) + fi], + [AC_MSG_RESULT(no)]) + ++AC_MSG_CHECKING(for --with-count-allocs) ++AC_ARG_WITH(count-allocs, ++[ --with(out)count-allocs enable/disable per-type instance accounting], [ ++if test "$withval" != no ++then ++ AC_DEFINE(COUNT_ALLOCS, 1, ++ [Define to keep records of the number of instances of each type]) ++ AC_MSG_RESULT(yes) ++else AC_MSG_RESULT(no) ++fi], ++[AC_MSG_RESULT(no)]) ++ ++AC_MSG_CHECKING(for --with-call-profile) ++AC_ARG_WITH(call-profile, ++[ --with(out)-call-profile enable/disable statistics on function call invocation], [ ++if test "$withval" != no ++then ++ AC_DEFINE(CALL_PROFILE, 1, ++ [Define to keep records on function call invocation]) ++ AC_MSG_RESULT(yes) ++else AC_MSG_RESULT(no) ++fi], ++[AC_MSG_RESULT(no)]) ++ + # Check for Python-specific malloc support + AC_MSG_CHECKING(for --with-pymalloc) + AC_ARG_WITH(pymalloc, +diff -up Python-2.6.5/pyconfig.h.in.more-configuration-flags Python-2.6.5/pyconfig.h.in +--- Python-2.6.5/pyconfig.h.in.more-configuration-flags 2010-05-24 18:51:45.677988086 -0400 ++++ Python-2.6.5/pyconfig.h.in 2010-05-24 19:00:44.163987730 -0400 +@@ -1019,6 +1019,12 @@ + /* Define to profile with the Pentium timestamp counter */ + #undef WITH_TSC + ++/* Define to keep records of the number of instances of each type */ ++#undef COUNT_ALLOCS ++ ++/* Define to keep records on function call invocation */ ++#undef CALL_PROFILE ++ + /* Define if you want pymalloc to be disabled when running under valgrind */ + #undef WITH_VALGRIND + diff --git a/SOURCES/00114-statvfs-f_flag-constants.patch b/SOURCES/00114-statvfs-f_flag-constants.patch new file mode 100644 index 0000000..83e7b59 --- /dev/null +++ b/SOURCES/00114-statvfs-f_flag-constants.patch @@ -0,0 +1,47 @@ +diff -up Python-2.7rc1/Modules/posixmodule.c.statvfs-f-flag-constants Python-2.7rc1/Modules/posixmodule.c +--- Python-2.7rc1/Modules/posixmodule.c.statvfs-f-flag-constants 2010-05-15 17:45:30.000000000 -0400 ++++ Python-2.7rc1/Modules/posixmodule.c 2010-06-07 22:54:16.162068624 -0400 +@@ -9174,6 +9174,43 @@ all_ins(PyObject *d) + #endif + #endif + ++ /* These came from statvfs.h */ ++#ifdef ST_RDONLY ++ if (ins(d, "ST_RDONLY", (long)ST_RDONLY)) return -1; ++#endif /* ST_RDONLY */ ++#ifdef ST_NOSUID ++ if (ins(d, "ST_NOSUID", (long)ST_NOSUID)) return -1; ++#endif /* ST_NOSUID */ ++ ++ /* GNU extensions */ ++#ifdef ST_NODEV ++ if (ins(d, "ST_NODEV", (long)ST_NODEV)) return -1; ++#endif /* ST_NODEV */ ++#ifdef ST_NOEXEC ++ if (ins(d, "ST_NOEXEC", (long)ST_NOEXEC)) return -1; ++#endif /* ST_NOEXEC */ ++#ifdef ST_SYNCHRONOUS ++ if (ins(d, "ST_SYNCHRONOUS", (long)ST_SYNCHRONOUS)) return -1; ++#endif /* ST_SYNCHRONOUS */ ++#ifdef ST_MANDLOCK ++ if (ins(d, "ST_MANDLOCK", (long)ST_MANDLOCK)) return -1; ++#endif /* ST_MANDLOCK */ ++#ifdef ST_WRITE ++ if (ins(d, "ST_WRITE", (long)ST_WRITE)) return -1; ++#endif /* ST_WRITE */ ++#ifdef ST_APPEND ++ if (ins(d, "ST_APPEND", (long)ST_APPEND)) return -1; ++#endif /* ST_APPEND */ ++#ifdef ST_NOATIME ++ if (ins(d, "ST_NOATIME", (long)ST_NOATIME)) return -1; ++#endif /* ST_NOATIME */ ++#ifdef ST_NODIRATIME ++ if (ins(d, "ST_NODIRATIME", (long)ST_NODIRATIME)) return -1; ++#endif /* ST_NODIRATIME */ ++#ifdef ST_RELATIME ++ if (ins(d, "ST_RELATIME", (long)ST_RELATIME)) return -1; ++#endif /* ST_RELATIME */ ++ + #if defined(PYOS_OS2) + if (insertvalues(d)) return -1; + #endif diff --git a/SOURCES/00121-add-Modules-to-build-path.patch b/SOURCES/00121-add-Modules-to-build-path.patch new file mode 100644 index 0000000..6e3294d --- /dev/null +++ b/SOURCES/00121-add-Modules-to-build-path.patch @@ -0,0 +1,13 @@ +--- Python-2.7.5/Lib/site.py.orig 2013-05-16 12:47:55.000000000 +0200 ++++ Python-2.7.5/Lib/site.py 2013-05-16 12:56:20.089058109 +0200 +@@ -529,6 +529,10 @@ def main(): + + abs__file__() + known_paths = removeduppaths() ++ from sysconfig import is_python_build ++ if is_python_build(): ++ from _sysconfigdata import build_time_vars ++ sys.path.append(os.path.join(build_time_vars['abs_builddir'], 'Modules')) + if ENABLE_USER_SITE is None: + ENABLE_USER_SITE = check_enableusersite() + known_paths = addusersitepackages(known_paths) diff --git a/SOURCES/00125-less-verbose-COUNT_ALLOCS.patch b/SOURCES/00125-less-verbose-COUNT_ALLOCS.patch new file mode 100644 index 0000000..8cef015 --- /dev/null +++ b/SOURCES/00125-less-verbose-COUNT_ALLOCS.patch @@ -0,0 +1,20 @@ +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/SOURCES/00131-disable-tests-in-test_io.patch b/SOURCES/00131-disable-tests-in-test_io.patch new file mode 100644 index 0000000..d81a2d0 --- /dev/null +++ b/SOURCES/00131-disable-tests-in-test_io.patch @@ -0,0 +1,11 @@ +diff -up Python-2.7.2/Lib/test/test_io.py.disable-tests-in-test_io Python-2.7.2/Lib/test/test_io.py +--- Python-2.7.2/Lib/test/test_io.py.disable-tests-in-test_io 2011-09-01 14:18:45.963304089 -0400 ++++ Python-2.7.2/Lib/test/test_io.py 2011-09-01 15:08:53.796098413 -0400 +@@ -2669,6 +2669,7 @@ class SignalsTest(unittest.TestCase): + self.check_interrupted_read_retry(lambda x: x, + mode="r") + ++ @unittest.skip('rhbz#732998') + @unittest.skipUnless(threading, 'Threading required for this test.') + def check_interrupted_write_retry(self, item, **fdopen_kwargs): + """Check that a buffered write, when it gets interrupted (either diff --git a/SOURCES/00132-add-rpmbuild-hooks-to-unittest.patch b/SOURCES/00132-add-rpmbuild-hooks-to-unittest.patch new file mode 100644 index 0000000..e63395f --- /dev/null +++ b/SOURCES/00132-add-rpmbuild-hooks-to-unittest.patch @@ -0,0 +1,68 @@ +diff -up Python-2.7.2/Lib/unittest/case.py.add-rpmbuild-hooks-to-unittest Python-2.7.2/Lib/unittest/case.py +--- Python-2.7.2/Lib/unittest/case.py.add-rpmbuild-hooks-to-unittest 2011-09-08 14:45:47.677169191 -0400 ++++ Python-2.7.2/Lib/unittest/case.py 2011-09-08 16:01:36.287858159 -0400 +@@ -1,6 +1,7 @@ + """Test case implementation""" + + import collections ++import os + import sys + import functools + import difflib +@@ -94,6 +95,43 @@ def expectedFailure(func): + return wrapper + + ++# Non-standard/downstream-only hooks for handling issues with specific test ++# cases: ++ ++def _skipInRpmBuild(reason): ++ """ ++ Non-standard/downstream-only decorator for marking a specific unit test ++ to be skipped when run within the %check of an rpmbuild. ++ ++ Specifically, this takes effect when WITHIN_PYTHON_RPM_BUILD is set within ++ the environment, and has no effect otherwise. ++ """ ++ if 'WITHIN_PYTHON_RPM_BUILD' in os.environ: ++ return skip(reason) ++ else: ++ return _id ++ ++def _expectedFailureInRpmBuild(func): ++ """ ++ Non-standard/downstream-only decorator for marking a specific unit test ++ as expected to fail within the %check of an rpmbuild. ++ ++ Specifically, this takes effect when WITHIN_PYTHON_RPM_BUILD is set within ++ the environment, and has no effect otherwise. ++ """ ++ @functools.wraps(func) ++ def wrapper(*args, **kwargs): ++ if 'WITHIN_PYTHON_RPM_BUILD' in os.environ: ++ try: ++ func(*args, **kwargs) ++ except Exception: ++ raise _ExpectedFailure(sys.exc_info()) ++ raise _UnexpectedSuccess ++ else: ++ # Call directly: ++ func(*args, **kwargs) ++ return wrapper ++ + class _AssertRaisesContext(object): + """A context manager used to implement TestCase.assertRaises* methods.""" + +diff -up Python-2.7.2/Lib/unittest/__init__.py.add-rpmbuild-hooks-to-unittest Python-2.7.2/Lib/unittest/__init__.py +--- Python-2.7.2/Lib/unittest/__init__.py.add-rpmbuild-hooks-to-unittest 2011-09-08 14:59:39.534112310 -0400 ++++ Python-2.7.2/Lib/unittest/__init__.py 2011-09-08 15:07:09.191081562 -0400 +@@ -57,7 +57,8 @@ __unittest = True + + from .result import TestResult + from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf, +- skipUnless, expectedFailure) ++ skipUnless, expectedFailure, ++ _skipInRpmBuild, _expectedFailureInRpmBuild) + from .suite import BaseTestSuite, TestSuite + from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, + findTestCases) diff --git a/SOURCES/00133-skip-test_dl.patch b/SOURCES/00133-skip-test_dl.patch new file mode 100644 index 0000000..04ad05b --- /dev/null +++ b/SOURCES/00133-skip-test_dl.patch @@ -0,0 +1,13 @@ +diff -up Python-2.7.2/Lib/test/test_dl.py.skip-test_dl Python-2.7.2/Lib/test/test_dl.py +--- Python-2.7.2/Lib/test/test_dl.py.skip-test_dl 2011-09-08 15:18:40.529034289 -0400 ++++ Python-2.7.2/Lib/test/test_dl.py 2011-09-08 16:29:45.184742670 -0400 +@@ -13,6 +13,9 @@ sharedlibs = [ + ('/usr/lib/libc.dylib', 'getpid'), + ] + ++# (also, "dl" is deprecated in favor of ctypes) ++@unittest._skipInRpmBuild('fails on 64-bit builds: ' ++ 'module dl requires sizeof(int) == sizeof(long) == sizeof(char*)') + def test_main(): + for s, func in sharedlibs: + try: diff --git a/SOURCES/00134-fix-COUNT_ALLOCS-failure-in-test_sys.patch b/SOURCES/00134-fix-COUNT_ALLOCS-failure-in-test_sys.patch new file mode 100644 index 0000000..38381ef --- /dev/null +++ b/SOURCES/00134-fix-COUNT_ALLOCS-failure-in-test_sys.patch @@ -0,0 +1,14 @@ +--- Python-2.7.2/Lib/test/test_sys.py.mark-tests-that-fail-in-rpmbuild 2011-09-08 18:02:31.627362039 -0400 ++++ Python-2.7.2/Lib/test/test_sys.py 2011-09-08 18:15:29.450308851 -0400 +@@ -734,6 +734,11 @@ class SizeofTest(unittest.TestCase): + # (PyTypeObject + PyNumberMethods + PyMappingMethods + + # PySequenceMethods + PyBufferProcs) + s = vsize('P2P15Pl4PP9PP11PI') + struct.calcsize('41P 10P 3P 6P') ++ ++ # 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/SOURCES/00135-skip-test-within-test_weakref-in-debug-build.patch b/SOURCES/00135-skip-test-within-test_weakref-in-debug-build.patch new file mode 100644 index 0000000..e464aa9 --- /dev/null +++ b/SOURCES/00135-skip-test-within-test_weakref-in-debug-build.patch @@ -0,0 +1,18 @@ +diff -up Python-2.7.2/Lib/test/test_weakref.py.skip-test-within-test_weakref-in-debug-build Python-2.7.2/Lib/test/test_weakref.py +--- Python-2.7.2/Lib/test/test_weakref.py.skip-test-within-test_weakref-in-debug-build 2011-09-08 17:55:09.675392260 -0400 ++++ Python-2.7.2/Lib/test/test_weakref.py 2011-09-08 17:59:08.857375903 -0400 +@@ -550,6 +550,14 @@ class ReferencesTestCase(TestBase): + del c1, c2, C, D + gc.collect() + ++ # In a debug build, this fails with: ++ # AssertionError: Lists differ: [] != ['C went away'] ++ # Second list contains 1 additional elements. ++ # First extra element 0: ++ # C went away ++ # - [] ++ # + ['C went away'] ++ @unittest.skipIf(hasattr(sys, 'getobjects'), 'debug build') + def test_callback_in_cycle_resurrection(self): + import gc + diff --git a/SOURCES/00136-skip-tests-of-seeking-stdin-in-rpmbuild.patch b/SOURCES/00136-skip-tests-of-seeking-stdin-in-rpmbuild.patch new file mode 100644 index 0000000..845fb2a --- /dev/null +++ b/SOURCES/00136-skip-tests-of-seeking-stdin-in-rpmbuild.patch @@ -0,0 +1,22 @@ +diff -up Python-2.7.2/Lib/test/test_file2k.py.skip-tests-of-seeking-stdin-in-rpmbuild Python-2.7.2/Lib/test/test_file2k.py +--- Python-2.7.2/Lib/test/test_file2k.py.skip-tests-of-seeking-stdin-in-rpmbuild 2011-09-08 17:23:50.922520729 -0400 ++++ Python-2.7.2/Lib/test/test_file2k.py 2011-09-08 17:24:41.368517277 -0400 +@@ -213,6 +213,7 @@ class OtherFileTests(unittest.TestCase): + else: + f.close() + ++ @unittest._skipInRpmBuild('seems not to raise the exception when run in Koji') + def testStdin(self): + # This causes the interpreter to exit on OSF1 v5.1. + if sys.platform != 'osf1V5': +diff -up Python-2.7.2/Lib/test/test_file.py.skip-tests-of-seeking-stdin-in-rpmbuild Python-2.7.2/Lib/test/test_file.py +--- Python-2.7.2/Lib/test/test_file.py.skip-tests-of-seeking-stdin-in-rpmbuild 2011-09-08 17:20:31.146534389 -0400 ++++ Python-2.7.2/Lib/test/test_file.py 2011-09-08 17:24:45.016517030 -0400 +@@ -154,6 +154,7 @@ class OtherFileTests(unittest.TestCase): + f.close() + self.fail('%r is an invalid file mode' % mode) + ++ @unittest._skipInRpmBuild('seems not to raise the exception when run in Koji') + def testStdin(self): + # This causes the interpreter to exit on OSF1 v5.1. + if sys.platform != 'osf1V5': diff --git a/SOURCES/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch b/SOURCES/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch new file mode 100644 index 0000000..8653772 --- /dev/null +++ b/SOURCES/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch @@ -0,0 +1,12 @@ +diff -up Python-2.7.3/Lib/distutils/tests/test_bdist_rpm.py.mark-tests-that-fail-in-rpmbuild Python-2.7.3/Lib/distutils/tests/test_bdist_rpm.py +--- Python-2.7.3/Lib/distutils/tests/test_bdist_rpm.py.mark-tests-that-fail-in-rpmbuild 2012-04-09 19:07:29.000000000 -0400 ++++ Python-2.7.3/Lib/distutils/tests/test_bdist_rpm.py 2012-04-13 00:20:08.223819263 -0400 +@@ -24,6 +24,7 @@ setup(name='foo', version='0.1', py_modu + + """ + ++@unittest._skipInRpmBuild("don't try to nest one rpm build inside another rpm build") + class BuildRpmTestCase(support.TempdirManager, + support.LoggingSilencer, + unittest.TestCase): +diff -up Python-2.7.3/Lib/distutils/tests/test_build_ext.py.mark-tests-that-fail-in-rpmbuild Python-2.7.3/Lib/distutils/tests/test_build_ext.py diff --git a/SOURCES/00138-fix-distutils-tests-in-debug-build.patch b/SOURCES/00138-fix-distutils-tests-in-debug-build.patch new file mode 100644 index 0000000..0bfda90 --- /dev/null +++ b/SOURCES/00138-fix-distutils-tests-in-debug-build.patch @@ -0,0 +1,68 @@ +diff -up Python-2.7.2/Lib/distutils/tests/test_build_ext.py.mark-tests-that-fail-in-rpmbuild Python-2.7.2/Lib/distutils/tests/test_build_ext.py +--- Python-2.7.2/Lib/distutils/tests/test_build_ext.py.mark-tests-that-fail-in-rpmbuild 2011-09-08 16:07:25.033834312 -0400 ++++ Python-2.7.2/Lib/distutils/tests/test_build_ext.py 2011-09-08 17:43:15.656441082 -0400 +@@ -330,6 +332,7 @@ class BuildExtTestCase(support.TempdirMa + self.assertEqual(lastdir, 'bar') + + def test_ext_fullpath(self): ++ debug_ext = sysconfig.get_config_var("DEBUG_EXT") + ext = sysconfig.get_config_vars()['SO'] + dist = Distribution() + cmd = build_ext(dist) +@@ -337,14 +340,14 @@ class BuildExtTestCase(support.TempdirMa + cmd.distribution.package_dir = {'': 'src'} + cmd.distribution.packages = ['lxml', 'lxml.html'] + curdir = os.getcwd() +- wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) ++ wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + debug_ext + ext) + path = cmd.get_ext_fullpath('lxml.etree') + self.assertEqual(wanted, path) + + # building lxml.etree not inplace + cmd.inplace = 0 + cmd.build_lib = os.path.join(curdir, 'tmpdir') +- wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + ext) ++ wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + debug_ext + ext) + path = cmd.get_ext_fullpath('lxml.etree') + self.assertEqual(wanted, path) + +@@ -354,13 +357,13 @@ class BuildExtTestCase(support.TempdirMa + cmd.distribution.packages = ['twisted', 'twisted.runner.portmap'] + path = cmd.get_ext_fullpath('twisted.runner.portmap') + wanted = os.path.join(curdir, 'tmpdir', 'twisted', 'runner', +- 'portmap' + ext) ++ 'portmap' + debug_ext + ext) + self.assertEqual(wanted, path) + + # building twisted.runner.portmap inplace + cmd.inplace = 1 + path = cmd.get_ext_fullpath('twisted.runner.portmap') +- wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext) ++ wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + debug_ext + ext) + self.assertEqual(wanted, path) + + def test_build_ext_inplace(self): +@@ -373,8 +376,9 @@ class BuildExtTestCase(support.TempdirMa + cmd.distribution.package_dir = {'': 'src'} + cmd.distribution.packages = ['lxml', 'lxml.html'] + curdir = os.getcwd() ++ debug_ext = sysconfig.get_config_var("DEBUG_EXT") + ext = sysconfig.get_config_var("SO") +- wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) ++ wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + debug_ext + ext) + path = cmd.get_ext_fullpath('lxml.etree') + self.assertEqual(wanted, path) + +@@ -412,10 +416,11 @@ class BuildExtTestCase(support.TempdirMa + dist = Distribution({'name': 'UpdateManager'}) + cmd = build_ext(dist) + cmd.ensure_finalized() ++ debug_ext = sysconfig.get_config_var("DEBUG_EXT") + ext = sysconfig.get_config_var("SO") + ext_name = os.path.join('UpdateManager', 'fdsend') + ext_path = cmd.get_ext_fullpath(ext_name) +- wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext) ++ wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + debug_ext + ext) + self.assertEqual(ext_path, wanted) + + def test_build_ext_path_cross_platform(self): diff --git a/SOURCES/00139-skip-test_float-known-failure-on-arm.patch b/SOURCES/00139-skip-test_float-known-failure-on-arm.patch new file mode 100644 index 0000000..9d0bfad --- /dev/null +++ b/SOURCES/00139-skip-test_float-known-failure-on-arm.patch @@ -0,0 +1,11 @@ +diff -up Python-2.7.2/Lib/test/test_float.py.skip-test_float-known-failure-on-arm Python-2.7.2/Lib/test/test_float.py +--- Python-2.7.2/Lib/test/test_float.py.skip-test_float-known-failure-on-arm 2011-09-08 19:34:09.000986128 -0400 ++++ Python-2.7.2/Lib/test/test_float.py 2011-09-08 19:34:57.969982779 -0400 +@@ -1072,6 +1072,7 @@ class HexFloatTestCase(unittest.TestCase + self.identical(got, expected) + + ++ @unittest.skip('Known failure on ARM: http://bugs.python.org/issue8265') + def test_from_hex(self): + MIN = self.MIN; + MAX = self.MAX; diff --git a/SOURCES/00140-skip-test_ctypes-known-failure-on-sparc.patch b/SOURCES/00140-skip-test_ctypes-known-failure-on-sparc.patch new file mode 100644 index 0000000..95aa41e --- /dev/null +++ b/SOURCES/00140-skip-test_ctypes-known-failure-on-sparc.patch @@ -0,0 +1,11 @@ +diff -up Python-2.7.2/Lib/ctypes/test/test_callbacks.py.skip-test_ctypes-known-failure-on-sparc Python-2.7.2/Lib/ctypes/test/test_callbacks.py +--- Python-2.7.2/Lib/ctypes/test/test_callbacks.py.skip-test_ctypes-known-failure-on-sparc 2011-09-08 19:42:35.541951490 -0400 ++++ Python-2.7.2/Lib/ctypes/test/test_callbacks.py 2011-09-08 19:43:40.676947036 -0400 +@@ -67,6 +67,7 @@ class Callbacks(unittest.TestCase): + self.check_type(c_longlong, 42) + self.check_type(c_longlong, -42) + ++ @unittest.skip('Known failure on Sparc: http://bugs.python.org/issue8314') + def test_ulonglong(self): + # test some 64-bit values, with and without msb set. + self.check_type(c_ulonglong, 10955412242170339782) diff --git a/SOURCES/00141-fix-test_gc_with_COUNT_ALLOCS.patch b/SOURCES/00141-fix-test_gc_with_COUNT_ALLOCS.patch new file mode 100644 index 0000000..d5bf3c9 --- /dev/null +++ b/SOURCES/00141-fix-test_gc_with_COUNT_ALLOCS.patch @@ -0,0 +1,24 @@ +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. diff --git a/SOURCES/00142-skip-failing-pty-tests-in-rpmbuild.patch b/SOURCES/00142-skip-failing-pty-tests-in-rpmbuild.patch new file mode 100644 index 0000000..414ffcd --- /dev/null +++ b/SOURCES/00142-skip-failing-pty-tests-in-rpmbuild.patch @@ -0,0 +1,22 @@ +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 +@@ -8,6 +8,7 @@ if not hasattr(os, "openpty"): + + + class OpenptyTest(unittest.TestCase): ++ @unittest._skipInRpmBuild('sometimes fails in Koji, possibly due to a mock issue (rhbz#714627)') + def test(self): + master, slave = os.openpty() + 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): + os.close(master_fd) + + ++ @unittest._skipInRpmBuild('sometimes fails in Koji, possibly due to a mock issue (rhbz#714627)') + def test_fork(self): + debug("calling pty.fork()") + pid, master_fd = pty.fork() diff --git a/SOURCES/00143-tsc-on-ppc.patch b/SOURCES/00143-tsc-on-ppc.patch new file mode 100644 index 0000000..447c6e3 --- /dev/null +++ b/SOURCES/00143-tsc-on-ppc.patch @@ -0,0 +1,58 @@ +diff -up Python-2.7.2/Python/ceval.c.tsc-on-ppc Python-2.7.2/Python/ceval.c +--- Python-2.7.2/Python/ceval.c.tsc-on-ppc 2011-08-23 14:59:48.051300849 -0400 ++++ Python-2.7.2/Python/ceval.c 2011-08-23 15:33:25.412162902 -0400 +@@ -37,24 +37,42 @@ typedef unsigned long long uint64; + */ + #if defined(__ppc__) || defined (__powerpc__) + +-#define READ_TIMESTAMP(var) ppc_getcounter(&var) ++#if defined( __powerpc64__) || defined(__LP64__) ++/* 64-bit PowerPC */ ++#define READ_TIMESTAMP(var) ppc64_getcounter(&var) ++static void ++ppc64_getcounter(uint64 *v) ++{ ++ /* On 64-bit PowerPC we can read the 64-bit timebase directly into a ++ 64-bit register */ ++ uint64 timebase; ++#ifdef _ARCH_PWR4 ++ asm volatile ("mfspr %0,268" : "=r" (timebase)); ++#else ++ asm volatile ("mftb %0" : "=r" (timebase)); ++#endif ++ *v = timebase; ++} ++ ++#else ++/* 32-bit PowerPC */ ++#define READ_TIMESTAMP(var) ppc32_getcounter(&var) + + static void +-ppc_getcounter(uint64 *v) ++ppc32_getcounter(uint64 *v) + { +- register unsigned long tbu, tb, tbu2; ++ union { long long ll; long ii[2]; } u; ++ long tmp; + + loop: +- asm volatile ("mftbu %0" : "=r" (tbu) ); +- asm volatile ("mftb %0" : "=r" (tb) ); +- asm volatile ("mftbu %0" : "=r" (tbu2)); +- if (__builtin_expect(tbu != tbu2, 0)) goto loop; +- +- /* The slightly peculiar way of writing the next lines is +- compiled better by GCC than any other way I tried. */ +- ((long*)(v))[0] = tbu; +- ((long*)(v))[1] = tb; ++ asm volatile ("mftbu %0" : "=r" (u.ii[0]) ); ++ asm volatile ("mftb %0" : "=r" (u.ii[1]) ); ++ asm volatile ("mftbu %0" : "=r" (tmp)); ++ if (__builtin_expect(u.ii[0] != tmp, 0)) goto loop; ++ ++ *v = u.ll; + } ++#endif /* powerpc 32/64 bit */ + + #elif defined(__i386__) + diff --git a/SOURCES/00144-no-gdbm.patch b/SOURCES/00144-no-gdbm.patch new file mode 100644 index 0000000..0378d44 --- /dev/null +++ b/SOURCES/00144-no-gdbm.patch @@ -0,0 +1,12 @@ +diff -up Python-2.7.2/Modules/Setup.dist.no-gdbm Python-2.7.2/Modules/Setup.dist +--- Python-2.7.2/Modules/Setup.dist.no-gdbm 2011-09-13 14:25:43.496095926 -0400 ++++ Python-2.7.2/Modules/Setup.dist 2011-09-13 14:25:46.491095724 -0400 +@@ -396,7 +396,7 @@ dl dlmodule.c + # + # First, look at Setup.config; configure may have set this for you. + +-gdbm gdbmmodule.c -lgdbm ++# gdbm gdbmmodule.c -lgdbm + + + # Sleepycat Berkeley DB interface. diff --git a/SOURCES/00146-hashlib-fips.patch b/SOURCES/00146-hashlib-fips.patch new file mode 100644 index 0000000..c67eb3b --- /dev/null +++ b/SOURCES/00146-hashlib-fips.patch @@ -0,0 +1,729 @@ +diff -up Python-2.7.2/Lib/hashlib.py.hashlib-fips Python-2.7.2/Lib/hashlib.py +--- Python-2.7.2/Lib/hashlib.py.hashlib-fips 2011-06-11 11:46:24.000000000 -0400 ++++ Python-2.7.2/Lib/hashlib.py 2011-09-14 00:21:26.194252001 -0400 +@@ -6,9 +6,12 @@ + + __doc__ = """hashlib module - A common interface to many hash functions. + +-new(name, string='') - returns a new hash object implementing the +- given hash function; initializing the hash +- using the given string data. ++new(name, string='', usedforsecurity=True) ++ - returns a new hash object implementing the given hash function; ++ initializing the hash using the given string data. ++ ++ "usedforsecurity" is a non-standard extension for better supporting ++ FIPS-compliant environments (see below) + + Named constructor functions are also available, these are much faster + than using new(): +@@ -24,6 +27,20 @@ the zlib module. + Choose your hash function wisely. Some have known collision weaknesses. + sha384 and sha512 will be slow on 32 bit platforms. + ++Our implementation of hashlib uses OpenSSL. ++ ++OpenSSL has a "FIPS mode", which, if enabled, may restrict the available hashes ++to only those that are compliant with FIPS regulations. For example, it may ++deny the use of MD5, on the grounds that this is not secure for uses such as ++authentication, system integrity checking, or digital signatures. ++ ++If you need to use such a hash for non-security purposes (such as indexing into ++a data structure for speed), you can override the keyword argument ++"usedforsecurity" from True to False to signify that your code is not relying ++on the hash for security purposes, and this will allow the hash to be usable ++even in FIPS mode. This is not a standard feature of Python 2.7's hashlib, and ++is included here to better support FIPS mode. ++ + Hash objects have these methods: + - update(arg): Update the hash object with the string arg. Repeated calls + are equivalent to a single call with the concatenation of all +@@ -63,74 +80,39 @@ algorithms = __always_supported + __all__ = __always_supported + ('new', 'algorithms') + + +-def __get_builtin_constructor(name): +- try: +- if name in ('SHA1', 'sha1'): +- import _sha +- return _sha.new +- elif name in ('MD5', 'md5'): +- import _md5 +- return _md5.new +- elif name in ('SHA256', 'sha256', 'SHA224', 'sha224'): +- import _sha256 +- bs = name[3:] +- if bs == '256': +- return _sha256.sha256 +- elif bs == '224': +- return _sha256.sha224 +- elif name in ('SHA512', 'sha512', 'SHA384', 'sha384'): +- import _sha512 +- bs = name[3:] +- if bs == '512': +- return _sha512.sha512 +- elif bs == '384': +- return _sha512.sha384 +- except ImportError: +- pass # no extension module, this hash is unsupported. +- +- raise ValueError('unsupported hash type ' + name) +- +- + def __get_openssl_constructor(name): + try: + f = getattr(_hashlib, 'openssl_' + name) + # Allow the C module to raise ValueError. The function will be + # defined but the hash not actually available thanks to OpenSSL. +- f() ++ # ++ # We pass "usedforsecurity=False" to disable FIPS-based restrictions: ++ # at this stage we're merely seeing if the function is callable, ++ # rather than using it for actual work. ++ f(usedforsecurity=False) + # Use the C function directly (very fast) + return f + except (AttributeError, ValueError): +- return __get_builtin_constructor(name) ++ raise + +- +-def __py_new(name, string=''): +- """new(name, string='') - Return a new hashing object using the named algorithm; +- optionally initialized with a string. +- """ +- return __get_builtin_constructor(name)(string) +- +- +-def __hash_new(name, string=''): ++def __hash_new(name, string='', usedforsecurity=True): + """new(name, string='') - Return a new hashing object using the named algorithm; + optionally initialized with a string. ++ Override 'usedforsecurity' to False when using for non-security purposes in ++ a FIPS environment + """ + try: +- return _hashlib.new(name, string) ++ return _hashlib.new(name, string, usedforsecurity) + except ValueError: +- # If the _hashlib module (OpenSSL) doesn't support the named +- # hash, try using our builtin implementations. +- # This allows for SHA224/256 and SHA384/512 support even though +- # the OpenSSL library prior to 0.9.8 doesn't provide them. +- return __get_builtin_constructor(name)(string) +- ++ raise + + try: + import _hashlib + new = __hash_new + __get_hash = __get_openssl_constructor + except ImportError: +- new = __py_new +- __get_hash = __get_builtin_constructor ++ # We don't build the legacy modules ++ raise + + for __func_name in __always_supported: + # try them all, some may not work due to the OpenSSL +@@ -143,4 +125,4 @@ for __func_name in __always_supported: + + # Cleanup locals() + del __always_supported, __func_name, __get_hash +-del __py_new, __hash_new, __get_openssl_constructor ++del __hash_new, __get_openssl_constructor +diff -up Python-2.7.2/Lib/test/test_hashlib.py.hashlib-fips Python-2.7.2/Lib/test/test_hashlib.py +--- Python-2.7.2/Lib/test/test_hashlib.py.hashlib-fips 2011-06-11 11:46:25.000000000 -0400 ++++ Python-2.7.2/Lib/test/test_hashlib.py 2011-09-14 01:08:55.525254195 -0400 +@@ -32,6 +32,19 @@ def hexstr(s): + r = r + h[(i >> 4) & 0xF] + h[i & 0xF] + return r + ++def openssl_enforces_fips(): ++ # Use the "openssl" command (if present) to try to determine if the local ++ # OpenSSL is configured to enforce FIPS ++ from subprocess import Popen, PIPE ++ try: ++ p = Popen(['openssl', 'md5'], ++ stdin=PIPE, stdout=PIPE, stderr=PIPE) ++ except OSError: ++ # "openssl" command not found ++ return False ++ stdout, stderr = p.communicate(input=b'abc') ++ return b'unknown cipher' in stderr ++OPENSSL_ENFORCES_FIPS = openssl_enforces_fips() + + class HashLibTestCase(unittest.TestCase): + supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1', +@@ -61,10 +74,10 @@ class HashLibTestCase(unittest.TestCase) + # of hashlib.new given the algorithm name. + for algorithm, constructors in self.constructors_to_test.items(): + constructors.add(getattr(hashlib, algorithm)) +- def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm): ++ def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm, usedforsecurity=True): + if data is None: +- return hashlib.new(_alg) +- return hashlib.new(_alg, data) ++ return hashlib.new(_alg, usedforsecurity=usedforsecurity) ++ return hashlib.new(_alg, data, usedforsecurity=usedforsecurity) + constructors.add(_test_algorithm_via_hashlib_new) + + _hashlib = self._conditional_import_module('_hashlib') +@@ -78,28 +91,13 @@ class HashLibTestCase(unittest.TestCase) + if constructor: + constructors.add(constructor) + +- _md5 = self._conditional_import_module('_md5') +- if _md5: +- self.constructors_to_test['md5'].add(_md5.new) +- _sha = self._conditional_import_module('_sha') +- if _sha: +- self.constructors_to_test['sha1'].add(_sha.new) +- _sha256 = self._conditional_import_module('_sha256') +- if _sha256: +- self.constructors_to_test['sha224'].add(_sha256.sha224) +- self.constructors_to_test['sha256'].add(_sha256.sha256) +- _sha512 = self._conditional_import_module('_sha512') +- if _sha512: +- self.constructors_to_test['sha384'].add(_sha512.sha384) +- self.constructors_to_test['sha512'].add(_sha512.sha512) +- + super(HashLibTestCase, self).__init__(*args, **kwargs) + + def test_hash_array(self): + a = array.array("b", range(10)) + constructors = self.constructors_to_test.itervalues() + for cons in itertools.chain.from_iterable(constructors): +- c = cons(a) ++ c = cons(a, usedforsecurity=False) + c.hexdigest() + + def test_algorithms_attribute(self): +@@ -115,28 +113,9 @@ class HashLibTestCase(unittest.TestCase) + self.assertRaises(ValueError, hashlib.new, 'spam spam spam spam spam') + self.assertRaises(TypeError, hashlib.new, 1) + +- def test_get_builtin_constructor(self): +- get_builtin_constructor = hashlib.__dict__[ +- '__get_builtin_constructor'] +- self.assertRaises(ValueError, get_builtin_constructor, 'test') +- try: +- import _md5 +- except ImportError: +- pass +- # This forces an ImportError for "import _md5" statements +- sys.modules['_md5'] = None +- try: +- self.assertRaises(ValueError, get_builtin_constructor, 'md5') +- finally: +- if '_md5' in locals(): +- sys.modules['_md5'] = _md5 +- else: +- del sys.modules['_md5'] +- self.assertRaises(TypeError, get_builtin_constructor, 3) +- + def test_hexdigest(self): + for name in self.supported_hash_names: +- h = hashlib.new(name) ++ h = hashlib.new(name, usedforsecurity=False) + self.assertTrue(hexstr(h.digest()) == h.hexdigest()) + + def test_large_update(self): +@@ -145,16 +125,16 @@ class HashLibTestCase(unittest.TestCase) + abcs = aas + bees + cees + + for name in self.supported_hash_names: +- m1 = hashlib.new(name) ++ m1 = hashlib.new(name, usedforsecurity=False) + m1.update(aas) + m1.update(bees) + m1.update(cees) + +- m2 = hashlib.new(name) ++ m2 = hashlib.new(name, usedforsecurity=False) + m2.update(abcs) + self.assertEqual(m1.digest(), m2.digest(), name+' update problem.') + +- m3 = hashlib.new(name, abcs) ++ m3 = hashlib.new(name, abcs, usedforsecurity=False) + self.assertEqual(m1.digest(), m3.digest(), name+' new problem.') + + def check(self, name, data, digest): +@@ -162,7 +142,7 @@ class HashLibTestCase(unittest.TestCase) + # 2 is for hashlib.name(...) and hashlib.new(name, ...) + self.assertGreaterEqual(len(constructors), 2) + for hash_object_constructor in constructors: +- computed = hash_object_constructor(data).hexdigest() ++ computed = hash_object_constructor(data, usedforsecurity=False).hexdigest() + self.assertEqual( + computed, digest, + "Hash algorithm %s constructed using %s returned hexdigest" +@@ -172,7 +152,8 @@ class HashLibTestCase(unittest.TestCase) + + def check_unicode(self, algorithm_name): + # Unicode objects are not allowed as input. +- expected = hashlib.new(algorithm_name, str(u'spam')).hexdigest() ++ expected = hashlib.new(algorithm_name, str(u'spam'), ++ usedforsecurity=False).hexdigest() + self.check(algorithm_name, u'spam', expected) + + def test_unicode(self): +@@ -354,6 +335,70 @@ class HashLibTestCase(unittest.TestCase) + + self.assertEqual(expected_hash, hasher.hexdigest()) + ++ def test_issue9146(self): ++ # Ensure that various ways to use "MD5" from "hashlib" don't segfault: ++ m = hashlib.md5(usedforsecurity=False) ++ m.update(b'abc\n') ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = hashlib.new('md5', usedforsecurity=False) ++ m.update(b'abc\n') ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = hashlib.md5(b'abc\n', usedforsecurity=False) ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = hashlib.new('md5', b'abc\n', usedforsecurity=False) ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ def assertRaisesUnknownCipher(self, callable_obj=None, *args, **kwargs): ++ try: ++ callable_obj(*args, **kwargs) ++ except ValueError, e: ++ if not e.args[0].endswith('unknown cipher'): ++ self.fail('Incorrect exception raised') ++ else: ++ self.fail('Exception was not raised') ++ ++ @unittest.skipUnless(OPENSSL_ENFORCES_FIPS, ++ 'FIPS enforcement required for this test.') ++ def test_hashlib_fips_mode(self): ++ # Ensure that we raise a ValueError on vanilla attempts to use MD5 ++ # in hashlib in a FIPS-enforced setting: ++ self.assertRaisesUnknownCipher(hashlib.md5) ++ self.assertRaisesUnknownCipher(hashlib.new, 'md5') ++ ++ @unittest.skipUnless(OPENSSL_ENFORCES_FIPS, ++ 'FIPS enforcement required for this test.') ++ def test_hashopenssl_fips_mode(self): ++ # Verify the _hashlib module's handling of md5: ++ import _hashlib ++ ++ assert hasattr(_hashlib, 'openssl_md5') ++ ++ # Ensure that _hashlib raises a ValueError on vanilla attempts to ++ # use MD5 in a FIPS-enforced setting: ++ self.assertRaisesUnknownCipher(_hashlib.openssl_md5) ++ self.assertRaisesUnknownCipher(_hashlib.new, 'md5') ++ ++ # Ensure that in such a setting we can whitelist a callsite with ++ # usedforsecurity=False and have it succeed: ++ m = _hashlib.openssl_md5(usedforsecurity=False) ++ m.update('abc\n') ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = _hashlib.new('md5', usedforsecurity=False) ++ m.update('abc\n') ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = _hashlib.openssl_md5('abc\n', usedforsecurity=False) ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ m = _hashlib.new('md5', 'abc\n', usedforsecurity=False) ++ self.assertEquals(m.hexdigest(), "0bee89b07a248e27c83fc3d5951213c1") ++ ++ ++ + def test_main(): + test_support.run_unittest(HashLibTestCase) + +diff -up Python-2.7.2/Modules/_hashopenssl.c.hashlib-fips Python-2.7.2/Modules/_hashopenssl.c +--- Python-2.7.2/Modules/_hashopenssl.c.hashlib-fips 2011-06-11 11:46:26.000000000 -0400 ++++ Python-2.7.2/Modules/_hashopenssl.c 2011-09-14 00:21:26.199252001 -0400 +@@ -36,6 +36,8 @@ + #endif + + /* EVP is the preferred interface to hashing in OpenSSL */ ++#include ++#include + #include + + #define MUNCH_SIZE INT_MAX +@@ -65,11 +67,19 @@ typedef struct { + + static PyTypeObject EVPtype; + ++/* Struct to hold all the cached information we need on a specific algorithm. ++ We have one of these per algorithm */ ++typedef struct { ++ PyObject *name_obj; ++ EVP_MD_CTX ctxs[2]; ++ /* ctx_ptrs will point to ctxs unless an error occurred, when it will ++ be NULL: */ ++ EVP_MD_CTX *ctx_ptrs[2]; ++ PyObject *error_msgs[2]; ++} EVPCachedInfo; + +-#define DEFINE_CONSTS_FOR_NEW(Name) \ +- static PyObject *CONST_ ## Name ## _name_obj = NULL; \ +- static EVP_MD_CTX CONST_new_ ## Name ## _ctx; \ +- static EVP_MD_CTX *CONST_new_ ## Name ## _ctx_p = NULL; ++#define DEFINE_CONSTS_FOR_NEW(Name) \ ++ static EVPCachedInfo cached_info_ ##Name; + + DEFINE_CONSTS_FOR_NEW(md5) + DEFINE_CONSTS_FOR_NEW(sha1) +@@ -115,6 +125,48 @@ EVP_hash(EVPobject *self, const void *vp + } + } + ++static void ++mc_ctx_init(EVP_MD_CTX *ctx, int usedforsecurity) ++{ ++ EVP_MD_CTX_init(ctx); ++ ++ /* ++ If the user has declared that this digest is being used in a ++ non-security role (e.g. indexing into a data structure), set ++ the exception flag for openssl to allow it ++ */ ++ if (!usedforsecurity) { ++#ifdef EVP_MD_CTX_FLAG_NON_FIPS_ALLOW ++ EVP_MD_CTX_set_flags(ctx, ++ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); ++#endif ++ } ++} ++ ++/* Get an error msg for the last error as a PyObject */ ++static PyObject * ++error_msg_for_last_error(void) ++{ ++ char *errstr; ++ ++ errstr = ERR_error_string(ERR_peek_last_error(), NULL); ++ ERR_clear_error(); ++ ++ return PyString_FromString(errstr); /* Can be NULL */ ++} ++ ++static void ++set_evp_exception(void) ++{ ++ char *errstr; ++ ++ errstr = ERR_error_string(ERR_peek_last_error(), NULL); ++ ERR_clear_error(); ++ ++ PyErr_SetString(PyExc_ValueError, errstr); ++} ++ ++ + /* Internal methods for a hash object */ + + static void +@@ -313,14 +365,15 @@ EVP_repr(PyObject *self) + static int + EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds) + { +- static char *kwlist[] = {"name", "string", NULL}; ++ static char *kwlist[] = {"name", "string", "usedforsecurity", NULL}; + PyObject *name_obj = NULL; ++ int usedforsecurity = 1; + Py_buffer view = { 0 }; + char *nameStr; + const EVP_MD *digest; + +- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s*:HASH", kwlist, +- &name_obj, &view)) { ++ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|s*i:HASH", kwlist, ++ &name_obj, &view, &usedforsecurity)) { + return -1; + } + +@@ -336,7 +389,12 @@ EVP_tp_init(EVPobject *self, PyObject *a + PyBuffer_Release(&view); + return -1; + } +- EVP_DigestInit(&self->ctx, digest); ++ mc_ctx_init(&self->ctx, usedforsecurity); ++ if (!EVP_DigestInit_ex(&self->ctx, digest, NULL)) { ++ set_evp_exception(); ++ PyBuffer_Release(&view); ++ return -1; ++ } + + self->name = name_obj; + Py_INCREF(self->name); +@@ -420,7 +478,8 @@ static PyTypeObject EVPtype = { + static PyObject * + EVPnew(PyObject *name_obj, + const EVP_MD *digest, const EVP_MD_CTX *initial_ctx, +- const unsigned char *cp, Py_ssize_t len) ++ const unsigned char *cp, Py_ssize_t len, ++ int usedforsecurity) + { + EVPobject *self; + +@@ -435,7 +494,12 @@ EVPnew(PyObject *name_obj, + if (initial_ctx) { + EVP_MD_CTX_copy(&self->ctx, initial_ctx); + } else { +- EVP_DigestInit(&self->ctx, digest); ++ mc_ctx_init(&self->ctx, usedforsecurity); ++ if (!EVP_DigestInit_ex(&self->ctx, digest, NULL)) { ++ set_evp_exception(); ++ Py_DECREF(self); ++ return NULL; ++ } + } + + if (cp && len) { +@@ -459,20 +523,28 @@ PyDoc_STRVAR(EVP_new__doc__, + An optional string argument may be provided and will be\n\ + automatically hashed.\n\ + \n\ +-The MD5 and SHA1 algorithms are always supported.\n"); ++The MD5 and SHA1 algorithms are always supported.\n\ ++\n\ ++An optional \"usedforsecurity=True\" keyword argument is provided for use in\n\ ++environments that enforce FIPS-based restrictions. Some implementations of\n\ ++OpenSSL can be configured to prevent the usage of non-secure algorithms (such\n\ ++as MD5). If you have a non-security use for these algorithms (e.g. a hash\n\ ++table), you can override this argument by marking the callsite as\n\ ++\"usedforsecurity=False\"."); + + static PyObject * + EVP_new(PyObject *self, PyObject *args, PyObject *kwdict) + { +- static char *kwlist[] = {"name", "string", NULL}; ++ static char *kwlist[] = {"name", "string", "usedforsecurity", NULL}; + PyObject *name_obj = NULL; + Py_buffer view = { 0 }; + PyObject *ret_obj; + char *name; + const EVP_MD *digest; ++ int usedforsecurity = 1; + +- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|s*:new", kwlist, +- &name_obj, &view)) { ++ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|s*i:new", kwlist, ++ &name_obj, &view, &usedforsecurity)) { + return NULL; + } + +@@ -484,58 +556,118 @@ EVP_new(PyObject *self, PyObject *args, + digest = EVP_get_digestbyname(name); + + ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, +- view.len); ++ view.len, usedforsecurity); + PyBuffer_Release(&view); + + return ret_obj; + } + + /* +- * This macro generates constructor function definitions for specific +- * hash algorithms. These constructors are much faster than calling +- * the generic one passing it a python string and are noticably +- * faster than calling a python new() wrapper. Thats important for ++ * This macro and function generates a family of constructor function ++ * definitions for specific hash algorithms. These constructors are much ++ * faster than calling the generic one passing it a python string and are ++ * noticably faster than calling a python new() wrapper. That's important for + * code that wants to make hashes of a bunch of small strings. + */ + #define GEN_CONSTRUCTOR(NAME) \ + static PyObject * \ +- EVP_new_ ## NAME (PyObject *self, PyObject *args) \ ++ EVP_new_ ## NAME (PyObject *self, PyObject *args, PyObject *kwdict) \ + { \ +- Py_buffer view = { 0 }; \ +- PyObject *ret_obj; \ +- \ +- if (!PyArg_ParseTuple(args, "|s*:" #NAME , &view)) { \ +- return NULL; \ +- } \ +- \ +- ret_obj = EVPnew( \ +- CONST_ ## NAME ## _name_obj, \ +- NULL, \ +- CONST_new_ ## NAME ## _ctx_p, \ +- (unsigned char*)view.buf, view.len); \ +- PyBuffer_Release(&view); \ +- return ret_obj; \ ++ return implement_specific_EVP_new(self, args, kwdict, \ ++ "|s*i:" #NAME, \ ++ &cached_info_ ## NAME ); \ + } + ++static PyObject * ++implement_specific_EVP_new(PyObject *self, PyObject *args, PyObject *kwdict, ++ const char *format, ++ EVPCachedInfo *cached_info) ++{ ++ static char *kwlist[] = {"string", "usedforsecurity", NULL}; ++ Py_buffer view = { 0 }; ++ int usedforsecurity = 1; ++ int idx; ++ PyObject *ret_obj = NULL; ++ ++ assert(cached_info); ++ ++ if (!PyArg_ParseTupleAndKeywords(args, kwdict, format, kwlist, ++ &view, &usedforsecurity)) { ++ return NULL; ++ } ++ ++ idx = usedforsecurity ? 1 : 0; ++ ++ /* ++ * If an error occurred during creation of the global content, the ctx_ptr ++ * will be NULL, and the error_msg will hopefully be non-NULL: ++ */ ++ if (cached_info->ctx_ptrs[idx]) { ++ /* We successfully initialized this context; copy it: */ ++ ret_obj = EVPnew(cached_info->name_obj, ++ NULL, ++ cached_info->ctx_ptrs[idx], ++ (unsigned char*)view.buf, view.len, ++ usedforsecurity); ++ } else { ++ /* Some kind of error happened initializing the global context for ++ this (digest, usedforsecurity) pair. ++ Raise an exception with the saved error message: */ ++ if (cached_info->error_msgs[idx]) { ++ PyErr_SetObject(PyExc_ValueError, cached_info->error_msgs[idx]); ++ } else { ++ PyErr_SetString(PyExc_ValueError, "Error initializing hash"); ++ } ++ } ++ ++ PyBuffer_Release(&view); ++ ++ return ret_obj; ++} ++ + /* a PyMethodDef structure for the constructor */ + #define CONSTRUCTOR_METH_DEF(NAME) \ +- {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, METH_VARARGS, \ ++ {"openssl_" #NAME, (PyCFunction)EVP_new_ ## NAME, \ ++ METH_VARARGS |METH_KEYWORDS, \ + PyDoc_STR("Returns a " #NAME \ + " hash object; optionally initialized with a string") \ + } + +-/* used in the init function to setup a constructor: initialize OpenSSL +- constructor constants if they haven't been initialized already. */ +-#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \ +- if (CONST_ ## NAME ## _name_obj == NULL) { \ +- CONST_ ## NAME ## _name_obj = PyString_FromString(#NAME); \ +- if (EVP_get_digestbyname(#NAME)) { \ +- CONST_new_ ## NAME ## _ctx_p = &CONST_new_ ## NAME ## _ctx; \ +- EVP_DigestInit(CONST_new_ ## NAME ## _ctx_p, EVP_get_digestbyname(#NAME)); \ +- } \ +- } \ ++/* ++ Macro/function pair to set up the constructors. ++ ++ Try to initialize a context for each hash twice, once with ++ EVP_MD_CTX_FLAG_NON_FIPS_ALLOW and once without. ++ ++ Any that have errors during initialization will end up wit a NULL ctx_ptrs ++ entry, and err_msgs will be set (unless we're very low on memory) ++*/ ++#define INIT_CONSTRUCTOR_CONSTANTS(NAME) do { \ ++ init_constructor_constant(&cached_info_ ## NAME, #NAME); \ + } while (0); + ++static void ++init_constructor_constant(EVPCachedInfo *cached_info, const char *name) ++{ ++ assert(cached_info); ++ cached_info->name_obj = PyString_FromString(name); ++ if (EVP_get_digestbyname(name)) { ++ int i; ++ for (i=0; i<2; i++) { ++ mc_ctx_init(&cached_info->ctxs[i], i); ++ if (EVP_DigestInit_ex(&cached_info->ctxs[i], ++ EVP_get_digestbyname(name), NULL)) { ++ /* Success: */ ++ cached_info->ctx_ptrs[i] = &cached_info->ctxs[i]; ++ } else { ++ /* Failure: */ ++ cached_info->ctx_ptrs[i] = NULL; ++ cached_info->error_msgs[i] = error_msg_for_last_error(); ++ } ++ } ++ } ++} ++ + GEN_CONSTRUCTOR(md5) + GEN_CONSTRUCTOR(sha1) + #ifdef _OPENSSL_SUPPORTS_SHA2 +@@ -565,13 +700,10 @@ init_hashlib(void) + { + PyObject *m; + ++ SSL_load_error_strings(); ++ SSL_library_init(); + OpenSSL_add_all_digests(); + +- /* TODO build EVP_functions openssl_* entries dynamically based +- * on what hashes are supported rather than listing many +- * but having some be unsupported. Only init appropriate +- * constants. */ +- + Py_TYPE(&EVPtype) = &PyType_Type; + if (PyType_Ready(&EVPtype) < 0) + return; +diff -up Python-2.7.2/Modules/Setup.dist.hashlib-fips Python-2.7.2/Modules/Setup.dist +--- Python-2.7.2/Modules/Setup.dist.hashlib-fips 2011-09-14 00:21:26.163252001 -0400 ++++ Python-2.7.2/Modules/Setup.dist 2011-09-14 00:21:26.201252001 -0400 +@@ -248,14 +248,14 @@ imageop imageop.c # Operations on images + # Message-Digest Algorithm, described in RFC 1321. The necessary files + # md5.c and md5.h are included here. + +-_md5 md5module.c md5.c ++#_md5 md5module.c md5.c + + + # The _sha module implements the SHA checksum algorithms. + # (NIST's Secure Hash Algorithms.) +-_sha shamodule.c +-_sha256 sha256module.c +-_sha512 sha512module.c ++#_sha shamodule.c ++#_sha256 sha256module.c ++#_sha512 sha512module.c + + + # SGI IRIX specific modules -- off by default. +diff -up Python-2.7.2/setup.py.hashlib-fips Python-2.7.2/setup.py +--- Python-2.7.2/setup.py.hashlib-fips 2011-09-14 00:21:25.722252001 -0400 ++++ Python-2.7.2/setup.py 2011-09-14 00:21:26.203252001 -0400 +@@ -768,21 +768,6 @@ class PyBuildExt(build_ext): + print ("warning: openssl 0x%08x is too old for _hashlib" % + openssl_ver) + missing.append('_hashlib') +- if COMPILED_WITH_PYDEBUG or not have_usable_openssl: +- # The _sha module implements the SHA1 hash algorithm. +- exts.append( Extension('_sha', ['shamodule.c']) ) +- # The _md5 module implements the RSA Data Security, Inc. MD5 +- # Message-Digest Algorithm, described in RFC 1321. The +- # necessary files md5.c and md5.h are included here. +- exts.append( Extension('_md5', +- sources = ['md5module.c', 'md5.c'], +- depends = ['md5.h']) ) +- +- min_sha2_openssl_ver = 0x00908000 +- if COMPILED_WITH_PYDEBUG or openssl_ver < min_sha2_openssl_ver: +- # OpenSSL doesn't do these until 0.9.8 so we'll bring our own hash +- exts.append( Extension('_sha256', ['sha256module.c']) ) +- exts.append( Extension('_sha512', ['sha512module.c']) ) + + # Modules that provide persistent dictionary-like semantics. You will + # probably want to arrange for at least one of them to be available on diff --git a/SOURCES/00147-add-debug-malloc-stats.patch b/SOURCES/00147-add-debug-malloc-stats.patch new file mode 100644 index 0000000..0ab8c94 --- /dev/null +++ b/SOURCES/00147-add-debug-malloc-stats.patch @@ -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) ++ ++ + class SizeofTest(unittest.TestCase): + + def setUp(self): +diff -up Python-2.7.2/Objects/classobject.c.add-debug-malloc-stats Python-2.7.2/Objects/classobject.c +--- Python-2.7.2/Objects/classobject.c.add-debug-malloc-stats 2011-06-11 11:46:27.000000000 -0400 ++++ Python-2.7.2/Objects/classobject.c 2011-09-16 19:03:25.110821625 -0400 +@@ -2670,3 +2670,12 @@ PyMethod_Fini(void) + { + (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) + } + + ++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/SOURCES/00153-fix-test_gdb-noise.patch b/SOURCES/00153-fix-test_gdb-noise.patch new file mode 100644 index 0000000..50a0917 --- /dev/null +++ b/SOURCES/00153-fix-test_gdb-noise.patch @@ -0,0 +1,31 @@ +--- Lib/test/test_gdb.py.old 2012-04-11 21:04:01.367073855 -0400 ++++ Lib/test/test_gdb.py 2012-04-12 08:52:58.320288761 -0400 +@@ -96,6 +96,15 @@ class DebuggerTests(unittest.TestCase): + # Generate a list of commands in gdb's language: + commands = ['set breakpoint pending yes', + 'break %s' % breakpoint, ++ ++ # GDB as of Fedora 17 onwards can distinguish between the ++ # value of a variable at entry vs current value: ++ # http://sourceware.org/gdb/onlinedocs/gdb/Variables.html ++ # which leads to the selftests failing with errors like this: ++ # AssertionError: 'v@entry=()' != '()' ++ # Disable this: ++ 'set print entry-values no', ++ + 'run'] + if cmds_after_breakpoint: + commands += cmds_after_breakpoint +--- Lib/test/test_gdb.py.old 2012-04-11 21:04:01.367073855 -0400 ++++ Lib/test/test_gdb.py 2012-04-12 08:52:58.320288761 -0400 +@@ -144,6 +153,10 @@ + 'Do you need "set solib-search-path" or ' + '"set sysroot"?', + ) ++ ignore_patterns += ('warning: Unable to open', ++ 'Missing separate debuginfo for', ++ 'Try: yum --disablerepo=', ++ 'Undefined set print command') + for line in errlines: + if not line.startswith(ignore_patterns): + unexpected_errlines.append(line) diff --git a/SOURCES/00155-avoid-ctypes-thunks.patch b/SOURCES/00155-avoid-ctypes-thunks.patch new file mode 100644 index 0000000..92dd668 --- /dev/null +++ b/SOURCES/00155-avoid-ctypes-thunks.patch @@ -0,0 +1,15 @@ +diff -up Python-2.7.3/Lib/ctypes/__init__.py.rhbz814391 Python-2.7.3/Lib/ctypes/__init__.py +--- Python-2.7.3/Lib/ctypes/__init__.py.rhbz814391 2012-04-20 14:51:19.390990244 -0400 ++++ Python-2.7.3/Lib/ctypes/__init__.py 2012-04-20 14:51:45.141668316 -0400 +@@ -272,11 +272,6 @@ def _reset_cache(): + # _SimpleCData.c_char_p_from_param + POINTER(c_char).from_param = c_char_p.from_param + _pointer_type_cache[None] = c_void_p +- # XXX for whatever reasons, creating the first instance of a callback +- # function is needed for the unittests on Win64 to succeed. This MAY +- # be a compiler bug, since the problem occurs only when _ctypes is +- # compiled with the MS SDK compiler. Or an uninitialized variable? +- CFUNCTYPE(c_int)(lambda: None) + + try: + from _ctypes import set_conversion_mode diff --git a/SOURCES/00156-gdb-autoload-safepath.patch b/SOURCES/00156-gdb-autoload-safepath.patch new file mode 100644 index 0000000..54a5a6e --- /dev/null +++ b/SOURCES/00156-gdb-autoload-safepath.patch @@ -0,0 +1,52 @@ +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.""" +@@ -112,15 +125,28 @@ class DebuggerTests(unittest.TestCase): + 'set print entry-values no', + + '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 = [] ++ + if cmds_after_breakpoint: + commands += cmds_after_breakpoint + else: + commands += ['backtrace'] + ++ # print init_commands + # print commands + + # Use "commands" to generate the arguments with which to invoke "gdb": + args = ["gdb", "--batch"] ++ args += ['--init-eval-command=%s' % cmd for cmd in init_commands] + args += ['--eval-command=%s' % cmd for cmd in commands] + args += ["--args", + sys.executable] diff --git a/SOURCES/00157-uid-gid-overflows.patch b/SOURCES/00157-uid-gid-overflows.patch new file mode 100644 index 0000000..13546bb --- /dev/null +++ b/SOURCES/00157-uid-gid-overflows.patch @@ -0,0 +1,49 @@ +diff -up Python-2.7.3/Lib/test/test_os.py.uid-gid-overflows Python-2.7.3/Lib/test/test_os.py +--- Python-2.7.3/Lib/test/test_os.py.uid-gid-overflows 2012-04-09 19:07:32.000000000 -0400 ++++ Python-2.7.3/Lib/test/test_os.py 2012-06-26 14:51:36.000817929 -0400 +@@ -677,30 +677,36 @@ if sys.platform != 'win32': + def test_setuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setuid, 0) ++ self.assertRaises(TypeError, os.setuid, 'not an int') + self.assertRaises(OverflowError, os.setuid, 1<<32) + + if hasattr(os, 'setgid'): + def test_setgid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setgid, 0) ++ self.assertRaises(TypeError, os.setgid, 'not an int') + self.assertRaises(OverflowError, os.setgid, 1<<32) + + if hasattr(os, 'seteuid'): + def test_seteuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.seteuid, 0) ++ self.assertRaises(TypeError, os.seteuid, 'not an int') + self.assertRaises(OverflowError, os.seteuid, 1<<32) + + if hasattr(os, 'setegid'): + def test_setegid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setegid, 0) ++ self.assertRaises(TypeError, os.setegid, 'not an int') + self.assertRaises(OverflowError, os.setegid, 1<<32) + + if hasattr(os, 'setreuid'): + def test_setreuid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setreuid, 0, 0) ++ self.assertRaises(TypeError, os.setreuid, 'not an int', 0) ++ self.assertRaises(TypeError, os.setreuid, 0, 'not an int') + self.assertRaises(OverflowError, os.setreuid, 1<<32, 0) + self.assertRaises(OverflowError, os.setreuid, 0, 1<<32) + +@@ -715,6 +721,8 @@ if sys.platform != 'win32': + def test_setregid(self): + if os.getuid() != 0: + self.assertRaises(os.error, os.setregid, 0, 0) ++ self.assertRaises(TypeError, os.setregid, 'not an int', 0) ++ self.assertRaises(TypeError, os.setregid, 0, 'not an int') + self.assertRaises(OverflowError, os.setregid, 1<<32, 0) + self.assertRaises(OverflowError, os.setregid, 0, 1<<32) + diff --git a/SOURCES/00165-crypt-module-salt-backport.patch b/SOURCES/00165-crypt-module-salt-backport.patch new file mode 100644 index 0000000..4308b4c --- /dev/null +++ b/SOURCES/00165-crypt-module-salt-backport.patch @@ -0,0 +1,285 @@ +diff -up Python-2.7.3/Doc/library/crypt.rst.crypt-module-salt-backport Python-2.7.3/Doc/library/crypt.rst +--- Python-2.7.3/Doc/library/crypt.rst.crypt-module-salt-backport 2012-04-09 19:07:28.000000000 -0400 ++++ Python-2.7.3/Doc/library/crypt.rst 2013-02-19 16:44:20.465334062 -0500 +@@ -16,9 +16,9 @@ + + This module implements an interface to the :manpage:`crypt(3)` routine, which is + a one-way hash function based upon a modified DES algorithm; see the Unix man +-page for further details. Possible uses include allowing Python scripts to +-accept typed passwords from the user, or attempting to crack Unix passwords with +-a dictionary. ++page for further details. Possible uses include storing hashed passwords ++so you can check passwords without storing the actual password, or attempting ++to crack Unix passwords with a dictionary. + + .. index:: single: crypt(3) + +@@ -27,15 +27,81 @@ the :manpage:`crypt(3)` routine in the r + extensions available on the current implementation will also be available on + this module. + ++Hashing Methods ++--------------- + +-.. function:: crypt(word, salt) ++The :mod:`crypt` module defines the list of hashing methods (not all methods ++are available on all platforms): ++ ++.. data:: METHOD_SHA512 ++ ++ A Modular Crypt Format method with 16 character salt and 86 character ++ hash. This is the strongest method. ++ ++.. versionadded:: 3.3 ++ ++.. data:: METHOD_SHA256 ++ ++ Another Modular Crypt Format method with 16 character salt and 43 ++ character hash. ++ ++.. versionadded:: 3.3 ++ ++.. data:: METHOD_MD5 ++ ++ Another Modular Crypt Format method with 8 character salt and 22 ++ character hash. ++ ++.. versionadded:: 3.3 ++ ++.. data:: METHOD_CRYPT ++ ++ The traditional method with a 2 character salt and 13 characters of ++ hash. This is the weakest method. ++ ++.. versionadded:: 3.3 ++ ++ ++Module Attributes ++----------------- ++ ++ ++.. attribute:: methods ++ ++ A list of available password hashing algorithms, as ++ ``crypt.METHOD_*`` objects. This list is sorted from strongest to ++ weakest, and is guaranteed to have at least ``crypt.METHOD_CRYPT``. ++ ++.. versionadded:: 3.3 ++ ++ ++Module Functions ++---------------- ++ ++The :mod:`crypt` module defines the following functions: ++ ++.. function:: crypt(word, salt=None) + + *word* will usually be a user's password as typed at a prompt or in a graphical +- interface. *salt* is usually a random two-character string which will be used +- to perturb the DES algorithm in one of 4096 ways. The characters in *salt* must +- be in the set ``[./a-zA-Z0-9]``. Returns the hashed password as a string, which +- will be composed of characters from the same alphabet as the salt (the first two +- characters represent the salt itself). ++ interface. The optional *salt* is either a string as returned from ++ :func:`mksalt`, one of the ``crypt.METHOD_*`` values (though not all ++ may be available on all platforms), or a full encrypted password ++ including salt, as returned by this function. If *salt* is not ++ provided, the strongest method will be used (as returned by ++ :func:`methods`. ++ ++ Checking a password is usually done by passing the plain-text password ++ as *word* and the full results of a previous :func:`crypt` call, ++ which should be the same as the results of this call. ++ ++ *salt* (either a random 2 or 16 character string, possibly prefixed with ++ ``$digit$`` to indicate the method) which will be used to perturb the ++ encryption algorithm. The characters in *salt* must be in the set ++ ``[./a-zA-Z0-9]``, with the exception of Modular Crypt Format which ++ prefixes a ``$digit$``. ++ ++ Returns the hashed password as a string, which will be composed of ++ characters from the same alphabet as the salt. + + .. index:: single: crypt(3) + +@@ -43,6 +109,27 @@ this module. + different sizes in the *salt*, it is recommended to use the full crypted + password as salt when checking for a password. + ++.. versionchanged:: 3.3 ++ Before version 3.3, *salt* must be specified as a string and cannot ++ accept ``crypt.METHOD_*`` values (which don't exist anyway). ++ ++ ++.. function:: mksalt(method=None) ++ ++ Return a randomly generated salt of the specified method. If no ++ *method* is given, the strongest method available as returned by ++ :func:`methods` is used. ++ ++ The return value is a string either of 2 characters in length for ++ ``crypt.METHOD_CRYPT``, or 19 characters starting with ``$digit$`` and ++ 16 random characters from the set ``[./a-zA-Z0-9]``, suitable for ++ passing as the *salt* argument to :func:`crypt`. ++ ++.. versionadded:: 3.3 ++ ++Examples ++-------- ++ + A simple example illustrating typical use:: + + import crypt, getpass, pwd +@@ -59,3 +146,11 @@ A simple example illustrating typical us + else: + return 1 + ++To generate a hash of a password using the strongest available method and ++check it against the original:: ++ ++ import crypt ++ ++ hashed = crypt.crypt(plaintext) ++ if hashed != crypt.crypt(plaintext, hashed): ++ raise "Hashed version doesn't validate against original" +diff -up Python-2.7.3/Lib/crypt.py.crypt-module-salt-backport Python-2.7.3/Lib/crypt.py +--- Python-2.7.3/Lib/crypt.py.crypt-module-salt-backport 2013-02-19 16:44:20.465334062 -0500 ++++ Python-2.7.3/Lib/crypt.py 2013-02-19 16:49:56.425311089 -0500 +@@ -0,0 +1,71 @@ ++"""Wrapper to the POSIX crypt library call and associated functionality. ++ ++Note that the ``methods`` and ``METHOD_*`` attributes are non-standard ++extensions to Python 2.7, backported from 3.3""" ++ ++import _crypt ++import string as _string ++from random import SystemRandom as _SystemRandom ++from collections import namedtuple as _namedtuple ++ ++ ++_saltchars = _string.ascii_letters + _string.digits + './' ++_sr = _SystemRandom() ++ ++ ++class _Method(_namedtuple('_Method', 'name ident salt_chars total_size')): ++ ++ """Class representing a salt method per the Modular Crypt Format or the ++ legacy 2-character crypt method.""" ++ ++ def __repr__(self): ++ return '' % self.name ++ ++ ++def mksalt(method=None): ++ """Generate a salt for the specified method. ++ ++ If not specified, the strongest available method will be used. ++ ++ This is a non-standard extension to Python 2.7, backported from 3.3 ++ """ ++ if method is None: ++ method = methods[0] ++ s = '$%s$' % method.ident if method.ident else '' ++ s += ''.join(_sr.sample(_saltchars, method.salt_chars)) ++ return s ++ ++ ++def crypt(word, salt=None): ++ """Return a string representing the one-way hash of a password, with a salt ++ prepended. ++ ++ If ``salt`` is not specified or is ``None``, the strongest ++ available method will be selected and a salt generated. Otherwise, ++ ``salt`` may be one of the ``crypt.METHOD_*`` values, or a string as ++ returned by ``crypt.mksalt()``. ++ ++ Note that these are non-standard extensions to Python 2.7's crypt.crypt() ++ entrypoint, backported from 3.3: the standard Python 2.7 crypt.crypt() ++ entrypoint requires two strings as the parameters, and does not support ++ keyword arguments. ++ """ ++ if salt is None or isinstance(salt, _Method): ++ salt = mksalt(salt) ++ return _crypt.crypt(word, salt) ++ ++ ++# available salting/crypto methods ++METHOD_CRYPT = _Method('CRYPT', None, 2, 13) ++METHOD_MD5 = _Method('MD5', '1', 8, 34) ++METHOD_SHA256 = _Method('SHA256', '5', 16, 63) ++METHOD_SHA512 = _Method('SHA512', '6', 16, 106) ++ ++methods = [] ++for _method in (METHOD_SHA512, METHOD_SHA256, METHOD_MD5): ++ _result = crypt('', _method) ++ if _result and len(_result) == _method.total_size: ++ methods.append(_method) ++methods.append(METHOD_CRYPT) ++del _result, _method ++ +diff -up Python-2.7.3/Lib/test/test_crypt.py.crypt-module-salt-backport Python-2.7.3/Lib/test/test_crypt.py +--- Python-2.7.3/Lib/test/test_crypt.py.crypt-module-salt-backport 2012-04-09 19:07:31.000000000 -0400 ++++ Python-2.7.3/Lib/test/test_crypt.py 2013-02-19 16:44:20.465334062 -0500 +@@ -10,6 +10,25 @@ class CryptTestCase(unittest.TestCase): + if test_support.verbose: + print 'Test encryption: ', c + ++ def test_salt(self): ++ self.assertEqual(len(crypt._saltchars), 64) ++ for method in crypt.methods: ++ salt = crypt.mksalt(method) ++ self.assertEqual(len(salt), ++ method.salt_chars + (3 if method.ident else 0)) ++ ++ def test_saltedcrypt(self): ++ for method in crypt.methods: ++ pw = crypt.crypt('assword', method) ++ self.assertEqual(len(pw), method.total_size) ++ pw = crypt.crypt('assword', crypt.mksalt(method)) ++ self.assertEqual(len(pw), method.total_size) ++ ++ def test_methods(self): ++ # Gurantee that METHOD_CRYPT is the last method in crypt.methods. ++ self.assertTrue(len(crypt.methods) >= 1) ++ self.assertEqual(crypt.METHOD_CRYPT, crypt.methods[-1]) ++ + def test_main(): + test_support.run_unittest(CryptTestCase) + +diff -up Python-2.7.3/Modules/cryptmodule.c.crypt-module-salt-backport Python-2.7.3/Modules/cryptmodule.c +--- Python-2.7.3/Modules/cryptmodule.c.crypt-module-salt-backport 2012-04-09 19:07:34.000000000 -0400 ++++ Python-2.7.3/Modules/cryptmodule.c 2013-02-19 16:44:20.466334063 -0500 +@@ -43,7 +43,7 @@ static PyMethodDef crypt_methods[] = { + }; + + PyMODINIT_FUNC +-initcrypt(void) ++init_crypt(void) + { +- Py_InitModule("crypt", crypt_methods); ++ Py_InitModule("_crypt", crypt_methods); + } +diff -up Python-2.7.3/Modules/Setup.dist.crypt-module-salt-backport Python-2.7.3/Modules/Setup.dist +--- Python-2.7.3/Modules/Setup.dist.crypt-module-salt-backport 2013-02-19 16:44:20.463334063 -0500 ++++ Python-2.7.3/Modules/Setup.dist 2013-02-19 16:44:20.466334063 -0500 +@@ -221,7 +221,7 @@ _ssl _ssl.c \ + # + # First, look at Setup.config; configure may have set this for you. + +-crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems ++_crypt _cryptmodule.c -lcrypt # crypt(3); needs -lcrypt on some systems + + + # Some more UNIX dependent modules -- off by default, since these +diff -up Python-2.7.3/setup.py.crypt-module-salt-backport Python-2.7.3/setup.py +--- Python-2.7.3/setup.py.crypt-module-salt-backport 2013-02-19 16:44:20.425334067 -0500 ++++ Python-2.7.3/setup.py 2013-02-19 16:44:20.466334063 -0500 +@@ -693,7 +693,7 @@ class PyBuildExt(build_ext): + libs = ['crypt'] + else: + libs = [] +- exts.append( Extension('crypt', ['cryptmodule.c'], libraries=libs) ) ++ exts.append( Extension('_crypt', ['_cryptmodule.c'], libraries=libs) ) + + # CSV files + exts.append( Extension('_csv', ['_csv.c']) ) diff --git a/SOURCES/00166-fix-fake-repr-in-gdb-hooks.patch b/SOURCES/00166-fix-fake-repr-in-gdb-hooks.patch new file mode 100644 index 0000000..bfd2459 --- /dev/null +++ b/SOURCES/00166-fix-fake-repr-in-gdb-hooks.patch @@ -0,0 +1,125 @@ +diff -up Python-2.7.3/Tools/gdb/libpython.py.fix-fake-repr-in-gdb-hooks Python-2.7.3/Tools/gdb/libpython.py +--- Python-2.7.3/Tools/gdb/libpython.py.fix-fake-repr-in-gdb-hooks 2013-02-19 17:21:33.541181366 -0500 ++++ Python-2.7.3/Tools/gdb/libpython.py 2013-02-19 17:21:42.090180782 -0500 +@@ -105,6 +105,24 @@ class TruncatedStringIO(object): + def getvalue(self): + return self._val + ++class FakeProxy(object): ++ """ ++ Class representing a non-descript PyObject* value in the inferior ++ process for when we don't have a custom scraper, intended to have ++ a sane repr(). ++ """ ++ def __init__(self, tp_name, address): ++ self.tp_name = tp_name ++ self.address = address ++ ++ def __repr__(self): ++ # For the NULL pointer, we have no way of knowing a type, so ++ # special-case it as per ++ # http://bugs.python.org/issue8032#msg100882 ++ if self.address == 0: ++ return '0x0' ++ return '<%s at remote 0x%x>' % (self.tp_name, self.address) ++ + class PyObjectPtr(object): + """ + Class wrapping a gdb.Value that's a either a (PyObject*) within the +@@ -232,28 +250,8 @@ class PyObjectPtr(object): + visiting object graphs with loops). Analogous to Py_ReprEnter and + Py_ReprLeave + ''' +- +- class FakeRepr(object): +- """ +- Class representing a non-descript PyObject* value in the inferior +- process for when we don't have a custom scraper, intended to have +- a sane repr(). +- """ +- +- def __init__(self, tp_name, address): +- self.tp_name = tp_name +- self.address = address +- +- def __repr__(self): +- # For the NULL pointer, we have no way of knowing a type, so +- # special-case it as per +- # http://bugs.python.org/issue8032#msg100882 +- if self.address == 0: +- return '0x0' +- return '<%s at remote 0x%x>' % (self.tp_name, self.address) +- +- return FakeRepr(self.safe_tp_name(), +- long(self._gdbval)) ++ return FakeProxy(self.safe_tp_name(), ++ long(self._gdbval)) + + def write_repr(self, out, visited): + ''' +@@ -384,7 +382,7 @@ def _write_instance_repr(out, visited, n + if not first: + out.write(', ') + first = False +- out.write(pyop_arg.proxyval(visited)) ++ out.write(str(pyop_arg.proxyval(visited))) + out.write('=') + pyop_val.write_repr(out, visited) + out.write(')') +@@ -785,6 +783,8 @@ class PyNoneStructPtr(PyObjectPtr): + def proxyval(self, visited): + return None + ++class CantReadFilename(ValueError): ++ pass + + class PyFrameObjectPtr(PyObjectPtr): + _typename = 'PyFrameObject' +@@ -861,7 +861,10 @@ class PyFrameObjectPtr(PyObjectPtr): + '''Get the path of the current Python source file, as a string''' + if self.is_optimized_out(): + return '(frame information optimized out)' +- return self.co_filename.proxyval(set()) ++ value = self.co_filename.proxyval(set()) ++ if isinstance(value, FakeProxy): ++ raise CantReadFilename('unable to extract filename)') ++ return value + + def current_line_num(self): + '''Get current line number as an integer (1-based) +@@ -907,7 +910,7 @@ class PyFrameObjectPtr(PyObjectPtr): + out.write(', ') + first = False + +- out.write(pyop_name.proxyval(visited)) ++ out.write(str(pyop_name.proxyval(visited))) + out.write('=') + pyop_value.write_repr(out, visited) + +@@ -1252,8 +1255,11 @@ class Frame(object): + if pyop: + sys.stdout.write('#%i %s\n' % (self.get_index(), pyop.get_truncated_repr(MAX_OUTPUT_LEN))) + if not pyop.is_optimized_out(): +- line = pyop.current_line() +- sys.stdout.write(' %s\n' % line.strip()) ++ try: ++ line = pyop.current_line() ++ sys.stdout.write(' %s\n' % line.strip()) ++ except CantReadFilename: ++ sys.stdout.write(' %s\n' % '(unable to read filename)') + else: + sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index()) + else: +@@ -1303,7 +1309,11 @@ class PyList(gdb.Command): + print 'Unable to read information on python frame' + return + +- filename = pyop.filename() ++ try: ++ filename = pyop.filename() ++ except CantReadFilename: ++ print "Unable to extract filename from python frame" ++ return + lineno = pyop.current_line_num() + + if start is None: diff --git a/SOURCES/00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch b/SOURCES/00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch new file mode 100644 index 0000000..3fa94fb --- /dev/null +++ b/SOURCES/00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch @@ -0,0 +1,43 @@ +diff -up Python-2.7.3/Lib/test/test_gdb.py.disable-stack-navigation-tests-when-optimized-in-test_gdb Python-2.7.3/Lib/test/test_gdb.py +--- Python-2.7.3/Lib/test/test_gdb.py.disable-stack-navigation-tests-when-optimized-in-test_gdb 2013-02-20 12:27:05.669526425 -0500 ++++ Python-2.7.3/Lib/test/test_gdb.py 2013-02-20 12:27:05.715526422 -0500 +@@ -653,10 +653,10 @@ class PyListTests(DebuggerTests): + ' 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(), +@@ -667,7 +667,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(), +@@ -675,7 +674,6 @@ $''') + self.assertEndsWith(bt, + 'Unable to find a newer python frame\n') + +- @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") + 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(), +@@ -683,9 +681,6 @@ $''') + self.assertEndsWith(bt, + 'Unable to find an older python frame\n') + +- @unittest.skipUnless(HAS_PYUP_PYDOWN, "test requires py-up/py-down commands") +- @unittest.skipIf(python_is_optimized(), +- "Python was compiled with optimizations") + def test_up_then_down(self): + 'Verify "py-up" followed by "py-down"' + bt = self.get_stack_trace(script=self.get_sample_script(), diff --git a/SOURCES/00168-distutils-cflags.patch b/SOURCES/00168-distutils-cflags.patch new file mode 100644 index 0000000..0c4a8df --- /dev/null +++ b/SOURCES/00168-distutils-cflags.patch @@ -0,0 +1,12 @@ +diff -up Python-2.6.6/Lib/distutils/sysconfig.py.distutils-cflags Python-2.6.6/Lib/distutils/sysconfig.py +--- Python-2.6.6/Lib/distutils/sysconfig.py.distutils-cflags 2011-08-12 17:18:17.833091153 -0400 ++++ Python-2.6.6/Lib/distutils/sysconfig.py 2011-08-12 17:18:27.449106938 -0400 +@@ -187,7 +187,7 @@ def customize_compiler(compiler): + if 'LDFLAGS' in os.environ: + ldshared = ldshared + ' ' + os.environ['LDFLAGS'] + if 'CFLAGS' in os.environ: +- cflags = opt + ' ' + os.environ['CFLAGS'] ++ cflags = cflags + ' ' + os.environ['CFLAGS'] + ldshared = ldshared + ' ' + os.environ['CFLAGS'] + if 'CPPFLAGS' in os.environ: + cpp = cpp + ' ' + os.environ['CPPFLAGS'] diff --git a/SOURCES/00169-avoid-implicit-usage-of-md5-in-multiprocessing.patch b/SOURCES/00169-avoid-implicit-usage-of-md5-in-multiprocessing.patch new file mode 100644 index 0000000..debf92f --- /dev/null +++ b/SOURCES/00169-avoid-implicit-usage-of-md5-in-multiprocessing.patch @@ -0,0 +1,41 @@ +diff --git a/Lib/multiprocessing/connection.py b/Lib/multiprocessing/connection.py +--- a/Lib/multiprocessing/connection.py ++++ b/Lib/multiprocessing/connection.py +@@ -41,6 +41,10 @@ + # A very generous timeout when it comes to local connections... + CONNECTION_TIMEOUT = 20. + ++# The hmac module implicitly defaults to using MD5. ++# Support using a stronger algorithm for the challenge/response code: ++HMAC_DIGEST_NAME='sha256' ++ + _mmap_counter = itertools.count() + + default_family = 'AF_INET' +@@ -700,12 +704,16 @@ + WELCOME = b'#WELCOME#' + FAILURE = b'#FAILURE#' + ++def get_digestmod_for_hmac(): ++ import hashlib ++ return getattr(hashlib, HMAC_DIGEST_NAME) ++ + def deliver_challenge(connection, authkey): + import hmac + assert isinstance(authkey, bytes) + message = os.urandom(MESSAGE_LENGTH) + connection.send_bytes(CHALLENGE + message) +- digest = hmac.new(authkey, message).digest() ++ digest = hmac.new(authkey, message, get_digestmod_for_hmac()).digest() + response = connection.recv_bytes(256) # reject large message + if response == digest: + connection.send_bytes(WELCOME) +@@ -719,7 +727,7 @@ + message = connection.recv_bytes(256) # reject large message + assert message[:len(CHALLENGE)] == CHALLENGE, 'message = %r' % message + message = message[len(CHALLENGE):] +- digest = hmac.new(authkey, message).digest() ++ digest = hmac.new(authkey, message, get_digestmod_for_hmac()).digest() + connection.send_bytes(digest) + response = connection.recv_bytes(256) # reject large message + if response != WELCOME: diff --git a/SOURCES/00170-gc-assertions.patch b/SOURCES/00170-gc-assertions.patch new file mode 100644 index 0000000..3fb37ff --- /dev/null +++ b/SOURCES/00170-gc-assertions.patch @@ -0,0 +1,276 @@ +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 @@ + import unittest +-from test.test_support import verbose, run_unittest ++from test.test_support import verbose, run_unittest, import_module + import sys ++import sysconfig + import time + import gc + import weakref +@@ -32,6 +33,8 @@ class GC_Detector(object): + self.wr = weakref.ref(C1055820(666), it_happened) + + ++BUILT_WITH_NDEBUG = ('-DNDEBUG' in sysconfig.get_config_vars()['PY_CFLAGS']) ++ + ### Tests + ############################################################################### + +@@ -476,6 +479,49 @@ class GCTests(unittest.TestCase): + # would be damaged, with an empty __dict__. + self.assertEqual(x, None) + ++ @unittest.skipIf(BUILT_WITH_NDEBUG, ++ 'built with -NDEBUG') ++ def test_refcount_errors(self): ++ # Verify the "handling" of objects with broken refcounts ++ ++ import_module("ctypes") #skip if not supported ++ ++ import subprocess ++ code = '''if 1: ++ a = [] ++ b = [a] ++ ++ # Simulate the refcount of "a" being too low (compared to the ++ # references held on it by live data), but keeping it above zero ++ # (to avoid deallocating it): ++ import ctypes ++ ctypes.pythonapi.Py_DecRef(ctypes.py_object(a)) ++ ++ # The garbage collector should now have a fatal error when it reaches ++ # the broken object: ++ import gc ++ gc.collect() ++ ''' ++ p = subprocess.Popen([sys.executable, "-c", code], ++ stdout=subprocess.PIPE, ++ stderr=subprocess.PIPE) ++ stdout, stderr = p.communicate() ++ p.stdout.close() ++ p.stderr.close() ++ # Verify that stderr has a useful error message: ++ self.assertRegexpMatches(stderr, ++ b'Modules/gcmodule.c:[0-9]+: visit_decref: Assertion "gc->gc.gc_refs != 0" failed.') ++ self.assertRegexpMatches(stderr, ++ b'refcount was too small') ++ self.assertRegexpMatches(stderr, ++ b'object : \[\]') ++ self.assertRegexpMatches(stderr, ++ b'type : list') ++ self.assertRegexpMatches(stderr, ++ b'refcount: 1') ++ self.assertRegexpMatches(stderr, ++ b'address : 0x[0-9a-f]+') ++ + class GCTogglingTests(unittest.TestCase): + def setUp(self): + gc.enable() +diff -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 +@@ -21,6 +21,73 @@ + #include "Python.h" + #include "frameobject.h" /* for PyFrame_ClearFreeList */ + ++/* ++ Define a pair of assertion macros. ++ ++ These work like the regular C assert(), in that they will abort the ++ process with a message on stderr if the given condition fails to hold, ++ but compile away to nothing if NDEBUG is defined. ++ ++ However, before aborting, Python will also try to call _PyObject_Dump() on ++ the given object. This may be of use when investigating bugs in which a ++ particular object is corrupt (e.g. buggy a tp_visit method in an extension ++ module breaking the garbage collector), to help locate the broken objects. ++ ++ The WITH_MSG variant allows you to supply an additional message that Python ++ will attempt to print to stderr, after the object dump. ++*/ ++#ifdef NDEBUG ++/* No debugging: compile away the assertions: */ ++#define PyObject_ASSERT_WITH_MSG(obj, expr, msg) ((void)0) ++#else ++/* With debugging: generate checks: */ ++#define PyObject_ASSERT_WITH_MSG(obj, expr, msg) \ ++ ((expr) \ ++ ? (void)(0) \ ++ : _PyObject_AssertFailed((obj), \ ++ (msg), \ ++ (__STRING(expr)), \ ++ (__FILE__), \ ++ (__LINE__), \ ++ (__PRETTY_FUNCTION__))) ++#endif ++ ++#define PyObject_ASSERT(obj, expr) \ ++ PyObject_ASSERT_WITH_MSG(obj, expr, NULL) ++ ++static void _PyObject_AssertFailed(PyObject *, const char *, ++ const char *, const char *, int, ++ const char *); ++ ++static void ++_PyObject_AssertFailed(PyObject *obj, const char *msg, const char *expr, ++ const char *file, int line, const char *function) ++{ ++ fprintf(stderr, ++ "%s:%d: %s: Assertion \"%s\" failed.\n", ++ file, line, function, expr); ++ if (msg) { ++ fprintf(stderr, "%s\n", msg); ++ } ++ ++ fflush(stderr); ++ ++ if (obj) { ++ /* This might succeed or fail, but we're about to abort, so at least ++ try to provide any extra info we can: */ ++ _PyObject_Dump(obj); ++ } ++ else { ++ fprintf(stderr, "NULL object\n"); ++ } ++ ++ fflush(stdout); ++ fflush(stderr); ++ ++ /* Terminate the process: */ ++ abort(); ++} ++ + /* Get an object's GC head */ + #define AS_GC(o) ((PyGC_Head *)(o)-1) + +@@ -288,7 +355,8 @@ update_refs(PyGC_Head *containers) + { + PyGC_Head *gc = containers->gc.gc_next; + for (; gc != containers; gc = gc->gc.gc_next) { +- assert(gc->gc.gc_refs == GC_REACHABLE); ++ PyObject_ASSERT(FROM_GC(gc), ++ gc->gc.gc_refs == GC_REACHABLE); + gc->gc.gc_refs = Py_REFCNT(FROM_GC(gc)); + /* Python's cyclic gc should never see an incoming refcount + * of 0: if something decref'ed to 0, it should have been +@@ -308,7 +376,8 @@ update_refs(PyGC_Head *containers) + * so serious that maybe this should be a release-build + * check instead of an assert? + */ +- assert(gc->gc.gc_refs != 0); ++ PyObject_ASSERT(FROM_GC(gc), ++ gc->gc.gc_refs != 0); + } + } + +@@ -323,7 +392,9 @@ visit_decref(PyObject *op, void *data) + * generation being collected, which can be recognized + * because only they have positive gc_refs. + */ +- assert(gc->gc.gc_refs != 0); /* else refcount was too small */ ++ PyObject_ASSERT_WITH_MSG(FROM_GC(gc), ++ gc->gc.gc_refs != 0, ++ "refcount was too small"); + if (gc->gc.gc_refs > 0) + gc->gc.gc_refs--; + } +@@ -383,9 +454,10 @@ visit_reachable(PyObject *op, PyGC_Head + * If gc_refs == GC_UNTRACKED, it must be ignored. + */ + else { +- assert(gc_refs > 0 +- || gc_refs == GC_REACHABLE +- || gc_refs == GC_UNTRACKED); ++ PyObject_ASSERT(FROM_GC(gc), ++ gc_refs > 0 ++ || gc_refs == GC_REACHABLE ++ || gc_refs == GC_UNTRACKED); + } + } + return 0; +@@ -427,7 +499,7 @@ move_unreachable(PyGC_Head *young, PyGC_ + */ + PyObject *op = FROM_GC(gc); + traverseproc traverse = Py_TYPE(op)->tp_traverse; +- assert(gc->gc.gc_refs > 0); ++ PyObject_ASSERT(op, gc->gc.gc_refs > 0); + gc->gc.gc_refs = GC_REACHABLE; + (void) traverse(op, + (visitproc)visit_reachable, +@@ -494,7 +566,8 @@ move_finalizers(PyGC_Head *unreachable, + for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) { + PyObject *op = FROM_GC(gc); + +- assert(IS_TENTATIVELY_UNREACHABLE(op)); ++ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op)); ++ + next = gc->gc.gc_next; + + if (has_finalizer(op)) { +@@ -570,7 +643,7 @@ handle_weakrefs(PyGC_Head *unreachable, + PyWeakReference **wrlist; + + op = FROM_GC(gc); +- assert(IS_TENTATIVELY_UNREACHABLE(op)); ++ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op)); + next = gc->gc.gc_next; + + if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) +@@ -591,9 +664,9 @@ handle_weakrefs(PyGC_Head *unreachable, + * the callback pointer intact. Obscure: it also + * changes *wrlist. + */ +- assert(wr->wr_object == op); ++ PyObject_ASSERT(wr->wr_object, wr->wr_object == op); + _PyWeakref_ClearRef(wr); +- assert(wr->wr_object == Py_None); ++ PyObject_ASSERT(wr->wr_object, wr->wr_object == Py_None); + if (wr->wr_callback == NULL) + continue; /* no callback */ + +@@ -627,7 +700,7 @@ handle_weakrefs(PyGC_Head *unreachable, + */ + if (IS_TENTATIVELY_UNREACHABLE(wr)) + continue; +- assert(IS_REACHABLE(wr)); ++ PyObject_ASSERT(op, IS_REACHABLE(wr)); + + /* Create a new reference so that wr can't go away + * before we can process it again. +@@ -636,7 +709,8 @@ handle_weakrefs(PyGC_Head *unreachable, + + /* Move wr to wrcb_to_call, for the next pass. */ + wrasgc = AS_GC(wr); +- assert(wrasgc != next); /* wrasgc is reachable, but ++ PyObject_ASSERT(op, wrasgc != next); ++ /* wrasgc is reachable, but + next isn't, so they can't + be the same */ + gc_list_move(wrasgc, &wrcb_to_call); +@@ -652,11 +726,11 @@ handle_weakrefs(PyGC_Head *unreachable, + + gc = wrcb_to_call.gc.gc_next; + op = FROM_GC(gc); +- assert(IS_REACHABLE(op)); +- assert(PyWeakref_Check(op)); ++ PyObject_ASSERT(op, IS_REACHABLE(op)); ++ PyObject_ASSERT(op, PyWeakref_Check(op)); + wr = (PyWeakReference *)op; + callback = wr->wr_callback; +- assert(callback != NULL); ++ PyObject_ASSERT(op, callback != NULL); + + /* copy-paste of weakrefobject.c's handle_callback() */ + temp = PyObject_CallFunctionObjArgs(callback, wr, NULL); +@@ -759,7 +833,7 @@ delete_garbage(PyGC_Head *collectable, P + PyGC_Head *gc = collectable->gc.gc_next; + PyObject *op = FROM_GC(gc); + +- assert(IS_TENTATIVELY_UNREACHABLE(op)); ++ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op)); + if (debug & DEBUG_SAVEALL) { + PyList_Append(garbage, op); + } diff --git a/SOURCES/00173-workaround-ENOPROTOOPT-in-bind_port.patch b/SOURCES/00173-workaround-ENOPROTOOPT-in-bind_port.patch new file mode 100644 index 0000000..eb34610 --- /dev/null +++ b/SOURCES/00173-workaround-ENOPROTOOPT-in-bind_port.patch @@ -0,0 +1,13 @@ +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 + 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/SOURCES/00174-fix-for-usr-move.patch b/SOURCES/00174-fix-for-usr-move.patch new file mode 100644 index 0000000..b48dc5c --- /dev/null +++ b/SOURCES/00174-fix-for-usr-move.patch @@ -0,0 +1,28 @@ +diff -up Python-2.7.3/Modules/getpath.c.fix-for-usr-move Python-2.7.3/Modules/getpath.c +--- Python-2.7.3/Modules/getpath.c.fix-for-usr-move 2013-03-06 14:25:32.801828698 -0500 ++++ Python-2.7.3/Modules/getpath.c 2013-03-06 15:59:30.872443168 -0500 +@@ -510,6 +510,24 @@ calculate_path(void) + MAXPATHLEN bytes long. + */ + ++ /* ++ Workaround for rhbz#817554, where an empty argv0_path erroneously ++ locates "prefix" as "/lib[64]/python2.7" due to it finding ++ "/lib[64]/python2.7/os.py" via the /lib -> /usr/lib symlink for ++ https://fedoraproject.org/wiki/Features/UsrMove ++ */ ++ if (argv0_path[0] == '\0' && 0 == strcmp(prog, "cmpi_swig")) { ++ /* ++ We have an empty argv0_path, presumably because prog aka ++ Py_GetProgramName() was not found on $PATH. ++ ++ Set argv0_path to "/usr/" so that search_for_prefix() and ++ search_for_exec_prefix() don't erroneously pick up ++ on /lib/ via the UsrMove symlink: ++ */ ++ strcpy(argv0_path, "/usr/"); ++ } ++ + if (!(pfound = search_for_prefix(argv0_path, home))) { + if (!Py_FrozenFlag) + fprintf(stderr, diff --git a/SOURCES/00180-python-add-support-for-ppc64p7.patch b/SOURCES/00180-python-add-support-for-ppc64p7.patch new file mode 100644 index 0000000..022944a --- /dev/null +++ b/SOURCES/00180-python-add-support-for-ppc64p7.patch @@ -0,0 +1,12 @@ +diff -r de35eae9048a config.sub +--- a/config.sub Wed Apr 24 23:33:20 2013 +0200 ++++ b/config.sub Thu Apr 25 08:51:00 2013 +0200 +@@ -1008,7 +1008,7 @@ + ;; + 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 | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown diff --git a/SOURCES/00181-allow-arbitrary-timeout-in-condition-wait.patch b/SOURCES/00181-allow-arbitrary-timeout-in-condition-wait.patch new file mode 100644 index 0000000..665965d --- /dev/null +++ b/SOURCES/00181-allow-arbitrary-timeout-in-condition-wait.patch @@ -0,0 +1,70 @@ +diff --git a/Lib/threading.py b/Lib/threading.py +index cb49c4a..c9795a5 100644 +--- a/Lib/threading.py ++++ b/Lib/threading.py +@@ -305,7 +305,7 @@ class _Condition(_Verbose): + else: + return True + +- def wait(self, timeout=None): ++ def wait(self, timeout=None, balancing=True): + """Wait until notified or until a timeout occurs. + + If the calling thread has not acquired the lock when this method is +@@ -354,7 +354,10 @@ class _Condition(_Verbose): + remaining = endtime - _time() + if remaining <= 0: + break +- delay = min(delay * 2, remaining, .05) ++ if balancing: ++ delay = min(delay * 2, remaining, 0.05) ++ else: ++ delay = remaining + _sleep(delay) + if not gotit: + if __debug__: +@@ -599,7 +602,7 @@ class _Event(_Verbose): + finally: + self.__cond.release() + +- def wait(self, timeout=None): ++ def wait(self, timeout=None, balancing=True): + """Block until the internal flag is true. + + If the internal flag is true on entry, return immediately. Otherwise, +@@ -617,7 +620,7 @@ class _Event(_Verbose): + self.__cond.acquire() + try: + if not self.__flag: +- self.__cond.wait(timeout) ++ self.__cond.wait(timeout, balancing) + return self.__flag + finally: + self.__cond.release() +@@ -908,7 +911,7 @@ class Thread(_Verbose): + if 'dummy_threading' not in _sys.modules: + raise + +- def join(self, timeout=None): ++ def join(self, timeout=None, balancing=True): + """Wait until the thread terminates. + + This blocks the calling thread until the thread whose join() method is +@@ -957,7 +960,7 @@ class Thread(_Verbose): + if __debug__: + self._note("%s.join(): timed out", self) + break +- self.__block.wait(delay) ++ self.__block.wait(delay, balancing) + else: + if __debug__: + self._note("%s.join(): thread stopped", self) +@@ -1143,7 +1146,7 @@ class _DummyThread(Thread): + def _set_daemon(self): + return True + +- def join(self, timeout=None): ++ def join(self, timeout=None, balancing=True): + assert False, "cannot join a dummy thread" + + diff --git a/SOURCES/00184-ctypes-should-build-with-libffi-multilib-wrapper.patch b/SOURCES/00184-ctypes-should-build-with-libffi-multilib-wrapper.patch new file mode 100644 index 0000000..8230986 --- /dev/null +++ b/SOURCES/00184-ctypes-should-build-with-libffi-multilib-wrapper.patch @@ -0,0 +1,13 @@ +diff -up Python-2.7.5/setup.py.orig Python-2.7.5/setup.py +--- Python-2.7.5/setup.py.orig 2013-07-17 15:20:12.086820082 +0200 ++++ Python-2.7.5/setup.py 2013-07-17 15:21:28.490023903 +0200 +@@ -2050,7 +2050,8 @@ class PyBuildExt(build_ext): + 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/SOURCES/00185-urllib2-honors-noproxy-for-ftp.patch b/SOURCES/00185-urllib2-honors-noproxy-for-ftp.patch new file mode 100644 index 0000000..b26c4d4 --- /dev/null +++ b/SOURCES/00185-urllib2-honors-noproxy-for-ftp.patch @@ -0,0 +1,12 @@ +diff -up Python-2.7.5/Lib/urllib2.py.orig Python-2.7.5/Lib/urllib2.py +--- Python-2.7.5/Lib/urllib2.py.orig 2013-07-17 12:22:58.595525622 +0200 ++++ Python-2.7.5/Lib/urllib2.py 2013-07-17 12:19:59.875898030 +0200 +@@ -728,6 +728,8 @@ class ProxyHandler(BaseHandler): + if proxy_type is None: + proxy_type = orig_type + ++ req.get_host() ++ + if req.host and proxy_bypass(req.host): + return None + diff --git a/SOURCES/00186-memory-leak-marshalc.patch b/SOURCES/00186-memory-leak-marshalc.patch new file mode 100644 index 0000000..19fb175 --- /dev/null +++ b/SOURCES/00186-memory-leak-marshalc.patch @@ -0,0 +1,57 @@ +--- Python-2.7.5/Python/marshal.c 2013-05-12 05:32:53.000000000 +0200 ++++ /home/rkuska/hg/cpython/Python/marshal.c 2013-07-18 10:33:26.392486235 +0200 +@@ -88,7 +88,7 @@ + } + + static void +-w_string(char *s, Py_ssize_t n, WFILE *p) ++w_string(const char *s, Py_ssize_t n, WFILE *p) + { + if (p->fp != NULL) { + fwrite(s, 1, n, p->fp); +@@ -141,6 +141,13 @@ + # define W_SIZE w_long + #endif + ++static void ++w_pstring(const char *s, Py_ssize_t n, WFILE *p) ++{ ++ W_SIZE(n, p); ++ w_string(s, n, p); ++} ++ + /* We assume that Python longs are stored internally in base some power of + 2**15; for the sake of portability we'll always read and write them in base + exactly 2**15. */ +@@ -338,9 +345,7 @@ + else { + w_byte(TYPE_STRING, p); + } +- n = PyString_GET_SIZE(v); +- W_SIZE(n, p); +- w_string(PyString_AS_STRING(v), n, p); ++ w_pstring(PyBytes_AS_STRING(v), PyString_GET_SIZE(v), p); + } + #ifdef Py_USING_UNICODE + else if (PyUnicode_CheckExact(v)) { +@@ -352,9 +357,7 @@ + return; + } + w_byte(TYPE_UNICODE, p); +- n = PyString_GET_SIZE(utf8); +- W_SIZE(n, p); +- w_string(PyString_AS_STRING(utf8), n, p); ++ w_pstring(PyString_AS_STRING(utf8), PyString_GET_SIZE(utf8), p); + Py_DECREF(utf8); + } + #endif +@@ -441,8 +444,7 @@ + PyBufferProcs *pb = v->ob_type->tp_as_buffer; + w_byte(TYPE_STRING, p); + n = (*pb->bf_getreadbuffer)(v, 0, (void **)&s); +- W_SIZE(n, p); +- w_string(s, n, p); ++ w_pstring(s, n, p); + } + else { + w_byte(TYPE_UNKNOWN, p); diff --git a/SOURCES/00187-add-RPATH-to-pyexpat.patch b/SOURCES/00187-add-RPATH-to-pyexpat.patch new file mode 100644 index 0000000..0ac5227 --- /dev/null +++ b/SOURCES/00187-add-RPATH-to-pyexpat.patch @@ -0,0 +1,25 @@ +diff -r e8b8279ca118 setup.py +--- a/setup.py Sun Jul 21 21:57:52 2013 -0400 ++++ b/setup.py Tue Aug 20 09:45:31 2013 +0200 +@@ -1480,12 +1480,21 @@ + 'expat/xmltok_impl.h' + ] + ++ # Add an explicit RPATH to pyexpat.so pointing at the directory ++ # containing the system expat (which has the extra XML_SetHashSalt ++ # symbol), to avoid an ImportError with a link error if there's an ++ # LD_LIBRARY_PATH containing a "vanilla" build of expat (without the ++ # symbol) (rhbz#833271): ++ EXPAT_RPATH = '/usr/lib64' if sys.maxint == 0x7fffffffffffffff else '/usr/lib' ++ ++ + exts.append(Extension('pyexpat', + define_macros = define_macros, + include_dirs = expat_inc, + libraries = expat_lib, + sources = ['pyexpat.c'] + expat_sources, + depends = expat_depends, ++ extra_link_args = ['-Wl,-rpath,%s' % EXPAT_RPATH] + )) + + # Fredrik Lundh's cElementTree module. Note that this also diff --git a/SOURCES/00188-CVE-2013-4238-hostname-check-bypass-in-SSL-module.patch b/SOURCES/00188-CVE-2013-4238-hostname-check-bypass-in-SSL-module.patch new file mode 100644 index 0000000..e215589 --- /dev/null +++ b/SOURCES/00188-CVE-2013-4238-hostname-check-bypass-in-SSL-module.patch @@ -0,0 +1,247 @@ +diff -r 9ddc63c039ba Lib/test/nullbytecert.pem +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/Lib/test/nullbytecert.pem Sun Aug 11 18:13:17 2013 +0200 +@@ -0,0 +1,90 @@ ++Certificate: ++ Data: ++ Version: 3 (0x2) ++ Serial Number: 0 (0x0) ++ Signature Algorithm: sha1WithRSAEncryption ++ Issuer: C=US, ST=Oregon, L=Beaverton, O=Python Software Foundation, OU=Python Core Development, CN=null.python.org\x00example.org/emailAddress=python-dev@python.org ++ Validity ++ Not Before: Aug 7 13:11:52 2013 GMT ++ Not After : Aug 7 13:12:52 2013 GMT ++ Subject: C=US, ST=Oregon, L=Beaverton, O=Python Software Foundation, OU=Python Core Development, CN=null.python.org\x00example.org/emailAddress=python-dev@python.org ++ Subject Public Key Info: ++ Public Key Algorithm: rsaEncryption ++ Public-Key: (2048 bit) ++ Modulus: ++ 00:b5:ea:ed:c9:fb:46:7d:6f:3b:76:80:dd:3a:f3: ++ 03:94:0b:a7:a6:db:ec:1d:df:ff:23:74:08:9d:97: ++ 16:3f:a3:a4:7b:3e:1b:0e:96:59:25:03:a7:26:e2: ++ 88:a9:cf:79:cd:f7:04:56:b0:ab:79:32:6e:59:c1: ++ 32:30:54:eb:58:a8:cb:91:f0:42:a5:64:27:cb:d4: ++ 56:31:88:52:ad:cf:bd:7f:f0:06:64:1f:cc:27:b8: ++ a3:8b:8c:f3:d8:29:1f:25:0b:f5:46:06:1b:ca:02: ++ 45:ad:7b:76:0a:9c:bf:bb:b9:ae:0d:16:ab:60:75: ++ ae:06:3e:9c:7c:31:dc:92:2f:29:1a:e0:4b:0c:91: ++ 90:6c:e9:37:c5:90:d7:2a:d7:97:15:a3:80:8f:5d: ++ 7b:49:8f:54:30:d4:97:2c:1c:5b:37:b5:ab:69:30: ++ 68:43:d3:33:78:4b:02:60:f5:3c:44:80:a1:8f:e7: ++ f0:0f:d1:5e:87:9e:46:cf:62:fc:f9:bf:0c:65:12: ++ f1:93:c8:35:79:3f:c8:ec:ec:47:f5:ef:be:44:d5: ++ ae:82:1e:2d:9a:9f:98:5a:67:65:e1:74:70:7c:cb: ++ d3:c2:ce:0e:45:49:27:dc:e3:2d:d4:fb:48:0e:2f: ++ 9e:77:b8:14:46:c0:c4:36:ca:02:ae:6a:91:8c:da: ++ 2f:85 ++ Exponent: 65537 (0x10001) ++ X509v3 extensions: ++ X509v3 Basic Constraints: critical ++ CA:FALSE ++ X509v3 Subject Key Identifier: ++ 88:5A:55:C0:52:FF:61:CD:52:A3:35:0F:EA:5A:9C:24:38:22:F7:5C ++ X509v3 Key Usage: ++ Digital Signature, Non Repudiation, Key Encipherment ++ X509v3 Subject Alternative Name: ++ ************************************************************* ++ WARNING: The values for DNS, email and URI are WRONG. OpenSSL ++ doesn't print the text after a NULL byte. ++ ************************************************************* ++ DNS:altnull.python.org, email:null@python.org, URI:http://null.python.org, IP Address:192.0.2.1, IP Address:2001:DB8:0:0:0:0:0:1 ++ Signature Algorithm: sha1WithRSAEncryption ++ ac:4f:45:ef:7d:49:a8:21:70:8e:88:59:3e:d4:36:42:70:f5: ++ a3:bd:8b:d7:a8:d0:58:f6:31:4a:b1:a4:a6:dd:6f:d9:e8:44: ++ 3c:b6:0a:71:d6:7f:b1:08:61:9d:60:ce:75:cf:77:0c:d2:37: ++ 86:02:8d:5e:5d:f9:0f:71:b4:16:a8:c1:3d:23:1c:f1:11:b3: ++ 56:6e:ca:d0:8d:34:94:e6:87:2a:99:f2:ae:ae:cc:c2:e8:86: ++ de:08:a8:7f:c5:05:fa:6f:81:a7:82:e6:d0:53:9d:34:f4:ac: ++ 3e:40:fe:89:57:7a:29:a4:91:7e:0b:c6:51:31:e5:10:2f:a4: ++ 60:76:cd:95:51:1a:be:8b:a1:b0:fd:ad:52:bd:d7:1b:87:60: ++ d2:31:c7:17:c4:18:4f:2d:08:25:a3:a7:4f:b7:92:ca:e2:f5: ++ 25:f1:54:75:81:9d:b3:3d:61:a2:f7:da:ed:e1:c6:6f:2c:60: ++ 1f:d8:6f:c5:92:05:ab:c9:09:62:49:a9:14:ad:55:11:cc:d6: ++ 4a:19:94:99:97:37:1d:81:5f:8b:cf:a3:a8:96:44:51:08:3d: ++ 0b:05:65:12:eb:b6:70:80:88:48:72:4f:c6:c2:da:cf:cd:8e: ++ 5b:ba:97:2f:60:b4:96:56:49:5e:3a:43:76:63:04:be:2a:f6: ++ c1:ca:a9:94 ++-----BEGIN CERTIFICATE----- ++MIIE2DCCA8CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBxTELMAkGA1UEBhMCVVMx ++DzANBgNVBAgMBk9yZWdvbjESMBAGA1UEBwwJQmVhdmVydG9uMSMwIQYDVQQKDBpQ ++eXRob24gU29mdHdhcmUgRm91bmRhdGlvbjEgMB4GA1UECwwXUHl0aG9uIENvcmUg ++RGV2ZWxvcG1lbnQxJDAiBgNVBAMMG251bGwucHl0aG9uLm9yZwBleGFtcGxlLm9y ++ZzEkMCIGCSqGSIb3DQEJARYVcHl0aG9uLWRldkBweXRob24ub3JnMB4XDTEzMDgw ++NzEzMTE1MloXDTEzMDgwNzEzMTI1MlowgcUxCzAJBgNVBAYTAlVTMQ8wDQYDVQQI ++DAZPcmVnb24xEjAQBgNVBAcMCUJlYXZlcnRvbjEjMCEGA1UECgwaUHl0aG9uIFNv ++ZnR3YXJlIEZvdW5kYXRpb24xIDAeBgNVBAsMF1B5dGhvbiBDb3JlIERldmVsb3Bt ++ZW50MSQwIgYDVQQDDBtudWxsLnB5dGhvbi5vcmcAZXhhbXBsZS5vcmcxJDAiBgkq ++hkiG9w0BCQEWFXB5dGhvbi1kZXZAcHl0aG9uLm9yZzCCASIwDQYJKoZIhvcNAQEB ++BQADggEPADCCAQoCggEBALXq7cn7Rn1vO3aA3TrzA5QLp6bb7B3f/yN0CJ2XFj+j ++pHs+Gw6WWSUDpybiiKnPec33BFawq3kyblnBMjBU61ioy5HwQqVkJ8vUVjGIUq3P ++vX/wBmQfzCe4o4uM89gpHyUL9UYGG8oCRa17dgqcv7u5rg0Wq2B1rgY+nHwx3JIv ++KRrgSwyRkGzpN8WQ1yrXlxWjgI9de0mPVDDUlywcWze1q2kwaEPTM3hLAmD1PESA ++oY/n8A/RXoeeRs9i/Pm/DGUS8ZPINXk/yOzsR/XvvkTVroIeLZqfmFpnZeF0cHzL ++08LODkVJJ9zjLdT7SA4vnne4FEbAxDbKAq5qkYzaL4UCAwEAAaOB0DCBzTAMBgNV ++HRMBAf8EAjAAMB0GA1UdDgQWBBSIWlXAUv9hzVKjNQ/qWpwkOCL3XDALBgNVHQ8E ++BAMCBeAwgZAGA1UdEQSBiDCBhYIeYWx0bnVsbC5weXRob24ub3JnAGV4YW1wbGUu ++Y29tgSBudWxsQHB5dGhvbi5vcmcAdXNlckBleGFtcGxlLm9yZ4YpaHR0cDovL251 ++bGwucHl0aG9uLm9yZwBodHRwOi8vZXhhbXBsZS5vcmeHBMAAAgGHECABDbgAAAAA ++AAAAAAAAAAEwDQYJKoZIhvcNAQEFBQADggEBAKxPRe99SaghcI6IWT7UNkJw9aO9 ++i9eo0Fj2MUqxpKbdb9noRDy2CnHWf7EIYZ1gznXPdwzSN4YCjV5d+Q9xtBaowT0j ++HPERs1ZuytCNNJTmhyqZ8q6uzMLoht4IqH/FBfpvgaeC5tBTnTT0rD5A/olXeimk ++kX4LxlEx5RAvpGB2zZVRGr6LobD9rVK91xuHYNIxxxfEGE8tCCWjp0+3ksri9SXx ++VHWBnbM9YaL32u3hxm8sYB/Yb8WSBavJCWJJqRStVRHM1koZlJmXNx2BX4vPo6iW ++RFEIPQsFZRLrtnCAiEhyT8bC2s/Njlu6ly9gtJZWSV46Q3ZjBL4q9sHKqZQ= ++-----END CERTIFICATE----- +diff -r 9ddc63c039ba Lib/test/test_ssl.py +--- a/Lib/test/test_ssl.py Sun Aug 11 13:04:50 2013 +0300 ++++ b/Lib/test/test_ssl.py Sun Aug 11 18:13:17 2013 +0200 +@@ -25,6 +25,7 @@ + HOST = test_support.HOST + CERTFILE = None + SVN_PYTHON_ORG_ROOT_CERT = None ++NULLBYTECERT = None + + def handle_error(prefix): + exc_format = ' '.join(traceback.format_exception(*sys.exc_info())) +@@ -123,6 +124,27 @@ + ('DNS', 'projects.forum.nokia.com')) + ) + ++ def test_parse_cert_CVE_2013_4073(self): ++ p = ssl._ssl._test_decode_cert(NULLBYTECERT) ++ if test_support.verbose: ++ sys.stdout.write("\n" + pprint.pformat(p) + "\n") ++ subject = ((('countryName', 'US'),), ++ (('stateOrProvinceName', 'Oregon'),), ++ (('localityName', 'Beaverton'),), ++ (('organizationName', 'Python Software Foundation'),), ++ (('organizationalUnitName', 'Python Core Development'),), ++ (('commonName', 'null.python.org\x00example.org'),), ++ (('emailAddress', 'python-dev@python.org'),)) ++ self.assertEqual(p['subject'], subject) ++ self.assertEqual(p['issuer'], subject) ++ self.assertEqual(p['subjectAltName'], ++ (('DNS', 'altnull.python.org\x00example.com'), ++ ('email', 'null@python.org\x00user@example.org'), ++ ('URI', 'http://null.python.org\x00http://example.org'), ++ ('IP Address', '192.0.2.1'), ++ ('IP Address', '2001:DB8:0:0:0:0:0:1\n')) ++ ) ++ + def test_DER_to_PEM(self): + with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f: + pem = f.read() +@@ -1360,7 +1382,7 @@ + + + def test_main(verbose=False): +- global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT ++ global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT, NULLBYTECERT + CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir, + "keycert.pem") + SVN_PYTHON_ORG_ROOT_CERT = os.path.join( +@@ -1368,10 +1390,13 @@ + "https_svn_python_org_root.pem") + NOKIACERT = os.path.join(os.path.dirname(__file__) or os.curdir, + "nokia.pem") ++ NULLBYTECERT = os.path.join(os.path.dirname(__file__) or os.curdir, ++ "nullbytecert.pem") + + if (not os.path.exists(CERTFILE) or + not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT) or +- not os.path.exists(NOKIACERT)): ++ not os.path.exists(NOKIACERT) or ++ not os.path.exists(NULLBYTECERT)): + raise test_support.TestFailed("Can't read certificate files!") + + tests = [BasicTests, BasicSocketTests] +diff -r 9ddc63c039ba Modules/_ssl.c +--- a/Modules/_ssl.c Sun Aug 11 13:04:50 2013 +0300 ++++ b/Modules/_ssl.c Sun Aug 11 18:13:17 2013 +0200 +@@ -741,8 +741,13 @@ + + /* get a rendering of each name in the set of names */ + ++ int gntype; ++ ASN1_STRING *as = NULL; ++ + name = sk_GENERAL_NAME_value(names, j); +- if (name->type == GEN_DIRNAME) { ++ gntype = name-> type; ++ switch (gntype) { ++ case GEN_DIRNAME: + + /* we special-case DirName as a tuple of tuples of attributes */ + +@@ -764,11 +769,61 @@ + goto fail; + } + PyTuple_SET_ITEM(t, 1, v); ++ break; + +- } else { ++ case GEN_EMAIL: ++ case GEN_DNS: ++ case GEN_URI: ++ /* GENERAL_NAME_print() doesn't handle NUL bytes in ASN1_string ++ correctly. */ ++ t = PyTuple_New(2); ++ if (t == NULL) ++ goto fail; ++ switch (gntype) { ++ case GEN_EMAIL: ++ v = PyUnicode_FromString("email"); ++ as = name->d.rfc822Name; ++ break; ++ case GEN_DNS: ++ v = PyUnicode_FromString("DNS"); ++ as = name->d.dNSName; ++ break; ++ case GEN_URI: ++ v = PyUnicode_FromString("URI"); ++ as = name->d.uniformResourceIdentifier; ++ break; ++ } ++ if (v == NULL) { ++ Py_DECREF(t); ++ goto fail; ++ } ++ PyTuple_SET_ITEM(t, 0, v); ++ v = PyString_FromStringAndSize((char *)ASN1_STRING_data(as), ++ ASN1_STRING_length(as)); ++ if (v == NULL) { ++ Py_DECREF(t); ++ goto fail; ++ } ++ PyTuple_SET_ITEM(t, 1, v); ++ break; + ++ default: + /* for everything else, we use the OpenSSL print form */ +- ++ switch (gntype) { ++ /* check for new general name type */ ++ case GEN_OTHERNAME: ++ case GEN_X400: ++ case GEN_EDIPARTY: ++ case GEN_IPADD: ++ case GEN_RID: ++ break; ++ default: ++ if (PyErr_Warn(PyExc_RuntimeWarning, ++ "Unknown general name type") == -1) { ++ goto fail; ++ } ++ break; ++ } + (void) BIO_reset(biobuf); + GENERAL_NAME_print(biobuf, name); + len = BIO_gets(biobuf, buf, sizeof(buf)-1); +@@ -794,6 +849,7 @@ + goto fail; + } + PyTuple_SET_ITEM(t, 1, v); ++ break; + } + + /* and add that rendering to the list */ diff --git a/SOURCES/00189-gdb-py-bt-dont-raise-exception-from-eval.patch b/SOURCES/00189-gdb-py-bt-dont-raise-exception-from-eval.patch new file mode 100644 index 0000000..4e82859 --- /dev/null +++ b/SOURCES/00189-gdb-py-bt-dont-raise-exception-from-eval.patch @@ -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() == '': ++ return '(in an eval block)' + with open(self.filename(), 'r') as f: + all_lines = f.readlines() + # Convert from 1-based current_line_num to 0-based list offset: diff --git a/SOURCES/00190-gdb-fix-ppc64-failures.patch b/SOURCES/00190-gdb-fix-ppc64-failures.patch new file mode 100644 index 0000000..9bb723f --- /dev/null +++ b/SOURCES/00190-gdb-fix-ppc64-failures.patch @@ -0,0 +1,207 @@ +--- Tools/gdb/libpython.py.orig 2013-10-09 10:54:59.894701668 +0200 ++++ Tools/gdb/libpython.py 2013-10-09 11:09:30.278703290 +0200 +@@ -1194,39 +1194,113 @@ + iter_frame = iter_frame.newer() + return index + ++ # We divide frames into: ++ # - "python frames": ++ # - "bytecode frames" i.e. PyEval_EvalFrameEx ++ # - "other python frames": things that are of interest from a python ++ # POV, but aren't bytecode (e.g. GC, GIL) ++ # - everything else ++ ++ def is_python_frame(self): ++ '''Is this a PyEval_EvalFrameEx frame, or some other important ++ frame? (see is_other_python_frame for what "important" means in this ++ context)''' ++ if self.is_evalframeex(): ++ return True ++ if self.is_other_python_frame(): ++ return True ++ return False ++ + def is_evalframeex(self): +- '''Is this a PyEval_EvalFrameEx frame?''' +- if self._gdbframe.name() == 'PyEval_EvalFrameEx': +- ''' +- I believe we also need to filter on the inline +- struct frame_id.inline_depth, only regarding frames with +- an inline depth of 0 as actually being this function +- +- So we reject those with type gdb.INLINE_FRAME +- ''' +- if self._gdbframe.type() == gdb.NORMAL_FRAME: +- # We have a PyEval_EvalFrameEx frame: +- return True ++ if self._gdbframe.function(): ++ if self._gdbframe.function().name == 'PyEval_EvalFrameEx': ++ ''' ++ I believe we also need to filter on the inline ++ struct frame_id.inline_depth, only regarding frames with ++ an inline depth of 0 as actually being this function ++ ++ So we reject those with type gdb.INLINE_FRAME ++ ''' ++ if self._gdbframe.type() == gdb.NORMAL_FRAME: ++ # We have a PyEval_EvalFrameEx frame: ++ return True ++ ++ return False ++ ++ def is_other_python_frame(self): ++ '''Is this frame worth displaying in python backtraces? ++ Examples: ++ - waiting on the GIL ++ - garbage-collecting ++ - within a CFunction ++ If it is, return a descriptive string ++ For other frames, return False ++ ''' ++ if self.is_waiting_for_gil(): ++ return 'Waiting for a lock (e.g. GIL)' ++ elif self.is_gc_collect(): ++ return 'Garbage-collecting' ++ else: ++ # Detect invocations of PyCFunction instances: ++ if self._gdbframe.name() == 'PyCFunction_Call': ++ try: ++ func = self._gdbframe.read_var('func') ++ # Use the prettyprinter for the func: ++ return str(func) ++ except RuntimeError: ++ return 'PyCFunction invocation (unable to read "func")' ++ older = self.older() ++ if older and older._gdbframe.name() == 'call_function': ++ # Within that frame: ++ # 'call_function' contains, amongst other things, a ++ # hand-inlined copy of PyCFunction_Call. ++ # "func" is the local containing the PyObject* of the ++ # callable instance ++ # Report it, but only if it's a PyCFunction (since otherwise ++ # we'd be reporting an implementation detail of every other ++ # function invocation) ++ try: ++ func = older._gdbframe.read_var('func') ++ funcobj = PyObjectPtr.from_pyobject_ptr(func) ++ if isinstance(funcobj, PyCFunctionObjectPtr): ++ # Use the prettyprinter for the func: ++ return str(func) ++ except RuntimeError: ++ return False + ++ # This frame isn't worth reporting: + return False + ++ def is_waiting_for_gil(self): ++ '''Is this frame waiting for a lock?''' ++ framename = self._gdbframe.name() ++ if framename: ++ return 'pthread_cond_timedwait' in framename or \ ++ 'PyThread_acquire_lock' in framename ++ ++ def is_gc_collect(self): ++ '''Is this frame "collect" within the the garbage-collector?''' ++ return self._gdbframe.name() == 'collect' ++ + def get_pyop(self): + try: + f = self._gdbframe.read_var('f') +- frame = PyFrameObjectPtr.from_pyobject_ptr(f) +- if not frame.is_optimized_out(): +- return frame +- # gdb is unable to get the "f" argument of PyEval_EvalFrameEx() +- # because it was "optimized out". Try to get "f" from the frame +- # of the caller, PyEval_EvalCodeEx(). +- orig_frame = frame +- caller = self._gdbframe.older() +- if caller: +- f = caller.read_var('f') +- frame = PyFrameObjectPtr.from_pyobject_ptr(f) +- if not frame.is_optimized_out(): +- return frame +- return orig_frame ++ obj = PyFrameObjectPtr.from_pyobject_ptr(f) ++ if isinstance(obj, PyFrameObjectPtr): ++ return obj ++ else: ++ return None ++ except ValueError: ++ return None ++ ++ def get_py_co(self): ++ try: ++ co = self._gdbframe.read_var('co') ++ obj = PyCodeObjectPtr.from_pyobject_ptr(co) ++ if isinstance(obj, PyCodeObjectPtr): ++ return obj ++ else: ++ return None + except ValueError: + return None + +@@ -1239,8 +1313,22 @@ + + @classmethod + def get_selected_python_frame(cls): +- '''Try to obtain the Frame for the python code in the selected frame, +- or None''' ++ '''Try to obtain the Frame for the python-related code in the selected ++ frame, or None''' ++ frame = cls.get_selected_frame() ++ ++ while frame: ++ if frame.is_python_frame(): ++ return frame ++ frame = frame.older() ++ ++ # Not found: ++ return None ++ ++ @classmethod ++ def get_selected_bytecode_frame(cls): ++ '''Try to obtain the Frame for the python bytecode interpreter in the ++ selected GDB frame, or None''' + frame = cls.get_selected_frame() + + while frame: +@@ -1265,7 +1353,11 @@ + else: + sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index()) + else: +- sys.stdout.write('#%i\n' % self.get_index()) ++ info = self.is_other_python_frame() ++ if info: ++ sys.stdout.write('#%i %s\n' % (self.get_index(), info)) ++ else: ++ sys.stdout.write('#%i\n' % self.get_index()) + + class PyList(gdb.Command): + '''List the current Python source code, if any +@@ -1301,7 +1393,7 @@ + if m: + start, end = map(int, m.groups()) + +- frame = Frame.get_selected_python_frame() ++ frame = Frame.get_selected_bytecode_frame() + if not frame: + print 'Unable to locate python frame' + return +@@ -1353,7 +1445,7 @@ + if not iter_frame: + break + +- if iter_frame.is_evalframeex(): ++ if iter_frame.is_python_frame(): + # Result: + if iter_frame.select(): + iter_frame.print_summary() +@@ -1407,7 +1499,7 @@ + def invoke(self, args, from_tty): + frame = Frame.get_selected_python_frame() + while frame: +- if frame.is_evalframeex(): ++ if frame.is_python_frame(): + frame.print_summary() + frame = frame.older() + diff --git a/SOURCES/00191-add-RPATH-to-elementtree.patch b/SOURCES/00191-add-RPATH-to-elementtree.patch new file mode 100644 index 0000000..10cd585 --- /dev/null +++ b/SOURCES/00191-add-RPATH-to-elementtree.patch @@ -0,0 +1,21 @@ +diff -up Python-2.7.5/setup.py.orig Python-2.7.5/setup.py +--- Python-2.7.5/setup.py.orig 2013-11-07 01:36:18.853604232 +0100 ++++ Python-2.7.5/setup.py 2013-11-07 01:39:22.163305821 +0100 +@@ -1483,6 +1483,9 @@ class PyBuildExt(build_ext): + # Fredrik Lundh's cElementTree module. Note that this also + # uses expat (via the CAPI hook in pyexpat). + ++ # Add an explicit RPATH to _elementtree.so (rhbz#1019345) ++ EXPAT_RPATH = '/usr/lib64' if sys.maxint == 0x7fffffffffffffff else '/usr/lib' ++ + if os.path.isfile(os.path.join(srcdir, 'Modules', '_elementtree.c')): + define_macros.append(('USE_PYEXPAT_CAPI', None)) + exts.append(Extension('_elementtree', +@@ -1492,6 +1495,7 @@ class PyBuildExt(build_ext): + sources = ['_elementtree.c'], + depends = ['pyexpat.c'] + expat_sources + + expat_depends, ++ extra_link_args = ['-Wl,-rpath,%s' % EXPAT_RPATH] + )) + else: + missing.append('_elementtree') diff --git a/SOURCES/00192-Fix-missing-documentation-for-some-keywords.patch b/SOURCES/00192-Fix-missing-documentation-for-some-keywords.patch new file mode 100644 index 0000000..d40f0b0 --- /dev/null +++ b/SOURCES/00192-Fix-missing-documentation-for-some-keywords.patch @@ -0,0 +1,42 @@ +diff --git a/Doc/tools/sphinxext/pyspecific.py b/Doc/tools/sphinxext/pyspecific.py +--- a/Doc/tools/sphinxext/pyspecific.py ++++ b/Doc/tools/sphinxext/pyspecific.py +@@ -184,11 +184,11 @@ + 'bltin-null-object', 'bltin-type-objects', 'booleans', + 'break', 'callable-types', 'calls', 'class', 'comparisons', 'compound', + 'context-managers', 'continue', 'conversions', 'customization', 'debugger', +- 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'execmodel', ++ 'del', 'dict', 'dynamic-features', 'else', 'exceptions', 'exec', 'execmodel', + 'exprlists', 'floating', 'for', 'formatstrings', 'function', 'global', + 'id-classes', 'identifiers', 'if', 'imaginary', 'import', 'in', 'integers', + 'lambda', 'lists', 'naming', 'numbers', 'numeric-types', +- 'objects', 'operator-summary', 'pass', 'power', 'raise', 'return', ++ 'objects', 'operator-summary', 'pass', 'power', 'print', 'raise', 'return', + 'sequence-types', 'shifting', 'slicings', 'specialattrs', 'specialnames', + 'string-methods', 'strings', 'subscriptions', 'truth', 'try', 'types', + 'typesfunctions', 'typesmapping', 'typesmethods', 'typesmodules', +diff -up Python-2.7.5/Lib/pydoc_data/topics.py.orig Python-2.7.5/Lib/pydoc_data/topics.py +--- Python-2.7.5/Lib/pydoc_data/topics.py.orig 2014-01-14 12:29:32.511756259 +0100 ++++ Python-2.7.5/Lib/pydoc_data/topics.py 2014-01-14 12:29:40.396795516 +0100 +@@ -29,11 +29,12 @@ topics = {'assert': '\nThe ``assert`` st + 'dynamic-features': '\nInteraction with dynamic features\n*********************************\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n', + 'else': '\nThe ``if`` statement\n********************\n\nThe ``if`` statement is used for conditional execution:\n\n if_stmt ::= "if" expression ":" suite\n ( "elif" expression ":" suite )*\n ["else" ":" suite]\n\nIt selects exactly one of the suites by evaluating the expressions one\nby one until one is found to be true (see section *Boolean operations*\nfor the definition of true and false); then that suite is executed\n(and no other part of the ``if`` statement is executed or evaluated).\nIf all expressions are false, the suite of the ``else`` clause, if\npresent, is executed.\n', + 'exceptions': '\nExceptions\n**********\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', ++'exec': '\nThe ``exec`` statement\n**********************\n\n exec_stmt ::= "exec" or_expr ["in" expression ["," expression]]\n\nThis statement supports dynamic execution of Python code. The first\nexpression should evaluate to either a Unicode string, a *Latin-1*\nencoded string, an open file object, a code object, or a tuple. If it\nis a string, the string is parsed as a suite of Python statements\nwhich is then executed (unless a syntax error occurs). [1] If it is an\nopen file, the file is parsed until EOF and executed. If it is a code\nobject, it is simply executed. For the interpretation of a tuple, see\nbelow. In all cases, the code that\'s executed is expected to be valid\nas file input (see section *File input*). Be aware that the\n``return`` and ``yield`` statements may not be used outside of\nfunction definitions even within the context of code passed to the\n``exec`` statement.\n\nIn all cases, if the optional parts are omitted, the code is executed\nin the current scope. If only the first expression after ``in`` is\nspecified, it should be a dictionary, which will be used for both the\nglobal and the local variables. If two expressions are given, they\nare used for the global and local variables, respectively. If\nprovided, *locals* can be any mapping object. Remember that at module\nlevel, globals and locals are the same dictionary. If two separate\nobjects are given as *globals* and *locals*, the code will be executed\nas if it were embedded in a class definition.\n\nThe first expression may also be a tuple of length 2 or 3. In this\ncase, the optional parts must be omitted. The form ``exec(expr,\nglobals)`` is equivalent to ``exec expr in globals``, while the form\n``exec(expr, globals, locals)`` is equivalent to ``exec expr in\nglobals, locals``. The tuple form of ``exec`` provides compatibility\nwith Python 3, where ``exec`` is a function rather than a statement.\n\nChanged in version 2.4: Formerly, *locals* was required to be a\ndictionary.\n\nAs a side effect, an implementation may insert additional keys into\nthe dictionaries given besides those corresponding to variable names\nset by the executed code. For example, the current implementation may\nadd a reference to the dictionary of the built-in module\n``__builtin__`` under the key ``__builtins__`` (!).\n\n**Programmer\'s hints:** dynamic evaluation of expressions is supported\nby the built-in function ``eval()``. The built-in functions\n``globals()`` and ``locals()`` return the current global and local\ndictionary, respectively, which may be useful to pass around for use\nby ``exec``.\n\n-[ Footnotes ]-\n\n[1] Note that the parser only accepts the Unix-style end of line\n convention. If you are reading the code from a file, make sure to\n use *universal newlines* mode to convert Windows or Mac-style\n newlines.\n', + 'execmodel': '\nExecution model\n***************\n\n\nNaming and binding\n==================\n\n*Names* refer to objects. Names are introduced by name binding\noperations. Each occurrence of a name in the program text refers to\nthe *binding* of that name established in the innermost function block\ncontaining the use.\n\nA *block* is a piece of Python program text that is executed as a\nunit. The following are blocks: a module, a function body, and a class\ndefinition. Each command typed interactively is a block. A script\nfile (a file given as standard input to the interpreter or specified\non the interpreter command line the first argument) is a code block.\nA script command (a command specified on the interpreter command line\nwith the \'**-c**\' option) is a code block. The file read by the\nbuilt-in function ``execfile()`` is a code block. The string argument\npassed to the built-in function ``eval()`` and to the ``exec``\nstatement is a code block. The expression read and evaluated by the\nbuilt-in function ``input()`` is a code block.\n\nA code block is executed in an *execution frame*. A frame contains\nsome administrative information (used for debugging) and determines\nwhere and how execution continues after the code block\'s execution has\ncompleted.\n\nA *scope* defines the visibility of a name within a block. If a local\nvariable is defined in a block, its scope includes that block. If the\ndefinition occurs in a function block, the scope extends to any blocks\ncontained within the defining one, unless a contained block introduces\na different binding for the name. The scope of names defined in a\nclass block is limited to the class block; it does not extend to the\ncode blocks of methods -- this includes generator expressions since\nthey are implemented using a function scope. This means that the\nfollowing will fail:\n\n class A:\n a = 42\n b = list(a + i for i in range(10))\n\nWhen a name is used in a code block, it is resolved using the nearest\nenclosing scope. The set of all such scopes visible to a code block\nis called the block\'s *environment*.\n\nIf a name is bound in a block, it is a local variable of that block.\nIf a name is bound at the module level, it is a global variable. (The\nvariables of the module code block are local and global.) If a\nvariable is used in a code block but not defined there, it is a *free\nvariable*.\n\nWhen a name is not found at all, a ``NameError`` exception is raised.\nIf the name refers to a local variable that has not been bound, a\n``UnboundLocalError`` exception is raised. ``UnboundLocalError`` is a\nsubclass of ``NameError``.\n\nThe following constructs bind names: formal parameters to functions,\n``import`` statements, class and function definitions (these bind the\nclass or function name in the defining block), and targets that are\nidentifiers if occurring in an assignment, ``for`` loop header, in the\nsecond position of an ``except`` clause header or after ``as`` in a\n``with`` statement. The ``import`` statement of the form ``from ...\nimport *`` binds all names defined in the imported module, except\nthose beginning with an underscore. This form may only be used at the\nmodule level.\n\nA target occurring in a ``del`` statement is also considered bound for\nthis purpose (though the actual semantics are to unbind the name). It\nis illegal to unbind a name that is referenced by an enclosing scope;\nthe compiler will report a ``SyntaxError``.\n\nEach assignment or import statement occurs within a block defined by a\nclass or function definition or at the module level (the top-level\ncode block).\n\nIf a name binding operation occurs anywhere within a code block, all\nuses of the name within the block are treated as references to the\ncurrent block. This can lead to errors when a name is used within a\nblock before it is bound. This rule is subtle. Python lacks\ndeclarations and allows name binding operations to occur anywhere\nwithin a code block. The local variables of a code block can be\ndetermined by scanning the entire text of the block for name binding\noperations.\n\nIf the global statement occurs within a block, all uses of the name\nspecified in the statement refer to the binding of that name in the\ntop-level namespace. Names are resolved in the top-level namespace by\nsearching the global namespace, i.e. the namespace of the module\ncontaining the code block, and the builtins namespace, the namespace\nof the module ``__builtin__``. The global namespace is searched\nfirst. If the name is not found there, the builtins namespace is\nsearched. The global statement must precede all uses of the name.\n\nThe builtins namespace associated with the execution of a code block\nis actually found by looking up the name ``__builtins__`` in its\nglobal namespace; this should be a dictionary or a module (in the\nlatter case the module\'s dictionary is used). By default, when in the\n``__main__`` module, ``__builtins__`` is the built-in module\n``__builtin__`` (note: no \'s\'); when in any other module,\n``__builtins__`` is an alias for the dictionary of the ``__builtin__``\nmodule itself. ``__builtins__`` can be set to a user-created\ndictionary to create a weak form of restricted execution.\n\n**CPython implementation detail:** Users should not touch\n``__builtins__``; it is strictly an implementation detail. Users\nwanting to override values in the builtins namespace should ``import``\nthe ``__builtin__`` (no \'s\') module and modify its attributes\nappropriately.\n\nThe namespace for a module is automatically created the first time a\nmodule is imported. The main module for a script is always called\n``__main__``.\n\nThe ``global`` statement has the same scope as a name binding\noperation in the same block. If the nearest enclosing scope for a\nfree variable contains a global statement, the free variable is\ntreated as a global.\n\nA class definition is an executable statement that may use and define\nnames. These references follow the normal rules for name resolution.\nThe namespace of the class definition becomes the attribute dictionary\nof the class. Names defined at the class scope are not visible in\nmethods.\n\n\nInteraction with dynamic features\n---------------------------------\n\nThere are several cases where Python statements are illegal when used\nin conjunction with nested scopes that contain free variables.\n\nIf a variable is referenced in an enclosing scope, it is illegal to\ndelete the name. An error will be reported at compile time.\n\nIf the wild card form of import --- ``import *`` --- is used in a\nfunction and the function contains or is a nested block with free\nvariables, the compiler will raise a ``SyntaxError``.\n\nIf ``exec`` is used in a function and the function contains or is a\nnested block with free variables, the compiler will raise a\n``SyntaxError`` unless the exec explicitly specifies the local\nnamespace for the ``exec``. (In other words, ``exec obj`` would be\nillegal, but ``exec obj in ns`` would be legal.)\n\nThe ``eval()``, ``execfile()``, and ``input()`` functions and the\n``exec`` statement do not have access to the full environment for\nresolving names. Names may be resolved in the local and global\nnamespaces of the caller. Free variables are not resolved in the\nnearest enclosing namespace, but in the global namespace. [1] The\n``exec`` statement and the ``eval()`` and ``execfile()`` functions\nhave optional arguments to override the global and local namespace.\nIf only one namespace is specified, it is used for both.\n\n\nExceptions\n==========\n\nExceptions are a means of breaking out of the normal flow of control\nof a code block in order to handle errors or other exceptional\nconditions. An exception is *raised* at the point where the error is\ndetected; it may be *handled* by the surrounding code block or by any\ncode block that directly or indirectly invoked the code block where\nthe error occurred.\n\nThe Python interpreter raises an exception when it detects a run-time\nerror (such as division by zero). A Python program can also\nexplicitly raise an exception with the ``raise`` statement. Exception\nhandlers are specified with the ``try`` ... ``except`` statement. The\n``finally`` clause of such a statement can be used to specify cleanup\ncode which does not handle the exception, but is executed whether an\nexception occurred or not in the preceding code.\n\nPython uses the "termination" model of error handling: an exception\nhandler can find out what happened and continue execution at an outer\nlevel, but it cannot repair the cause of the error and retry the\nfailing operation (except by re-entering the offending piece of code\nfrom the top).\n\nWhen an exception is not handled at all, the interpreter terminates\nexecution of the program, or returns to its interactive main loop. In\neither case, it prints a stack backtrace, except when the exception is\n``SystemExit``.\n\nExceptions are identified by class instances. The ``except`` clause\nis selected depending on the class of the instance: it must reference\nthe class of the instance or a base class thereof. The instance can\nbe received by the handler and can carry additional information about\nthe exceptional condition.\n\nExceptions can also be identified by strings, in which case the\n``except`` clause is selected by object identity. An arbitrary value\ncan be raised along with the identifying string which can be passed to\nthe handler.\n\nNote: Messages to exceptions are not part of the Python API. Their\n contents may change from one version of Python to the next without\n warning and should not be relied on by code which will run under\n multiple versions of the interpreter.\n\nSee also the description of the ``try`` statement in section *The try\nstatement* and ``raise`` statement in section *The raise statement*.\n\n-[ Footnotes ]-\n\n[1] This limitation occurs because the code that is executed by these\n operations is not available at the time the module is compiled.\n', + 'exprlists': '\nExpression lists\n****************\n\n expression_list ::= expression ( "," expression )* [","]\n\nAn expression list containing at least one comma yields a tuple. The\nlength of the tuple is the number of expressions in the list. The\nexpressions are evaluated from left to right.\n\nThe trailing comma is required only to create a single tuple (a.k.a. a\n*singleton*); it is optional in all other cases. A single expression\nwithout a trailing comma doesn\'t create a tuple, but rather yields the\nvalue of that expression. (To create an empty tuple, use an empty pair\nof parentheses: ``()``.)\n', + 'floating': '\nFloating point literals\n***********************\n\nFloating point literals are described by the following lexical\ndefinitions:\n\n floatnumber ::= pointfloat | exponentfloat\n pointfloat ::= [intpart] fraction | intpart "."\n exponentfloat ::= (intpart | pointfloat) exponent\n intpart ::= digit+\n fraction ::= "." digit+\n exponent ::= ("e" | "E") ["+" | "-"] digit+\n\nNote that the integer and exponent parts of floating point numbers can\nlook like octal integers, but are interpreted using radix 10. For\nexample, ``077e010`` is legal, and denotes the same number as\n``77e10``. The allowed range of floating point literals is\nimplementation-dependent. Some examples of floating point literals:\n\n 3.14 10. .001 1e100 3.14e-10 0e0\n\nNote that numeric literals do not include a sign; a phrase like ``-1``\nis actually an expression composed of the unary operator ``-`` and the\nliteral ``1``.\n', + 'for': '\nThe ``for`` statement\n*********************\n\nThe ``for`` statement is used to iterate over the elements of a\nsequence (such as a string, tuple or list) or other iterable object:\n\n for_stmt ::= "for" target_list "in" expression_list ":" suite\n ["else" ":" suite]\n\nThe expression list is evaluated once; it should yield an iterable\nobject. An iterator is created for the result of the\n``expression_list``. The suite is then executed once for each item\nprovided by the iterator, in the order of ascending indices. Each\nitem in turn is assigned to the target list using the standard rules\nfor assignments, and then the suite is executed. When the items are\nexhausted (which is immediately when the sequence is empty), the suite\nin the ``else`` clause, if present, is executed, and the loop\nterminates.\n\nA ``break`` statement executed in the first suite terminates the loop\nwithout executing the ``else`` clause\'s suite. A ``continue``\nstatement executed in the first suite skips the rest of the suite and\ncontinues with the next item, or with the ``else`` clause if there was\nno next item.\n\nThe suite may assign to the variable(s) in the target list; this does\nnot affect the next item assigned to it.\n\nThe target list is not deleted when the loop is finished, but if the\nsequence is empty, it will not have been assigned to at all by the\nloop. Hint: the built-in function ``range()`` returns a sequence of\nintegers suitable to emulate the effect of Pascal\'s ``for i := a to b\ndo``; e.g., ``range(3)`` returns the list ``[0, 1, 2]``.\n\nNote: There is a subtlety when the sequence is being modified by the loop\n (this can only occur for mutable sequences, i.e. lists). An internal\n counter is used to keep track of which item is used next, and this\n is incremented on each iteration. When this counter has reached the\n length of the sequence the loop terminates. This means that if the\n suite deletes the current (or a previous) item from the sequence,\n the next item will be skipped (since it gets the index of the\n current item which has already been treated). Likewise, if the\n suite inserts an item in the sequence before the current item, the\n current item will be treated again the next time through the loop.\n This can lead to nasty bugs that can be avoided by making a\n temporary copy using a slice of the whole sequence, e.g.,\n\n for x in a[:]:\n if x < 0: a.remove(x)\n', +- 'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings ``\'10\'`` or\n``\':-]\'``) within a format string. The *arg_name* can be followed by\nany number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nChanged in version 2.7: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nThe *fill* character can be any character other than \'{\' or \'}\'. The\npresence of a fill character is signaled by the character following\nit, which must be one of the alignment options. If the second\ncharacter of *format_spec* is not a valid alignment option, then it is\nassumed that both the fill character and the alignment option are\nabsent.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 2.7: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero (``\'0\'``) character enables\nsign-aware zero-padding for numeric types. This is equivalent to a\n*fill* character of ``\'0\'`` with an *alignment* type of ``\'=\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Positive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 2.7+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point(object):\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19.5\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 88.64%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print \'{0:{width}{base}}\'.format(num, base=base, width=width),\n ... print\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', ++ 'formatstrings': '\nFormat String Syntax\n********************\n\nThe ``str.format()`` method and the ``Formatter`` class share the same\nsyntax for format strings (although in the case of ``Formatter``,\nsubclasses can define their own format string syntax).\n\nFormat strings contain "replacement fields" surrounded by curly braces\n``{}``. Anything that is not contained in braces is considered literal\ntext, which is copied unchanged to the output. If you need to include\na brace character in the literal text, it can be escaped by doubling:\n``{{`` and ``}}``.\n\nThe grammar for a replacement field is as follows:\n\n replacement_field ::= "{" [field_name] ["!" conversion] [":" format_spec] "}"\n field_name ::= arg_name ("." attribute_name | "[" element_index "]")*\n arg_name ::= [identifier | integer]\n attribute_name ::= identifier\n element_index ::= integer | index_string\n index_string ::= +\n conversion ::= "r" | "s"\n format_spec ::= \n\nIn less formal terms, the replacement field can start with a\n*field_name* that specifies the object whose value is to be formatted\nand inserted into the output instead of the replacement field. The\n*field_name* is optionally followed by a *conversion* field, which is\npreceded by an exclamation point ``\'!\'``, and a *format_spec*, which\nis preceded by a colon ``\':\'``. These specify a non-default format\nfor the replacement value.\n\nSee also the *Format Specification Mini-Language* section.\n\nThe *field_name* itself begins with an *arg_name* that is either a\nnumber or a keyword. If it\'s a number, it refers to a positional\nargument, and if it\'s a keyword, it refers to a named keyword\nargument. If the numerical arg_names in a format string are 0, 1, 2,\n... in sequence, they can all be omitted (not just some) and the\nnumbers 0, 1, 2, ... will be automatically inserted in that order.\nBecause *arg_name* is not quote-delimited, it is not possible to\nspecify arbitrary dictionary keys (e.g., the strings ``\'10\'`` or\n``\':-]\'``) within a format string. The *arg_name* can be followed by\nany number of index or attribute expressions. An expression of the\nform ``\'.name\'`` selects the named attribute using ``getattr()``,\nwhile an expression of the form ``\'[index]\'`` does an index lookup\nusing ``__getitem__()``.\n\nChanged in version 2.7: The positional argument specifiers can be\nomitted, so ``\'{} {}\'`` is equivalent to ``\'{0} {1}\'``.\n\nSome simple format string examples:\n\n "First, thou shalt count to {0}" # References first positional argument\n "Bring me a {}" # Implicitly references the first positional argument\n "From {} to {}" # Same as "From {0} to {1}"\n "My quest is {name}" # References keyword argument \'name\'\n "Weight in tons {0.weight}" # \'weight\' attribute of first positional arg\n "Units destroyed: {players[0]}" # First element of keyword argument \'players\'.\n\nThe *conversion* field causes a type coercion before formatting.\nNormally, the job of formatting a value is done by the\n``__format__()`` method of the value itself. However, in some cases\nit is desirable to force a type to be formatted as a string,\noverriding its own definition of formatting. By converting the value\nto a string before calling ``__format__()``, the normal formatting\nlogic is bypassed.\n\nTwo conversion flags are currently supported: ``\'!s\'`` which calls\n``str()`` on the value, and ``\'!r\'`` which calls ``repr()``.\n\nSome examples:\n\n "Harold\'s a clever {0!s}" # Calls str() on the argument first\n "Bring out the holy {name!r}" # Calls repr() on the argument first\n\nThe *format_spec* field contains a specification of how the value\nshould be presented, including such details as field width, alignment,\npadding, decimal precision and so on. Each value type can define its\nown "formatting mini-language" or interpretation of the *format_spec*.\n\nMost built-in types support a common formatting mini-language, which\nis described in the next section.\n\nA *format_spec* field can also include nested replacement fields\nwithin it. These nested replacement fields can contain only a field\nname; conversion flags and format specifications are not allowed. The\nreplacement fields within the format_spec are substituted before the\n*format_spec* string is interpreted. This allows the formatting of a\nvalue to be dynamically specified.\n\nSee the *Format examples* section for some examples.\n\n\nFormat Specification Mini-Language\n==================================\n\n"Format specifications" are used within replacement fields contained\nwithin a format string to define how individual values are presented\n(see *Format String Syntax*). They can also be passed directly to the\nbuilt-in ``format()`` function. Each formattable type may define how\nthe format specification is to be interpreted.\n\nMost built-in types implement the following options for format\nspecifications, although some of the formatting options are only\nsupported by the numeric types.\n\nA general convention is that an empty format string (``""``) produces\nthe same result as if you had called ``str()`` on the value. A non-\nempty format string typically modifies the result.\n\nThe general form of a *standard format specifier* is:\n\n format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]\n fill ::= \n align ::= "<" | ">" | "=" | "^"\n sign ::= "+" | "-" | " "\n width ::= integer\n precision ::= integer\n type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"\n\nIf a valid *align* value is specified, it can be preceded by a *fill*\ncharacter that can be any character and defaults to a space if\nomitted. Note that it is not possible to use ``{`` and ``}`` as *fill*\nchar while using the ``str.format()`` method; this limitation however\ndoesn\'t affect the ``format()`` function.\n\nThe meaning of the various alignment options is as follows:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'<\'`` | Forces the field to be left-aligned within the available |\n | | space (this is the default for most objects). |\n +-----------+------------------------------------------------------------+\n | ``\'>\'`` | Forces the field to be right-aligned within the available |\n | | space (this is the default for numbers). |\n +-----------+------------------------------------------------------------+\n | ``\'=\'`` | Forces the padding to be placed after the sign (if any) |\n | | but before the digits. This is used for printing fields |\n | | in the form \'+000000120\'. This alignment option is only |\n | | valid for numeric types. |\n +-----------+------------------------------------------------------------+\n | ``\'^\'`` | Forces the field to be centered within the available |\n | | space. |\n +-----------+------------------------------------------------------------+\n\nNote that unless a minimum field width is defined, the field width\nwill always be the same size as the data to fill it, so that the\nalignment option has no meaning in this case.\n\nThe *sign* option is only valid for number types, and can be one of\nthe following:\n\n +-----------+------------------------------------------------------------+\n | Option | Meaning |\n +===========+============================================================+\n | ``\'+\'`` | indicates that a sign should be used for both positive as |\n | | well as negative numbers. |\n +-----------+------------------------------------------------------------+\n | ``\'-\'`` | indicates that a sign should be used only for negative |\n | | numbers (this is the default behavior). |\n +-----------+------------------------------------------------------------+\n | space | indicates that a leading space should be used on positive |\n | | numbers, and a minus sign on negative numbers. |\n +-----------+------------------------------------------------------------+\n\nThe ``\'#\'`` option is only valid for integers, and only for binary,\noctal, or hexadecimal output. If present, it specifies that the\noutput will be prefixed by ``\'0b\'``, ``\'0o\'``, or ``\'0x\'``,\nrespectively.\n\nThe ``\',\'`` option signals the use of a comma for a thousands\nseparator. For a locale aware separator, use the ``\'n\'`` integer\npresentation type instead.\n\nChanged in version 2.7: Added the ``\',\'`` option (see also **PEP\n378**).\n\n*width* is a decimal integer defining the minimum field width. If not\nspecified, then the field width will be determined by the content.\n\nPreceding the *width* field by a zero (``\'0\'``) character enables\nsign-aware zero-padding for numeric types. This is equivalent to a\n*fill* character of ``\'0\'`` with an *alignment* type of ``\'=\'``.\n\nThe *precision* is a decimal number indicating how many digits should\nbe displayed after the decimal point for a floating point value\nformatted with ``\'f\'`` and ``\'F\'``, or before and after the decimal\npoint for a floating point value formatted with ``\'g\'`` or ``\'G\'``.\nFor non-number types the field indicates the maximum field size - in\nother words, how many characters will be used from the field content.\nThe *precision* is not allowed for integer values.\n\nFinally, the *type* determines how the data should be presented.\n\nThe available string presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'s\'`` | String format. This is the default type for strings and |\n | | may be omitted. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'s\'``. |\n +-----------+------------------------------------------------------------+\n\nThe available integer presentation types are:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'b\'`` | Binary format. Outputs the number in base 2. |\n +-----------+------------------------------------------------------------+\n | ``\'c\'`` | Character. Converts the integer to the corresponding |\n | | unicode character before printing. |\n +-----------+------------------------------------------------------------+\n | ``\'d\'`` | Decimal Integer. Outputs the number in base 10. |\n +-----------+------------------------------------------------------------+\n | ``\'o\'`` | Octal format. Outputs the number in base 8. |\n +-----------+------------------------------------------------------------+\n | ``\'x\'`` | Hex format. Outputs the number in base 16, using lower- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'X\'`` | Hex format. Outputs the number in base 16, using upper- |\n | | case letters for the digits above 9. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'d\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'d\'``. |\n +-----------+------------------------------------------------------------+\n\nIn addition to the above presentation types, integers can be formatted\nwith the floating point presentation types listed below (except\n``\'n\'`` and None). When doing so, ``float()`` is used to convert the\ninteger to a floating point number before formatting.\n\nThe available presentation types for floating point and decimal values\nare:\n\n +-----------+------------------------------------------------------------+\n | Type | Meaning |\n +===========+============================================================+\n | ``\'e\'`` | Exponent notation. Prints the number in scientific |\n | | notation using the letter \'e\' to indicate the exponent. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'E\'`` | Exponent notation. Same as ``\'e\'`` except it uses an upper |\n | | case \'E\' as the separator character. |\n +-----------+------------------------------------------------------------+\n | ``\'f\'`` | Fixed point. Displays the number as a fixed-point number. |\n | | The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'F\'`` | Fixed point. Same as ``\'f\'``. |\n +-----------+------------------------------------------------------------+\n | ``\'g\'`` | General format. For a given precision ``p >= 1``, this |\n | | rounds the number to ``p`` significant digits and then |\n | | formats the result in either fixed-point format or in |\n | | scientific notation, depending on its magnitude. The |\n | | precise rules are as follows: suppose that the result |\n | | formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1`` would have exponent ``exp``. Then if ``-4 <= exp |\n | | < p``, the number is formatted with presentation type |\n | | ``\'f\'`` and precision ``p-1-exp``. Otherwise, the number |\n | | is formatted with presentation type ``\'e\'`` and precision |\n | | ``p-1``. In both cases insignificant trailing zeros are |\n | | removed from the significand, and the decimal point is |\n | | also removed if there are no remaining digits following |\n | | it. Positive and negative infinity, positive and negative |\n | | zero, and nans, are formatted as ``inf``, ``-inf``, ``0``, |\n | | ``-0`` and ``nan`` respectively, regardless of the |\n | | precision. A precision of ``0`` is treated as equivalent |\n | | to a precision of ``1``. The default precision is ``6``. |\n +-----------+------------------------------------------------------------+\n | ``\'G\'`` | General format. Same as ``\'g\'`` except switches to ``\'E\'`` |\n | | if the number gets too large. The representations of |\n | | infinity and NaN are uppercased, too. |\n +-----------+------------------------------------------------------------+\n | ``\'n\'`` | Number. This is the same as ``\'g\'``, except that it uses |\n | | the current locale setting to insert the appropriate |\n | | number separator characters. |\n +-----------+------------------------------------------------------------+\n | ``\'%\'`` | Percentage. Multiplies the number by 100 and displays in |\n | | fixed (``\'f\'``) format, followed by a percent sign. |\n +-----------+------------------------------------------------------------+\n | None | The same as ``\'g\'``. |\n +-----------+------------------------------------------------------------+\n\n\nFormat examples\n===============\n\nThis section contains examples of the new format syntax and comparison\nwith the old ``%``-formatting.\n\nIn most of the cases the syntax is similar to the old\n``%``-formatting, with the addition of the ``{}`` and with ``:`` used\ninstead of ``%``. For example, ``\'%03.2f\'`` can be translated to\n``\'{:03.2f}\'``.\n\nThe new format syntax also supports new and different options, shown\nin the follow examples.\n\nAccessing arguments by position:\n\n >>> \'{0}, {1}, {2}\'.format(\'a\', \'b\', \'c\')\n \'a, b, c\'\n >>> \'{}, {}, {}\'.format(\'a\', \'b\', \'c\') # 2.7+ only\n \'a, b, c\'\n >>> \'{2}, {1}, {0}\'.format(\'a\', \'b\', \'c\')\n \'c, b, a\'\n >>> \'{2}, {1}, {0}\'.format(*\'abc\') # unpacking argument sequence\n \'c, b, a\'\n >>> \'{0}{1}{0}\'.format(\'abra\', \'cad\') # arguments\' indices can be repeated\n \'abracadabra\'\n\nAccessing arguments by name:\n\n >>> \'Coordinates: {latitude}, {longitude}\'.format(latitude=\'37.24N\', longitude=\'-115.81W\')\n \'Coordinates: 37.24N, -115.81W\'\n >>> coord = {\'latitude\': \'37.24N\', \'longitude\': \'-115.81W\'}\n >>> \'Coordinates: {latitude}, {longitude}\'.format(**coord)\n \'Coordinates: 37.24N, -115.81W\'\n\nAccessing arguments\' attributes:\n\n >>> c = 3-5j\n >>> (\'The complex number {0} is formed from the real part {0.real} \'\n ... \'and the imaginary part {0.imag}.\').format(c)\n \'The complex number (3-5j) is formed from the real part 3.0 and the imaginary part -5.0.\'\n >>> class Point(object):\n ... def __init__(self, x, y):\n ... self.x, self.y = x, y\n ... def __str__(self):\n ... return \'Point({self.x}, {self.y})\'.format(self=self)\n ...\n >>> str(Point(4, 2))\n \'Point(4, 2)\'\n\nAccessing arguments\' items:\n\n >>> coord = (3, 5)\n >>> \'X: {0[0]}; Y: {0[1]}\'.format(coord)\n \'X: 3; Y: 5\'\n\nReplacing ``%s`` and ``%r``:\n\n >>> "repr() shows quotes: {!r}; str() doesn\'t: {!s}".format(\'test1\', \'test2\')\n "repr() shows quotes: \'test1\'; str() doesn\'t: test2"\n\nAligning the text and specifying a width:\n\n >>> \'{:<30}\'.format(\'left aligned\')\n \'left aligned \'\n >>> \'{:>30}\'.format(\'right aligned\')\n \' right aligned\'\n >>> \'{:^30}\'.format(\'centered\')\n \' centered \'\n >>> \'{:*^30}\'.format(\'centered\') # use \'*\' as a fill char\n \'***********centered***********\'\n\nReplacing ``%+f``, ``%-f``, and ``% f`` and specifying a sign:\n\n >>> \'{:+f}; {:+f}\'.format(3.14, -3.14) # show it always\n \'+3.140000; -3.140000\'\n >>> \'{: f}; {: f}\'.format(3.14, -3.14) # show a space for positive numbers\n \' 3.140000; -3.140000\'\n >>> \'{:-f}; {:-f}\'.format(3.14, -3.14) # show only the minus -- same as \'{:f}; {:f}\'\n \'3.140000; -3.140000\'\n\nReplacing ``%x`` and ``%o`` and converting the value to different\nbases:\n\n >>> # format also supports binary numbers\n >>> "int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}".format(42)\n \'int: 42; hex: 2a; oct: 52; bin: 101010\'\n >>> # with 0x, 0o, or 0b as prefix:\n >>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)\n \'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010\'\n\nUsing the comma as a thousands separator:\n\n >>> \'{:,}\'.format(1234567890)\n \'1,234,567,890\'\n\nExpressing a percentage:\n\n >>> points = 19.5\n >>> total = 22\n >>> \'Correct answers: {:.2%}\'.format(points/total)\n \'Correct answers: 88.64%\'\n\nUsing type-specific formatting:\n\n >>> import datetime\n >>> d = datetime.datetime(2010, 7, 4, 12, 15, 58)\n >>> \'{:%Y-%m-%d %H:%M:%S}\'.format(d)\n \'2010-07-04 12:15:58\'\n\nNesting arguments and more complex examples:\n\n >>> for align, text in zip(\'<^>\', [\'left\', \'center\', \'right\']):\n ... \'{0:{fill}{align}16}\'.format(text, fill=align, align=align)\n ...\n \'left<<<<<<<<<<<<\'\n \'^^^^^center^^^^^\'\n \'>>>>>>>>>>>right\'\n >>>\n >>> octets = [192, 168, 0, 1]\n >>> \'{:02X}{:02X}{:02X}{:02X}\'.format(*octets)\n \'C0A80001\'\n >>> int(_, 16)\n 3232235521\n >>>\n >>> width = 5\n >>> for num in range(5,12):\n ... for base in \'dXob\':\n ... print \'{0:{width}{base}}\'.format(num, base=base, width=width),\n ... print\n ...\n 5 5 5 101\n 6 6 6 110\n 7 7 7 111\n 8 8 10 1000\n 9 9 11 1001\n 10 A 12 1010\n 11 B 13 1011\n', + 'function': '\nFunction definitions\n********************\n\nA function definition defines a user-defined function object (see\nsection *The standard type hierarchy*):\n\n decorated ::= decorators (classdef | funcdef)\n decorators ::= decorator+\n decorator ::= "@" dotted_name ["(" [argument_list [","]] ")"] NEWLINE\n funcdef ::= "def" funcname "(" [parameter_list] ")" ":" suite\n dotted_name ::= identifier ("." identifier)*\n parameter_list ::= (defparameter ",")*\n ( "*" identifier ["," "**" identifier]\n | "**" identifier\n | defparameter [","] )\n defparameter ::= parameter ["=" expression]\n sublist ::= parameter ("," parameter)* [","]\n parameter ::= identifier | "(" sublist ")"\n funcname ::= identifier\n\nA function definition is an executable statement. Its execution binds\nthe function name in the current local namespace to a function object\n(a wrapper around the executable code for the function). This\nfunction object contains a reference to the current global namespace\nas the global namespace to be used when the function is called.\n\nThe function definition does not execute the function body; this gets\nexecuted only when the function is called. [3]\n\nA function definition may be wrapped by one or more *decorator*\nexpressions. Decorator expressions are evaluated when the function is\ndefined, in the scope that contains the function definition. The\nresult must be a callable, which is invoked with the function object\nas the only argument. The returned value is bound to the function name\ninstead of the function object. Multiple decorators are applied in\nnested fashion. For example, the following code:\n\n @f1(arg)\n @f2\n def func(): pass\n\nis equivalent to:\n\n def func(): pass\n func = f1(arg)(f2(func))\n\nWhen one or more top-level *parameters* have the form *parameter*\n``=`` *expression*, the function is said to have "default parameter\nvalues." For a parameter with a default value, the corresponding\n*argument* may be omitted from a call, in which case the parameter\'s\ndefault value is substituted. If a parameter has a default value, all\nfollowing parameters must also have a default value --- this is a\nsyntactic restriction that is not expressed by the grammar.\n\n**Default parameter values are evaluated when the function definition\nis executed.** This means that the expression is evaluated once, when\nthe function is defined, and that the same "pre-computed" value is\nused for each call. This is especially important to understand when a\ndefault parameter is a mutable object, such as a list or a dictionary:\nif the function modifies the object (e.g. by appending an item to a\nlist), the default value is in effect modified. This is generally not\nwhat was intended. A way around this is to use ``None`` as the\ndefault, and explicitly test for it in the body of the function, e.g.:\n\n def whats_on_the_telly(penguin=None):\n if penguin is None:\n penguin = []\n penguin.append("property of the zoo")\n return penguin\n\nFunction call semantics are described in more detail in section\n*Calls*. A function call always assigns values to all parameters\nmentioned in the parameter list, either from position arguments, from\nkeyword arguments, or from default values. If the form\n"``*identifier``" is present, it is initialized to a tuple receiving\nany excess positional parameters, defaulting to the empty tuple. If\nthe form "``**identifier``" is present, it is initialized to a new\ndictionary receiving any excess keyword arguments, defaulting to a new\nempty dictionary.\n\nIt is also possible to create anonymous functions (functions not bound\nto a name), for immediate use in expressions. This uses lambda forms,\ndescribed in section *Lambdas*. Note that the lambda form is merely a\nshorthand for a simplified function definition; a function defined in\na "``def``" statement can be passed around or assigned to another name\njust like a function defined by a lambda form. The "``def``" form is\nactually more powerful since it allows the execution of multiple\nstatements.\n\n**Programmer\'s note:** Functions are first-class objects. A "``def``"\nform executed inside a function definition defines a local function\nthat can be returned or passed around. Free variables used in the\nnested function can access the local variables of the function\ncontaining the def. See section *Naming and binding* for details.\n', + 'global': '\nThe ``global`` statement\n************************\n\n global_stmt ::= "global" identifier ("," identifier)*\n\nThe ``global`` statement is a declaration which holds for the entire\ncurrent code block. It means that the listed identifiers are to be\ninterpreted as globals. It would be impossible to assign to a global\nvariable without ``global``, although free variables may refer to\nglobals without being declared global.\n\nNames listed in a ``global`` statement must not be used in the same\ncode block textually preceding that ``global`` statement.\n\nNames listed in a ``global`` statement must not be defined as formal\nparameters or in a ``for`` loop control target, ``class`` definition,\nfunction definition, or ``import`` statement.\n\n**CPython implementation detail:** The current implementation does not\nenforce the latter two restrictions, but programs should not abuse\nthis freedom, as future implementations may enforce them or silently\nchange the meaning of the program.\n\n**Programmer\'s note:** the ``global`` is a directive to the parser.\nIt applies only to code parsed at the same time as the ``global``\nstatement. In particular, a ``global`` statement contained in an\n``exec`` statement does not affect the code block *containing* the\n``exec`` statement, and code contained in an ``exec`` statement is\nunaffected by ``global`` statements in the code containing the\n``exec`` statement. The same applies to the ``eval()``,\n``execfile()`` and ``compile()`` functions.\n', + 'id-classes': '\nReserved classes of identifiers\n*******************************\n\nCertain classes of identifiers (besides keywords) have special\nmeanings. These classes are identified by the patterns of leading and\ntrailing underscore characters:\n\n``_*``\n Not imported by ``from module import *``. The special identifier\n ``_`` is used in the interactive interpreter to store the result of\n the last evaluation; it is stored in the ``__builtin__`` module.\n When not in interactive mode, ``_`` has no special meaning and is\n not defined. See section *The import statement*.\n\n Note: The name ``_`` is often used in conjunction with\n internationalization; refer to the documentation for the\n ``gettext`` module for more information on this convention.\n\n``__*__``\n System-defined names. These names are defined by the interpreter\n and its implementation (including the standard library). Current\n system names are discussed in the *Special method names* section\n and elsewhere. More will likely be defined in future versions of\n Python. *Any* use of ``__*__`` names, in any context, that does\n not follow explicitly documented use, is subject to breakage\n without warning.\n\n``__*``\n Class-private names. Names in this category, when used within the\n context of a class definition, are re-written to use a mangled form\n to help avoid name clashes between "private" attributes of base and\n derived classes. See section *Identifiers (Names)*.\n', +@@ -52,6 +53,7 @@ topics = {'assert': '\nThe ``assert`` st + 'operator-summary': '\nOperator precedence\n*******************\n\nThe following table summarizes the operator precedences in Python,\nfrom lowest precedence (least binding) to highest precedence (most\nbinding). Operators in the same box have the same precedence. Unless\nthe syntax is explicitly given, operators are binary. Operators in\nthe same box group left to right (except for comparisons, including\ntests, which all have the same precedence and chain from left to right\n--- see section *Comparisons* --- and exponentiation, which groups\nfrom right to left).\n\n+-------------------------------------------------+---------------------------------------+\n| Operator | Description |\n+=================================================+=======================================+\n| ``lambda`` | Lambda expression |\n+-------------------------------------------------+---------------------------------------+\n| ``if`` -- ``else`` | Conditional expression |\n+-------------------------------------------------+---------------------------------------+\n| ``or`` | Boolean OR |\n+-------------------------------------------------+---------------------------------------+\n| ``and`` | Boolean AND |\n+-------------------------------------------------+---------------------------------------+\n| ``not`` ``x`` | Boolean NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``in``, ``not in``, ``is``, ``is not``, ``<``, | Comparisons, including membership |\n| ``<=``, ``>``, ``>=``, ``<>``, ``!=``, ``==`` | tests and identity tests |\n+-------------------------------------------------+---------------------------------------+\n| ``|`` | Bitwise OR |\n+-------------------------------------------------+---------------------------------------+\n| ``^`` | Bitwise XOR |\n+-------------------------------------------------+---------------------------------------+\n| ``&`` | Bitwise AND |\n+-------------------------------------------------+---------------------------------------+\n| ``<<``, ``>>`` | Shifts |\n+-------------------------------------------------+---------------------------------------+\n| ``+``, ``-`` | Addition and subtraction |\n+-------------------------------------------------+---------------------------------------+\n| ``*``, ``/``, ``//``, ``%`` | Multiplication, division, remainder |\n| | [8] |\n+-------------------------------------------------+---------------------------------------+\n| ``+x``, ``-x``, ``~x`` | Positive, negative, bitwise NOT |\n+-------------------------------------------------+---------------------------------------+\n| ``**`` | Exponentiation [9] |\n+-------------------------------------------------+---------------------------------------+\n| ``x[index]``, ``x[index:index]``, | Subscription, slicing, call, |\n| ``x(arguments...)``, ``x.attribute`` | attribute reference |\n+-------------------------------------------------+---------------------------------------+\n| ``(expressions...)``, ``[expressions...]``, | Binding or tuple display, list |\n| ``{key: value...}``, ```expressions...``` | display, dictionary display, string |\n| | conversion |\n+-------------------------------------------------+---------------------------------------+\n\n-[ Footnotes ]-\n\n[1] In Python 2.3 and later releases, a list comprehension "leaks" the\n control variables of each ``for`` it contains into the containing\n scope. However, this behavior is deprecated, and relying on it\n will not work in Python 3.\n\n[2] While ``abs(x%y) < abs(y)`` is true mathematically, for floats it\n may not be true numerically due to roundoff. For example, and\n assuming a platform on which a Python float is an IEEE 754 double-\n precision number, in order that ``-1e-100 % 1e100`` have the same\n sign as ``1e100``, the computed result is ``-1e-100 + 1e100``,\n which is numerically exactly equal to ``1e100``. The function\n ``math.fmod()`` returns a result whose sign matches the sign of\n the first argument instead, and so returns ``-1e-100`` in this\n case. Which approach is more appropriate depends on the\n application.\n\n[3] If x is very close to an exact integer multiple of y, it\'s\n possible for ``floor(x/y)`` to be one larger than ``(x-x%y)/y``\n due to rounding. In such cases, Python returns the latter result,\n in order to preserve that ``divmod(x,y)[0] * y + x % y`` be very\n close to ``x``.\n\n[4] While comparisons between unicode strings make sense at the byte\n level, they may be counter-intuitive to users. For example, the\n strings ``u"\\u00C7"`` and ``u"\\u0043\\u0327"`` compare differently,\n even though they both represent the same unicode character (LATIN\n CAPITAL LETTER C WITH CEDILLA). To compare strings in a human\n recognizable way, compare using ``unicodedata.normalize()``.\n\n[5] The implementation computes this efficiently, without constructing\n lists or sorting.\n\n[6] Earlier versions of Python used lexicographic comparison of the\n sorted (key, value) lists, but this was very expensive for the\n common case of comparing for equality. An even earlier version of\n Python compared dictionaries by identity only, but this caused\n surprises because people expected to be able to test a dictionary\n for emptiness by comparing it to ``{}``.\n\n[7] Due to automatic garbage-collection, free lists, and the dynamic\n nature of descriptors, you may notice seemingly unusual behaviour\n in certain uses of the ``is`` operator, like those involving\n comparisons between instance methods, or constants. Check their\n documentation for more info.\n\n[8] The ``%`` operator is also used for string formatting; the same\n precedence applies.\n\n[9] The power operator ``**`` binds less tightly than an arithmetic or\n bitwise unary operator on its right, that is, ``2**-1`` is\n ``0.5``.\n', + 'pass': '\nThe ``pass`` statement\n**********************\n\n pass_stmt ::= "pass"\n\n``pass`` is a null operation --- when it is executed, nothing happens.\nIt is useful as a placeholder when a statement is required\nsyntactically, but no code needs to be executed, for example:\n\n def f(arg): pass # a function that does nothing (yet)\n\n class C: pass # a class with no methods (yet)\n', + 'power': '\nThe power operator\n******************\n\nThe power operator binds more tightly than unary operators on its\nleft; it binds less tightly than unary operators on its right. The\nsyntax is:\n\n power ::= primary ["**" u_expr]\n\nThus, in an unparenthesized sequence of power and unary operators, the\noperators are evaluated from right to left (this does not constrain\nthe evaluation order for the operands): ``-1**2`` results in ``-1``.\n\nThe power operator has the same semantics as the built-in ``pow()``\nfunction, when called with two arguments: it yields its left argument\nraised to the power of its right argument. The numeric arguments are\nfirst converted to a common type. The result type is that of the\narguments after coercion.\n\nWith mixed operand types, the coercion rules for binary arithmetic\noperators apply. For int and long int operands, the result has the\nsame type as the operands (after coercion) unless the second argument\nis negative; in that case, all arguments are converted to float and a\nfloat result is delivered. For example, ``10**2`` returns ``100``, but\n``10**-2`` returns ``0.01``. (This last feature was added in Python\n2.2. In Python 2.1 and before, if both arguments were of integer types\nand the second argument was negative, an exception was raised).\n\nRaising ``0.0`` to a negative power results in a\n``ZeroDivisionError``. Raising a negative number to a fractional power\nresults in a ``ValueError``.\n', ++ 'print': '\nThe ``print`` statement\n***********************\n\n print_stmt ::= "print" ([expression ("," expression)* [","]]\n | ">>" expression [("," expression)+ [","]])\n\n``print`` evaluates each expression in turn and writes the resulting\nobject to standard output (see below). If an object is not a string,\nit is first converted to a string using the rules for string\nconversions. The (resulting or original) string is then written. A\nspace is written before each object is (converted and) written, unless\nthe output system believes it is positioned at the beginning of a\nline. This is the case (1) when no characters have yet been written\nto standard output, (2) when the last character written to standard\noutput is a whitespace character except ``\' \'``, or (3) when the last\nwrite operation on standard output was not a ``print`` statement. (In\nsome cases it may be functional to write an empty string to standard\noutput for this reason.)\n\nNote: Objects which act like file objects but which are not the built-in\n file objects often do not properly emulate this aspect of the file\n object\'s behavior, so it is best not to rely on this.\n\nA ``\'\\n\'`` character is written at the end, unless the ``print``\nstatement ends with a comma. This is the only action if the statement\ncontains just the keyword ``print``.\n\nStandard output is defined as the file object named ``stdout`` in the\nbuilt-in module ``sys``. If no such object exists, or if it does not\nhave a ``write()`` method, a ``RuntimeError`` exception is raised.\n\n``print`` also has an extended form, defined by the second portion of\nthe syntax described above. This form is sometimes referred to as\n"``print`` chevron." In this form, the first expression after the\n``>>`` must evaluate to a "file-like" object, specifically an object\nthat has a ``write()`` method as described above. With this extended\nform, the subsequent expressions are printed to this file object. If\nthe first expression evaluates to ``None``, then ``sys.stdout`` is\nused as the file for output.\n', + 'raise': '\nThe ``raise`` statement\n***********************\n\n raise_stmt ::= "raise" [expression ["," expression ["," expression]]]\n\nIf no expressions are present, ``raise`` re-raises the last exception\nthat was active in the current scope. If no exception is active in\nthe current scope, a ``TypeError`` exception is raised indicating that\nthis is an error (if running under IDLE, a ``Queue.Empty`` exception\nis raised instead).\n\nOtherwise, ``raise`` evaluates the expressions to get three objects,\nusing ``None`` as the value of omitted expressions. The first two\nobjects are used to determine the *type* and *value* of the exception.\n\nIf the first object is an instance, the type of the exception is the\nclass of the instance, the instance itself is the value, and the\nsecond object must be ``None``.\n\nIf the first object is a class, it becomes the type of the exception.\nThe second object is used to determine the exception value: If it is\nan instance of the class, the instance becomes the exception value. If\nthe second object is a tuple, it is used as the argument list for the\nclass constructor; if it is ``None``, an empty argument list is used,\nand any other object is treated as a single argument to the\nconstructor. The instance so created by calling the constructor is\nused as the exception value.\n\nIf a third object is present and not ``None``, it must be a traceback\nobject (see section *The standard type hierarchy*), and it is\nsubstituted instead of the current location as the place where the\nexception occurred. If the third object is present and not a\ntraceback object or ``None``, a ``TypeError`` exception is raised.\nThe three-expression form of ``raise`` is useful to re-raise an\nexception transparently in an except clause, but ``raise`` with no\nexpressions should be preferred if the exception to be re-raised was\nthe most recently active exception in the current scope.\n\nAdditional information on exceptions can be found in section\n*Exceptions*, and information about handling exceptions is in section\n*The try statement*.\n', + 'return': '\nThe ``return`` statement\n************************\n\n return_stmt ::= "return" [expression_list]\n\n``return`` may only occur syntactically nested in a function\ndefinition, not within a nested class definition.\n\nIf an expression list is present, it is evaluated, else ``None`` is\nsubstituted.\n\n``return`` leaves the current function call with the expression list\n(or ``None``) as return value.\n\nWhen ``return`` passes control out of a ``try`` statement with a\n``finally`` clause, that ``finally`` clause is executed before really\nleaving the function.\n\nIn a generator function, the ``return`` statement is not allowed to\ninclude an ``expression_list``. In that context, a bare ``return``\nindicates that the generator is done and will cause ``StopIteration``\nto be raised.\n', + 'sequence-types': "\nEmulating container types\n*************************\n\nThe following methods can be defined to implement container objects.\nContainers usually are sequences (such as lists or tuples) or mappings\n(like dictionaries), but can represent other containers as well. The\nfirst set of methods is used either to emulate a sequence or to\nemulate a mapping; the difference is that for a sequence, the\nallowable keys should be the integers *k* for which ``0 <= k < N``\nwhere *N* is the length of the sequence, or slice objects, which\ndefine a range of items. (For backwards compatibility, the method\n``__getslice__()`` (see below) can also be defined to handle simple,\nbut not extended slices.) It is also recommended that mappings provide\nthe methods ``keys()``, ``values()``, ``items()``, ``has_key()``,\n``get()``, ``clear()``, ``setdefault()``, ``iterkeys()``,\n``itervalues()``, ``iteritems()``, ``pop()``, ``popitem()``,\n``copy()``, and ``update()`` behaving similar to those for Python's\nstandard dictionary objects. The ``UserDict`` module provides a\n``DictMixin`` class to help create those methods from a base set of\n``__getitem__()``, ``__setitem__()``, ``__delitem__()``, and\n``keys()``. Mutable sequences should provide methods ``append()``,\n``count()``, ``index()``, ``extend()``, ``insert()``, ``pop()``,\n``remove()``, ``reverse()`` and ``sort()``, like Python standard list\nobjects. Finally, sequence types should implement addition (meaning\nconcatenation) and multiplication (meaning repetition) by defining the\nmethods ``__add__()``, ``__radd__()``, ``__iadd__()``, ``__mul__()``,\n``__rmul__()`` and ``__imul__()`` described below; they should not\ndefine ``__coerce__()`` or other numerical operators. It is\nrecommended that both mappings and sequences implement the\n``__contains__()`` method to allow efficient use of the ``in``\noperator; for mappings, ``in`` should be equivalent of ``has_key()``;\nfor sequences, it should search through the values. It is further\nrecommended that both mappings and sequences implement the\n``__iter__()`` method to allow efficient iteration through the\ncontainer; for mappings, ``__iter__()`` should be the same as\n``iterkeys()``; for sequences, it should iterate through the values.\n\nobject.__len__(self)\n\n Called to implement the built-in function ``len()``. Should return\n the length of the object, an integer ``>=`` 0. Also, an object\n that doesn't define a ``__nonzero__()`` method and whose\n ``__len__()`` method returns zero is considered to be false in a\n Boolean context.\n\nobject.__getitem__(self, key)\n\n Called to implement evaluation of ``self[key]``. For sequence\n types, the accepted keys should be integers and slice objects.\n Note that the special interpretation of negative indexes (if the\n class wishes to emulate a sequence type) is up to the\n ``__getitem__()`` method. If *key* is of an inappropriate type,\n ``TypeError`` may be raised; if of a value outside the set of\n indexes for the sequence (after any special interpretation of\n negative values), ``IndexError`` should be raised. For mapping\n types, if *key* is missing (not in the container), ``KeyError``\n should be raised.\n\n Note: ``for`` loops expect that an ``IndexError`` will be raised for\n illegal indexes to allow proper detection of the end of the\n sequence.\n\nobject.__setitem__(self, key, value)\n\n Called to implement assignment to ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support changes to the values for keys, or if new keys\n can be added, or for sequences if elements can be replaced. The\n same exceptions should be raised for improper *key* values as for\n the ``__getitem__()`` method.\n\nobject.__delitem__(self, key)\n\n Called to implement deletion of ``self[key]``. Same note as for\n ``__getitem__()``. This should only be implemented for mappings if\n the objects support removal of keys, or for sequences if elements\n can be removed from the sequence. The same exceptions should be\n raised for improper *key* values as for the ``__getitem__()``\n method.\n\nobject.__iter__(self)\n\n This method is called when an iterator is required for a container.\n This method should return a new iterator object that can iterate\n over all the objects in the container. For mappings, it should\n iterate over the keys of the container, and should also be made\n available as the method ``iterkeys()``.\n\n Iterator objects also need to implement this method; they are\n required to return themselves. For more information on iterator\n objects, see *Iterator Types*.\n\nobject.__reversed__(self)\n\n Called (if present) by the ``reversed()`` built-in to implement\n reverse iteration. It should return a new iterator object that\n iterates over all the objects in the container in reverse order.\n\n If the ``__reversed__()`` method is not provided, the\n ``reversed()`` built-in will fall back to using the sequence\n protocol (``__len__()`` and ``__getitem__()``). Objects that\n support the sequence protocol should only provide\n ``__reversed__()`` if they can provide an implementation that is\n more efficient than the one provided by ``reversed()``.\n\n New in version 2.6.\n\nThe membership test operators (``in`` and ``not in``) are normally\nimplemented as an iteration through a sequence. However, container\nobjects can supply the following special method with a more efficient\nimplementation, which also does not require the object be a sequence.\n\nobject.__contains__(self, item)\n\n Called to implement membership test operators. Should return true\n if *item* is in *self*, false otherwise. For mapping objects, this\n should consider the keys of the mapping rather than the values or\n the key-item pairs.\n\n For objects that don't define ``__contains__()``, the membership\n test first tries iteration via ``__iter__()``, then the old\n sequence iteration protocol via ``__getitem__()``, see *this\n section in the language reference*.\n", diff --git a/SOURCES/00193-buffer-overflow.patch b/SOURCES/00193-buffer-overflow.patch new file mode 100644 index 0000000..164b462 --- /dev/null +++ b/SOURCES/00193-buffer-overflow.patch @@ -0,0 +1,43 @@ + +# HG changeset patch +# User Benjamin Peterson +# Date 1389671978 18000 +# Node ID 87673659d8f7ba1623cd4914f09ad3d2ade034e9 +# Parent 2631d33ee7fbd5f0288931ef37872218d511d2e8 +complain when nbytes > buflen to fix possible buffer overflow (closes #20246) + +diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py +--- a/Lib/test/test_socket.py ++++ b/Lib/test/test_socket.py +@@ -1620,6 +1620,16 @@ class BufferIOTest(SocketConnectedTest): + + _testRecvFromIntoMemoryview = _testRecvFromIntoArray + ++ def testRecvFromIntoSmallBuffer(self): ++ # See issue #20246. ++ buf = bytearray(8) ++ self.assertRaises(ValueError, self.cli_conn.recvfrom_into, buf, 1024) ++ ++ def _testRecvFromIntoSmallBuffer(self): ++ with test_support.check_py3k_warnings(): ++ buf = buffer(MSG*2048) ++ self.serv_conn.send(buf) ++ + + TIPC_STYPE = 2000 + TIPC_LOWER = 200 +diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c +--- a/Modules/socketmodule.c ++++ b/Modules/socketmodule.c +@@ -2742,6 +2742,10 @@ sock_recvfrom_into(PySocketSockObject *s + if (recvlen == 0) { + /* If nbytes was not specified, use the buffer's length */ + recvlen = buflen; ++ } else if (recvlen > buflen) { ++ PyErr_SetString(PyExc_ValueError, ++ "nbytes is greater than the length of the buffer"); ++ goto error; + } + + readlen = sock_recvfrom_guts(s, buf.buf, recvlen, flags, &addr); + diff --git a/SOURCES/00194-gdb-dont-fail-on-frame-with-address.patch b/SOURCES/00194-gdb-dont-fail-on-frame-with-address.patch new file mode 100644 index 0000000..501b5db --- /dev/null +++ b/SOURCES/00194-gdb-dont-fail-on-frame-with-address.patch @@ -0,0 +1,19 @@ +--- Lib/test/test_gdb.py.orig 2014-08-01 14:30:43.397473152 +0200 ++++ Lib/test/test_gdb.py 2014-08-01 14:34:50.907325691 +0200 +@@ -135,6 +135,16 @@ + # Disable this: + 'set print entry-values no', + ++ # The tests assume that the first frame of printed ++ # backtrace will not contain program counter, ++ # that is however not guaranteed by gdb (rhbz#1125657) ++ # therefore we need to use 'set print address off' to ++ # make sure the counter is not there. For example: ++ # #0 in PyObject_Print ... ++ # is assumed, but sometimes this can be e.g. ++ # #0 0x00003fffb7dd1798 in PyObject_Print ... ++ 'set print address off', ++ + 'run'] + + if HAS_AUTOLOAD_SAFEPATH: diff --git a/SOURCES/05000-autotool-intermediates.patch b/SOURCES/05000-autotool-intermediates.patch new file mode 100644 index 0000000..cfedc25 --- /dev/null +++ b/SOURCES/05000-autotool-intermediates.patch @@ -0,0 +1,216 @@ +diff -up ./configure.autotool-intermediates ./configure +--- ./configure.autotool-intermediates 2013-04-09 11:24:01.024185796 +0200 ++++ ./configure 2013-04-09 11:24:01.780183954 +0200 +@@ -639,6 +639,8 @@ TRUE + MACHDEP_OBJS + DYNLOADFILE + DLINCLDIR ++DTRACEHDRS ++DTRACEOBJS + THREADOBJ + LDLAST + USE_THREAD_MODULE +@@ -659,6 +661,8 @@ OTHER_LIBTOOL_OPT + UNIVERSAL_ARCH_FLAGS + BASECFLAGS + OPT ++DEBUG_SUFFIX ++DEBUG_EXT + LN + MKDIR_P + INSTALL_DATA +@@ -795,8 +799,11 @@ with_pth + enable_ipv6 + with_doc_strings + with_tsc ++with_count_allocs ++with_call_profile + with_pymalloc + with_valgrind ++with_dtrace + with_wctype_functions + with_fpectl + with_libm +@@ -1472,8 +1479,11 @@ Optional Packages: + --with-pth use GNU pth threading libraries + --with(out)-doc-strings disable/enable documentation strings + --with(out)-tsc enable/disable timestamp counter profile ++ --with(out)count-allocs enable/disable per-type instance accounting ++ --with(out)-call-profile enable/disable statistics on function call invocation + --with(out)-pymalloc disable/enable specialized mallocs + --with-valgrind Enable Valgrind support ++ --with(out)-dtrace disable/enable dtrace support + --with-wctype-functions use wctype.h functions + --with-fpectl enable SIGFPE catching + --with-libm=STRING math library +@@ -5171,7 +5181,7 @@ esac + $as_echo_n "checking LIBRARY... " >&6; } + if test -z "$LIBRARY" + then +- LIBRARY='libpython$(VERSION).a' ++ LIBRARY='libpython$(VERSION)$(DEBUG_EXT).a' + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBRARY" >&5 + $as_echo "$LIBRARY" >&6; } +@@ -5343,8 +5353,8 @@ $as_echo "#define Py_ENABLE_SHARED 1" >> + INSTSONAME="$LDLIBRARY".$SOVERSION + ;; + Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*) +- LDLIBRARY='libpython$(VERSION).so' +- BLDLIBRARY='-L. -lpython$(VERSION)' ++ LDLIBRARY='libpython$(VERSION)$(DEBUG_EXT).so' ++ BLDLIBRARY='-L. -lpython$(VERSION)$(DEBUG_EXT)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH} + case $ac_sys_system in + FreeBSD*) +@@ -5367,7 +5377,7 @@ $as_echo "#define Py_ENABLE_SHARED 1" >> + ;; + OSF*) + LDLIBRARY='libpython$(VERSION).so' +- BLDLIBRARY='-rpath $(LIBDIR) -L. -lpython$(VERSION)' ++ BLDLIBRARY='-L. -lpython$(VERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH} + ;; + atheos*) +@@ -5894,6 +5904,14 @@ $as_echo "no" >&6; } + fi + + ++if test "$Py_DEBUG" = 'true' ++then ++ DEBUG_EXT=_d ++ DEBUG_SUFFIX=-debug ++fi ++ ++ ++ + # XXX Shouldn't the code above that fiddles with BASECFLAGS and OPT be + # merged with this chunk of code? + +@@ -9958,6 +9976,50 @@ $as_echo "no" >&6; } + fi + + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-count-allocs" >&5 ++$as_echo_n "checking for --with-count-allocs... " >&6; } ++ ++# Check whether --with-count-allocs was given. ++if test "${with_count_allocs+set}" = set; then : ++ withval=$with_count_allocs; ++if test "$withval" != no ++then ++ ++$as_echo "#define COUNT_ALLOCS 1" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-call-profile" >&5 ++$as_echo_n "checking for --with-call-profile... " >&6; } ++ ++# Check whether --with-call-profile was given. ++if test "${with_call_profile+set}" = set; then : ++ withval=$with_call_profile; ++if test "$withval" != no ++then ++ ++$as_echo "#define CALL_PROFILE 1" >>confdefs.h ++ ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 ++$as_echo "yes" >&6; } ++else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++else ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 ++$as_echo "no" >&6; } ++fi ++ ++ + # Check for Python-specific malloc support + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-pymalloc" >&5 + $as_echo_n "checking for --with-pymalloc... " >&6; } +@@ -10007,6 +10069,46 @@ fi + + fi + ++# Check for dtrace support ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-dtrace" >&5 ++$as_echo_n "checking for --with-dtrace... " >&6; } ++ ++# Check whether --with-dtrace was given. ++if test "${with_dtrace+set}" = set; then : ++ withval=$with_dtrace; ++fi ++ ++ ++if test ! -z "$with_dtrace" ++then ++ if dtrace -G -o /dev/null -s $srcdir/Include/pydtrace.d 2>/dev/null ++ then ++ ++$as_echo "#define WITH_DTRACE 1" >>confdefs.h ++ ++ with_dtrace="Sun" ++ DTRACEOBJS="Python/dtrace.o" ++ DTRADEHDRS="" ++ elif dtrace -h -o /dev/null -s $srcdir/Include/pydtrace.d ++ then ++ ++$as_echo "#define WITH_DTRACE 1" >>confdefs.h ++ ++ with_dtrace="Apple" ++ DTRACEOBJS="" ++ DTRADEHDRS="pydtrace.h" ++ else ++ with_dtrace="no" ++ fi ++else ++ with_dtrace="no" ++fi ++ ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_dtrace" >&5 ++$as_echo "$with_dtrace" >&6; } ++ ++ ++ + # Check for --with-wctype-functions + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-wctype-functions" >&5 + $as_echo_n "checking for --with-wctype-functions... " >&6; } +diff -up ./pyconfig.h.in.autotool-intermediates ./pyconfig.h.in +--- ./pyconfig.h.in.autotool-intermediates 2013-04-09 11:24:01.020185806 +0200 ++++ ./pyconfig.h.in 2013-04-09 11:24:02.088183204 +0200 +@@ -18,6 +18,12 @@ + /* Define this if you have BeOS threads. */ + #undef BEOS_THREADS + ++/* Define to keep records on function call invocation */ ++#undef CALL_PROFILE ++ ++/* Define to keep records of the number of instances of each type */ ++#undef COUNT_ALLOCS ++ + /* Define if you have the Mach cthreads package */ + #undef C_THREADS + +@@ -1119,12 +1125,6 @@ + /* Define to profile with the Pentium timestamp counter */ + #undef WITH_TSC + +-/* Define to keep records of the number of instances of each type */ +-#undef COUNT_ALLOCS +- +-/* Define to keep records on function call invocation */ +-#undef CALL_PROFILE +- + /* Define if you want pymalloc to be disabled when running under valgrind */ + #undef WITH_VALGRIND + diff --git a/SOURCES/libpython.stp b/SOURCES/libpython.stp new file mode 100644 index 0000000..56cf2fb --- /dev/null +++ b/SOURCES/libpython.stp @@ -0,0 +1,17 @@ +/* Systemtap tapset to make it easier to trace Python */ + +/* + Define python.function.entry/return: +*/ +probe python.function.entry = process("python").library("LIBRARY_PATH").mark("function__entry") +{ + filename = user_string($arg1); + funcname = user_string($arg2); + lineno = $arg3; +} +probe python.function.return = process("python").library("LIBRARY_PATH").mark("function__return") +{ + filename = user_string($arg1); + funcname = user_string($arg2); + lineno = $arg3; +} diff --git a/SOURCES/macros.python2 b/SOURCES/macros.python2 new file mode 100644 index 0000000..982b51f --- /dev/null +++ b/SOURCES/macros.python2 @@ -0,0 +1,4 @@ +%__python2 /usr/bin/python2 +%python2_sitelib %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())") +%python2_sitearch %(%{__python2} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))") +%python2_version %(%{__python2} -c "import sys; sys.stdout.write(sys.version[:3])") diff --git a/SOURCES/pyfuntop.stp b/SOURCES/pyfuntop.stp new file mode 100644 index 0000000..f235a23 --- /dev/null +++ b/SOURCES/pyfuntop.stp @@ -0,0 +1,21 @@ +#!/usr/bin/stap + +global fn_calls; + +probe python.function.entry +{ + fn_calls[pid(), filename, funcname, lineno] += 1; +} + +probe timer.ms(1000) { + printf("\033[2J\033[1;1H") /* clear screen */ + printf("%6s %80s %6s %30s %6s\n", + "PID", "FILENAME", "LINE", "FUNCTION", "CALLS") + foreach ([pid, filename, funcname, lineno] in fn_calls- limit 20) { + printf("%6d %80s %6d %30s %6d\n", + pid, filename, lineno, funcname, + fn_calls[pid, filename, funcname, lineno]); + } + + delete fn_calls; +} diff --git a/SOURCES/pynche b/SOURCES/pynche new file mode 100644 index 0000000..368d740 --- /dev/null +++ b/SOURCES/pynche @@ -0,0 +1,2 @@ +#!/bin/bash +exec `python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(plat_specific = True))"`/pynche/pynche diff --git a/SOURCES/python-2.5-cflags.patch b/SOURCES/python-2.5-cflags.patch new file mode 100644 index 0000000..32243bf --- /dev/null +++ b/SOURCES/python-2.5-cflags.patch @@ -0,0 +1,11 @@ +--- Python-2.5c1/Makefile.pre.in.cflags 2006-08-18 11:05:40.000000000 -0400 ++++ Python-2.5c1/Makefile.pre.in 2006-08-18 11:09:26.000000000 -0400 +@@ -334,7 +334,7 @@ + + # Build the interpreter + $(BUILDPYTHON): Modules/python.o $(LIBRARY) $(LDLIBRARY) +- $(LINKCC) $(LDFLAGS) $(LINKFORSHARED) -o $@ \ ++ $(LINKCC) $(CFLAGS) $(LDFLAGS) $(LINKFORSHARED) -o $@ \ + Modules/python.o \ + $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) + diff --git a/SOURCES/python-2.5.1-plural-fix.patch b/SOURCES/python-2.5.1-plural-fix.patch new file mode 100644 index 0000000..040adaf --- /dev/null +++ b/SOURCES/python-2.5.1-plural-fix.patch @@ -0,0 +1,12 @@ +diff -up Python-2.5.1/Lib/gettext.py.plural Python-2.5.1/Lib/gettext.py +--- Python-2.5.1/Lib/gettext.py.plural 2007-09-10 11:38:57.000000000 -0400 ++++ Python-2.5.1/Lib/gettext.py 2007-09-10 11:39:00.000000000 -0400 +@@ -299,6 +299,8 @@ class GNUTranslations(NullTranslations): + item = item.strip() + if not item: + continue ++ if item.startswith("#"): ++ continue + if ':' in item: + k, v = item.split(':', 1) + k = k.strip().lower() diff --git a/SOURCES/python-2.5.1-sqlite-encoding.patch b/SOURCES/python-2.5.1-sqlite-encoding.patch new file mode 100644 index 0000000..ff2a3f8 --- /dev/null +++ b/SOURCES/python-2.5.1-sqlite-encoding.patch @@ -0,0 +1,24 @@ +diff -up Python-2.5.1/Lib/sqlite3/dbapi2.py.encoding Python-2.5.1/Lib/sqlite3/dbapi2.py +--- Python-2.5.1/Lib/sqlite3/dbapi2.py.encoding 2007-09-14 10:41:50.000000000 -0400 ++++ Python-2.5.1/Lib/sqlite3/dbapi2.py 2007-09-14 10:42:00.000000000 -0400 +@@ -1,7 +1,6 @@ +-# -*- coding: iso-8859-1 -*- + # pysqlite2/dbapi2.py: the DB-API 2.0 interface + # +-# Copyright (C) 2004-2005 Gerhard H�ring ++# Copyright (C) 2004-2005 Gerhard Haering + # + # This file is part of pysqlite. + # +diff -up Python-2.5.1/Lib/sqlite3/__init__.py.encoding Python-2.5.1/Lib/sqlite3/__init__.py +--- Python-2.5.1/Lib/sqlite3/__init__.py.encoding 2007-09-14 10:41:47.000000000 -0400 ++++ Python-2.5.1/Lib/sqlite3/__init__.py 2007-09-14 10:42:06.000000000 -0400 +@@ -1,7 +1,6 @@ +-#-*- coding: ISO-8859-1 -*- + # pysqlite2/__init__.py: the pysqlite2 package. + # +-# Copyright (C) 2005 Gerhard H�ring ++# Copyright (C) 2005 Gerhard Haering + # + # This file is part of pysqlite. + # diff --git a/SOURCES/python-2.6-rpath.patch b/SOURCES/python-2.6-rpath.patch new file mode 100644 index 0000000..43e3ec4 --- /dev/null +++ b/SOURCES/python-2.6-rpath.patch @@ -0,0 +1,12 @@ +diff -up Python-2.6/configure.ac.rpath Python-2.6/configure.ac +--- Python-2.6/configure.ac.rpath 2008-11-24 02:51:06.000000000 -0500 ++++ Python-2.6/configure.ac 2008-11-24 02:51:21.000000000 -0500 +@@ -729,7 +729,7 @@ if test $enable_shared = "yes"; then + ;; + OSF*) + LDLIBRARY='libpython$(VERSION).so' +- BLDLIBRARY='-rpath $(LIBDIR) -L. -lpython$(VERSION)' ++ BLDLIBRARY='-L. -lpython$(VERSION)' + RUNSHARED=LD_LIBRARY_PATH=`pwd`:${LD_LIBRARY_PATH} + ;; + atheos*) diff --git a/SOURCES/python-2.6.4-distutils-rpath.patch b/SOURCES/python-2.6.4-distutils-rpath.patch new file mode 100644 index 0000000..f156507 --- /dev/null +++ b/SOURCES/python-2.6.4-distutils-rpath.patch @@ -0,0 +1,20 @@ +diff -up Python-2.6.4/Lib/distutils/unixccompiler.py.distutils-rpath Python-2.6.4/Lib/distutils/unixccompiler.py +--- Python-2.6.4/Lib/distutils/unixccompiler.py.distutils-rpath 2009-09-09 04:34:06.000000000 -0400 ++++ Python-2.6.4/Lib/distutils/unixccompiler.py 2010-03-15 21:33:25.000000000 -0400 +@@ -142,6 +142,16 @@ class UnixCCompiler(CCompiler): + if sys.platform == "cygwin": + exe_extension = ".exe" + ++ def _fix_lib_args(self, libraries, library_dirs, runtime_library_dirs): ++ """Remove standard library path from rpath""" ++ libraries, library_dirs, runtime_library_dirs = \ ++ CCompiler._fix_lib_args(self, libraries, library_dirs, ++ runtime_library_dirs) ++ libdir = sysconfig.get_config_var('LIBDIR') ++ if runtime_library_dirs and (libdir in runtime_library_dirs): ++ runtime_library_dirs.remove(libdir) ++ return libraries, library_dirs, runtime_library_dirs ++ + def preprocess(self, source, + output_file=None, macros=None, include_dirs=None, + extra_preargs=None, extra_postargs=None): diff --git a/SOURCES/python-2.7-lib64-sysconfig.patch b/SOURCES/python-2.7-lib64-sysconfig.patch new file mode 100644 index 0000000..0cef361 --- /dev/null +++ b/SOURCES/python-2.7-lib64-sysconfig.patch @@ -0,0 +1,44 @@ +diff -up Python-2.7/Lib/sysconfig.py.lib64-sysconfig Python-2.7/Lib/sysconfig.py +--- Python-2.7/Lib/sysconfig.py.lib64-sysconfig 2010-07-08 14:18:41.386898476 -0400 ++++ Python-2.7/Lib/sysconfig.py 2010-07-08 14:22:02.837896461 -0400 +@@ -7,20 +7,20 @@ from os.path import pardir, realpath + + _INSTALL_SCHEMES = { + 'posix_prefix': { +- 'stdlib': '{base}/lib/python{py_version_short}', +- 'platstdlib': '{platbase}/lib/python{py_version_short}', ++ 'stdlib': '{base}/lib64/python{py_version_short}', ++ 'platstdlib': '{platbase}/lib64/python{py_version_short}', + 'purelib': '{base}/lib/python{py_version_short}/site-packages', +- 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', ++ 'platlib': '{platbase}/lib64/python{py_version_short}/site-packages', + 'include': '{base}/include/python{py_version_short}', + 'platinclude': '{platbase}/include/python{py_version_short}', + 'scripts': '{base}/bin', + 'data': '{base}', + }, + 'posix_home': { +- 'stdlib': '{base}/lib/python', +- 'platstdlib': '{base}/lib/python', ++ 'stdlib': '{base}/lib64/python', ++ 'platstdlib': '{base}/lib64/python', + 'purelib': '{base}/lib/python', +- 'platlib': '{base}/lib/python', ++ 'platlib': '{base}/lib64/python', + 'include': '{base}/include/python', + 'platinclude': '{base}/include/python', + 'scripts': '{base}/bin', +@@ -65,10 +65,10 @@ _INSTALL_SCHEMES = { + 'data' : '{userbase}', + }, + 'posix_user': { +- 'stdlib': '{userbase}/lib/python{py_version_short}', +- 'platstdlib': '{userbase}/lib/python{py_version_short}', ++ 'stdlib': '{userbase}/lib64/python{py_version_short}', ++ 'platstdlib': '{userbase}/lib64/python{py_version_short}', + 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', +- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', ++ 'platlib': '{userbase}/lib64/python{py_version_short}/site-packages', + 'include': '{userbase}/include/python{py_version_short}', + 'scripts': '{userbase}/bin', + 'data' : '{userbase}', diff --git a/SOURCES/python-2.7.1-config.patch b/SOURCES/python-2.7.1-config.patch new file mode 100644 index 0000000..6976d5c --- /dev/null +++ b/SOURCES/python-2.7.1-config.patch @@ -0,0 +1,283 @@ +--- Python-2.7.4/Modules/Setup.dist.rhconfig 2013-04-06 16:02:34.000000000 +0200 ++++ Python-2.7.4/Modules/Setup.dist 2013-04-08 10:05:16.369985654 +0200 +@@ -153,7 +153,7 @@ GLHACK=-Dclear=__GLclear + # modules are to be built as shared libraries (see above for more + # detail; also note that *static* reverses this effect): + +-#*shared* ++*shared* + + # GNU readline. Unlike previous Python incarnations, GNU readline is + # now incorporated in an optional module, configured in the Setup file +@@ -163,77 +163,77 @@ GLHACK=-Dclear=__GLclear + # it, depending on your system -- see the GNU readline instructions. + # It's okay for this to be a shared library, too. + +-#readline readline.c -lreadline -ltermcap ++readline readline.c -lreadline -ltermcap + + + # Modules that should always be present (non UNIX dependent): + +-#array arraymodule.c # array objects +-#cmath cmathmodule.c _math.c # -lm # complex math library functions +-#math mathmodule.c _math.c # -lm # math library functions, e.g. sin() +-#_struct _struct.c # binary structure packing/unpacking +-#time timemodule.c # -lm # time operations and variables +-#operator operator.c # operator.add() and similar goodies +-#_testcapi _testcapimodule.c # Python C API test module +-#_random _randommodule.c # Random number generator +-#_collections _collectionsmodule.c # Container types ++array arraymodule.c # array objects ++cmath cmathmodule.c _math.c # -lm # complex math library functions ++math mathmodule.c _math.c # -lm # math library functions, e.g. sin() ++_struct _struct.c # binary structure packing/unpacking ++time timemodule.c # -lm # time operations and variables ++operator operator.c # operator.add() and similar goodies ++_testcapi _testcapimodule.c # Python C API test module ++_random _randommodule.c # Random number generator ++_collections _collectionsmodule.c # Container types + #_heapq _heapqmodule.c # Heapq type +-#itertools itertoolsmodule.c # Functions creating iterators for efficient looping +-#strop stropmodule.c # String manipulations +-#_functools _functoolsmodule.c # Tools for working with functions and callable objects ++itertools itertoolsmodule.c # Functions creating iterators for efficient looping ++strop stropmodule.c # String manipulations ++_functools _functoolsmodule.c # Tools for working with functions and callable objects + #_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator + #_pickle _pickle.c # pickle accelerator + #datetime datetimemodule.c # date/time type +-#_bisect _bisectmodule.c # Bisection algorithms ++_bisect _bisectmodule.c # Bisection algorithms + +-#unicodedata unicodedata.c # static Unicode character database ++unicodedata unicodedata.c # static Unicode character database + + # access to ISO C locale support +-#_locale _localemodule.c # -lintl ++_locale _localemodule.c # -lintl + + # Standard I/O baseline + #_io -I$(srcdir)/Modules/_io _io/bufferedio.c _io/bytesio.c _io/fileio.c _io/iobase.c _io/_iomodule.c _io/stringio.c _io/textio.c + + + # Modules with some UNIX dependencies -- on by default: + # (If you have a really backward UNIX, select and socket may not be + # supported...) + +-#fcntl fcntlmodule.c # fcntl(2) and ioctl(2) +-#spwd spwdmodule.c # spwd(3) +-#grp grpmodule.c # grp(3) +-#select selectmodule.c # select(2); not on ancient System V ++fcntl fcntlmodule.c # fcntl(2) and ioctl(2) ++spwd spwdmodule.c # spwd(3) ++grp grpmodule.c # grp(3) ++select selectmodule.c # select(2); not on ancient System V + + # Memory-mapped files (also works on Win32). +-#mmap mmapmodule.c ++mmap mmapmodule.c + + # CSV file helper +-#_csv _csv.c ++_csv _csv.c + + # Socket module helper for socket(2) +-#_socket socketmodule.c timemodule.c ++_socket socketmodule.c timemodule.c + + # Socket module helper for SSL support; you must comment out the other + # socket line above, and possibly edit the SSL variable: + #SSL=/usr/local/ssl +-#_ssl _ssl.c \ +-# -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ +-# -L$(SSL)/lib -lssl -lcrypto ++_ssl _ssl.c \ ++ -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ ++ -L$(SSL)/lib -lssl -lcrypto + + # The crypt module is now disabled by default because it breaks builds + # on many systems (where -lcrypt is needed), e.g. Linux (I believe). + # + # First, look at Setup.config; configure may have set this for you. + +-#crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems ++crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems + + + # Some more UNIX dependent modules -- off by default, since these + # are not supported by all UNIX systems: + +-#nis nismodule.c -lnsl # Sun yellow pages -- not everywhere +-#termios termios.c # Steen Lumholt's termios module +-#resource resource.c # Jeremy Hylton's rlimit interface ++nis nismodule.c -lnsl # Sun yellow pages -- not everywhere ++termios termios.c # Steen Lumholt's termios module ++resource resource.c # Jeremy Hylton's rlimit interface + + + # Multimedia modules -- off by default. +@@ -238,8 +238,8 @@ GLHACK=-Dclear=__GLclear + # #993173 says audioop works on 64-bit platforms, though. + # These represent audio samples or images as strings: + +-#audioop audioop.c # Operations on audio samples +-#imageop imageop.c # Operations on images ++audioop audioop.c # Operations on audio samples ++imageop imageop.c # Operations on images + + + # Note that the _md5 and _sha modules are normally only built if the +@@ -249,14 +249,14 @@ GLHACK=-Dclear=__GLclear + # Message-Digest Algorithm, described in RFC 1321. The necessary files + # md5.c and md5.h are included here. + +-#_md5 md5module.c md5.c ++_md5 md5module.c md5.c + + + # The _sha module implements the SHA checksum algorithms. + # (NIST's Secure Hash Algorithms.) +-#_sha shamodule.c +-#_sha256 sha256module.c +-#_sha512 sha512module.c ++_sha shamodule.c ++_sha256 sha256module.c ++_sha512 sha512module.c + + + # SGI IRIX specific modules -- off by default. +@@ -303,12 +303,12 @@ GLHACK=-Dclear=__GLclear + # A Linux specific module -- off by default; this may also work on + # some *BSDs. + +-#linuxaudiodev linuxaudiodev.c ++linuxaudiodev linuxaudiodev.c + + + # George Neville-Neil's timing module: + +-#timing timingmodule.c ++timing timingmodule.c + + + # The _tkinter module. +@@ -323,7 +323,7 @@ GLHACK=-Dclear=__GLclear + # every system. + + # *** Always uncomment this (leave the leading underscore in!): +-# _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ ++_tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ + # *** Uncomment and edit to reflect where your Tcl/Tk libraries are: + # -L/usr/local/lib \ + # *** Uncomment and edit to reflect where your Tcl/Tk headers are: +@@ -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: +@@ -342,7 +342,7 @@ GLHACK=-Dclear=__GLclear + # *** Uncomment and edit for TOGL extension only: + # -DWITH_TOGL togl.c \ + # *** Uncomment and edit to reflect your Tcl/Tk versions: +-# -ltk8.2 -ltcl8.2 \ ++ -ltk -ltcl \ + # *** Uncomment and edit to reflect where your X11 libraries are: + # -L/usr/X11R6/lib \ + # *** Or uncomment this for Solaris: +@@ -352,7 +352,7 @@ GLHACK=-Dclear=__GLclear + # *** Uncomment for AIX: + # -lld \ + # *** Always uncomment this; X11 libraries to link with: +-# -lX11 ++ -lX11 + + # Lance Ellinghaus's syslog module + #syslog syslogmodule.c # syslog daemon interface +@@ -374,7 +374,7 @@ GLHACK=-Dclear=__GLclear + # it is a highly experimental and dangerous device for calling + # *arbitrary* C functions in *arbitrary* shared libraries: + +-#dl dlmodule.c ++dl dlmodule.c + + + # Modules that provide persistent dictionary-like semantics. You will +@@ -397,7 +397,7 @@ GLHACK=-Dclear=__GLclear + # + # First, look at Setup.config; configure may have set this for you. + +-#gdbm gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm ++gdbm gdbmmodule.c -lgdbm + + + # Sleepycat Berkeley DB interface. +@@ -412,11 +412,9 @@ GLHACK=-Dclear=__GLclear + # + # Edit the variables DB and DBLIBVERto point to the db top directory + # and the subdirectory of PORT where you built it. +-#DB=/usr/local/BerkeleyDB.4.0 +-#DBLIBVER=4.0 +-#DBINC=$(DB)/include +-#DBLIB=$(DB)/lib +-#_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER) ++DBINC=/usr/include/libdb ++DBLIB=/usr/lib ++_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb + + # Historical Berkeley DB 1.85 + # +@@ -431,14 +430,14 @@ GLHACK=-Dclear=__GLclear + + + # Helper module for various ascii-encoders +-#binascii binascii.c ++binascii binascii.c + + # Fred Drake's interface to the Python parser +-#parser parsermodule.c ++parser parsermodule.c + + # cStringIO and cPickle +-#cStringIO cStringIO.c +-#cPickle cPickle.c ++cStringIO cStringIO.c ++cPickle cPickle.c + + + # Lee Busby's SIGFPE modules. +@@ -461,7 +460,7 @@ GLHACK=-Dclear=__GLclear + # Andrew Kuchling's zlib module. + # This require zlib 1.1.3 (or later). + # See http://www.gzip.org/zlib/ +-#zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz ++zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz + + # Interface to the Expat XML parser + # +@@ -480,14 +479,14 @@ GLHACK=-Dclear=__GLclear + # Hye-Shik Chang's CJKCodecs + + # multibytecodec is required for all the other CJK codec modules +-#_multibytecodec cjkcodecs/multibytecodec.c ++_multibytecodec cjkcodecs/multibytecodec.c + +-#_codecs_cn cjkcodecs/_codecs_cn.c +-#_codecs_hk cjkcodecs/_codecs_hk.c +-#_codecs_iso2022 cjkcodecs/_codecs_iso2022.c +-#_codecs_jp cjkcodecs/_codecs_jp.c +-#_codecs_kr cjkcodecs/_codecs_kr.c +-#_codecs_tw cjkcodecs/_codecs_tw.c ++_codecs_cn cjkcodecs/_codecs_cn.c ++_codecs_hk cjkcodecs/_codecs_hk.c ++_codecs_iso2022 cjkcodecs/_codecs_iso2022.c ++_codecs_jp cjkcodecs/_codecs_jp.c ++_codecs_kr cjkcodecs/_codecs_kr.c ++_codecs_tw cjkcodecs/_codecs_tw.c + + # Example -- included for reference only: + # xx xxmodule.c diff --git a/SOURCES/python-2.7.1-fix_test_abc_with_COUNT_ALLOCS.patch b/SOURCES/python-2.7.1-fix_test_abc_with_COUNT_ALLOCS.patch new file mode 100644 index 0000000..bb38281 --- /dev/null +++ b/SOURCES/python-2.7.1-fix_test_abc_with_COUNT_ALLOCS.patch @@ -0,0 +1,27 @@ +diff -up Python-2.7.1/Lib/test/test_abc.py.cache_leak Python-2.7.1/Lib/test/test_abc.py +--- Python-2.7.1/Lib/test/test_abc.py.cache_leak 2010-12-28 18:06:35.551938356 -0500 ++++ Python-2.7.1/Lib/test/test_abc.py 2010-12-28 18:09:09.021059202 -0500 +@@ -3,6 +3,8 @@ + + """Unit tests for abc.py.""" + ++import sys ++ + import unittest, weakref + from test import test_support + +@@ -229,8 +231,12 @@ class TestABC(unittest.TestCase): + # Trigger cache. + C().f() + del C +- test_support.gc_collect() +- self.assertEqual(r(), None) ++ # This doesn't work in our debug build, presumably due to its use ++ # of COUNT_ALLOCS, which makes heap-allocated types immortal (once ++ # they've ever had an instance): ++ if not hasattr(sys, 'getcounts'): ++ test_support.gc_collect() ++ self.assertEqual(r(), None) + + def test_main(): + test_support.run_unittest(TestABC) diff --git a/SOURCES/python-2.7.2-add-extension-suffix-to-python-config.patch b/SOURCES/python-2.7.2-add-extension-suffix-to-python-config.patch new file mode 100644 index 0000000..d1ff052 --- /dev/null +++ b/SOURCES/python-2.7.2-add-extension-suffix-to-python-config.patch @@ -0,0 +1,18 @@ +diff -up Python-2.7.2/Misc/python-config.in.add-extension-suffix-to-python-config Python-2.7.2/Misc/python-config.in +--- Python-2.7.2/Misc/python-config.in.add-extension-suffix-to-python-config 2011-08-23 18:15:41.832497124 -0400 ++++ Python-2.7.2/Misc/python-config.in 2011-08-23 18:17:25.854490011 -0400 +@@ -6,7 +6,7 @@ import getopt + from distutils import sysconfig + + valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags', +- 'ldflags', 'help'] ++ 'ldflags', 'extension-suffix', 'help'] + + def exit_with_usage(code=1): + print >>sys.stderr, "Usage: %s [%s]" % (sys.argv[0], +@@ -54,3 +54,5 @@ for opt in opt_flags: + libs.extend(getvar('LINKFORSHARED').split()) + print ' '.join(libs) + ++ elif opt == '--extension-suffix': ++ print (sys.pydebug and "_d" or "") + sysconfig.get_config_var('SO') diff --git a/SOURCES/python-2.7.3-debug-build.patch b/SOURCES/python-2.7.3-debug-build.patch new file mode 100644 index 0000000..5b6cda7 --- /dev/null +++ b/SOURCES/python-2.7.3-debug-build.patch @@ -0,0 +1,292 @@ +diff -up Python-2.7.3/configure.ac.debug-build Python-2.7.3/configure.ac +--- Python-2.7.3/configure.ac.debug-build 2012-04-18 19:46:22.066498521 -0400 ++++ Python-2.7.3/configure.ac 2012-04-18 19:46:22.078498372 -0400 +@@ -635,7 +635,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) + +@@ -780,8 +780,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} + case $ac_sys_system in + FreeBSD*) +@@ -905,6 +905,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? + +diff -up Python-2.7.3/Lib/distutils/command/build_ext.py.debug-build Python-2.7.3/Lib/distutils/command/build_ext.py +--- Python-2.7.3/Lib/distutils/command/build_ext.py.debug-build 2012-04-09 19:07:29.000000000 -0400 ++++ Python-2.7.3/Lib/distutils/command/build_ext.py 2012-04-18 19:46:22.079498360 -0400 +@@ -676,7 +676,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 +@@ -761,6 +764,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 -up Python-2.7.3/Lib/distutils/sysconfig.py.debug-build Python-2.7.3/Lib/distutils/sysconfig.py +--- Python-2.7.3/Lib/distutils/sysconfig.py.debug-build 2012-04-18 19:46:21.988499499 -0400 ++++ Python-2.7.3/Lib/distutils/sysconfig.py 2012-04-18 19:46:22.080498348 -0400 +@@ -85,7 +85,8 @@ def get_python_inc(plat_specific=0, pref + # 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": +@@ -250,7 +251,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 -up Python-2.7.3/Lib/distutils/tests/test_install.py.debug-build Python-2.7.3/Lib/distutils/tests/test_install.py +--- Python-2.7.3/Lib/distutils/tests/test_install.py.debug-build 2012-04-18 19:46:21.997499385 -0400 ++++ Python-2.7.3/Lib/distutils/tests/test_install.py 2012-04-18 19:46:22.080498348 -0400 +@@ -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 -up Python-2.7.3/Makefile.pre.in.debug-build Python-2.7.3/Makefile.pre.in +--- Python-2.7.3/Makefile.pre.in.debug-build 2012-04-18 19:46:22.073498437 -0400 ++++ Python-2.7.3/Makefile.pre.in 2012-04-18 19:48:46.336694896 -0400 +@@ -102,8 +102,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 +@@ -117,6 +117,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@ +@@ -180,8 +186,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_BUILD=@PYTHON_FOR_BUILD@ + _PYTHON_HOST_PLATFORM=@_PYTHON_HOST_PLATFORM@ +@@ -413,7 +419,7 @@ sharedmods: $(BUILDPYTHON) + $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ + $(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) $@; \ +@@ -796,18 +802,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) +@@ -820,7 +826,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); \ +@@ -970,10 +976,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) +@@ -994,13 +1001,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: all python-config ++libainstall: all python$(DEBUG_SUFFIX)-config + @for i in $(LIBDIR) $(LIBP) $(LIBPL) $(LIBPC); \ + do \ + if test ! -d $(DESTDIR)$$i; then \ +@@ -1016,11 +1023,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 -up Python-2.7.3/Misc/python-config.in.debug-build Python-2.7.3/Misc/python-config.in +--- Python-2.7.3/Misc/python-config.in.debug-build 2012-04-09 19:07:33.000000000 -0400 ++++ Python-2.7.3/Misc/python-config.in 2012-04-18 19:46:22.082498324 -0400 +@@ -45,7 +45,7 @@ for opt in opt_flags: + + elif opt in ('--libs', '--ldflags'): + libs = getvar('LIBS').split() + getvar('SYSLIBS').split() +- libs.append('-lpython'+pyver) ++ libs.append('-lpython' + pyver + (sys.pydebug and "_d" or "")) + # add the prefix/lib/pythonX.Y/config dir, but only if there is no + # shared library in prefix/lib/. + if opt == '--ldflags': +diff -up Python-2.7.3/Modules/makesetup.debug-build Python-2.7.3/Modules/makesetup +--- Python-2.7.3/Modules/makesetup.debug-build 2012-04-09 19:07:34.000000000 -0400 ++++ Python-2.7.3/Modules/makesetup 2012-04-18 19:46:22.083498312 -0400 +@@ -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 -up Python-2.7.3/Python/dynload_shlib.c.debug-build Python-2.7.3/Python/dynload_shlib.c +--- Python-2.7.3/Python/dynload_shlib.c.debug-build 2012-04-09 19:07:35.000000000 -0400 ++++ Python-2.7.3/Python/dynload_shlib.c 2012-04-18 19:46:22.083498312 -0400 +@@ -46,11 +46,16 @@ const struct filedescr _PyImport_DynLoad + {"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 -up Python-2.7.3/Python/sysmodule.c.debug-build Python-2.7.3/Python/sysmodule.c +--- Python-2.7.3/Python/sysmodule.c.debug-build 2012-04-09 19:07:35.000000000 -0400 ++++ Python-2.7.3/Python/sysmodule.c 2012-04-18 19:46:22.083498312 -0400 +@@ -1506,6 +1506,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/SOURCES/python-2.7.3-lib64.patch b/SOURCES/python-2.7.3-lib64.patch new file mode 100644 index 0000000..71f32c5 --- /dev/null +++ b/SOURCES/python-2.7.3-lib64.patch @@ -0,0 +1,196 @@ +diff -up Python-2.7.3/Lib/distutils/command/install.py.lib64 Python-2.7.3/Lib/distutils/command/install.py +--- Python-2.7.3/Lib/distutils/command/install.py.lib64 2012-04-09 19:07:29.000000000 -0400 ++++ Python-2.7.3/Lib/distutils/command/install.py 2013-02-19 13:58:20.446015129 -0500 +@@ -42,14 +42,14 @@ else: + INSTALL_SCHEMES = { + 'unix_prefix': { + 'purelib': '$base/lib/python$py_version_short/site-packages', +- 'platlib': '$platbase/lib/python$py_version_short/site-packages', ++ 'platlib': '$platbase/lib64/python$py_version_short/site-packages', + 'headers': '$base/include/python$py_version_short/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'unix_home': { + 'purelib': '$base/lib/python', +- 'platlib': '$base/lib/python', ++ 'platlib': '$base/lib64/python', + 'headers': '$base/include/python/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', +diff -up Python-2.7.3/Lib/distutils/sysconfig.py.lib64 Python-2.7.3/Lib/distutils/sysconfig.py +--- Python-2.7.3/Lib/distutils/sysconfig.py.lib64 2012-04-09 19:07:29.000000000 -0400 ++++ Python-2.7.3/Lib/distutils/sysconfig.py 2013-02-19 13:58:20.446015129 -0500 +@@ -114,8 +114,12 @@ def get_python_lib(plat_specific=0, stan + prefix = plat_specific and EXEC_PREFIX or PREFIX + + if os.name == "posix": ++ if plat_specific or standard_lib: ++ lib = "lib64" ++ else: ++ lib = "lib" + libpython = os.path.join(prefix, +- "lib", "python" + get_python_version()) ++ lib, "python" + get_python_version()) + if standard_lib: + return libpython + else: +diff -up Python-2.7.3/Lib/site.py.lib64 Python-2.7.3/Lib/site.py +--- Python-2.7.3/Lib/site.py.lib64 2012-04-09 19:07:31.000000000 -0400 ++++ Python-2.7.3/Lib/site.py 2013-02-19 13:58:20.447015128 -0500 +@@ -300,12 +300,16 @@ def getsitepackages(): + if sys.platform in ('os2emx', 'riscos'): + sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) + elif os.sep == '/': ++ sitepackages.append(os.path.join(prefix, "lib64", ++ "python" + sys.version[:3], ++ "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", + "python" + sys.version[:3], + "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", "site-python")) + else: + sitepackages.append(prefix) ++ sitepackages.append(os.path.join(prefix, "lib64", "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", "site-packages")) + if sys.platform == "darwin": + # for framework builds *only* we add the standard Apple +diff -up Python-2.7.3/Lib/test/test_site.py.lib64 Python-2.7.3/Lib/test/test_site.py +--- Python-2.7.3/Lib/test/test_site.py.lib64 2012-04-09 19:07:32.000000000 -0400 ++++ Python-2.7.3/Lib/test/test_site.py 2013-02-19 13:58:20.447015128 -0500 +@@ -241,17 +241,20 @@ class HelperFunctionsTests(unittest.Test + self.assertEqual(dirs[2], wanted) + elif os.sep == '/': + # OS X non-framwework builds, Linux, FreeBSD, etc +- self.assertEqual(len(dirs), 2) +- wanted = os.path.join('xoxo', 'lib', 'python' + sys.version[:3], ++ self.assertEqual(len(dirs), 3) ++ wanted = os.path.join('xoxo', 'lib64', 'python' + sys.version[:3], + 'site-packages') + self.assertEqual(dirs[0], wanted) +- wanted = os.path.join('xoxo', 'lib', 'site-python') ++ wanted = os.path.join('xoxo', 'lib', 'python' + sys.version[:3], ++ 'site-packages') + self.assertEqual(dirs[1], wanted) ++ wanted = os.path.join('xoxo', 'lib', 'site-python') ++ self.assertEqual(dirs[2], wanted) + else: + # other platforms + self.assertEqual(len(dirs), 2) + self.assertEqual(dirs[0], 'xoxo') +- wanted = os.path.join('xoxo', 'lib', 'site-packages') ++ wanted = os.path.join('xoxo', 'lib64', 'site-packages') + self.assertEqual(dirs[1], wanted) + + class PthFile(object): +diff -up Python-2.7.3/Makefile.pre.in.lib64 Python-2.7.3/Makefile.pre.in +--- Python-2.7.3/Makefile.pre.in.lib64 2013-02-19 13:58:20.435015131 -0500 ++++ Python-2.7.3/Makefile.pre.in 2013-02-19 13:58:20.447015128 -0500 +@@ -97,7 +97,7 @@ LIBDIR= @libdir@ + MANDIR= @mandir@ + INCLUDEDIR= @includedir@ + CONFINCLUDEDIR= $(exec_prefix)/include +-SCRIPTDIR= $(prefix)/lib ++SCRIPTDIR= $(prefix)/lib64 + + # Detailed destination directories + BINLIBDEST= $(LIBDIR)/python$(VERSION) +diff -up Python-2.7.3/Modules/getpath.c.lib64 Python-2.7.3/Modules/getpath.c +--- Python-2.7.3/Modules/getpath.c.lib64 2012-04-09 19:07:34.000000000 -0400 ++++ Python-2.7.3/Modules/getpath.c 2013-02-19 13:58:20.448015128 -0500 +@@ -117,8 +117,8 @@ + #endif + + #ifndef PYTHONPATH +-#define PYTHONPATH PREFIX "/lib/python" VERSION ":" \ +- EXEC_PREFIX "/lib/python" VERSION "/lib-dynload" ++#define PYTHONPATH PREFIX "/lib64/python" VERSION ":" \ ++ EXEC_PREFIX "/lib64/python" VERSION "/lib-dynload" + #endif + + #ifndef LANDMARK +@@ -129,7 +129,7 @@ static char prefix[MAXPATHLEN+1]; + static char exec_prefix[MAXPATHLEN+1]; + static char progpath[MAXPATHLEN+1]; + static char *module_search_path = NULL; +-static char lib_python[] = "lib/python" VERSION; ++static char lib_python[] = "lib64/python" VERSION; + + static void + reduce(char *dir) +@@ -528,7 +528,7 @@ calculate_path(void) + } + else + strncpy(zip_path, PREFIX, MAXPATHLEN); +- joinpath(zip_path, "lib/python00.zip"); ++ joinpath(zip_path, "lib64/python00.zip"); + bufsz = strlen(zip_path); /* Replace "00" with version */ + zip_path[bufsz - 6] = VERSION[0]; + zip_path[bufsz - 5] = VERSION[2]; +@@ -538,7 +538,7 @@ calculate_path(void) + fprintf(stderr, + "Could not find platform dependent libraries \n"); + strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); +- joinpath(exec_prefix, "lib/lib-dynload"); ++ joinpath(exec_prefix, "lib64/lib-dynload"); + } + /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ + +diff -up Python-2.7.3/Modules/Setup.dist.lib64 Python-2.7.3/Modules/Setup.dist +--- Python-2.7.3/Modules/Setup.dist.lib64 2013-02-19 13:58:20.442015131 -0500 ++++ Python-2.7.3/Modules/Setup.dist 2013-02-19 14:02:25.255998391 -0500 +@@ -413,7 +413,7 @@ gdbm gdbmmodule.c -lgdbm + # Edit the variables DB and DBLIBVERto point to the db top directory + # and the subdirectory of PORT where you built it. + DBINC=/usr/include/libdb +-DBLIB=/usr/lib ++DBLIB=/usr/lib64 + _bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb + + # Historical Berkeley DB 1.85 +@@ -459,7 +459,7 @@ cPickle cPickle.c + # Andrew Kuchling's zlib module. + # This require zlib 1.1.3 (or later). + # See http://www.gzip.org/zlib/ +-zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz ++zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib64 -lz + + # Interface to the Expat XML parser + # +diff -up Python-2.7.3/setup.py.lib64 Python-2.7.3/setup.py +--- Python-2.7.3/setup.py.lib64 2012-04-09 19:07:36.000000000 -0400 ++++ Python-2.7.3/setup.py 2013-02-19 13:58:20.449015129 -0500 +@@ -369,7 +369,7 @@ class PyBuildExt(build_ext): + + def detect_modules(self): + # Ensure that /usr/local is always used +- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') ++ add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib64') + add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') + self.add_gcc_paths() + self.add_multiarch_paths() +@@ -677,11 +677,11 @@ class PyBuildExt(build_ext): + elif curses_library: + readline_libs.append(curses_library) + elif self.compiler.find_library_file(lib_dirs + +- ['/usr/lib/termcap'], ++ ['/usr/lib64/termcap'], + 'termcap'): + readline_libs.append('termcap') + exts.append( Extension('readline', ['readline.c'], +- library_dirs=['/usr/lib/termcap'], ++ library_dirs=['/usr/lib64/termcap'], + extra_link_args=readline_extra_link_args, + libraries=readline_libs) ) + else: +@@ -715,8 +715,8 @@ class PyBuildExt(build_ext): + if krb5_h: + ssl_incs += krb5_h + ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs, +- ['/usr/local/ssl/lib', +- '/usr/contrib/ssl/lib/' ++ ['/usr/local/ssl/lib64', ++ '/usr/contrib/ssl/lib64/' + ] ) + + if (ssl_incs is not None and diff --git a/SOURCES/python-2.7rc1-binutils-no-dep.patch b/SOURCES/python-2.7rc1-binutils-no-dep.patch new file mode 100644 index 0000000..ee6157c --- /dev/null +++ b/SOURCES/python-2.7rc1-binutils-no-dep.patch @@ -0,0 +1,14 @@ +diff -up Python-2.7rc1/Lib/ctypes/util.py.binutils-no-dep Python-2.7rc1/Lib/ctypes/util.py +--- Python-2.7rc1/Lib/ctypes/util.py.binutils-no-dep 2010-03-15 09:42:23.000000000 -0400 ++++ Python-2.7rc1/Lib/ctypes/util.py 2010-06-06 05:03:02.155975210 -0400 +@@ -140,7 +140,9 @@ elif os.name == "posix": + dump = f.read() + rv = f.close() + if rv == 10: +- raise OSError, 'objdump command not found' ++ return os.path.basename(f) # This is good for GLibc, I think, ++ # and a dep on binutils is big (for ++ # live CDs). + f = os.popen(cmd) + try: + data = f.read() diff --git a/SOURCES/python-2.7rc1-socketmodule-constants.patch b/SOURCES/python-2.7rc1-socketmodule-constants.patch new file mode 100644 index 0000000..c32e103 --- /dev/null +++ b/SOURCES/python-2.7rc1-socketmodule-constants.patch @@ -0,0 +1,64 @@ +--- Python-2.7rc1/Modules/socketmodule.c.socketmodule 2010-05-09 10:46:46.000000000 -0400 ++++ Python-2.7rc1/Modules/socketmodule.c 2010-06-07 23:04:19.374234780 -0400 +@@ -4783,6 +4783,61 @@ init_socket(void) + PyModule_AddIntConstant(m, "SO_SETFIB", SO_SETFIB); + #endif + ++#ifdef SO_SNDBUFFORCE ++ PyModule_AddIntConstant(m, "SO_SNDBUFFORCE", SO_SNDBUFFORCE); ++#endif ++#ifdef SO_RCVBUFFORCE ++ PyModule_AddIntConstant(m, "SO_RCVBUFFORCE", SO_RCVBUFFORCE); ++#endif ++#ifdef SO_NO_CHECK ++ PyModule_AddIntConstant(m, "SO_NO_CHECK", SO_NO_CHECK); ++#endif ++#ifdef SO_PRIORITY ++ PyModule_AddIntConstant(m, "SO_PRIORITY", SO_PRIORITY); ++#endif ++#ifdef SO_BSDCOMPAT ++ PyModule_AddIntConstant(m, "SO_BSDCOMPAT", SO_BSDCOMPAT); ++#endif ++#ifdef SO_PASSCRED ++ PyModule_AddIntConstant(m, "SO_PASSCRED", SO_PASSCRED); ++#endif ++#ifdef SO_PEERCRED ++ PyModule_AddIntConstant(m, "SO_PEERCRED", SO_PEERCRED); ++#endif ++#ifdef SO_SECURITY_AUTHENTICATION ++ PyModule_AddIntConstant(m, "SO_SECURITY_AUTHENTICATION", SO_SECURITY_AUTHENTICATION); ++#endif ++#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT ++ PyModule_AddIntConstant(m, "SO_SECURITY_ENCRYPTION_TRANSPORT", SO_SECURITY_ENCRYPTION_TRANSPORT); ++#endif ++#ifdef SO_SECURITY_ENCRYPTION_NETWORK ++ PyModule_AddIntConstant(m, "SO_SECURITY_ENCRYPTION_NETWORK", SO_SECURITY_ENCRYPTION_NETWORK); ++#endif ++#ifdef SO_BINDTODEVICE ++ PyModule_AddIntConstant(m, "SO_BINDTODEVICE", SO_BINDTODEVICE); ++#endif ++#ifdef SO_ATTACH_FILTER ++ PyModule_AddIntConstant(m, "SO_ATTACH_FILTER", SO_ATTACH_FILTER); ++#endif ++#ifdef SO_DETACH_FILTER ++ PyModule_AddIntConstant(m, "SO_DETACH_FILTER", SO_DETACH_FILTER); ++#endif ++#ifdef SO_PEERNAME ++ PyModule_AddIntConstant(m, "SO_PEERNAME", SO_PEERNAME); ++#endif ++#ifdef SO_TIMESTAMP ++ PyModule_AddIntConstant(m, "SO_TIMESTAMP", SO_TIMESTAMP); ++#endif ++#ifdef SO_PEERSEC ++ PyModule_AddIntConstant(m, "SO_PEERSEC", SO_PEERSEC); ++#endif ++#ifdef SO_PASSSEC ++ PyModule_AddIntConstant(m, "SO_PASSSEC", SO_PASSSEC); ++#endif ++#ifdef SO_TIMESTAMPNS ++ PyModule_AddIntConstant(m, "SO_TIMESTAMPNS", SO_TIMESTAMPNS); ++#endif ++ + /* Maximum number of connections for "listen" */ + #ifdef SOMAXCONN + PyModule_AddIntConstant(m, "SOMAXCONN", SOMAXCONN); diff --git a/SOURCES/python-2.7rc1-socketmodule-constants2.patch b/SOURCES/python-2.7rc1-socketmodule-constants2.patch new file mode 100644 index 0000000..896ac88 --- /dev/null +++ b/SOURCES/python-2.7rc1-socketmodule-constants2.patch @@ -0,0 +1,19 @@ +diff -up Python-2.7rc1/Modules/socketmodule.c.socketmodule2 Python-2.7rc1/Modules/socketmodule.c +--- Python-2.7rc1/Modules/socketmodule.c.socketmodule2 2010-06-07 23:06:59.133498087 -0400 ++++ Python-2.7rc1/Modules/socketmodule.c 2010-06-07 23:11:51.249520087 -0400 +@@ -5253,6 +5253,15 @@ init_socket(void) + #ifdef TCP_QUICKACK + PyModule_AddIntConstant(m, "TCP_QUICKACK", TCP_QUICKACK); + #endif ++#ifdef TCP_CONGESTION ++ PyModule_AddIntConstant(m, "TCP_CONGESTION", TCP_CONGESTION); ++#endif ++#ifdef TCP_MD5SIG ++ PyModule_AddIntConstant(m, "TCP_MD5SIG", TCP_MD5SIG); ++#endif ++#ifdef TCP_MD5SIG_MAXKEYLEN ++ PyModule_AddIntConstant(m, "TCP_MD5SIG_MAXKEYLEN", TCP_MD5SIG_MAXKEYLEN); ++#endif + + + /* IPX options */ diff --git a/SOURCES/pythondeps.sh b/SOURCES/pythondeps.sh new file mode 100755 index 0000000..10a060a --- /dev/null +++ b/SOURCES/pythondeps.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +[ $# -ge 1 ] || { + cat > /dev/null + exit 0 +} + +case $1 in +-P|--provides) + shift + # Match buildroot/payload paths of the form + # /PATH/OF/BUILDROOT/usr/bin/pythonMAJOR.MINOR + # generating a line of the form + # python(abi) = MAJOR.MINOR + # (Don't match against -config tools e.g. /usr/bin/python2.6-config) + grep "/usr/bin/python.\..$" \ + | sed -e "s|.*/usr/bin/python\(.\..\)|python(abi) = \1|" + ;; +-R|--requires) + shift + # Match buildroot paths of the form + # /PATH/OF/BUILDROOT/usr/lib/pythonMAJOR.MINOR/ and + # /PATH/OF/BUILDROOT/usr/lib64/pythonMAJOR.MINOR/ + # generating (uniqely) lines of the form: + # python(abi) = MAJOR.MINOR + grep "/usr/lib[^/]*/python.\../.*" \ + | sed -e "s|.*/usr/lib[^/]*/python\(.\..\)/.*|python(abi) = \1|g" \ + | sort | uniq + ;; +esac + +exit 0 diff --git a/SOURCES/systemtap-example.stp b/SOURCES/systemtap-example.stp new file mode 100644 index 0000000..164333a --- /dev/null +++ b/SOURCES/systemtap-example.stp @@ -0,0 +1,19 @@ +/* + Example usage of the Python systemtap tapset to show a nested view of all + Python function calls (and returns) across the whole system. + + Run this using + stap systemtap-example.stp + to instrument all Python processes on the system, or (for example) using + stap systemtap-example.stp -c COMMAND + to instrument a specific program (implemented in Python) +*/ +probe python.function.entry +{ + printf("%s => %s in %s:%d\n", thread_indent(1), funcname, filename, lineno); +} + +probe python.function.return +{ + printf("%s <= %s in %s:%d\n", thread_indent(-1), funcname, filename, lineno); +} diff --git a/SPECS/python.spec b/SPECS/python.spec new file mode 100644 index 0000000..fab3009 --- /dev/null +++ b/SPECS/python.spec @@ -0,0 +1,3493 @@ +# ====================================================== +# Conditionals and other variables controlling the build +# ====================================================== + +%{!?__python_ver:%global __python_ver EMPTY} +#global __python_ver 27 +%global unicode ucs4 + +%if "%{__python_ver}" != "EMPTY" +%global main_python 0 +%global python python%{__python_ver} +%global tkinter tkinter%{__python_ver} +%else +%global main_python 1 +%global python python +%global tkinter tkinter +%endif + +%global pybasever 2.7 +%global pylibdir %{_libdir}/python%{pybasever} +%global tools_dir %{pylibdir}/Tools +%global demo_dir %{pylibdir}/Demo +%global doc_tools_dir %{pylibdir}/Doc/tools +%global dynload_dir %{pylibdir}/lib-dynload +%global site_packages %{pylibdir}/site-packages + +# Python's configure script defines SOVERSION, and this is used in the Makefile +# to determine INSTSONAME, the name of the libpython DSO: +# LDLIBRARY='libpython$(VERSION).so' +# INSTSONAME="$LDLIBRARY".$SOVERSION +# We mirror this here in order to make it easier to add the -gdb.py hooks. +# (if these get out of sync, the payload of the libs subpackage will fail +# and halt the build) +%global py_SOVERSION 1.0 +%global py_INSTSONAME_optimized libpython%{pybasever}.so.%{py_SOVERSION} +%global py_INSTSONAME_debug libpython%{pybasever}_d.so.%{py_SOVERSION} + +%global with_debug_build 1 + +# Disabled for now: +%global with_huntrleaks 0 + +%global with_gdb_hooks 1 + +%global with_systemtap 1 + +# some arches don't have valgrind so we need to disable its support on them +%ifarch %{ix86} x86_64 ppc %{power64} s390x aarch64 +%global with_valgrind 1 +%else +%global with_valgrind 0 +%endif + +%global with_gdbm 1 + +# Turn this to 0 to turn off the "check" phase: +%global run_selftest_suite 1 + +# Some of the files below /usr/lib/pythonMAJOR.MINOR/test (e.g. bad_coding.py) +# are deliberately invalid, leading to SyntaxError exceptions if they get +# byte-compiled. +# +# These errors are ignored by the normal python build, and aren't normally a +# problem in the buildroots since /usr/bin/python isn't present. +# +# However, for the case where we're rebuilding the python srpm on a machine +# that does have python installed we need to set this to avoid +# brp-python-bytecompile treating these as fatal errors: +# +%global _python_bytecompile_errors_terminate_build 0 + +# We need to get a newer configure generated out of configure.in for the following +# patches: +# patch 4 (CFLAGS) +# patch 52 (valgrind) +# patch 55 (systemtap) +# patch 145 (linux2) +# +# For patch 55 (systemtap), we need to get a new header for configure to use +# +# configure.in requires autoconf-2.65, but the version in Fedora is currently +# autoconf-2.66 +# +# For now, we'll generate a patch to the generated configure script and +# pyconfig.h.in on a machine that has a local copy of autoconf 2.65 +# +# Instructions on obtaining such a copy can be seen at +# http://bugs.python.org/issue7997 +# +# To make it easy to regenerate the patch, this specfile can be run in two +# ways: +# (i) regenerate_autotooling_patch 0 : the normal approach: prep the +# source tree using a pre-generated patch to the "configure" script, and do a +# full build +# (ii) regenerate_autotooling_patch 1 : intended to be run on a developer's +# workstation: prep the source tree without patching configure, then rerun a +# local copy of autoconf-2.65, regenerate the patch, then exit, without doing +# the rest of the build +%global regenerate_autotooling_patch 0 + + +# ================== +# Top-level metadata +# ================== +Summary: An interpreted, interactive, object-oriented programming language +Name: %{python} +# Remember to also rebase python-docs when changing this: +Version: 2.7.5 +Release: 18%{?dist} +License: Python +Group: Development/Languages +Requires: %{python}-libs%{?_isa} = %{version}-%{release} +Provides: python-abi = %{pybasever} +Provides: python(abi) = %{pybasever} + + +# ======================= +# Build-time requirements +# ======================= + +# (keep this list alphabetized) + +BuildRequires: autoconf +BuildRequires: bluez-libs-devel +BuildRequires: bzip2 +BuildRequires: bzip2-devel + +# expat 2.1.0 added the symbol XML_SetHashSalt without bumping SONAME. We use +# it (in pyexpat) in order to enable the fix in Python-2.7.3 for CVE-2012-0876: +BuildRequires: expat-devel >= 2.1.0 + +BuildRequires: findutils +BuildRequires: gcc-c++ +%if %{with_gdbm} +BuildRequires: gdbm-devel +%endif +BuildRequires: glibc-devel +BuildRequires: gmp-devel +BuildRequires: libdb-devel +BuildRequires: libffi-devel +BuildRequires: libGL-devel +BuildRequires: libX11-devel +BuildRequires: ncurses-devel +BuildRequires: openssl-devel +BuildRequires: pkgconfig +BuildRequires: readline-devel +BuildRequires: sqlite-devel + +%if 0%{?with_systemtap} +BuildRequires: systemtap-sdt-devel +# (this introduces a circular dependency, in that systemtap-sdt-devel's +# /usr/bin/dtrace is a python script) +%global tapsetdir /usr/share/systemtap/tapset +%endif # with_systemtap + +BuildRequires: tar +BuildRequires: tcl-devel +BuildRequires: tix-devel +BuildRequires: tk-devel + +%if 0%{?with_valgrind} +BuildRequires: valgrind-devel +%endif + +BuildRequires: zlib-devel + + + +# ======================= +# Source code and patches +# ======================= + +Source: http://www.python.org/ftp/python/%{version}/Python-%{version}.tar.xz + +# Work around bug 562906 until it's fixed in rpm-build by providing a fixed +# version of pythondeps.sh: +Source2: pythondeps.sh +%global __python_requires %{SOURCE2} + +# Systemtap tapset to make it easier to use the systemtap static probes +# (actually a template; LIBRARY_PATH will get fixed up during install) +# Written by dmalcolm; not yet sent upstream +Source3: libpython.stp + + +# Example systemtap script using the tapset +# Written by wcohen, mjw, dmalcolm; not yet sent upstream +Source4: systemtap-example.stp + +# Another example systemtap script that uses the tapset +# Written by dmalcolm; not yet sent upstream +Source5: pyfuntop.stp + +# Supply various useful macros for building python 2 modules: +# __python2, python2_sitelib, python2_sitearch, python2_version +Source6: macros.python2 + +Source7: pynche + +# Modules/Setup.dist is ultimately used by the "makesetup" script to construct +# the Makefile and config.c +# +# Upstream leaves many things disabled by default, to try to make it easy as +# possible to build the code on as many platforms as possible. +# +# TODO: many modules can also now be built by setup.py after the python binary +# has been built; need to assess if we should instead build things there +# +# We patch it downstream as follows: +# - various modules are built by default by upstream as static libraries; +# we built them as shared libraries +# - build the "readline" module (appears to also be handled by setup.py now) +# - enable the build of the following modules: +# - array arraymodule.c # array objects +# - cmath cmathmodule.c # -lm # complex math library functions +# - math mathmodule.c # -lm # math library functions, e.g. sin() +# - _struct _struct.c # binary structure packing/unpacking +# - time timemodule.c # -lm # time operations and variables +# - operator operator.c # operator.add() and similar goodies +# - _weakref _weakref.c # basic weak reference support +# - _testcapi _testcapimodule.c # Python C API test module +# - _random _randommodule.c # Random number generator +# - _collections _collectionsmodule.c # Container types +# - itertools itertoolsmodule.c +# - strop stropmodule.c +# - _functools _functoolsmodule.c +# - _bisect _bisectmodule.c # Bisection algorithms +# - unicodedata unicodedata.c # static Unicode character database +# - _locale _localemodule.c +# - fcntl fcntlmodule.c # fcntl(2) and ioctl(2) +# - spwd spwdmodule.c # spwd(3) +# - grp grpmodule.c # grp(3) +# - select selectmodule.c # select(2); not on ancient System V +# - mmap mmapmodule.c # Memory-mapped files +# - _csv _csv.c # CSV file helper +# - _socket socketmodule.c # Socket module helper for socket(2) +# - _ssl _ssl.c +# - crypt cryptmodule.c -lcrypt # crypt(3) +# - 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 +# - audioop audioop.c # Operations on audio samples +# - imageop imageop.c # Operations on images +# - _md5 md5module.c md5.c +# - _sha shamodule.c +# - _sha256 sha256module.c +# - _sha512 sha512module.c +# - linuxaudiodev linuxaudiodev.c +# - timing timingmodule.c +# - _tkinter _tkinter.c tkappinit.c +# - dl dlmodule.c +# - gdbm gdbmmodule.c +# - _bsddb _bsddb.c +# - binascii binascii.c +# - parser parsermodule.c +# - cStringIO cStringIO.c +# - cPickle cPickle.c +# - zlib zlibmodule.c +# - _multibytecodec cjkcodecs/multibytecodec.c +# - _codecs_cn cjkcodecs/_codecs_cn.c +# - _codecs_hk cjkcodecs/_codecs_hk.c +# - _codecs_iso2022 cjkcodecs/_codecs_iso2022.c +# - _codecs_jp cjkcodecs/_codecs_jp.c +# - _codecs_kr cjkcodecs/_codecs_kr.c +# - _codecs_tw cjkcodecs/_codecs_tw.c +Patch0: python-2.7.1-config.patch + +# Removes the "-g" option from "pydoc", for some reason; I believe +# (dmalcolm 2010-01-29) that this was introduced in this change: +# - fix pydoc (#68082) +# in 2.2.1-12 as a response to the -g option needing TkInter installed +# (Red Hat Linux 8) +# Not upstream +Patch1: 00001-pydocnogui.patch + +# Add $(CFLAGS) to the linker arguments when linking the "python" binary +# since some architectures (sparc64) need this (rhbz:199373). +# Not yet filed upstream +Patch4: python-2.5-cflags.patch + +# Work around a bug in Python' gettext module relating to the "Plural-Forms" +# header (rhbz:252136) +# Related to upstream issues: +# http://bugs.python.org/issue1448060 and http://bugs.python.org/issue1475523 +# though the proposed upstream patches are, alas, different +Patch6: python-2.5.1-plural-fix.patch + +# This patch was listed in the changelog as: +# * Fri Sep 14 2007 Jeremy Katz - 2.5.1-11 +# - fix encoding of sqlite .py files to work around weird encoding problem +# in Turkish (#283331) +# A traceback attached to rhbz 244016 shows the problem most clearly: a +# traceback on attempting to import the sqlite module, with: +# "SyntaxError: encoding problem: with BOM (__init__.py, line 1)" +# This seems to come from Parser/tokenizer.c:check_coding_spec +# Our patch changes two source files within sqlite3, removing the +# "coding: ISO-8859-1" specs and character E4 = U+00E4 = +# LATIN SMALL LETTER A WITH DIAERESIS from in ghaering's surname. +# +# It may be that the conversion of "ISO-8859-1" to "iso-8859-1" is thwarted +# by the implementation of "tolower" in the Turkish locale; see: +# https://bugzilla.redhat.com/show_bug.cgi?id=191096#c9 +# +# TODO: Not yet sent upstream, and appears to me (dmalcolm 2010-01-29) that +# it may be papering over a symptom +Patch7: python-2.5.1-sqlite-encoding.patch + +# FIXME: Lib/ctypes/util.py posix implementation defines a function +# _get_soname(f). Upstreams's implementation of this uses objdump to read the +# SONAME from a library; we avoid this, apparently to minimize space +# requirements on the live CD: +# (rhbz:307221) +Patch10: python-2.7rc1-binutils-no-dep.patch + +# Upstream as of Python 2.7.3: +# Patch11: python-2.7rc1-codec-ascii-tolower.patch + +# Add various constants to the socketmodule (rhbz#436560): +# TODO: these patches were added in 2.5.1-22 and 2.5.1-24 but appear not to +# have been sent upstream yet: +Patch13: python-2.7rc1-socketmodule-constants.patch +Patch14: python-2.7rc1-socketmodule-constants2.patch + +# Remove an "-rpath $(LIBDIR)" argument from the linkage args in configure.in: +# FIXME: is this for OSF, not Linux? +Patch16: python-2.6-rpath.patch + +# Fixup distutils/unixccompiler.py to remove standard library path from rpath: +# Adapted from Patch0 in ivazquez' python3000 specfile, removing usage of +# super() as it's an old-style class +Patch17: python-2.6.4-distutils-rpath.patch + +# 00055 # +# Systemtap support: add statically-defined probe points +# Patch based on upstream bug: http://bugs.python.org/issue4111 +# fixed up by mjw and wcohen for 2.6.2, then fixed up by dmalcolm for 2.6.4 +# then rewritten by mjw (attachment 390110 of rhbz 545179), then reformatted +# for 2.7rc1 by dmalcolm: +Patch55: 00055-systemtap.patch + +# Upstream as of Python 2.7.4 +# Patch101: 00101-lib64-regex.patch + +# Only used when "%{_lib}" == "lib64" +# Fixup various paths throughout the build and in distutils from "lib" to "lib64", +# and add the /usr/lib64/pythonMAJOR.MINOR/site-packages to sitedirs, in front of +# /usr/lib/pythonMAJOR.MINOR/site-packages +# Not upstream +Patch102: python-2.7.3-lib64.patch + +# Python 2.7 split out much of the path-handling from distutils/sysconfig.py to +# a new sysconfig.py (in r77704). +# We need to make equivalent changes to that new file to ensure that the stdlib +# and platform-specific code go to /usr/lib64 not /usr/lib, on 64-bit archs: +Patch103: python-2.7-lib64-sysconfig.patch + +# 00104 # +# Only used when "%{_lib}" == "lib64" +# Another lib64 fix, for distutils/tests/test_install.py; not upstream: +Patch104: 00104-lib64-fix-for-test_install.patch + +# 00111 # +# Patch the Makefile.pre.in so that the generated Makefile doesn't try to build +# a libpythonMAJOR.MINOR.a (bug 550692): +# Downstream only: not appropriate for upstream +Patch111: 00111-no-static-lib.patch + +# 00112 # +# Patch to support building both optimized vs debug stacks DSO ABIs, sharing +# the same .py and .pyc files, using "_d.so" to signify a debug build of an +# extension module. +# +# Based on Debian's patch for the same, +# http://patch-tracker.debian.org/patch/series/view/python2.6/2.6.5-2/debug-build.dpatch +# +# (which was itself based on the upstream Windows build), but with some +# changes: +# +# * Debian's patch to dynload_shlib.c looks for module_d.so, then module.so, +# but this can potentially find a module built against the wrong DSO ABI. We +# instead search for just module_d.so in a debug build +# +# * We remove this change from configure.in's build of the Makefile: +# SO=$DEBUG_EXT.so +# so that sysconfig.py:customize_compiler stays with shared_lib_extension='.so' +# on debug builds, so that UnixCCompiler.find_library_file can find system +# libraries (otherwise "make sharedlibs" fails to find system libraries, +# erroneously looking e.g. for "libffi_d.so" rather than "libffi.so") +# +# * We change Lib/distutils/command/build_ext.py:build_ext.get_ext_filename +# to add the _d there, when building an extension. This way, "make sharedlibs" +# can build ctypes, by finding the sysmtem libffi.so (rather than failing to +# find "libffi_d.so"), and builds the module as _ctypes_d.so +# +# * Similarly, update build_ext:get_libraries handling of Py_ENABLE_SHARED by +# appending "_d" to the python library's name for the debug configuration +# +# * We modify Modules/makesetup to add the "_d" to the generated Makefile +# rules for the various Modules/*.so targets +# +# This may introduce issues when building an extension that links directly +# against another extension (e.g. users of NumPy?), but seems more robust when +# searching for external libraries +# +# * We don't change Lib/distutils/command/build.py: build.build_purelib to +# embed plat_specifier, leaving it as is, as pure python builds should be +# unaffected by these differences (we'll be sharing the .py and .pyc files) +# +# * We introduce DEBUG_SUFFIX as well as DEBUG_EXT: +# - DEBUG_EXT is used by ELF files (names and SONAMEs); it will be "_d" for +# a debug build +# - DEBUG_SUFFIX is used by filesystem paths; it will be "-debug" for a +# debug build +# +# Both will be empty in an optimized build. "_d" contains characters that +# are valid ELF metadata, but this leads to various ugly filesystem paths (such +# as the include path), and DEBUG_SUFFIX allows these paths to have more natural +# names. Changing this requires changes elsewhere in the distutils code. +# +# * We add DEBUG_SUFFIX to PYTHON in the Makefile, so that the two +# configurations build parallel-installable binaries with different names +# ("python-debug" vs "python"). +# +# * Similarly, we add DEBUG_SUFFIX within python-config and +# python$(VERSION)-config, so that the two configuration get different paths +# for these. +# +# See also patch 130 below +# +Patch112: python-2.7.3-debug-build.patch + + +# 00113 # +# Add configure-time support for the COUNT_ALLOCS and CALL_PROFILE options +# described at http://svn.python.org/projects/python/trunk/Misc/SpecialBuilds.txt +# so that if they are enabled, they will be in that build's pyconfig.h, so that +# extension modules will reliably use them +# Not yet sent upstream +Patch113: 00113-more-configuration-flags.patch + +# 00114 # +# Add flags for statvfs.f_flag to the constant list in posixmodule (i.e. "os") +# (rhbz:553020); partially upstream as http://bugs.python.org/issue7647 +# Not yet sent upstream +Patch114: 00114-statvfs-f_flag-constants.patch + +# Upstream as of Python 2.7.3: +# Patch115: make-pydoc-more-robust-001.patch + +# Upstream r79310 removed the "Modules" directory from sys.path when Python is +# running from the build directory on POSIX to fix a unit test (issue #8205). +# This seems to have broken the compileall.py done in "make install": it cannot +# find shared library extension modules at this point in the build (sys.path +# does not contain DESTDIR/usr/lib(64)/python-2.7/lib-dynload for some reason), +# leading to the build failing with: +# Traceback (most recent call last): +# File "/home/david/rpmbuild/BUILDROOT/python-2.7-0.1.rc2.fc14.x86_64/usr/lib64/python2.7/compileall.py", line 17, in +# import struct +# File "/home/david/rpmbuild/BUILDROOT/python-2.7-0.1.rc2.fc14.x86_64/usr/lib64/python2.7/struct.py", line 1, in +# from _struct import * +# ImportError: No module named _struct +# This patch adds the build Modules directory to build path. +Patch121: 00121-add-Modules-to-build-path.patch + +# 00125 # +# COUNT_ALLOCS is useful for debugging, but the upstream behaviour of always +# emitting debug info to stdout on exit is too verbose and makes it harder to +# use the debug build. Add a "PYTHONDUMPCOUNTS" environment variable which +# must be set to enable the output on exit +# Not yet sent upstream +Patch125: 00125-less-verbose-COUNT_ALLOCS.patch + +# Upstream as of Python 2.7.5 +# Patch126: fix-dbm_contains-on-64bit-bigendian.patch + +# Upstream as of Python 2.7.5 +# Patch127: fix-test_structmember-on-64bit-bigendian.patch + +# 2.7.1 (in r84230) added a test to test_abc which fails if python is +# configured with COUNT_ALLOCS, which is the case for our debug build +# (the COUNT_ALLOCS instrumentation keeps "C" alive). +# Not yet sent upstream +Patch128: python-2.7.1-fix_test_abc_with_COUNT_ALLOCS.patch + +# 00130 # +# Add "--extension-suffix" option to python-config and python-debug-config +# (rhbz#732808) +# +# This is adapted from 3.2's PEP-3149 support. +# +# Fedora's debug build has some non-standard features (see also patch 112 +# above), though largely shared with Debian/Ubuntu and Windows +# +# In particular, SO in the Makefile is currently always just ".so" for our +# python 2 optimized builds, but for python 2 debug it should be '_d.so', to +# distinguish the debug vs optimized ABI, following the pattern in the above +# patch. +# +# Not yet sent upstream +Patch130: python-2.7.2-add-extension-suffix-to-python-config.patch + +# 00131 # +# The four tests in test_io built on top of check_interrupted_write_retry +# fail when built in Koji, for ppc and ppc64; for some reason, the SIGALRM +# handlers are never called, and the call to write runs to completion +# (rhbz#732998) +Patch131: 00131-disable-tests-in-test_io.patch + +# 00132 # +# Add non-standard hooks to unittest for use in the "check" phase below, when +# running selftests within the build: +# @unittest._skipInRpmBuild(reason) +# for tests that hang or fail intermittently within the build environment, and: +# @unittest._expectedFailureInRpmBuild +# for tests that always fail within the build environment +# +# The hooks only take effect if WITHIN_PYTHON_RPM_BUILD is set in the +# environment, which we set manually in the appropriate portion of the "check" +# phase below (and which potentially other python-* rpms could set, to reuse +# these unittest hooks in their own "check" phases) +Patch132: 00132-add-rpmbuild-hooks-to-unittest.patch + +# 00133 # +# "dl" is deprecated, and test_dl doesn't work on 64-bit builds: +Patch133: 00133-skip-test_dl.patch + +# 00134 # +# Fix a failure in test_sys.py when configured with COUNT_ALLOCS enabled +# Not yet sent upstream +Patch134: 00134-fix-COUNT_ALLOCS-failure-in-test_sys.patch + +# 00135 # +# Skip "test_callback_in_cycle_resurrection" in a debug build, where it fails: +# Not yet sent upstream +Patch135: 00135-skip-test-within-test_weakref-in-debug-build.patch + +# 00136 # +# Some tests try to seek on sys.stdin, but don't work as expected when run +# within Koji/mock; skip them within the rpm build: +Patch136: 00136-skip-tests-of-seeking-stdin-in-rpmbuild.patch + +# 00137 # +# Some tests within distutils fail when run in an rpmbuild: +Patch137: 00137-skip-distutils-tests-that-fail-in-rpmbuild.patch + +# 00138 # +# Fixup some tests within distutils to work with how debug builds are set up: +Patch138: 00138-fix-distutils-tests-in-debug-build.patch + +# 00139 # +# ARM-specific: skip known failure in test_float: +# http://bugs.python.org/issue8265 (rhbz#706253) +Patch139: 00139-skip-test_float-known-failure-on-arm.patch + +# 00140 # +# Sparc-specific: skip known failure in test_ctypes: +# http://bugs.python.org/issue8314 (rhbz#711584) +# which appears to be a libffi bug +Patch140: 00140-skip-test_ctypes-known-failure-on-sparc.patch + +# 00141 # +# Fix test_gc's test_newinstance case when configured with COUNT_ALLOCS: +# Not yet sent upstream +Patch141: 00141-fix-test_gc_with_COUNT_ALLOCS.patch + +# 00142 # +# Some pty tests fail when run in mock (rhbz#714627): +Patch142: 00142-skip-failing-pty-tests-in-rpmbuild.patch + +# 00143 # +# Fix the --with-tsc option on ppc64, and rework it on 32-bit ppc to avoid +# aliasing violations (rhbz#698726) +# Sent upstream as http://bugs.python.org/issue12872 +Patch143: 00143-tsc-on-ppc.patch + +# 00144 # +# (Optionally) disable the gdbm module: +Patch144: 00144-no-gdbm.patch + +# 00145 # +# Upstream as of Python 2.7.3: +# Patch145: 00145-force-sys-platform-to-be-linux2.patch + +# 00146 # +# Support OpenSSL FIPS mode (e.g. when OPENSSL_FORCE_FIPS_MODE=1 is set) +# - handle failures from OpenSSL (e.g. on attempts to use MD5 in a +# FIPS-enforcing environment) +# - add a new "usedforsecurity" keyword argument to the various digest +# algorithms in hashlib so that you can whitelist a callsite with +# "usedforsecurity=False" +# (sent upstream for python 3 as http://bugs.python.org/issue9216; this is a +# backport to python 2.7; see RHEL6 patch 119) +# - enforce usage of the _hashlib implementation: don't fall back to the _md5 +# and _sha* modules (leading to clearer error messages if fips selftests +# fail) +# - don't build the _md5 and _sha* modules; rely on the _hashlib implementation +# of hashlib (for example, md5.py will use _hashlib's implementation of MD5, +# if permitted by the FIPS setting) +# (rhbz#563986) +Patch146: 00146-hashlib-fips.patch + +# 00147 # +# Add a sys._debugmallocstats() function +# Based on patch 202 from RHEL 5's python.spec, with updates from rhbz#737198 +# Sent upstream as http://bugs.python.org/issue14785 +Patch147: 00147-add-debug-malloc-stats.patch + +# 00148 # +# Upstream as of Python 2.7.3: +# Patch148: 00148-gdbm-1.9-magic-values.patch + +# 00149 # +# python3.spec's +# Patch149: 00149-backport-issue11254-pycache-bytecompilation-fix.patch +# is not relevant for Python 2 + +# 00150 # +# python3.spec has: +# Patch150: 00150-disable-rAssertAlmostEqual-cmath-on-ppc.patch +# as a workaround for a glibc bug on PPC (bz #750811) + +# 00151 # +# Upstream as of Python 2.7.3: +# Patch151: 00151-fork-deadlock.patch + +# 00152 # +# python3.spec has: +# Patch152: 00152-fix-test-gdb-regex.patch + +# 00153 # +# Strip out lines of the form "warning: Unable to open ..." from gdb's stderr +# when running test_gdb.py; also cope with change to gdb in F17 onwards in +# which values are printed as "v@entry" rather than just "v": +# Not yet sent upstream +Patch153: 00153-fix-test_gdb-noise.patch + +# 00154 # +# python3.spec on f15 has: +# Patch154: 00154-skip-urllib-test-requiring-working-DNS.patch + +# 00155 # +# Avoid allocating thunks in ctypes unless absolutely necessary, to avoid +# generating SELinux denials on "import ctypes" and "import uuid" when +# embedding Python within httpd (rhbz#814391) +Patch155: 00155-avoid-ctypes-thunks.patch + +# 00156 # +# Recent builds of gdb will only auto-load scripts from certain safe +# locations. Turn off this protection when running test_gdb in the selftest +# suite to ensure that it can load our -gdb.py script (rhbz#817072): +# Not yet sent upstream +Patch156: 00156-gdb-autoload-safepath.patch + +# 00157 # +# Update uid/gid handling throughout the standard library: uid_t and gid_t are +# unsigned 32-bit values, but existing code often passed them through C long +# values, which are signed 32-bit values on 32-bit architectures, leading to +# negative int objects for uid/gid values >= 2^31 on 32-bit architectures. +# +# Introduce _PyObject_FromUid/Gid to convert uid_t/gid_t values to python +# objects, using int objects where the value will fit (long objects otherwise), +# and _PyArg_ParseUid/Gid to convert int/long to uid_t/gid_t, with -1 allowed +# as a special case (since this is given special meaning by the chown syscall) +# +# Update standard library to use this throughout for uid/gid values, so that +# very large uid/gid values are round-trippable, and -1 remains usable. +# (rhbz#697470) +Patch157: 00157-uid-gid-overflows.patch + +# Upstream as of Python 2.7.4 +# Patch158: 00158-fix-hashlib-leak.patch + +# 00160 # +# python3.spec's +# Patch160: 00160-disable-test_fs_holes-in-rpm-build.patch +# is not relevant for Python 2 + +# 00161 # +# python3.spec has: +# Patch161: 00161-fix-test_tools-directory.patch +# which will likely become relevant for Python 2 next time we rebase + +# 00162 # +# python3.spec has: +# Patch162: 00162-distutils-sysconfig-fix-CC-options.patch + +# 00163 # +# python3.spec has: +# Patch163: 00163-disable-parts-of-test_socket-in-rpm-build.patch + +# 00164 # +# python3.spec has: +# Patch164: 00164-disable-interrupted_write-tests-on-ppc.patch + +# 00165 # +# Backport to Python 2 from Python 3.3 of improvements to the "crypt" module +# adding precanned ways of salting a password (rhbz#835021) +# Based on r88500 patch to py3k from Python 3.3 +# plus 6482dd1c11ed, 0586c699d467, 62994662676a, 74a1110a3b50, plus edits +# to docstrings to note that this additional functionality is not standard +# within 2.7 +Patch165: 00165-crypt-module-salt-backport.patch + +# 00166 # +# Bulletproof the gdb debugging hooks against the case where co_filename for +# a frame can't be read from the inferior process (rhbz#912025) +# +# Not yet sent upstream +Patch166: 00166-fix-fake-repr-in-gdb-hooks.patch + +# 00167 # +# Don't run any of the stack navigation tests in test_gdb when Python is +# optimized, since there appear to be many different ways in which gdb can +# fail to read the PyFrameObject* for arbitrary places in the callstack, +# presumably due to compiler optimization (rhbz#912025) +# +# Not yet sent upstream +Patch167: 00167-disable-stack-navigation-tests-when-optimized-in-test_gdb.patch + +# 00168 # +# Update distutils.sysconfig so that if CFLAGS is defined in the environment, +# when building extension modules, it is appended to the full compilation +# flags from Python's Makefile, rather than instead reducing the compilation +# flags to the subset within OPT and adding it to those. +# +# In particular, this should ensure that "-fno-strict-aliasing" is used by +# "python setup.py build" even when CFLAGS is defined in the environment. +# +# (rhbz#849994) +Patch168: 00168-distutils-cflags.patch + +# 00169 # +# Use SHA-256 rather than implicitly using MD5 within the challenge handling +# in multiprocessing.connection +# +# Sent upstream as http://bugs.python.org/issue17258 +# (rhbz#879695) +Patch169: 00169-avoid-implicit-usage-of-md5-in-multiprocessing.patch + +# 00170 # +# In debug builds, try to print repr() when a C-level assert fails in the +# garbage collector (typically indicating a reference-counting error +# somewhere else e.g in an extension module) +# Backported to 2.7 from a patch I sent upstream for py3k +# http://bugs.python.org/issue9263 (rhbz#614680) +# hiding the proposed new macros/functions within gcmodule.c to avoid exposing +# them within the extension API. +# (rhbz#850013) +Patch170: 00170-gc-assertions.patch + +# Upstream as of Python 2.7.4 +# Patch171: 00171-raise-correct-exception-when-dev-urandom-is-missing.patch + +# Upstream as of Python 2.7.4 +# Patch172: 00172-use-poll-for-multiprocessing-socket-connection.patch + +# 00173 # +# Workaround for ENOPROTOOPT seen in Koji within +# test.test_support.bind_port() +# (rhbz#913732) +Patch173: 00173-workaround-ENOPROTOOPT-in-bind_port.patch + +# 00174 # +# Workaround for failure to set up prefix/exec_prefix when running +# an embededed libpython that sets Py_SetProgramName() to a name not +# on $PATH when run from the root directory due to +# https://fedoraproject.org/wiki/Features/UsrMove +# e.g. cmpi-bindings under systemd (rhbz#817554): +Patch174: 00174-fix-for-usr-move.patch + +# 00175 # +# Upstream as of Python 2.7.5 +# Patch175: 00175-fix-configure-Wformat.patch + +# 00176 # +# python3.spec had: +# Patch176: 00176-upstream-issue16754-so-extension.patch +# doesn't affect python2 + +# 00177 # +# python3.spec has +# Patch177: 00177-platform-unicode.patch +# Does not affect python2 + +# 00178 # +# python3.spec has +# Patch178: 00178-dont-duplicate-flags-in-sysconfig.patch +# Does not affect python2 AFAICS (different sysconfig values initialization) + +# 00179 # +# python3.spec has +# Patch179: 00179-dont-raise-error-on-gdb-corrupted-frames-in-backtrace.patch +# Doesn't seem to affect python2 + +# 00180 # +# Enable building on ppc64p7 +# Not appropriate for upstream, Fedora-specific naming +Patch180: 00180-python-add-support-for-ppc64p7.patch + +# 00181 # +# Allow arbitrary timeout for Condition.wait, as reported in +# https://bugzilla.redhat.com/show_bug.cgi?id=917709 +# Upstream doesn't want this: http://bugs.python.org/issue17748 +# But we have no better solution downstream yet, and since there is +# no API breakage, we apply this patch. +# Doesn't apply to Python 3, where this is fixed otherwise and works. +Patch181: 00181-allow-arbitrary-timeout-in-condition-wait.patch + +# 00182 # +# python3.spec had +# Patch182: 00182-fix-test_gdb-test_threads.patch + +# 00183 # +# python3.spec has +# Patch183: 00183-cve-2013-2099-fix-ssl-match_hostname-dos.patch + +# 00184 # +# Fix for https://bugzilla.redhat.com/show_bug.cgi?id=979696 +# Fixes build of ctypes against libffi with multilib wrapper +# Python recognizes ffi.h only if it contains "#define LIBFFI_H", +# but the wrapper doesn't contain that, which makes the build fail +# We patch this by also accepting "#define ffi_wrapper_h" +Patch184: 00184-ctypes-should-build-with-libffi-multilib-wrapper.patch + +# 00185 # +# Makes urllib2 honor "no_proxy" enviroment variable for "ftp:" URLs +# when ftp_proxy is set +# Resolves rhbz#971267 +Patch185: 00185-urllib2-honors-noproxy-for-ftp.patch + +# 00186 # +# Fix memory leak of variable utf8 in marshal.c +# (rhbz#990554) +Patch186: 00186-memory-leak-marshalc.patch + +# 00187 # +# Add an explicit RPATH to pyexpat.so pointing at the directory +# containing the system expat (which has the extra XML_SetHashSalt +# symbol), to avoid an ImportError with a link error if there's an +# LD_LIBRARY_PATH containing a "vanilla" build of expat (without the +# symbol) (originally rhbz#833271, for rhel 7 rhbz#996665): +Patch187: 00187-add-RPATH-to-pyexpat.patch + +# 00188 # +# Fix for CVE-2013-4238 -- +# SSL module fails to handle NULL bytes inside subjectAltNames general names +# http://bugs.python.org/issue18709 +# rhbz#998781 +Patch188: 00188-CVE-2013-4238-hostname-check-bypass-in-SSL-module.patch + +# 00189 # +# Fixes gdb py-bt command not to raise exception while processing +# statements from eval +# rhbz#1008154 (patch by Attila Fazekas) +Patch189: 00189-gdb-py-bt-dont-raise-exception-from-eval.patch + +# 190 # +# Don't fail various gdb tests on ppc64 if glibc debug +# symbols are installed +Patch190: 00190-gdb-fix-ppc64-failures.patch + +# 00191 # +# Add explicit RPATH to _elementtree.so +# rhbz#1019345 +Patch191: 00191-add-RPATH-to-elementtree.patch + +# 00192 # +# Fix missing documentation for some keywords +# rhbz#1032116 +Patch192: 00192-Fix-missing-documentation-for-some-keywords.patch + +# 00193 # +# Fix buffer overflow (upstream patch, http://bugs.python.org/issue20246) +# rhbz#1062376 +Patch193: 00193-buffer-overflow.patch + +# 00194 # +# Make GDB test pass even if GDB prints program counter for +# the first trace frame +Patch194: 00194-gdb-dont-fail-on-frame-with-address.patch + +# (New patches go here ^^^) +# +# When adding new patches to "python" and "python3" in Fedora 17 onwards, +# please try to keep the patch numbers in-sync between the two specfiles: +# +# - use the same patch number across both specfiles for conceptually-equivalent +# fixes, ideally with the same name +# +# - when a patch is relevant to both specfiles, use the same introductory +# comment in both specfiles where possible (to improve "diff" output when +# comparing them) +# +# - when a patch is only relevant for one of the two specfiles, leave a gap +# in the patch numbering in the other specfile, adding a comment when +# omitting a patch, both in the manifest section here, and in the "prep" +# phase below +# +# Hopefully this will make it easier to ensure that all relevant fixes are +# applied to both versions. + +# This is the generated patch to "configure"; see the description of +# %{regenerate_autotooling_patch} +# above: +Patch5000: 05000-autotool-intermediates.patch + +# ====================================================== +# Additional metadata, and subpackages +# ====================================================== + +%if %{main_python} +Obsoletes: Distutils +Provides: Distutils +Obsoletes: python2 +Provides: python2 = %{version} +Obsoletes: python-elementtree <= 1.2.6 +Obsoletes: python-sqlite < 2.3.2 +Provides: python-sqlite = 2.3.2 +Obsoletes: python-ctypes < 1.0.1 +Provides: python-ctypes = 1.0.1 +Obsoletes: python-hashlib < 20081120 +Provides: python-hashlib = 20081120 +Obsoletes: python-uuid < 1.31 +Provides: python-uuid = 1.31 + +# python-sqlite2-2.3.5-5.fc18 was retired. Obsolete the old package here +# so it gets uninstalled on updates +%if 0%{?fedora} >= 17 +Obsoletes: python-sqlite2 <= 2.3.5-6 +%endif + +# python-argparse is part of python as of version 2.7 +# drop this Provides in F17 +# (having Obsoletes here caused problems with multilib; see rhbz#667984) +Provides: python-argparse = %{version}-%{release} +%endif + +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) + +URL: http://www.python.org/ + +%description +Python is an interpreted, interactive, object-oriented programming +language often compared to Tcl, Perl, Scheme or Java. Python includes +modules, classes, exceptions, very high level dynamic data types and +dynamic typing. Python supports interfaces to many system calls and +libraries, as well as to various windowing systems (X11, Motif, Tk, +Mac and MFC). + +Programmers can write new built-in modules for Python in C or C++. +Python can be used as an extension language for applications that need +a programmable interface. + +Note that documentation for Python is provided in the python-docs +package. + +This package provides the "python" executable; most of the actual +implementation is within the "python-libs" package. + +%package libs +Summary: Runtime libraries for Python +Group: Applications/System + +# Needed for ctypes, to load libraries, worked around for Live CDs size +# Requires: binutils + +# expat 2.1.0 added the symbol XML_SetHashSalt without bumping SONAME. We use +# this symbol (in pyexpat), so we must explicitly state this dependency to +# prevent "import pyexpat" from failing with a linker error if someone hasn't +# yet upgraded expat: +Requires: expat >= 2.1.0 + +%description libs +This package contains runtime libraries for use by Python: +- the libpython dynamic library, for use by applications that embed Python as +a scripting language, and by the main "python" executable +- the Python standard library + +%package devel +Summary: The libraries and header files needed for Python development +Group: Development/Libraries +Requires: %{python}%{?_isa} = %{version}-%{release} +Requires: pkgconfig +# Needed here because of the migration of Makefile from -devel to the main +# package +Conflicts: %{python} < %{version}-%{release} +%if %{main_python} +Obsoletes: python2-devel +Provides: python2-devel = %{version}-%{release} +%endif + +%description devel +The Python programming language's interpreter can be extended with +dynamically loaded extensions and can be embedded in other programs. +This package contains the header files and libraries needed to do +these types of tasks. + +Install python-devel if you want to develop Python extensions. The +python package will also need to be installed. You'll probably also +want to install the python-docs package, which contains Python +documentation. + +%package tools +Summary: A collection of development tools included with Python +Group: Development/Tools +Requires: %{name} = %{version}-%{release} +Requires: %{tkinter} = %{version}-%{release} +%if %{main_python} +Obsoletes: python2-tools +Provides: python2-tools = %{version} +%endif + +%description tools +This package includes several tools to help with the development of Python +programs, including IDLE (an IDE with editing and debugging facilities), a +color editor (pynche), and a python gettext program (pygettext.py). + +%package -n %{tkinter} +Summary: A graphical user interface for the Python scripting language +Group: Development/Languages +Requires: %{name} = %{version}-%{release} +%if %{main_python} +Obsoletes: tkinter2 +Provides: tkinter2 = %{version} +%endif + +%description -n %{tkinter} + +The Tkinter (Tk interface) program is an graphical user interface for +the Python scripting language. + +You should install the tkinter package if you'd like to use a graphical +user interface for Python programming. + +%package test +Summary: The test modules from the main python package +Group: Development/Languages +Requires: %{name} = %{version}-%{release} + +%description test + +The test modules from the main python package: %{name} +These have been removed to save space, as they are never or almost +never used in production. + +You might want to install the python-test package if you're developing python +code that uses more than just unittest and/or test_support.py. + +%if 0%{?with_debug_build} +%package debug +Summary: Debug version of the Python runtime +Group: Applications/System + +# The debug build is an all-in-one package version of the regular build, and +# shares the same .py/.pyc files and directories as the regular build. Hence +# we depend on all of the subpackages of the regular build: +Requires: %{name}%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-devel%{?_isa} = %{version}-%{release} +Requires: %{name}-test%{?_isa} = %{version}-%{release} +Requires: tkinter%{?_isa} = %{version}-%{release} +Requires: %{name}-tools%{?_isa} = %{version}-%{release} + +%description debug +python-debug provides a version of the Python runtime with numerous debugging +features enabled, aimed at advanced Python users, such as developers of Python +extension modules. + +This version uses more memory and will be slower than the regular Python build, +but is useful for tracking down reference-counting issues, and other bugs. + +The bytecodes are unchanged, so that .pyc files are compatible between the two +version of Python, but the debugging features mean that C/C++ extension modules +are ABI-incompatible with those built for the standard runtime. + +It shares installation directories with the standard Python runtime, so that +.py and .pyc files can be shared. All compiled extension modules gain a "_d" +suffix ("foo_d.so" rather than "foo.so") so that each Python implementation can +load its own extensions. +%endif # with_debug_build + + +# ====================================================== +# The prep phase of the build: +# ====================================================== + +%prep +%setup -q -n Python-%{version} + +%if 0%{?with_systemtap} +# Provide an example of usage of the tapset: +cp -a %{SOURCE4} . +cp -a %{SOURCE5} . +%endif # with_systemtap + +# Ensure that we're using the system copy of various libraries, rather than +# copies shipped by upstream in the tarball: +# Remove embedded copy of expat: +rm -r Modules/expat || exit 1 + +# Remove embedded copy of libffi: +for SUBDIR in darwin libffi libffi_arm_wince libffi_msvc libffi_osx ; do + rm -r Modules/_ctypes/$SUBDIR || exit 1 ; +done + +# Remove embedded copy of zlib: +rm -r Modules/zlib || exit 1 + +# Don't build upstream Python's implementation of these crypto algorithms; +# instead rely on _hashlib and OpenSSL. +# +# For example, in our builds md5.py uses always uses hashlib.md5 (rather than +# falling back to _md5 when hashlib.md5 is not available); hashlib.md5 is +# implemented within _hashlib via OpenSSL (and thus respects FIPS mode) +for f in md5module.c md5.c shamodule.c sha256module.c sha512module.c; do + rm Modules/$f +done + +# +# Apply patches: +# +%patch0 -p1 -b .rhconfig +%patch1 -p1 -b .no_gui +%patch4 -p1 -b .cflags +%patch6 -p1 -b .plural +%patch7 -p1 + +# Try not disabling egg-infos, bz#414711 +#patch50 -p1 -b .egginfo + +# patch101: upstream as of Python 2.7.4 +%if "%{_lib}" == "lib64" +%patch102 -p1 -b .lib64 +%patch103 -p1 -b .lib64-sysconfig +%patch104 -p1 +%endif + +%patch10 -p1 -b .binutils-no-dep +# patch11: upstream as of Python 2.7.3 +%patch13 -p1 -b .socketmodule +%patch14 -p1 -b .socketmodule2 +%patch16 -p1 -b .rpath +%patch17 -p1 -b .distutils-rpath + +%if 0%{?with_systemtap} +%patch55 -p1 -b .systemtap +%endif + +%patch111 -p1 -b .no-static-lib + +%patch112 -p1 -b .debug-build + +%patch113 -p1 -b .more-configuration-flags + +%patch114 -p1 -b .statvfs-f-flag-constants + +# patch115: upstream as of Python 2.7.3 + +%patch121 -p1 +%patch125 -p1 -b .less-verbose-COUNT_ALLOCS +# 00126: upstream as of Python 2.7.5 +# 00127: upstream as of Python 2.7.5 +%patch128 -p1 + +%patch130 -p1 + +%ifarch ppc %{power64} +%patch131 -p1 +%endif + +%patch132 -p1 +%patch133 -p1 +%patch134 -p1 +%patch135 -p1 +%patch136 -p1 +%patch137 -p1 +%patch138 -p1 +%ifarch %{arm} +%patch139 -p1 +%endif +%ifarch %{sparc} +%patch140 -p1 +%endif +%patch141 -p1 +%patch142 -p1 +%patch143 -p1 -b .tsc-on-ppc +%if !%{with_gdbm} +%patch144 -p1 +%endif +# 00145: upstream as of Python 2.7.3 +%patch146 -p1 +%patch147 -p1 +# 00148: upstream as of Python 2.7.3 +# 00149: not for python 2 +# 00150: not for python 2 +# 00151: upstream as of Python 2.7.3 +# 00152: not for python 2 +%patch153 -p0 +# 00154: not for python 2 +%patch155 -p1 +%patch156 -p1 +%patch157 -p1 +# 00158: upstream as of Python 2.7.4 +# 00160: not for python 2 +# 00161: not for python 2 yet +# 00162: not for python 2 yet +# 00163: not for python 2 yet +# 00164: not for python 2 yet +%patch165 -p1 +mv Modules/cryptmodule.c Modules/_cryptmodule.c +%patch166 -p1 +%patch167 -p1 +%patch168 -p1 +%patch169 -p1 +%patch170 -p1 +# 00171: upstream as of Python 2.7.4 +# 00171: upstream as of Python 2.7.4 +%patch173 -p1 +%patch174 -p1 -b .fix-for-usr-move +# 00175: upstream as of Python 2.7.5 +# 00176: not for python 2 +# 00177: not for python 2 +# 00178: not for python 2 +# 00179: not for python 2 +%patch180 -p1 +%patch181 -p1 +# 00182: not for python2 +# 00183: not for python2 +%patch184 -p1 +%patch185 -p1 +%patch186 -p1 +%patch187 -p1 +%patch188 -p1 +%patch189 -p1 +%patch190 -p0 +%patch191 -p1 +%patch192 -p1 +%patch193 -p1 +%patch194 -p0 + + +# This shouldn't be necesarry, but is right now (2.2a3) +find -name "*~" |xargs rm -f + +%if ! 0%{regenerate_autotooling_patch} +# Normally we apply the patch to "configure" +# We don't apply the patch if we're working towards regenerating it +%patch5000 -p0 -b .autotool-intermediates +%endif + + +# ====================================================== +# Configuring and building the code: +# ====================================================== + +%build +topdir=$(pwd) +export CFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC -fwrapv" +export CXXFLAGS="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC -fwrapv" +export CPPFLAGS="$(pkg-config --cflags-only-I libffi)" +export OPT="$RPM_OPT_FLAGS -D_GNU_SOURCE -fPIC -fwrapv" +export LINKCC="gcc" +export LDFLAGS="$RPM_LD_FLAGS" +if pkg-config openssl ; then + export CFLAGS="$CFLAGS $(pkg-config --cflags openssl)" + export LDFLAGS="$LDFLAGS $(pkg-config --libs-only-L openssl)" +fi +# compile with -O3 for ppc64 as requested in +# https://bugzilla.redhat.com/show_bug.cgi?id=1051076 +%ifarch %{power64} +export CFLAGS="$CFLAGS -O3" +export CXXFLAGS="$CXXFLAGS -O3" +export OPT="$OPT -O3" +%endif +# Force CC +export CC=gcc + +%if 0%{regenerate_autotooling_patch} +# If enabled, this code regenerates the patch to "configure", using a +# local copy of autoconf-2.65, then exits the build +# +# The following assumes that the copy is installed to ~/autoconf-2.65/bin +# as per these instructions: +# http://bugs.python.org/issue7997 + +for f in pyconfig.h.in configure ; do + cp $f $f.autotool-intermediates ; +done + +# Rerun the autotools: +PATH=~/autoconf-2.65/bin:$PATH autoconf +autoheader + +# Regenerate the patch: +gendiff . .autotool-intermediates > %{PATCH5000} + + +# Exit the build +exit 1 +%endif + +# Define a function, for how to perform a "build" of python for a given +# configuration: +BuildPython() { + ConfName=$1 + BinaryName=$2 + SymlinkName=$3 + ExtraConfigArgs=$4 + PathFixWithThisBinary=$5 + + ConfDir=build/$ConfName + + echo STARTING: BUILD OF PYTHON FOR CONFIGURATION: $ConfName - %{_bindir}/$BinaryName + mkdir -p $ConfDir + + pushd $ConfDir + + # Use the freshly created "configure" script, but in the directory two above: + %global _configure $topdir/configure + +%configure \ + --enable-ipv6 \ + --enable-shared \ + --enable-unicode=%{unicode} \ + --with-dbmliborder=gdbm:ndbm:bdb \ + --with-system-expat \ + --with-system-ffi \ +%if 0%{?with_systemtap} + --with-dtrace \ + --with-tapset-install-dir=%{tapsetdir} \ +%endif +%if 0%{?with_valgrind} + --with-valgrind \ +%endif + $ExtraConfigArgs \ + %{nil} + +make EXTRA_CFLAGS="$CFLAGS" %{?_smp_mflags} + +# We need to fix shebang lines across the full source tree. +# +# We do this using the pathfix.py script, which requires one of the +# freshly-built Python binaries. +# +# We use the optimized python binary, and make the shebangs point at that same +# optimized python binary: +if $PathFixWithThisBinary +then + LD_LIBRARY_PATH="$topdir/$ConfDir" ./$BinaryName \ + $topdir/Tools/scripts/pathfix.py \ + -i "%{_bindir}/env $BinaryName" \ + $topdir +fi + +# Rebuild with new python +# We need a link to a versioned python in the build directory +ln -s $BinaryName $SymlinkName +LD_LIBRARY_PATH="$topdir/$ConfDir" PATH=$PATH:$topdir/$ConfDir make -s EXTRA_CFLAGS="$CFLAGS" %{?_smp_mflags} + + popd + echo FINISHED: BUILD OF PYTHON FOR CONFIGURATION: $ConfDir +} + +# Use "BuildPython" to support building with different configurations: + +%if 0%{?with_debug_build} +BuildPython debug \ + python-debug \ + python%{pybasever}-debug \ +%ifarch %{ix86} x86_64 ppc %{power64} + "--with-pydebug --with-tsc --with-count-allocs --with-call-profile" \ +%else + "--with-pydebug --with-count-allocs --with-call-profile" \ +%endif + false +%endif # with_debug_build + +BuildPython optimized \ + python \ + python%{pybasever} \ + "" \ + true + + +# ====================================================== +# Installing the built code: +# ====================================================== + +%install +topdir=$(pwd) +rm -rf %{buildroot} +mkdir -p %{buildroot}%{_prefix} %{buildroot}%{_mandir} + +# Clean up patched .py files that are saved as .lib64 +for f in distutils/command/install distutils/sysconfig; do + rm -f Lib/$f.py.lib64 +done + +InstallPython() { + + ConfName=$1 + BinaryName=$2 + PyInstSoName=$3 + + ConfDir=build/$ConfName + + echo STARTING: INSTALL OF PYTHON FOR CONFIGURATION: $ConfName - %{_bindir}/$BinaryName + mkdir -p $ConfDir + + pushd $ConfDir + +make install DESTDIR=%{buildroot} + +# We install a collection of hooks for gdb that make it easier to debug +# executables linked against libpython (such as /usr/lib/python itself) +# +# These hooks are implemented in Python itself +# +# gdb-archer looks for them in the same path as the ELF file, with a -gdb.py suffix. +# We put them in the debuginfo package by installing them to e.g.: +# /usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py +# (note that the debug path is /usr/lib/debug for both 32/64 bit) +# +# See https://fedoraproject.org/wiki/Features/EasierPythonDebugging for more +# information +# +# Initially I tried: +# /usr/lib/libpython2.6.so.1.0-gdb.py +# but doing so generated noise when ldconfig was rerun (rhbz:562980) +# + +%if 0%{?with_gdb_hooks} +DirHoldingGdbPy=%{_prefix}/lib/debug/%{_libdir} +PathOfGdbPy=$DirHoldingGdbPy/$PyInstSoName.debug-gdb.py + +mkdir -p %{buildroot}$DirHoldingGdbPy +cp $topdir/Tools/gdb/libpython.py %{buildroot}$PathOfGdbPy + +# Manually byte-compile the file, in case find-debuginfo.sh is run before +# brp-python-bytecompile, so that the .pyc/.pyo files are properly listed in +# the debuginfo manifest: +LD_LIBRARY_PATH="$topdir/$ConfDir" $topdir/$ConfDir/$BinaryName \ + -c "import compileall; import sys; compileall.compile_dir('%{buildroot}$DirHoldingGdbPy', ddir='$DirHoldingGdbPy')" + +LD_LIBRARY_PATH="$topdir/$ConfDir" $topdir/$ConfDir/$BinaryName -O \ + -c "import compileall; import sys; compileall.compile_dir('%{buildroot}$DirHoldingGdbPy', ddir='$DirHoldingGdbPy')" +%endif # with_gdb_hooks + + popd + + echo FINISHED: INSTALL OF PYTHON FOR CONFIGURATION: $ConfName +} + +# Use "InstallPython" to support building with different configurations: + +# Install the "debug" build first, so that we can move some files aside +%if 0%{?with_debug_build} +InstallPython debug \ + python%{pybasever}-debug \ + %{py_INSTSONAME_debug} +%endif # with_debug_build + +# Now the optimized build: +InstallPython optimized \ + python%{pybasever} \ + %{py_INSTSONAME_optimized} + + +# Fix the interpreter path in binaries installed by distutils +# (which changes them by itself) +# Make sure we preserve the file permissions +for fixed in %{buildroot}%{_bindir}/pydoc; do + sed 's,#!.*/python$,#!%{_bindir}/env python%{pybasever},' $fixed > $fixed- \ + && cat $fixed- > $fixed && rm -f $fixed- +done + +# Junk, no point in putting in -test sub-pkg +rm -f %{buildroot}/%{pylibdir}/idlelib/testcode.py* + +# don't include tests that are run at build time in the package +# This is documented, and used: rhbz#387401 +if /bin/false; then + # Move this to -test subpackage. +mkdir save_bits_of_test +for i in test_support.py __init__.py; do + cp -a %{buildroot}/%{pylibdir}/test/$i save_bits_of_test +done +rm -rf %{buildroot}/%{pylibdir}/test +mkdir %{buildroot}/%{pylibdir}/test +cp -a save_bits_of_test/* %{buildroot}/%{pylibdir}/test +fi + +%if %{main_python} +%else +mv %{buildroot}%{_bindir}/python %{buildroot}%{_bindir}/%{python} +%if 0%{?with_debug_build} +mv %{buildroot}%{_bindir}/python-debug %{buildroot}%{_bindir}/%{python}-debug +%endif # with_debug_build +mv %{buildroot}/%{_mandir}/man1/python.1 %{buildroot}/%{_mandir}/man1/python%{pybasever}.1 +%endif + +# tools + +mkdir -p ${RPM_BUILD_ROOT}%{site_packages} + +#pynche +install -p -m755 %{SOURCE7} ${RPM_BUILD_ROOT}%{_bindir}/pynche +chmod 755 ${RPM_BUILD_ROOT}%{_bindir}/pynche +rm -f Tools/pynche/*.pyw +cp -rp Tools/pynche \ + ${RPM_BUILD_ROOT}%{site_packages}/ + +mv Tools/pynche/README Tools/pynche/README.pynche + +#gettext +install -m755 Tools/i18n/pygettext.py %{buildroot}%{_bindir}/ +install -m755 Tools/i18n/msgfmt.py %{buildroot}%{_bindir}/ + +# Useful development tools +install -m755 -d %{buildroot}%{tools_dir}/scripts +install Tools/README %{buildroot}%{tools_dir}/ +install Tools/scripts/*py %{buildroot}%{tools_dir}/scripts/ + +# Documentation tools +install -m755 -d %{buildroot}%{doc_tools_dir} +#install -m755 Doc/tools/mkhowto %{buildroot}%{doc_tools_dir} + +# Useful demo scripts +install -m755 -d %{buildroot}%{demo_dir} +cp -ar Demo/* %{buildroot}%{demo_dir} + +# Get rid of crap +find %{buildroot}/ -name "*~"|xargs rm -f +find %{buildroot}/ -name ".cvsignore"|xargs rm -f +find %{buildroot}/ -name "*.bat"|xargs rm -f +find . -name "*~"|xargs rm -f +find . -name ".cvsignore"|xargs rm -f +#zero length +rm -f %{buildroot}%{pylibdir}/LICENSE.txt + + +#make the binaries install side by side with the main python +%if !%{main_python} +pushd %{buildroot}%{_bindir} +mv idle idle%{__python_ver} +mv pynche pynche%{__python_ver} +mv pygettext.py pygettext%{__python_ver}.py +mv msgfmt.py msgfmt%{__python_ver}.py +mv smtpd.py smtpd%{__python_ver}.py +mv pydoc pydoc%{__python_ver} +popd +%endif + +# Fix for bug #136654 +rm -f %{buildroot}%{pylibdir}/email/test/data/audiotest.au %{buildroot}%{pylibdir}/test/audiotest.au + +# Fix bug #143667: python should own /usr/lib/python2.x on 64-bit machines +%if "%{_lib}" == "lib64" +install -d %{buildroot}/usr/lib/python%{pybasever}/site-packages +%endif + +# Make python-devel multilib-ready (bug #192747, #139911) +%global _pyconfig32_h pyconfig-32.h +%global _pyconfig64_h pyconfig-64.h + +%ifarch %{power64} s390x x86_64 ia64 alpha sparc64 aarch64 +%global _pyconfig_h %{_pyconfig64_h} +%else +%global _pyconfig_h %{_pyconfig32_h} +%endif + +%if 0%{?with_debug_build} +%global PyIncludeDirs python%{pybasever} python%{pybasever}-debug +%else +%global PyIncludeDirs python%{pybasever} +%endif + +for PyIncludeDir in %{PyIncludeDirs} ; do + mv %{buildroot}%{_includedir}/$PyIncludeDir/pyconfig.h \ + %{buildroot}%{_includedir}/$PyIncludeDir/%{_pyconfig_h} + cat > %{buildroot}%{_includedir}/$PyIncludeDir/pyconfig.h << EOF +#include + +#if __WORDSIZE == 32 +#include "%{_pyconfig32_h}" +#elif __WORDSIZE == 64 +#include "%{_pyconfig64_h}" +#else +#error "Unknown word size" +#endif +EOF +done +ln -s ../../libpython%{pybasever}.so %{buildroot}%{pylibdir}/config/libpython%{pybasever}.so + +# Fix for bug 201434: make sure distutils looks at the right pyconfig.h file +# Similar for sysconfig: sysconfig.get_config_h_filename tries to locate +# pyconfig.h so it can be parsed, and needs to do this at runtime in site.py +# when python starts up. +# +# Split this out so it goes directly to the pyconfig-32.h/pyconfig-64.h +# variants: +sed -i -e "s/'pyconfig.h'/'%{_pyconfig_h}'/" \ + %{buildroot}%{pylibdir}/distutils/sysconfig.py \ + %{buildroot}%{pylibdir}/sysconfig.py + +# Install macros for rpm: +mkdir -p %{buildroot}/%{_sysconfdir}/rpm +install -m 644 %{SOURCE6} %{buildroot}/%{_sysconfdir}/rpm + +# Ensure that the curses module was linked against libncursesw.so, rather than +# libncurses.so (bug 539917) +ldd %{buildroot}/%{dynload_dir}/_curses*.so \ + | grep curses \ + | grep libncurses.so && (echo "_curses.so linked against libncurses.so" ; exit 1) + +# Ensure that the debug modules are linked against the debug libpython, and +# likewise for the optimized modules and libpython: +for Module in %{buildroot}/%{dynload_dir}/*.so ; do + case $Module in + *_d.so) + ldd $Module | grep %{py_INSTSONAME_optimized} && + (echo Debug module $Module linked against optimized %{py_INSTSONAME_optimized} ; exit 1) + + ;; + *) + ldd $Module | grep %{py_INSTSONAME_debug} && + (echo Optimized module $Module linked against debug %{py_INSTSONAME_optimized} ; exit 1) + ;; + esac +done + +# +# Systemtap hooks: +# +%if 0%{?with_systemtap} +# Install a tapset for this libpython into tapsetdir, fixing up the path to the +# library: +mkdir -p %{buildroot}%{tapsetdir} +%ifarch %{power64} s390x x86_64 ia64 alpha sparc64 aarch64 +%global libpython_stp_optimized libpython%{pybasever}-64.stp +%global libpython_stp_debug libpython%{pybasever}-debug-64.stp +%else +%global libpython_stp_optimized libpython%{pybasever}-32.stp +%global libpython_stp_debug libpython%{pybasever}-debug-32.stp +%endif + +sed \ + -e "s|LIBRARY_PATH|%{_libdir}/%{py_INSTSONAME_optimized}|" \ + %{SOURCE3} \ + > %{buildroot}%{tapsetdir}/%{libpython_stp_optimized} + +%if 0%{?with_debug_build} +sed \ + -e "s|LIBRARY_PATH|%{_libdir}/%{py_INSTSONAME_debug}|" \ + %{SOURCE3} \ + > %{buildroot}%{tapsetdir}/%{libpython_stp_debug} +%endif # with_debug_build +%endif # with_systemtap + +# Replace scripts shebangs in usr/bin of subpackage tools +#(rhbz#987038) +sed -i "s|^#\!.\?/usr/bin.*$|#\! %{__python}|" \ + %{buildroot}%{_bindir}/pygettext.py \ + %{buildroot}%{_bindir}/msgfmt.py \ + %{buildroot}%{_bindir}/smtpd.py \ + %{buildroot}%{demo_dir}/scripts/find-uname.py \ + %{buildroot}%{demo_dir}/pdist/rcvs \ + %{buildroot}%{demo_dir}/pdist/rcsbump \ + %{buildroot}%{demo_dir}/pdist/rrcs \ + %{buildroot}%{site_packages}/pynche/pynche + +# Make library-files user writable +# rhbz#1046276 +/usr/bin/chmod 755 %{buildroot}%{dynload_dir}/*.so +/usr/bin/chmod 755 %{buildroot}%{_libdir}/libpython%{pybasever}.so.1.0 +/usr/bin/chmod 755 %{buildroot}%{_libdir}/libpython%{pybasever}_d.so.1.0 + +# ====================================================== +# Running the upstream test suite +# ====================================================== + +%check +topdir=$(pwd) +CheckPython() { + ConfName=$1 + BinaryName=$2 + ConfDir=$(pwd)/build/$ConfName + + echo STARTING: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName + + # Note that we're running the tests using the version of the code in the + # builddir, not in the buildroot. + + pushd $ConfDir + + EXTRATESTOPTS="--verbose" + +%if 0%{?with_huntrleaks} + # Try to detect reference leaks on debug builds. By default this means + # running every test 10 times (6 to stabilize, then 4 to watch): + if [ "$ConfName" = "debug" ] ; then + EXTRATESTOPTS="$EXTRATESTOPTS --huntrleaks : " + fi +%endif + + # Run the upstream test suite, setting "WITHIN_PYTHON_RPM_BUILD" so that the + # our non-standard decorators take effect on the relevant tests: + # @unittest._skipInRpmBuild(reason) + # @unittest._expectedFailureInRpmBuild + WITHIN_PYTHON_RPM_BUILD= EXTRATESTOPTS="$EXTRATESTOPTS" make test + + popd + + echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName + +} + +%if 0%{run_selftest_suite} + +# Check each of the configurations: +%if 0%{?with_debug_build} +CheckPython \ + debug \ + python%{pybasever}-debug +%endif # with_debug_build +CheckPython \ + optimized \ + python%{pybasever} + +%endif # run_selftest_suite + + +# ====================================================== +# Cleaning up +# ====================================================== + +%clean +rm -fr %{buildroot} + + +# ====================================================== +# Scriptlets +# ====================================================== + +%post libs -p /sbin/ldconfig + +%postun libs -p /sbin/ldconfig + + + +%files +%defattr(-, root, root, -) +%doc LICENSE README +%{_bindir}/pydoc* +%{_bindir}/%{python} +%if %{main_python} +%{_bindir}/python2 +%endif +%{_bindir}/python%{pybasever} +%{_mandir}/*/* + +%files libs +%defattr(-,root,root,-) +%doc LICENSE README +%dir %{pylibdir} +%dir %{dynload_dir} +%{dynload_dir}/Python-%{version}-py%{pybasever}.egg-info +%{dynload_dir}/_bisectmodule.so +%{dynload_dir}/_bsddb.so +%{dynload_dir}/_codecs_cn.so +%{dynload_dir}/_codecs_hk.so +%{dynload_dir}/_codecs_iso2022.so +%{dynload_dir}/_codecs_jp.so +%{dynload_dir}/_codecs_kr.so +%{dynload_dir}/_codecs_tw.so +%{dynload_dir}/_collectionsmodule.so +%{dynload_dir}/_csv.so +%{dynload_dir}/_ctypes.so +%{dynload_dir}/_curses.so +%{dynload_dir}/_curses_panel.so +%{dynload_dir}/_elementtree.so +%{dynload_dir}/_functoolsmodule.so +%{dynload_dir}/_hashlib.so +%{dynload_dir}/_heapq.so +%{dynload_dir}/_hotshot.so +%{dynload_dir}/_io.so +%{dynload_dir}/_json.so +%{dynload_dir}/_localemodule.so +%{dynload_dir}/_lsprof.so +%{dynload_dir}/_multibytecodecmodule.so +%{dynload_dir}/_multiprocessing.so +%{dynload_dir}/_randommodule.so +%{dynload_dir}/_socketmodule.so +%{dynload_dir}/_sqlite3.so +%{dynload_dir}/_ssl.so +%{dynload_dir}/_struct.so +%{dynload_dir}/arraymodule.so +%{dynload_dir}/audioop.so +%{dynload_dir}/binascii.so +%{dynload_dir}/bz2.so +%{dynload_dir}/cPickle.so +%{dynload_dir}/cStringIO.so +%{dynload_dir}/cmathmodule.so +%{dynload_dir}/_cryptmodule.so +%{dynload_dir}/datetime.so +%{dynload_dir}/dbm.so +%{dynload_dir}/dlmodule.so +%{dynload_dir}/fcntlmodule.so +%{dynload_dir}/future_builtins.so +%if %{with_gdbm} +%{dynload_dir}/gdbmmodule.so +%endif +%{dynload_dir}/grpmodule.so +%{dynload_dir}/imageop.so +%{dynload_dir}/itertoolsmodule.so +%{dynload_dir}/linuxaudiodev.so +%{dynload_dir}/math.so +%{dynload_dir}/mmapmodule.so +%{dynload_dir}/nismodule.so +%{dynload_dir}/operator.so +%{dynload_dir}/ossaudiodev.so +%{dynload_dir}/parsermodule.so +%{dynload_dir}/pyexpat.so +%{dynload_dir}/readline.so +%{dynload_dir}/resource.so +%{dynload_dir}/selectmodule.so +%{dynload_dir}/spwdmodule.so +%{dynload_dir}/stropmodule.so +%{dynload_dir}/syslog.so +%{dynload_dir}/termios.so +%{dynload_dir}/timemodule.so +%{dynload_dir}/timingmodule.so +%{dynload_dir}/unicodedata.so +%{dynload_dir}/xxsubtype.so +%{dynload_dir}/zlibmodule.so + +%dir %{site_packages} +%{site_packages}/README +%{pylibdir}/*.py* +%{pylibdir}/*.doc +%{pylibdir}/wsgiref.egg-info +%dir %{pylibdir}/bsddb +%{pylibdir}/bsddb/*.py* +%{pylibdir}/compiler +%dir %{pylibdir}/ctypes +%{pylibdir}/ctypes/*.py* +%{pylibdir}/ctypes/macholib +%{pylibdir}/curses +%dir %{pylibdir}/distutils +%{pylibdir}/distutils/*.py* +%{pylibdir}/distutils/README +%{pylibdir}/distutils/command +%exclude %{pylibdir}/distutils/command/wininst-*.exe +%dir %{pylibdir}/email +%{pylibdir}/email/*.py* +%{pylibdir}/email/mime +%{pylibdir}/encodings +%{pylibdir}/hotshot +%{pylibdir}/idlelib +%{pylibdir}/importlib +%dir %{pylibdir}/json +%{pylibdir}/json/*.py* +%{pylibdir}/lib2to3 +%exclude %{pylibdir}/lib2to3/tests +%{pylibdir}/logging +%{pylibdir}/multiprocessing +%{pylibdir}/plat-linux2 +%{pylibdir}/pydoc_data +%dir %{pylibdir}/sqlite3 +%{pylibdir}/sqlite3/*.py* +%dir %{pylibdir}/test +%{pylibdir}/test/test_support.py* +%{pylibdir}/test/__init__.py* +%{pylibdir}/unittest +%{pylibdir}/wsgiref +%{pylibdir}/xml +%if "%{_lib}" == "lib64" +%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever} +%attr(0755,root,root) %dir %{_prefix}/lib/python%{pybasever}/site-packages +%endif + +# "Makefile" and the config-32/64.h file are needed by +# distutils/sysconfig.py:_init_posix(), so we include them in the libs +# package, along with their parent directories (bug 531901): +%dir %{pylibdir}/config +%{pylibdir}/config/Makefile +%dir %{_includedir}/python%{pybasever} +%{_includedir}/python%{pybasever}/%{_pyconfig_h} + +%{_libdir}/%{py_INSTSONAME_optimized} +%if 0%{?with_systemtap} +%{tapsetdir}/%{libpython_stp_optimized} +%doc systemtap-example.stp pyfuntop.stp +%endif + +%files devel +%defattr(-,root,root,-) +%{_libdir}/pkgconfig/python-%{pybasever}.pc +%{_libdir}/pkgconfig/python.pc +%{_libdir}/pkgconfig/python2.pc +%{pylibdir}/config/* +%exclude %{pylibdir}/config/Makefile +%{pylibdir}/distutils/command/wininst-*.exe +%{_includedir}/python%{pybasever}/*.h +%exclude %{_includedir}/python%{pybasever}/%{_pyconfig_h} +%doc Misc/README.valgrind Misc/valgrind-python.supp Misc/gdbinit +%if %{main_python} +%{_bindir}/python-config +%{_bindir}/python2-config +%endif +%{_bindir}/python%{pybasever}-config +%{_libdir}/libpython%{pybasever}.so +%{_sysconfdir}/rpm/macros.python2 + +%files tools +%defattr(-,root,root,755) +%doc Tools/pynche/README.pynche +%{site_packages}/pynche +%{_bindir}/smtpd*.py* +%{_bindir}/2to3* +%{_bindir}/idle* +%{_bindir}/pynche* +%{_bindir}/pygettext*.py* +%{_bindir}/msgfmt*.py* +%{tools_dir} +%{demo_dir} +%{pylibdir}/Doc + +%files -n %{tkinter} +%defattr(-,root,root,755) +%{pylibdir}/lib-tk +%{dynload_dir}/_tkinter.so + +%files test +%defattr(-, root, root, -) +%{pylibdir}/bsddb/test +%{pylibdir}/ctypes/test +%{pylibdir}/distutils/tests +%{pylibdir}/email/test +%{pylibdir}/json/tests +%{pylibdir}/lib2to3/tests +%{pylibdir}/sqlite3/test +%{pylibdir}/test/* +# These two are shipped in the main subpackage: +%exclude %{pylibdir}/test/test_support.py* +%exclude %{pylibdir}/test/__init__.py* +%{dynload_dir}/_ctypes_test.so +%{dynload_dir}/_testcapimodule.so + + +# We don't bother splitting the debug build out into further subpackages: +# if you need it, you're probably a developer. + +# Hence the manifest is the combination of analogous files in the manifests of +# all of the other subpackages + +%if 0%{?with_debug_build} +%files debug +%defattr(-,root,root,-) + +# Analog of the core subpackage's files: +%{_bindir}/%{python}-debug +%if %{main_python} +%{_bindir}/python2-debug +%endif +%{_bindir}/python%{pybasever}-debug + +# Analog of the -libs subpackage's files, with debug builds of the built-in +# "extension" modules: +%{dynload_dir}/_bisectmodule_d.so +%{dynload_dir}/_bsddb_d.so +%{dynload_dir}/_codecs_cn_d.so +%{dynload_dir}/_codecs_hk_d.so +%{dynload_dir}/_codecs_iso2022_d.so +%{dynload_dir}/_codecs_jp_d.so +%{dynload_dir}/_codecs_kr_d.so +%{dynload_dir}/_codecs_tw_d.so +%{dynload_dir}/_collectionsmodule_d.so +%{dynload_dir}/_csv_d.so +%{dynload_dir}/_ctypes_d.so +%{dynload_dir}/_curses_d.so +%{dynload_dir}/_curses_panel_d.so +%{dynload_dir}/_elementtree_d.so +%{dynload_dir}/_functoolsmodule_d.so +%{dynload_dir}/_hashlib_d.so +%{dynload_dir}/_heapq_d.so +%{dynload_dir}/_hotshot_d.so +%{dynload_dir}/_io_d.so +%{dynload_dir}/_json_d.so +%{dynload_dir}/_localemodule_d.so +%{dynload_dir}/_lsprof_d.so +%{dynload_dir}/_multibytecodecmodule_d.so +%{dynload_dir}/_multiprocessing_d.so +%{dynload_dir}/_randommodule_d.so +%{dynload_dir}/_socketmodule_d.so +%{dynload_dir}/_sqlite3_d.so +%{dynload_dir}/_ssl_d.so +%{dynload_dir}/_struct_d.so +%{dynload_dir}/arraymodule_d.so +%{dynload_dir}/audioop_d.so +%{dynload_dir}/binascii_d.so +%{dynload_dir}/bz2_d.so +%{dynload_dir}/cPickle_d.so +%{dynload_dir}/cStringIO_d.so +%{dynload_dir}/cmathmodule_d.so +%{dynload_dir}/_cryptmodule_d.so +%{dynload_dir}/datetime_d.so +%{dynload_dir}/dbm_d.so +%{dynload_dir}/dlmodule_d.so +%{dynload_dir}/fcntlmodule_d.so +%{dynload_dir}/future_builtins_d.so +%if %{with_gdbm} +%{dynload_dir}/gdbmmodule_d.so +%endif +%{dynload_dir}/grpmodule_d.so +%{dynload_dir}/imageop_d.so +%{dynload_dir}/itertoolsmodule_d.so +%{dynload_dir}/linuxaudiodev_d.so +%{dynload_dir}/math_d.so +%{dynload_dir}/mmapmodule_d.so +%{dynload_dir}/nismodule_d.so +%{dynload_dir}/operator_d.so +%{dynload_dir}/ossaudiodev_d.so +%{dynload_dir}/parsermodule_d.so +%{dynload_dir}/pyexpat_d.so +%{dynload_dir}/readline_d.so +%{dynload_dir}/resource_d.so +%{dynload_dir}/selectmodule_d.so +%{dynload_dir}/spwdmodule_d.so +%{dynload_dir}/stropmodule_d.so +%{dynload_dir}/syslog_d.so +%{dynload_dir}/termios_d.so +%{dynload_dir}/timemodule_d.so +%{dynload_dir}/timingmodule_d.so +%{dynload_dir}/unicodedata_d.so +%{dynload_dir}/xxsubtype_d.so +%{dynload_dir}/zlibmodule_d.so + +# No need to split things out the "Makefile" and the config-32/64.h file as we +# do for the regular build above (bug 531901), since they're all in one package +# now; they're listed below, under "-devel": + +%{_libdir}/%{py_INSTSONAME_debug} +%if 0%{?with_systemtap} +%{tapsetdir}/%{libpython_stp_debug} +%endif + +# Analog of the -devel subpackage's files: +%dir %{pylibdir}/config-debug +%{_libdir}/pkgconfig/python-%{pybasever}-debug.pc +%{_libdir}/pkgconfig/python-debug.pc +%{_libdir}/pkgconfig/python2-debug.pc +%{pylibdir}/config-debug/* +%{_includedir}/python%{pybasever}-debug/*.h +%if %{main_python} +%{_bindir}/python-debug-config +%{_bindir}/python2-debug-config +%endif +%{_bindir}/python%{pybasever}-debug-config +%{_libdir}/libpython%{pybasever}_d.so + +# Analog of the -tools subpackage's files: +# None for now; we could build precanned versions that have the appropriate +# shebang if needed + +# Analog of the tkinter subpackage's files: +%{dynload_dir}/_tkinter_d.so + +# Analog of the -test subpackage's files: +%{dynload_dir}/_ctypes_test_d.so +%{dynload_dir}/_testcapimodule_d.so + +%endif # with_debug_build + +# We put the debug-gdb.py file inside /usr/lib/debug to avoid noise from +# ldconfig (rhbz:562980). +# +# The /usr/lib/rpm/redhat/macros defines the __debug_package macro to use +# debugfiles.list, and it appears that everything below /usr/lib/debug and +# (/usr/src/debug) gets added to this file (via LISTFILES) in +# /usr/lib/rpm/find-debuginfo.sh +# +# Hence by installing it below /usr/lib/debug we ensure it is added to the +# -debuginfo subpackage +# (if it doesn't, then the rpmbuild ought to fail since the debug-gdb.py +# payload file would be unpackaged) + + +# ====================================================== +# Finally, the changelog: +# ====================================================== + +%changelog +* Wed Sep 3 2014 Peter Robinson 2.7.5-18 +- valgrind is now supported on aarch64/ppc64le +Resolves: rhbz#1137039 + +* Thu Aug 07 2014 Slavek Kabrda - 2.7.5-17 +- Fix building on ppc64le (fix test_gdb, disable valgrind support). +Resolves: rhbz#1125657 + +* Mon Feb 10 2014 Tomas Radej - 2.7.5-16 +- Fix buffer overflow (upstream patch) +Resolves: rhbz#1062376 + +* Tue Jan 28 2014 Daniel Mach - 2.7.5-15 +- Mass rebuild 2014-01-24 + +* Tue Jan 14 2014 Matej Stuchlik - 2.7.5-14 +- Fix missing documentation for some keywords +Resolves: rhbz#1032116 + +* Mon Jan 13 2014 Matej Stuchlik - 2.7.5-13 +- Make library-files user writable +Resolves: rhbz#1046276 + +* Fri Jan 10 2014 Bohuslav Kabrda - 2.7.5-12 +- Use -O3 when building on ppc64. +Resolves: rhbz#1051076 + +* Fri Dec 27 2013 Daniel Mach - 2.7.5-11 +- Mass rebuild 2013-12-27 + +* Thu Nov 07 2013 Matej Stuchlik - 2.7.5-10 +- Added an explicit RPATH to _elementtree.so +Resolves: rhbz#1019345 + +* Thu Nov 07 2013 Matej Stuchlik - 2.7.5-9 +- Fixed instances of #!/usr/bin/env python +Resolves: rhbz#1019336 + +* Wed Oct 09 2013 Bohuslav Kabrda - 2.7.5-8 +- Fix gdb bindings on ppc64. +Resolves: rhbz#835053 + +* Tue Aug 20 2013 Matej Stuchlik - 2.7.5-7 +- Added fix for CVE-2013-4238 +Resolves: rhbz#998781 + +* Tue Aug 20 2013 Bohuslav Kabrda - 2.7.5-6 +- Add explicit RPATH to pyexpat pointing at system libexpat (rhbz#996665). + +* Mon Aug 05 2013 Bohuslav Kabrda - 2.7.5-5 +- Fix memory leak in marshal.c, fixes rhbz#990554. + +* Wed Jul 24 2013 Robert Kuska - 2.7.5-4 +- Change shebangs of scripts in tools subpackage +(rhbz#987038) + +* Wed Jul 17 2013 Matej Stuchlik - 2.7.5-3 +- Added patch that makes urllib2 honor no_proxy variable for ftp URLs + (rhbz#971267) + +* Wed Jul 17 2013 Matej Stuchlik - 2.7.5-2 +- Pulled patch fixing build with libffi containing multilib wrapper for ffi.h + from Fedora (rhbz#979696) + +* Thu May 16 2013 Bohuslav Kabrda - 2.7.5-1 +- Updated to Python 2.7.5. +- Refreshed patches: 0 (config), 102 (lib64), 121 (add Modules to build path), +153 (gdb test noise) +- Dropped patches: 126, 127 (big endian issues, both fixed upstream), +175 (configure -Wformat, fixed upstream) +- Synced patch numbers with python3.spec. + +* Tue May 14 2013 David Malcolm - 2.7.4-5 +- fix multilib issue in python-tools due to /usr/bin/pynche (source 7; +rhbz#831437) + +* Thu May 02 2013 Bohuslav Kabrda - 2.7.4-4 +- Add patch that enables building on ppc64p7. + +* Mon Apr 22 2013 Bohuslav Kabrda - 2.7.4-3 +- Allow arbitrary timeout in Condition.wait (rhbz#917709). + +* Thu Apr 11 2013 Kalev Lember - 2.7.4-2 +- Build with libdb 5.3 instead of libdb4 +- Refreshed patches: 0 (config), 102 (lib64) +- Dropped patches: 54 (db4 version), 159 (db4 include path adjustment) + +* Mon Apr 08 2013 Bohuslav Kabrda - 2.7.4-1 +- Updated to Python 2.7.4. +- Refreshed patches: 0 (config), 7 (sqlite encoding), 16 (rpath in config), +55 (systemtap), 111 (no static lib), 112 (debug build), 113 (more +configuration flags), 130 (add extension to python config), 134 (fix +COUNT_ALLOCS in test_sys), 146 (haslib FIPS), 147 (add debug malloc stats), +153 (fix gdb test noise), 157 (uid, gid overflow - fixed upstream, just +keeping few more downstream tests), 165 (crypt module salt backport), +175 (fix configure Wformat), 5000 (regenerated autotooling patch) +- Dropped patches: 101 (lib64 regex; merged upstream), 171 (exception on +missing /dev/urandom; merged upstream), 172 (poll for multiprocessing socket +connection; merged upstream) + +* Mon Mar 25 2013 David Malcolm - 2.7.3-35 +- fix gcc 4.8 incompatibility (rhbz#927358); regenerate autotool intermediates + +* Wed Mar 6 2013 David Malcolm - 2.7.3-34 +- restrict scope of workaround for cmpi-bindings issue to avoid breaking +in-tree running of test_sys and test_subprocess (rhbz#817554) + +* Wed Mar 6 2013 David Malcolm - 2.7.3-33 +- add workaround for cmpi-bindings issue (rhbz#817554) + +* Mon Mar 4 2013 David Malcolm - 2.7.3-32 +- add workaround for ENOPROTOOPT seen running selftests in Koji +(rhbz#913732) + +* Mon Mar 4 2013 David Malcolm - 2.7.3-31 +- remove config flag from /etc/rpm/macros.python2 + +* Fri Feb 22 2013 David Malcolm - 2.7.3-30 +- remove __debug_package macro from comment + +* Fri Feb 22 2013 David Malcolm - 2.7.3-29 +- drop -b from application of patch 157 (uid/gid overflows) + +* Fri Feb 22 2013 David Malcolm - 2.7.3-28 +- fix bogus dates in changelog + +* Thu Feb 21 2013 David Malcolm - 2.7.3-27 +- port _multiprocessing.Connection.poll() to use the "poll" syscall, rather +than "select", allowing large numbers of subprocesses (patch 172; +rhbz#849992) + +* Thu Feb 21 2013 David Malcolm - 2.7.3-26 +- raise correct exception in os.urandom() when /dev/urandom is missing +(patch 171; rhbz#907383) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-25 +- in debug builds, try to print repr() when a C-level assert fails in the +garbage collector (typically indicating a reference-counting error somewhere +else e.g in an extension module) (patch 170; rhbz#850013) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-24 +- move lib2to3/tests from python-libs to python-test (rhbz#850056) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-23 +- use SHA-256 rather than implicitly using MD5 within the challenge handling +in multiprocessing.connection (patch 169; rhbz#879695) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-22 +- fix a problem with distutils.sysconfig when CFLAGS is defined in the +environment (patch 168; rhbz#849994) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-21 +- don't run any stack navigation tests in test_gdb for optimized builds +(patch 167; rhbz#912025) + +* Wed Feb 20 2013 David Malcolm - 2.7.3-20 +- s/cryptmodule/_cryptmodule/ in package payload (rhbz#835021) + +* Tue Feb 19 2013 David Malcolm - 2.7.3-19 +- bulletproof the gdb debugging hooks against a failure seen in ARM builds +(patch 166; rhbz#912025) +- re-enable make check on ARM (rhbz#912025) + +* Tue Feb 19 2013 David Malcolm - 2.7.3-18 +- backport pre-canned ways of salting a password to the "crypt" module from 3.3 +(rhbz#835021) + +* Tue Feb 19 2013 David Malcolm - 2.7.3-17 +- remove "_default_patch_fuzz" directive to avoid patches being silently +misapplied (refresh patch 1, patch 101, patch 102, patch 111, patch 121, +patch 158; rename patch 1, patch 101, patch 121; apply patch 54 before the +lib64 patches to avoid fuzz problems caused by the conditional application +of the lib64 patches) + +* Mon Feb 18 2013 Peter Robinson 2.7.3-16 +- disable make check on ARM for the moment until 912025 is fixed + +* Mon Feb 11 2013 David Malcolm - 2.7.3-15 +- add aarch64 (rhbz#909783) + +* Thu Nov 29 2012 David Malcolm - 2.7.3-14 +- add BR on bluez-libs-devel (rhbz#879720) + +* Thu Aug 9 2012 David Malcolm - 2.7.3-13 +- remove f18 conditional from patch 159 + +* Fri Jul 27 2012 Fedora Release Engineering - 2.7.3-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Tue Jul 17 2012 Bohuslav Kabrda - 2.7.3-11 +- fix memory leak in module _hashlib (patch 158, rhbz#836285) +- fix db4 include path for libdb4 package (f18 and above) (patch 159) + +* Tue Jun 26 2012 David Malcolm - 2.7.3-10 +- fix missing include in uid/gid handling patch (patch 157; rhbz#830405) + +* Fri Jun 22 2012 David Malcolm - 2.7.3-9 +- use rpm macro for power64 (rhbz#834653) + +* Tue May 15 2012 David Malcolm - 2.7.3-8 +- update uid/gid handling to avoid int overflows seen with uid/gid +values >= 2^31 on 32-bit architectures (patch 157; rhbz#697470) + +* Fri May 4 2012 David Malcolm - 2.7.3-7 +- renumber autotools patch from 300 to 5000 +- specfile cleanups + +* Mon Apr 30 2012 David Malcolm - 2.7.3-6 +- try again to fix test_gdb.py (patch 156; rhbz#817072) + +* Mon Apr 30 2012 David Malcolm - 2.7.3-5 +- fix test_gdb.py (patch 156; rhbz#817072) + +* Fri Apr 20 2012 David Malcolm - 2.7.3-4 +- avoid allocating thunks in ctypes unless absolutely necessary, to avoid +generating SELinux denials on "import ctypes" and "import uuid" when embedding +Python within httpd (patch 155; rhbz#814391) + +* Thu Apr 19 2012 David Malcolm - 2.7.3-3 +- add explicit version requirements on expat to avoid linkage problems with +XML_SetHashSalt + +* Wed Apr 18 2012 David Malcolm - 2.7.3-2 +- fix -config symlinks (patch 112; rhbz#813836) + +* Wed Apr 11 2012 David Malcolm - 2.7.3-1 +- 2.7.3: refresh patch 102 (lib64); drop upstream patches 11 (ascii-to-lower), +115 (pydoc robustness), 145 (linux2), 148 (gdbm magic values), 151 (deadlock +in fork); refresh patch 112 (debug build); revise patch 127 +(test_structmember); fix test_gdb (patch 153); refresh patch 137 (distutils +tests); add python2.pc to python-devel; regenerate the autotool intermediates +patch (patch 300) + +* Sat Feb 25 2012 Thomas Spura - 2.7.2-20 +- fix deadlock issue (#787712) + +* Fri Feb 17 2012 Toshio Kuratomi - 2.7.2-19 +- Obsolete python-sqlite2 + +* Thu Nov 24 2011 Ville Skyttä - 2.7.2-18 +- Build with $RPM_LD_FLAGS (#756862). +- Use xz-compressed source tarball. + +* Wed Oct 26 2011 Fedora Release Engineering - 2.7.2-17 +- Rebuilt for glibc bug#747377 + +* Fri Sep 30 2011 David Malcolm - 2.7.2-16 +- re-enable gdbm (patch 148; rhbz#742242) + +* Fri Sep 16 2011 David Malcolm - 2.7.2-15 +- add a sys._debugmallocstats() function (patch 147) + +* Wed Sep 14 2011 David Malcolm - 2.7.2-14 +- support OpenSSL FIPS mode in _hashlib and hashlib; don't build the _md5 and +_sha* modules, relying on _hashlib in hashlib, and thus within md5 etc +(rhbz#563986; patch 146) + +* Wed Sep 14 2011 David Malcolm - 2.7.2-13 +- force sys.platform to be "linux2" (patch 145) + +* Tue Sep 13 2011 David Malcolm - 2.7.2-12 +- disable gdbm module to prepare for gdbm soname bump + +* Mon Sep 12 2011 David Malcolm - 2.7.2-11 +- rename and renumber patches for consistency with python3.spec (55, 111, 113, +114, 125, 131, 129 to 143) + +* Sat Sep 10 2011 David Malcolm - 2.7.2-10 +- rewrite of "check", introducing downstream-only hooks for skipping specific +cases in an rpmbuild (patch 132), and fixing/skipping failing tests in a more +fine-grained manner than before (patches 104, 133-142) + +* Thu Sep 1 2011 David Malcolm - 2.7.2-9 +- run selftests with "--verbose" +- disable parts of test_io on ppc (rhbz#732998) + +* Tue Aug 23 2011 David Malcolm - 2.7.2-8 +- add --extension-suffix option to python-config (patch 130; rhbz#732808) + +* Tue Aug 23 2011 David Malcolm - 2.7.2-7 +- re-enable and fix the --with-tsc option on ppc64, and rework it on 32-bit +ppc to avoid aliasing violations (patch 129; rhbz#698726) + +* Tue Aug 23 2011 David Malcolm - 2.7.2-6 +- don't use --with-tsc on ppc64 debug builds (rhbz#698726) + +* Thu Aug 18 2011 David Malcolm - 2.7.2-5 +- add rpm macros file (rhbz#731800) + +* Fri Jul 8 2011 David Malcolm - 2.7.2-4 +- cleanup of BuildRequires; add comment headings to specfile sections + +* Wed Jun 22 2011 David Malcolm - 2.7.2-3 +- reorganize test exclusions (test_openpty and test_pty seem to be failing on +every arch, not just the explicitly-listed ones) + +* Mon Jun 13 2011 Dan Horák - 2.7.2-2 +- add s390(x) excluded tests + +* Mon Jun 13 2011 David Malcolm - 2.7.2-1 +- 2.7.2; drop upstreamed patches: patch 122 (parallel make fix), patch 124 +(test_commands and SELinux), patch 130 (ppc preprocessor macro in debug +build); patch 131 (decimal in Turkish locale); regenerate the autotool +intermediates patch (patch 300) + +* Tue Jun 07 2011 Dennis Gilmore - 2.7.1-9 +- fix sparc building by excluding failing tests RHBZ#711584 + +* Mon May 23 2011 Peter Robinson - 2.7.1-8 +- fix compile on ARM by excluding failing tests on arm - RHBZ #706253 + +* Tue Apr 12 2011 David Malcolm - 2.7.1-7 +- fix "import decimal" in the Turkish locale (patch 131; rhbz#694928) + +* Wed Feb 09 2011 Fedora Release Engineering - 2.7.1-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Fri Jan 21 2011 Toshio Kuratomi - 2.7.1-5 +- Switch from setting OPT to setting EXTRA_CFLAGS so we don't overwrite the + DNDEBUG flag + +* Fri Jan 7 2011 David Malcolm - 2.7.1-4 +- for now, drop "obsoletes" of python-argparse, since it interracts badly with +multilib (rhbz#667984) + +* Fri Jan 7 2011 Thomas Spura - 2.7.1-3 +- obsolete/provide python-argparse (new in 2.7) + +* Thu Jan 6 2011 David Malcolm - 2.7.1-2 +- fix the ppc build of the debug configuration (patch 130; rhbz#661510) + +* Thu Dec 23 2010 David Malcolm - 2.7.1-1 +- 2.7.1, reworking patch 0 (config), patch 102 (lib64); drop upstream +patch 56 (cfgparse), patch 110 (ctypes/SELinux/noexecmem), patch 119 (expat +compat), patch 123 (2to3 on "from itertools import *") +- fix test_abc's test_cache_leak in the debug build (patch 128) +- drop _weakref.so from manifest (_weakref became a core module in r84230) + +* Wed Sep 29 2010 jkeating - 2.7-13 +- Rebuilt for gcc bug 634757 + +* Mon Sep 27 2010 David Malcolm - 2.7-12 +- fix test_structmember on 64bit-bigendian (patch 127) + +* Fri Sep 24 2010 David Malcolm - 2.7-11 +- fix dbm_contains on 64bit-bigendian (patch 126; rhbz#626756) + +* Thu Sep 16 2010 Toshio Kuratomi - 2.7-10 +- backport a patch to fix a change in behaviour in configparse. + +* Thu Sep 9 2010 David Malcolm - 2.7-9 +- move most of the payload of the core package to the libs subpackage, given +that the libs aren't meaningfully usable without the standard libraries + +* Wed Aug 18 2010 David Malcolm - 2.7-8 +- add %%check section +- update lib64 patch (patch 102) to fix expected output in test_site.py on +64-bit systems +- patch test_commands.py to work with SELinux (patch 124) +- patch the debug build's usage of COUNT_ALLOCS to be less verbose (patch 125) + +* Mon Jul 26 2010 David Malcolm - 2.7-7 +- fixup missing -lcrypt to "crypt" module in config patch (patch 0) + +* Mon Jul 26 2010 David Malcolm - 2.7-6 +- re-enable systemtap +- cherrypick upstream patch to 2to3 for "from itertools import *" +traceback (patch 123) + +* Thu Jul 22 2010 David Malcolm - 2.7-5 +- disable systemtap for now (dtrace is failing on startup due to the bug +mentioned in 2.7-4) +- provide relative path to python binary when running pathfix.py +- fix parallel make (patch 122) + +* Thu Jul 22 2010 David Malcolm - 2.7-4 +- fix reference to pyconfig.h in sysconfig that led to failure on startup if +python-devel was not installed + +* Thu Jul 8 2010 David Malcolm - 2.7-3 +- add patch to fixup the new sysconfig.py for our multilib support on +64-bit (patch 103) + +* Thu Jul 8 2010 David Malcolm - 2.7-2 +- add machinery for regenerating the "configure" script in the face of +mismatching autoconf versions (patch 300) + +* Tue Jul 6 2010 David Malcolm - 2.7-1 +- 2.7 final; drop alphatag +- drop patch 117 (upstream), patch 120 (upstreamed) +- fix the commented-out __python_ver from 26 to 27 + +* Tue Jun 22 2010 David Malcolm - 2.7-0.1.rc2 +- 2.7rc2 +- revert r79310 (patch 121) +- remove modulator: upstream removed it in r78338 +- rename mathmodule(_d).so to math(_d).so in manifests (appears to be changed +by r76861) +- _bytesio(_d).so and _filesio(_d).so were consolidated into _io(_d).so in +r73394 (upstream issue 6215) +- use the gdb hooks from the upstream tarball, rather than keeping our own +copy. The upstream version has some whitespace changes, a new write_repr for +unicode objects, and various bulletproofings for being run on older gdbs + +* Tue Jun 22 2010 David Malcolm - 2.7-0.1.rc1 +- 2.7rc1: + - rework patches to apply against 2.7 (which among other changes has had a +whitespace cleanup of the .c code): .rhconfig (patch0), .binutils-no-dep +(patch10), .ascii-tolower (patch11), .socketmodule (patch13), .socketmodule2 +(patch14), .systemtap (patch55), .lib64 (patch102), .selinux (patch110), +.no-static-lib (patch111), .debug-build (patch112), .statvfs-f-flag-constants +(patch114), ..CVE-2010-2089 (patch117) + - drop upstream patches: .expat (patch3), .brprpm (patch51), .valgrind +(patch52), .db48 (patch53), .CVE-2010-1634 (patch 116), .CVE-2008-5983 (patch +118) + +* Tue Jun 22 2010 David Malcolm - 2.6.5-17 +- Stop python bailing out with an assertion failure when UnicodeDecodeErrors +occur on very large buffers (patch 120, upstream issue 9058) + +* Mon Jun 21 2010 David Malcolm - 2.6.5-16 +- Fix an incompatibility between pyexpat and the system expat-2.0.1 that led to +a segfault running test_pyexpat.py (patch 119; upstream issue 9054) + +* Tue Jun 8 2010 David Malcolm - 2.6.5-15 +- add a flag to make it easy to turn off the debug build when troubleshooting +the rpm build + +* Sat Jun 5 2010 Dan Horák - 2.6.5-14 +- reading the timestamp counter is available only on some arches (see Python/ceval.c) +- disable --with-valgrind on s390(x) arches + +* Fri Jun 4 2010 David Malcolm - 2.6.5-13 +- ensure that the compiler is invoked with "-fwrapv" (rhbz#594819) +- CVE-2010-1634: fix various integer overflow checks in the audioop +module (patch 116) +- CVE-2010-2089: further checks within the audioop module (patch 117) +- CVE-2008-5983: the new PySys_SetArgvEx entry point from r81399 (patch 118) + +* Thu May 27 2010 David Malcolm - 2.6.5-12 +- make "pydoc -k" more robust in the face of broken modules (rhbz:461419, patch115) + +* Wed May 26 2010 David Malcolm - 2.6.5-11 +- add flags for statvfs.f_flag to the constant list in posixmodule (i.e. "os") +(patch 114) + +* Tue May 25 2010 David Malcolm - 2.6.5-10 +- add configure-time support for COUNT_ALLOCS and CALL_PROFILE debug options +(patch 113); enable them and the WITH_TSC option within the debug build + +* Tue May 18 2010 David Malcolm - 2.6.5-9 +- build and install two different configurations of Python: debug and standard, +packaging the debug build in a new "python-debug" subpackage (patch 112) + +* Tue May 4 2010 David Malcolm - 2.6.5-8 +- don't delete wsgiref.egg-info (rhbz:588426) + +* Mon Apr 26 2010 David Malcolm - 2.6.5-7 +- disable --with-valgrind on sparc arches + +* Mon Apr 12 2010 David Malcolm - 2.6.5-6 +- move the "bdist_wininst" command's template .exe files from the core package +to the devel subpackage, to save space (rhbz:525469) +- fix stray doublelisting of config directory wildcard in devel subpackage + +* Wed Mar 31 2010 David Malcolm - 2.6.5-5 +- update python-gdb.py from v4 to v5 (improving performance and stability, +adding commands) + +* Thu Mar 25 2010 David Malcolm - 2.6.5-4 +- update python-gdb.py from v3 to v4 (fixing infinite recursion on reference +cycles and tracebacks on bytes 0x80-0xff in strings, adding handlers for sets +and exceptions) + +* Wed Mar 24 2010 David Malcolm - 2.6.5-3 +- refresh gdb hooks to v3 (reworking how they are packaged) + +* Mon Mar 22 2010 David Malcolm - 2.6.5-2 +- remove unnecessary arch-conditionality for patch 101 + +* Fri Mar 19 2010 David Malcolm - 2.6.5-1 +- update to 2.6.5: http://www.python.org/download/releases/2.6.5/ +- replace our patch to compile against db4.8 with a patch from +upstream (patch 53, from r78974); update patch 54 since part of it is now in +that upstream patch +- update patch 110 so that it still applies in the face of upstream r78380 + +* Tue Mar 16 2010 David Malcolm - 2.6.4-23 +- fixup distutils/unixccompiler.py to remove standard library path from +rpath (patch 17) +- delete DOS batch files + +* Fri Mar 12 2010 David Malcolm - 2.6.4-22 +- add pyfuntop.stp; allow systemtap support to be disabled +- remove trailing period from tkinter summary +- don't own /usr/bin/python-config if you're not the main python + +* Thu Mar 11 2010 Marcela Mašláňová - 2.6.4-21 +- rebuild with new gdbm + +* Thu Feb 11 2010 David Malcolm - 2.6.4-20 +- avoid having the "test" subdirectory and the files within it that are in the +core subpackage also be owned by the test subpackage (rhbz:467588) + +* Wed Feb 10 2010 David Malcolm - 2.6.4-19 +- revise the systemtap patch (patch 55:python-2.6.4-dtrace.patch) to the +new version by mjw in attachment 390110 of rhbz:545179, as this should +eliminate the performance penalty for the case where the probes aren't in +use, and eliminate all architecture-specific code (rhbz:563541; except on +sparc) + +* Tue Feb 9 2010 David Malcolm - 2.6.4-18 +- add a systemtap tapset defining "python.function.entry" and +"python.function.return" to make it easy to use the static probepoint within +Python; add an example of using the tapset to the docs + +* Tue Feb 9 2010 David Malcolm - 2.6.4-17 +- add systemtap static probes (wcohen; patch 55; rh bug #545179) +- update some comments in specfile relating to gdb work +- manually byte-compile the gdb.py file with the freshly-built python to ensure +that .pyx and .pyo files make it into the debuginfo manifest if they are later +byte-compiled after find-debuginfo.sh is run + +* Mon Feb 8 2010 David Malcolm - 2.6.4-16 +- move the -gdb.py file from %%{_libdir}/INSTSONAME-gdb.py to +%%{_prefix}/lib/debug/%%{_libdir}/INSTSONAME.debug-gdb.py to avoid noise from +ldconfig (bug 562980), and which should also ensure it becomes part of the +debuginfo subpackage, rather than the libs subpackage +- introduce %%{py_SOVERSION} and %%{py_INSTSONAME} to reflect the upstream +configure script, and to avoid fragile scripts that try to figure this out +dynamically (e.g. for the -gdb.py change) + +* Mon Feb 8 2010 David Malcolm - 2.6.4-15 +- work around bug 562906 by supplying a fixed version of pythondeps.sh +- set %%{_python_bytecompile_errors_terminate_build} to 0 to prevent the broken +test files from killing the build on buildroots where python is installed + +* Fri Feb 5 2010 David Malcolm - 2.6.4-14 +- add gdb hooks for easier debugging + +* Fri Jan 29 2010 David Malcolm - 2.6.4-13 +- document all patches, and remove the commented-out ones + +* Tue Jan 26 2010 David Malcolm - 2.6.4-12 +- Address some of the issues identified in package review (bug 226342): + - update libs requirement on base package to use %%{name} for consistency's +sake + - convert from backticks to $() syntax throughout + - wrap value of LD_LIBRARY_PATH in quotes + - convert "/usr/bin/find" requirement to "findutils" + - remove trailing periods from summaries of -devel and -tools subpackages + - fix spelling mistake in description of -test subpackage + - convert usage of $$RPM_BUILD_ROOT to %%{buildroot} throughout, for +stylistic consistency + - supply dirmode arguments to defattr directives + +* Mon Jan 25 2010 David Malcolm - 2.6.4-11 +- update python-2.6.2-config.patch to remove downstream customization of build +of pyexpat and elementtree modules +- add patch adapted from upstream (patch 3) to add support for building against +system expat; add --with-system-expat to "configure" invocation +- remove embedded copy of expat from source tree during "prep" + +* Mon Jan 25 2010 David Malcolm - 2.6.4-10 +- introduce macros for 3 directories, replacing expanded references throughout: +%%{pylibdir}, %%{dynload_dir}, %%{site_packages} +- explicitly list all lib-dynload files, rather than dynamically gathering the +payload into a temporary text file, so that we can be sure what we are +shipping; remove now-redundant testing for presence of certain .so files +- remove embedded copy of zlib from source tree before building + +* Mon Jan 25 2010 David Malcolm - 2.6.4-9 +- change python-2.6.2-config.patch to remove our downstream change to curses +configuration in Modules/Setup.dist, so that the curses modules are built using +setup.py with the downstream default (linking against libncursesw.so, rather +than libncurses.so), rather than within the Makefile; add a test to %%install +to verify the dso files that the curses module is linked against the correct +DSO (bug 539917; changes _cursesmodule.so -> _curses.so) + +* Fri Jan 22 2010 David Malcolm - 2.6.4-8 +- rebuild (bug 556975) + +* Wed Jan 20 2010 David Malcolm - 2.6.4-7 +- move lib2to3 from -tools subpackage to main package (bug 556667) + +* Mon Jan 18 2010 David Malcolm - 2.6.4-6 +- patch Makefile.pre.in to avoid building static library (patch111, bug 556092) +- split up the "configure" invocation flags onto individual lines + +* Fri Jan 15 2010 David Malcolm - 2.6.4-5 +- replace usage of %%define with %%global +- use the %%{_isa} macro to ensure that the python-devel dependency on python +is for the correct multilib arch (#555943) +- delete bundled copy of libffi to make sure we use the system one +- replace references to /usr with %%{_prefix}; replace references to +/usr/include with %%{_includedir} + +* Wed Dec 16 2009 David Malcolm - 2.6.4-4 +- automatically disable arena allocator when run under valgrind (upstream +issue 2422; patch 52) +- add patch from Josh Boyer containing diff against upstream PyBSDDB to make +the bsddb module compile against db-4.8 (patch 53, #544275); bump the necessary +version of db4-devel to 4.8 +- patch setup.py so that it searches for db-4.8, and enable debug output for +said search; make Setup.dist use db-4.8 (patch 54) + +* Thu Nov 12 2009 David Malcolm - 2.6.4-3 +- fixup the build when __python_ver is set (Zach Sadecki; bug 533989); use +pybasever in the files section + +* Thu Oct 29 2009 David Malcolm - 2.6.4-2 +- "Makefile" and the config-32/64.h file are needed by distutils/sysconfig.py +_init_posix(), so we include them in the core package, along with their parent +directories (bug 531901) + +* Mon Oct 26 2009 David Malcolm - 2.6.4-1 +- Update to 2.6.4 + +* Fri Aug 21 2009 Tomas Mraz - 2.6.2-2 +- rebuilt with new openssl + +* Mon Jul 27 2009 James Antill - 2.6.2-1 +- Update to 2.6.2 + +* Sun Jul 26 2009 Fedora Release Engineering - 2.6-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Sat Jul 4 2009 Jonathan Steffan - 2.6-10 +- Move python-config to devel subpackage (#506153) +- Update BuildRoot for new standard + +* Sun Jun 28 2009 Jonathan Steffan - 2.6-9 +- Update python-tools description (#448940) + +* Wed Apr 15 2009 Ignacio Vazquez-Abrams 2.6-8 +- Replace python-hashlib and python-uuid (#484715) + +* Tue Mar 17 2009 James Antill - 2.6-7 +- Use system libffi +- Resolves: bug#490573 +- Fix SELinux execmem problems +- Resolves: bug#488396 + +* Thu Feb 26 2009 Fedora Release Engineering - 2.6-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Fri Jan 16 2009 Tomas Mraz - 2.6-4 +- rebuild with new openssl + +* Tue Jan 6 2009 James Antill - 2.6-3 +- Fix distutils generated rpms. +- Resolves: bug#236535 + +* Wed Dec 10 2008 Ignacio Vazquez-Abrams - 2.6-2 +- Enable -lcrypt for cryptmodule + +* Fri Nov 28 2008 Ignacio Vazquez-Abrams - 2.6-1 +- Update to 2.6 + +* Tue Sep 30 2008 James Antill - 2.5.2-1 +- Move to 2.5.2 +- Fix CVE-2008-2316 hashlib overflow. + +* Thu Jul 17 2008 Jeremy Katz - 2.5.1-30 +- Fix up the build for new rpm +- And actually build against db4-4.7 (#455170) + +* Thu Jul 10 2008 Tom "spot" Callaway - 2.5.1-27 +- fix license tag +- enable support for db4-4.7 + +* Sun Jun 15 2008 James Antill - 2.5.1-26 +- Fix sporadic listdir problem +- Resolves: bug#451494 + +* Mon Apr 7 2008 James Antill - 2.5.1-25 +- Rebuild to re-gen autoconf file due to glibc change. +- Resolves: bug#441003 + +* Tue Mar 25 2008 James Antill - 2.5.1-24 +- Add more constants to socketmodule + +* Sat Mar 8 2008 James Antill - 2.5.1-22 +- Add constants to socketmodule +- Resolves: bug#436560 + +* Tue Feb 19 2008 Fedora Release Engineering - 2.5.1-22 +- Autorebuild for GCC 4.3 + +* Sun Jan 13 2008 Tom "spot" Callaway - 2.5.1-21 +- rebuild for new tk in rawhide + +* Mon Jan 7 2008 James Antill - 2.5.1-20 +- Add valgrind support files, as doc, to python-devel +- Relates: rhbz#418621 +- Add new API from 2.6, set_wakeup_fd ... use at own risk, presumably won't +- change but I have no control to guarantee that. +- Resolves: rhbz#427794 +- Add gdbinit support file, as doc, to python-devel + +* Fri Jan 4 2008 Tom "spot" Callaway - 2.5.1-19 +- rebuild for new tcl/tk in rawhide + +* Fri Dec 7 2007 James Antill - 2.5.1-18 +- Create a python-test sub-module, over 3MB of stuff noone wants. +- Don't remove egginfo files, try this see what happens ... may revert. +- Resolves: rhbz#414711 + +* Mon Dec 3 2007 Jeremy Katz - 2.5.1-17 +- rebuild for new libssl + +* Fri Nov 30 2007 James Antill - 2.5.1-16 +- Fix pyconfig.h comment typo. +- Add back test_support.py and the __init__.py file. +- Resolves: rhbz#387401 + +* Tue Oct 30 2007 James Antill - 2.5.1-15 +- Do codec lowercase in C Locale. +- Resolves: 207134 191096 +- Fix stupid namespacing in pysqlite, minimal upgrade to 2.3.3 pysqlite +- Resolves: 263221 + +* Wed Oct 24 2007 James Antill - 2.5.1-14 +- Remove bintuils dep. for live CD ... add work around for ctypes + +* Mon Oct 22 2007 James Antill - 2.5.1-13 +- Add tix buildprereq +- Add tkinter patch +- Resolves: #281751 +- Fix ctypes loading of libraries, add requires on binutils +- Resolves: #307221 +- Possible fix for CVE-2007-4965 possible exploitable integer overflow +- Resolves: #295971 + +* Tue Oct 16 2007 Mike Bonnet - 2.5.1-12 +- fix marshalling of objects in xmlrpclib (python bug #1739842) + +* Fri Sep 14 2007 Jeremy Katz - 2.5.1-11 +- fix encoding of sqlite .py files to work around weird encoding problem + in Turkish (#283331) + +* Mon Sep 10 2007 Jeremy Katz - 2.5.1-10 +- work around problems with multi-line plural specification (#252136) + +* Tue Aug 28 2007 Jeremy Katz - 2.5.1-9 +- rebuild against new expat + +* Tue Aug 14 2007 Jeremy Katz - 2.5.1-8 +- build against db4.6 + +* Tue Aug 14 2007 Dennis Gilmore - 2.5.1-7 +- add sparc64 to the list of archs for _pyconfig64_h + +* Fri Aug 10 2007 Jeremy Katz - 2.5.1-6 +- fix ctypes again on some arches (Hans de Goede, #251637) + +* Fri Jul 6 2007 Jeremy Katz - 2.5.1-5 +- link curses modules with ncursesw (#246385) + +* Wed Jun 27 2007 Jeremy Katz - 2.5.1-4 +- fix _elementtree.so build (#245703) +- ensure that extension modules we expect are actually built rather than + having them silently fall out of the package + +* Tue Jun 26 2007 Jeremy Katz - 2.5.1-3 +- link with system expat (#245703) + +* Thu Jun 21 2007 Jeremy Katz - 2.5.1-2 +- rebuild to take advantage of hardlinking between identical pyc/pyo files + +* Thu May 31 2007 Jeremy Katz - 2.5.1-1 +- update to python 2.5.1 + +* Mon Mar 19 2007 Jeremy Katz - 2.5.3-12 +- fix alpha build (#231961) + +* Tue Feb 13 2007 Jeremy Katz - 2.5.3-11 +- tcl/tk was reverted; rebuild again + +* Thu Feb 1 2007 Jeremy Katz - 2.5.3-10 +- rebuild for new tcl/tk + +* Tue Jan 16 2007 Miroslav Lichvar - 2.5.3-9 +- link with ncurses + +* Sat Jan 6 2007 Jeremy Katz - 2.5.3-8 +- fix extensions to use shared libpython (#219564) +- all 64bit platforms need the regex fix (#122304) + +* Wed Jan 3 2007 Jeremy Katz - 2.5.3-7 +- fix ctypes to not require execstack (#220669) + +* Fri Dec 15 2006 Jeremy Katz - 2.5.3-6 +- don't link against compat-db (Robert Scheck) + +* Wed Dec 13 2006 Jarod Wilson - 2.5.3-5 +- fix invalid assert in debug mode (upstream changeset 52622) + +* Tue Dec 12 2006 Jeremy Katz - 2.5.3-4 +- obsolete/provide python-ctypes (#219256) + +* Mon Dec 11 2006 Jeremy Katz - 2.5.3-3 +- fix atexit traceback with failed syslog logger (#218214) +- split libpython into python-libs subpackage for multilib apps + embedding python interpreters + +* Wed Dec 6 2006 Jeremy Katz - 2.5.3-2 +- disable installation of .egg-info files for now + +* Tue Dec 5 2006 Jeremy Katz +- support db 4.5 +- obsolete python-elementtree; since it requires some code tweaks, don't + provide it +- obsolete old python-sqlite; provide the version that's actually included + +* Mon Oct 30 2006 Jeremy Katz +- fix _md5 and _sha modules (Robert Sheck) +- no longer provide optik compat; it's been a couple of years now +- no longer provide the old shm module; if this is still needed, let's + build it separately +- no longer provide japanese codecs; should be a separate package + +* Mon Oct 23 2006 Jeremy Katz - 2.5-0 +- update to 2.5.0 final + +* Fri Aug 18 2006 Mihai Ibanescu - 2.4.99.c1 +- Updated to 2.5c1. Merged fixes from FC6 too: +- Fixed bug #199373 (on some platforms CFLAGS is needed when linking) +- Fixed bug #198971 (case conversion not locale safe in logging library) +- Verified bug #201434 (distutils.sysconfig is confused by the change to make + python-devel multilib friendly) is fixed upstream + +* Sun Jul 16 2006 Mihai Ibanescu - 2.4.99.b2 +- Updated to 2.5b2 (which for comparison reasons is re-labeled 2.4.99.b2) + +* Fri Jun 23 2006 Mihai Ibanescu - 2.4.99.b1 +- Updated to 2.5b1 (which for comparison reasons is re-labeled 2.4.99.b1) + +* Tue Jun 13 2006 Jeremy Katz - 2.4.3-11.FC6 +- and fix it for real + +* Tue Jun 13 2006 Jeremy Katz - 2.4.3-10.FC6 +- fix python-devel on ia64 + +* Tue Jun 13 2006 Mihai Ibanescu - 2.4.3-9 +- Fixed python-devel to be multilib friendly (bug #192747, #139911) + +* Tue Jun 13 2006 Mihai Ibanescu - 2.4.3-8 +- Only copying mkhowto from the Docs - we don't need perl dependencies from + python-tools. + +* Mon Jun 12 2006 Mihai Ibanescu - 2.4.3-7 +- Fixed bug #121198 (webbrowser.py should use the user's preferences first) + +* Mon Jun 12 2006 Mihai Ibanescu - 2.4.3-6 +- Fixed bug #192592 (too aggressive assertion fails) - SF#1257960 +- Fixed bug #167468 (Doc/tools not included) - added in the python-tools package + +* Thu Jun 8 2006 Mihai Ibanescu - 2.4.3-5 +- Fixed bug #193484 (added pydoc in the main package) + +* Mon Jun 5 2006 Mihai Ibanescu - 2.4.3-4 +- Added dist in the release + +* Mon May 15 2006 Mihai Ibanescu - 2.4.3-3 +- rebuilt to fix broken libX11 dependency + +* Wed Apr 12 2006 Jeremy Katz - 2.4.3-2 +- rebuild with new gcc to fix #188649 + +* Thu Apr 6 2006 Mihai Ibanescu - 2.4.3-1 +- Updated to 2.4.3 + +* Fri Feb 10 2006 Jesse Keating - 2.4.2-3.2.1 +- bump again for double-long bug on ppc(64) + +* Fri Feb 10 2006 Mihai Ibanescu - 2.4.3-3.2 +- rebuilt for newer tix + +* Tue Feb 07 2006 Jesse Keating - 2.4.2-3.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Fri Jan 20 2006 Mihai Ibanescu 2.4.2-3 +- fixed #136654 for another instance of audiotest.au + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Sat Nov 19 2005 Bill Nottingham 2.4.2-2 +- fix build for modular X, remove X11R6 path references + +* Tue Nov 15 2005 Mihai Ibanescu 2.4.2-1 +- Upgraded to 2.4.2 +- BuildRequires autoconf + +* Wed Nov 9 2005 Mihai Ibanescu 2.4.1-16 +- Rebuilding against newer openssl. +- XFree86-devel no longer exists + +* Mon Sep 26 2005 Peter Jones 2.4.1-14 +- Once more -- this time, to fix -EPERM when you run it in a directory + you can't read from. + +* Mon Sep 26 2005 Peter Jones 2.4.1-13 +- So, 5 or 6 people have said it works for them with this patch... + +* Sun Sep 25 2005 Peter Jones 2.4.1-12 +- Fixed bug #169159 (check for argc>0 and argv[0] == NULL, not just + argv[0][0]='\0') + Reworked the patch from -8 a bit more. + +* Fri Sep 23 2005 Mihai Ibanescu 2.4.1-10 +- Fixed bug #169159 (don't let python core dump if no arguments are passed in) + Reworked the patch from -8 a bit more. + +* Thu Sep 22 2005 Peter Jones 2.4.1-8 +- Fix bug #169046 more correctly. + +* Thu Sep 22 2005 Mihai Ibanescu 2.4.1-7 +- Fixed bug #169046 (realpath is unsafe); thanks to + Peter Jones and Arjan van de Ven for + diagnosing and the patch. + +* Tue Sep 20 2005 Mihai Ibanescu 2.4.1-4 +- Fixed bug #168655 (fixes for building as python24) + +* Tue Jul 26 2005 Mihai Ibanescu 2.4.1-3 +- Fixed bug #163435 (pynche doesn't start)) + +* Wed Apr 20 2005 Mihai Ibanescu 2.4.1-2 +- Fixed bug #143667 (python should own /usr/lib/python* on 64-bit systems, for + noarch packages) +- Fixed bug #143419 (BuildRequires db4 is not versioned) + +* Wed Apr 6 2005 Mihai Ibanescu 2.4.1-1 +- updated to 2.4.1 + +* Mon Mar 14 2005 Mihai Ibanescu 2.4-6 +- building the docs from a different source rpm, to decouple bootstrapping + python from having tetex installed + +* Fri Mar 11 2005 Dan Williams 2.4-5 +- Rebuild to pick up new libssl.so.5 + +* Wed Feb 2 2005 Mihai Ibanescu 2.4-4 +- Fixed security issue in SimpleXMLRPCServer.py (#146647) + +* Wed Jan 12 2005 Tim Waugh 2.4-3 +- Rebuilt for new readline. + +* Mon Dec 6 2004 Jeff Johnson 2.4-2 +- db-4.3.21 returns DB_BUFFER_SMALL rather than ENOMEM (#141994). +- add Provide: python(abi) = 2.4 +- include msgfmt/pygettext *.pyc and *.pyo from brp-python-bytecompile. + +* Fri Dec 3 2004 Mihai Ibanescu 2.4-1 +- Python-2.4.tar.bz2 (final) + +* Fri Nov 19 2004 Mihai Ibanescu 2.4-0.c1.1 +- Python-2.4c1.tar.bz2 (release candidate 1) + +* Thu Nov 11 2004 Jeff Johnson 2.4-0.b2.4 +- rebuild against db-4.3.21. + +* Mon Nov 8 2004 Jeremy Katz - 2.4-0.b2.3 +- fix the lib64 patch so that 64bit arches still look in /usr/lib/python... + +* Mon Nov 8 2004 Jeremy Katz - 2.4-0.b2.2 +- cryptmodule still needs -lcrypt (again) + +* Thu Nov 4 2004 Mihai Ibanescu 2.4-0.b2.1 +- Updated to python 2.4b2 (and labeled it 2.4-0.b2.1 to avoid breaking rpm's + version comparison) + +* Thu Nov 4 2004 Mihai Ibanescu 2.3.4-13 +- Fixed bug #138112 (python overflows stack buffer) - SF bug 105470 + +* Tue Nov 2 2004 Mihai Ibanescu 2.3.4-12 +- Fixed bugs #131439 #136023 #137863 (.pyc/.pyo files had the buildroot added) + +* Tue Oct 26 2004 Mihai Ibanescu 2.3.4-11 +- Fixed bug #136654 (python has sketchy audio clip) + +* Tue Aug 31 2004 Mihai Ibanescu 2.3.4-10 +- Fixed bug #77418 (Demo dir not packaged) +- More tweaking on #19347 (Moved Tools/ under /usr/lib/python2.3/Tools) + +* Fri Aug 13 2004 Mihai Ibanescu 2.3.4-8 +- Fixed bug #129769: Makefile in new python conflicts with older version found + in old python-devel +- Reorganized the spec file to get rid of the aspython2 define; __python_ver + is more powerful. + +* Tue Aug 3 2004 Mihai Ibanescu 2.3.4-7 +- Including html documentation for non-i386 arches +- Fixed #125362 (python-doc html files have japanese character encoding) +- Fixed #128923 (missing dependency between python and python-devel) + +* Fri Jul 30 2004 Mihai Ibanescu 2.3.4-6 +- Fixed #128030 (help() not printing anything) +- Fixed #125472 (distutils.sysconfig.get_python_lib() not returning the right + path on 64-bit systems) +- Fixed #127357 (building python as a shared library) +- Fixed #19347 (including the contents of Tools/scripts/ in python-tools) + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Tue Jun 8 2004 Mihai Ibanescu 2.3.4-3 +- Added an optik.py that provides the same interface from optparse for + backward compatibility; obsoleting python-optik + +* Mon Jun 7 2004 Mihai Ibanescu 2.3.4-2 +- Patched bdist_rpm to allow for builds of multiple binary rpms (bug #123598) + +* Fri Jun 4 2004 Mihai Ibanescu 2.3.4-1 +- Updated to 2.3.4-1 with Robert Scheck's help (bug #124764) +- Added BuildRequires: tix-devel (bug #124918) + +* Fri May 7 2004 Mihai Ibanescu 2.3.3-6 +- Correct fix for #122304 from upstream: + http://sourceforge.net/tracker/?func=detail&atid=105470&aid=931848&group_id=5470 + +* Thu May 6 2004 Mihai Ibanescu 2.3.3-4 +- Fix for bug #122304 : splitting the domain name fails on 64-bit arches +- Fix for bug #120879 : including Makefile into the main package + +- Requires XFree86-devel instead of -libs (see bug #118442) + +* Tue Mar 16 2004 Mihai Ibanescu 2.3.3-3 +- Requires XFree86-devel instead of -libs (see bug #118442) + +* Tue Mar 02 2004 Elliot Lee +- rebuilt + +* Fri Feb 13 2004 Elliot Lee +- rebuilt + +* Fri Dec 19 2003 Jeff Johnson 2.3.3-1 +- upgrade to 2.3.3. + +* Sat Dec 13 2003 Jeff Johnson 2.3.2-9 +- rebuild against db-4.2.52. + +* Fri Dec 12 2003 Jeremy Katz 2.3.2-8 +- more rebuilding for new tcl/tk + +* Wed Dec 3 2003 Jeff Johnson 2.3.2-7.1 +- rebuild against db-4.2.42. + +* Fri Nov 28 2003 Mihai Ibanescu 2.3.2-7 +- rebuilt against newer tcl/tk + +* Mon Nov 24 2003 Mihai Ibanescu 2.3.2-6 +- added a Provides: python-abi + +* Wed Nov 12 2003 Mihai Ibanescu 2.3.2-5 +- force CC (#109268) + +* Sun Nov 9 2003 Jeremy Katz 2.3.2-4 +- cryptmodule still needs -lcrypt + +* Wed Nov 5 2003 Mihai Ibanescu 2.3.2-2 +- Added patch for missing mkhowto + +* Thu Oct 16 2003 Mihai Ibanescu 2.3.2-1 +- Updated to 2.3.2 + +* Thu Sep 25 2003 Mihai Ibanescu 2.3.1-1 +- 2.3.1 final + +* Tue Sep 23 2003 Mihai Ibanescu 2.3.1-0.8.RC1 +- Building the python 2.3.1 release candidate +- Updated the lib64 patch + +* Wed Jul 30 2003 Mihai Ibanescu 2.3-0.2 +- Building python 2.3 +- Added more BuildRequires +- Updated the startup files for modulator and pynche; idle installs its own + now. + +* Thu Jul 3 2003 Mihai Ibanescu 2.2.3-4 +- Rebuilt against newer db4 packages (bug #98539) + +* Mon Jun 9 2003 Elliot Lee 2.2.3-3 +- rebuilt + +* Sat Jun 7 2003 Mihai Ibanescu 2.2.3-2 +- Rebuilt + +* Fri Jun 6 2003 Mihai Ibanescu 2.2.3-1 +- Upgraded to 2.2.3 + +* Wed Apr 2 2003 Mihai Ibanescu 2.2.2-28 +- Rebuilt + +* Wed Apr 2 2003 Mihai Ibanescu 2.2.2-27 +- Modified the ftpuri patch conforming to http://ietf.org/rfc/rfc1738.txt + +* Mon Feb 24 2003 Elliot Lee +- rebuilt + +* Mon Feb 24 2003 Mihai Ibanescu 2.2.2-25 +- Fixed bug #84886: pydoc dies when run w/o arguments +- Fixed bug #84205: add python shm module back (used to be shipped with 1.5.2) +- Fixed bug #84966: path in byte-compiled code still wrong + +* Thu Feb 20 2003 Jeremy Katz 2.2.2-23 +- ftp uri's should be able to specify being rooted at the root instead of + where you login via ftp (#84692) + +* Mon Feb 10 2003 Mihai Ibanescu 2.2.2-22 +- Using newer Japanese codecs (1.4.9). Thanks to + Peter Bowen for pointing this out. + +* Thu Feb 6 2003 Mihai Ibanescu 2.2.2-21 +- Rebuild + +* Wed Feb 5 2003 Mihai Ibanescu 2.2.2-20 +- Release number bumped really high: turning on UCS4 (ABI compatibility + breakage) + +* Fri Jan 31 2003 Mihai Ibanescu 2.2.2-13 +- Attempt to look both in /usr/lib64 and /usr/lib/python2.2/site-packages/: + some work on python-2.2.2-lib64.patch + +* Thu Jan 30 2003 Mihai Ibanescu 2.2.2-12 +- Rebuild to incorporate the removal of .lib64 and - files. + +* Thu Jan 30 2003 Mihai Ibanescu 2.2.2-11.7.3 +- Fixed bug #82544: Errata removes most tools +- Fixed bug #82435: Python 2.2.2 errata breaks redhat-config-users +- Removed .lib64 and - files that get installed after we fix the multilib + .py files. + +* Wed Jan 22 2003 Tim Powers +- rebuilt + +* Wed Jan 15 2003 Jens Petersen 2.2.2-10 +- rebuild to update tkinter's tcltk deps +- convert changelog to utf-8 + +* Tue Jan 7 2003 Nalin Dahyabhai 2.2.2-9 +- rebuild + +* Fri Jan 3 2003 Nalin Dahyabhai +- pick up OpenSSL cflags and ldflags from pkgconfig if available + +* Thu Jan 2 2003 Jeremy Katz 2.2.2-8 +- urllib2 didn't support non-anonymous ftp. add support based on how + urllib did it (#80676, #78168) + +* Mon Dec 16 2002 Mihai Ibanescu 2.2.2-7 +- Fix bug #79647 (Rebuild of SRPM fails if python isn't installed) +- Added a bunch of missing BuildRequires found while fixing the + above-mentioned bug + +* Tue Dec 10 2002 Tim Powers 2.2.2-6 +- rebuild to fix broken tcltk deps for tkinter + +* Fri Nov 22 2002 Mihai Ibanescu +2.2.2-3.7.3 +- Recompiled for 7.3 (to fix the -lcrypt bug) +- Fix for the spurious error message at the end of the build (build-requires + gets confused by executable files starting with """"): make the tests + non-executable. + +* Wed Nov 20 2002 Mihai Ibanescu +2.2.2-5 +- Fixed configuration patch to add -lcrypt when compiling cryptmodule.c + +2.2.2-4 +- Spec file change from Matt Wilson to disable linking + with the C++ compiler. + +* Mon Nov 11 2002 Mihai Ibanescu +2.2.2-3.* +- Merged patch from Karsten Hopp from 2.2.1-17hammer to + use %%{_libdir} +- Added XFree86-libs as BuildRequires (because of tkinter) +- Fixed duplicate listing of plat-linux2 +- Fixed exclusion of lib-dynload/japanese +- Added lib64 patch for the japanese codecs +- Use setup magic instead of using tar directly on JapaneseCodecs + +* Tue Nov 5 2002 Mihai Ibanescu +2.2.2-2 +- Fix #76912 (python-tools contains idle, which uses tkinter, but there is no + requirement of tkinter from python-tools). +- Fix #74013 (rpm is missing the /usr/lib/python2.2/test directory) + +* Mon Nov 4 2002 Mihai Ibanescu +- builds as python2 require a different libdb +- changed the buildroot name of python to match python2 builds + +* Fri Nov 1 2002 Mihai Ibanescu +- updated python to 2.2.2 and adjusted the patches accordingly + +* Mon Oct 21 2002 Mihai Ibanescu +- Fix #53930 (Python-2.2.1-buildroot-bytecode.patch) +- Added BuildPrereq dependency on gcc-c++ + +* Fri Aug 30 2002 Trond Eivind Glomsrød 2.2.1-17 +- security fix for _execvpe + +* Tue Aug 13 2002 Trond Eivind Glomsrød 2.2.1-16 +- Fix #71011,#71134, #58157 + +* Wed Aug 7 2002 Trond Eivind Glomsrød 2.2.1-15 +- Resurrect tkinter +- Fix for distutils (#67671) +- Fix #69962 + +* Thu Jul 25 2002 Trond Eivind Glomsrød 2.2.1-14 +- Obsolete tkinter/tkinter2 (#69838) + +* Tue Jul 23 2002 Trond Eivind Glomsrød 2.2.1-13 +- Doc fixes (#53951) - not on alpha at the momemt + +* Mon Jul 8 2002 Trond Eivind Glomsrød 2.2.1-12 +- fix pydoc (#68082) + +* Mon Jul 8 2002 Trond Eivind Glomsrød 2.2.1-11 +- Add db4-devel as a BuildPrereq + +* Fri Jun 21 2002 Tim Powers 2.2.1-10 +- automated rebuild + +* Mon Jun 17 2002 Trond Eivind Glomsrød 2.2.1-9 +- Add Japanese codecs (#66352) + +* Tue Jun 11 2002 Trond Eivind Glomsrød 2.2.1-8 +- No more tkinter... + +* Wed May 29 2002 Trond Eivind Glomsrød 2.2.1-7 +- Rebuild + +* Tue May 21 2002 Trond Eivind Glomsrød 2.2.1-6 +- Add the email subcomponent (#65301) + +* Fri May 10 2002 Trond Eivind Glomsrød 2.2.1-5 +- Rebuild + +* Thu May 02 2002 Than Ngo 2.2.1-4 +- rebuild i new enviroment + +* Tue Apr 23 2002 Trond Eivind Glomsrød +- Use ucs2, not ucs4, to avoid breaking tkinter (#63965) + +* Mon Apr 22 2002 Trond Eivind Glomsrød 2.2.1-2 +- Make it use db4 + +* Fri Apr 12 2002 Trond Eivind Glomsrød 2.2.1-1 +- 2.2.1 - a bugfix-only release + +* Fri Apr 12 2002 Trond Eivind Glomsrød 2.2-16 +- the same, but in builddirs - this will remove them from the + docs package, which doesn't look in the buildroot for files. + +* Fri Apr 12 2002 Trond Eivind Glomsrød 2.2-15 +- Get rid of temporary files and .cvsignores included + in the tarball and make install + +* Fri Apr 5 2002 Trond Eivind Glomsrød 2.2-14 +- Don't own lib-tk in main package, only in tkinter (#62753) + +* Mon Mar 25 2002 Trond Eivind Glomsrød 2.2-13 +- rebuild + +* Mon Mar 25 2002 Trond Eivind Glomsrød 2.2-12 +- rebuild + +* Fri Mar 1 2002 Trond Eivind Glomsrød 2.2-11 +- Add a not to the Distutils obsoletes test (doh!) + +* Fri Mar 1 2002 Trond Eivind Glomsrød 2.2-10 +- Rebuild + +* Mon Feb 25 2002 Trond Eivind Glomsrød 2.2-9 +- Only obsolete Distutils when built as python + +* Thu Feb 21 2002 Trond Eivind Glomsrød 2.2-8 +- Make files in /usr/bin install side by side with python 1.5 when +- Drop explicit requirement of db4 + built as python2 + +* Thu Jan 31 2002 Elliot Lee 2.2-7 +- Use version and pybasever macros to make updating easy +- Use _smp_mflags macro + +* Tue Jan 29 2002 Trond Eivind Glomsrød 2.2-6 +- Add db4-devel to BuildPrereq + +* Fri Jan 25 2002 Nalin Dahyabhai 2.2-5 +- disable ndbm support, which is db2 in disguise (really interesting things + can happen when you mix db2 and db4 in a single application) + +* Thu Jan 24 2002 Trond Eivind Glomsrød 2.2-4 +- Obsolete subpackages if necesarry +- provide versioned python2 +- build with db4 + +* Wed Jan 16 2002 Trond Eivind Glomsrød 2.2-3 +- Alpha toolchain broken. Disable build on alpha. +- New openssl + +* Wed Dec 26 2001 Trond Eivind Glomsrød 2.2-1 +- 2.2 final + +* Fri Dec 14 2001 Trond Eivind Glomsrød 2.2-0.11c1 +- 2.2 RC 1 +- Don't include the _tkinter module in the main package - it's + already in the tkiter packace +- Turn off the mpzmodule, something broke in the buildroot + +* Wed Nov 28 2001 Trond Eivind Glomsrød 2.2-0.10b2 +- Use -fPIC for OPT as well, in lack of a proper libpython.so + +* Mon Nov 26 2001 Matt Wilson 2.2-0.9b2 +- changed DESTDIR to point to / so that distutils will install dynload + modules properly in the installroot + +* Fri Nov 16 2001 Matt Wilson 2.2-0.8b2 +- 2.2b2 + +* Fri Oct 26 2001 Matt Wilson 2.2-0.7b1 +- python2ify + +* Fri Oct 19 2001 Trond Eivind Glomsrød 2.2-0.5b1 +- 2.2b1 + +* Sun Sep 30 2001 Trond Eivind Glomsrød 2.2-0.4a4 +- 2.2a4 +- Enable UCS4 support +- Enable IPv6 +- Provide distutils +- Include msgfmt.py and pygettext.py + +* Fri Sep 14 2001 Trond Eivind Glomsrød 2.2-0.3a3 +- Obsolete Distutils, which is now part of the main package +- Obsolete python2 + +* Thu Sep 13 2001 Trond Eivind Glomsrød 2.2-0.2a3 +- Add docs, tools and tkinter subpackages, to match the 1.5 layout + +* Wed Sep 12 2001 Trond Eivind Glomsrød 2.2-0.1a3 +- 2.2a3 +- don't build tix and blt extensions + +* Mon Aug 13 2001 Trond Eivind Glomsrød +- Add tk and tix to build dependencies + +* Sat Jul 21 2001 Trond Eivind Glomsrød +- 2.1.1 bugfix release - with a GPL compatible license + +* Fri Jul 20 2001 Trond Eivind Glomsrød +- Add new build dependencies (#49753) + +* Tue Jun 26 2001 Nalin Dahyabhai +- build with -fPIC + +* Fri Jun 1 2001 Trond Eivind Glomsrød +- 2.1 +- reorganization of file includes + +* Wed Dec 20 2000 Trond Eivind Glomsrød +- fix the "requires" clause, it lacked a space causing problems +- use %%{_tmppath} +- don't define name, version etc +- add the available patches from the Python home page + +* Fri Dec 15 2000 Matt Wilson +- added devel subpackage + +* Fri Dec 15 2000 Matt Wilson +- modify all files to use "python2.0" as the intrepter +- don't build the Expat bindings +- build against db1 + +* Mon Oct 16 2000 Jeremy Hylton +- updated for 2.0 final + +* Mon Oct 9 2000 Jeremy Hylton +- updated for 2.0c1 +- build audioop, imageop, and rgbimg extension modules +- include xml.parsers subpackage +- add test.xml.out to files list + +* Thu Oct 5 2000 Jeremy Hylton +- added bin/python2.0 to files list (suggested by Martin v. L?) + +* Tue Sep 26 2000 Jeremy Hylton +- updated for release 1 of 2.0b2 +- use .bz2 version of Python source + +* Tue Sep 12 2000 Jeremy Hylton +- Version 2 of 2.0b1 +- Make the package relocatable. Thanks to Suchandra Thapa. +- Exclude Tkinter from main RPM. If it is in a separate RPM, it is + easier to track Tk releases.