diff --git a/00102-lib64.patch b/00102-lib64.patch deleted file mode 100644 index e507131..0000000 --- a/00102-lib64.patch +++ /dev/null @@ -1,188 +0,0 @@ -diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py -index 9474e9c..c0ce4c6 100644 ---- a/Lib/distutils/command/install.py -+++ b/Lib/distutils/command/install.py -@@ -30,14 +30,14 @@ WINDOWS_SCHEME = { - INSTALL_SCHEMES = { - 'unix_prefix': { - 'purelib': '$base/lib/platform-python$py_version_short/site-packages', -- 'platlib': '$platbase/lib/platform-python$py_version_short/site-packages', -+ 'platlib': '$platbase/lib64/platform-python$py_version_short/site-packages', - 'headers': '$base/include/platform-python$py_version_short$abiflags/$dist_name', - 'scripts': '$base/bin', - 'data' : '$base', - }, - 'unix_home': { - 'purelib': '$base/lib/python', -- 'platlib': '$base/lib/python', -+ 'platlib': '$base/lib64/python', - 'headers': '$base/include/python/$dist_name', - 'scripts': '$base/bin', - 'data' : '$base', -diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py -index 026cca7..6d3e077 100644 ---- a/Lib/distutils/sysconfig.py -+++ b/Lib/distutils/sysconfig.py -@@ -132,8 +132,12 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): - prefix = plat_specific and EXEC_PREFIX or PREFIX - - if os.name == "posix": -+ if plat_specific or standard_lib: -+ lib = "lib64" -+ else: -+ lib = "lib" - libpython = os.path.join(prefix, -- "lib", "platform-python" + get_python_version()) -+ lib, "platform-python" + get_python_version()) - if standard_lib: - return libpython - else: -diff --git a/Lib/site.py b/Lib/site.py -index a84e3bb..ba0d3ea 100644 ---- a/Lib/site.py -+++ b/Lib/site.py -@@ -303,11 +303,15 @@ def getsitepackages(prefixes=None): - seen.add(prefix) - - if os.sep == '/': -+ sitepackages.append(os.path.join(prefix, "lib64", -+ "platform-python" + sys.version[:3], -+ "site-packages")) - sitepackages.append(os.path.join(prefix, "lib", - "platform-python%d.%d" % sys.version_info[:2], - "site-packages")) - 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 --git a/Lib/sysconfig.py b/Lib/sysconfig.py -index b9bbfe5..2a5f29c 100644 ---- a/Lib/sysconfig.py -+++ b/Lib/sysconfig.py -@@ -20,10 +20,10 @@ __all__ = [ - - _INSTALL_SCHEMES = { - 'posix_prefix': { -- 'stdlib': '{installed_base}/lib/platform-python{py_version_short}', -- 'platstdlib': '{platbase}/lib/platform-python{py_version_short}', -+ 'stdlib': '{installed_base}/lib64/platform-python{py_version_short}', -+ 'platstdlib': '{platbase}/lib64/platform-python{py_version_short}', - 'purelib': '{base}/lib/platform-python{py_version_short}/site-packages', -- 'platlib': '{platbase}/lib/platform-python{py_version_short}/site-packages', -+ 'platlib': '{platbase}/lib64/platform-python{py_version_short}/site-packages', - 'include': - '{installed_base}/include/platform-python{py_version_short}{abiflags}', - 'platinclude': -@@ -61,10 +61,10 @@ _INSTALL_SCHEMES = { - 'data': '{userbase}', - }, - 'posix_user': { -- 'stdlib': '{installed_base}/lib/platform-python{py_version_short}', -- 'platstdlib': '{platbase}/lib/platform-python{py_version_short}', -+ 'stdlib': '{installed_base}/lib64/platform-python{py_version_short}', -+ 'platstdlib': '{platbase}/lib64/platform-python{py_version_short}', - 'purelib': '{base}/lib/platform-python{py_version_short}/site-packages', -- 'platlib': '{platbase}/lib/platform-python{py_version_short}/site-packages', -+ 'platlib': '{platbase}/lib64/platform-python{py_version_short}/site-packages', - 'include': '{installed_base}/include/platform-python{py_version_short}{abiflags}', - 'scripts': '{base}/bin', - 'data': '{base}', -diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py -index f698927..bc977b5 100644 ---- a/Lib/test/test_site.py -+++ b/Lib/test/test_site.py -@@ -248,8 +248,8 @@ class HelperFunctionsTests(unittest.TestCase): - self.assertEqual(dirs[1], wanted) - elif os.sep == '/': - # OS X non-framwework builds, Linux, FreeBSD, etc -- self.assertEqual(len(dirs), 1) -- wanted = os.path.join('xoxo', 'lib', -+ self.assertEqual(len(dirs), 2) -+ wanted = os.path.join('xoxo', 'lib64', - 'python%d.%d' % sys.version_info[:2], - 'site-packages') - self.assertEqual(dirs[0], wanted) -diff --git a/Makefile.pre.in b/Makefile.pre.in -index 8fa7934..a693917 100644 ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -126,7 +126,7 @@ LIBDIR= @libdir@ - MANDIR= @mandir@ - INCLUDEDIR= @includedir@ - CONFINCLUDEDIR= $(exec_prefix)/include --SCRIPTDIR= $(prefix)/lib -+SCRIPTDIR= $(prefix)/lib64 - ABIFLAGS= @ABIFLAGS@ - - # Detailed destination directories -diff --git a/Modules/getpath.c b/Modules/getpath.c -index 65b47a3..eaa756c 100644 ---- a/Modules/getpath.c -+++ b/Modules/getpath.c -@@ -494,7 +494,7 @@ calculate_path(void) - _pythonpath = Py_DecodeLocale(PYTHONPATH, NULL); - _prefix = Py_DecodeLocale(PREFIX, NULL); - _exec_prefix = Py_DecodeLocale(EXEC_PREFIX, NULL); -- lib_python = Py_DecodeLocale("lib/platform-python" VERSION, NULL); -+ lib_python = Py_DecodeLocale("lib64/platform-python" VERSION, NULL); - - if (!_pythonpath || !_prefix || !_exec_prefix || !lib_python) { - Py_FatalError( -@@ -683,7 +683,7 @@ calculate_path(void) - } - else - wcsncpy(zip_path, _prefix, MAXPATHLEN); -- joinpath(zip_path, L"lib/python00.zip"); -+ joinpath(zip_path, L"lib64/python00.zip"); - bufsz = wcslen(zip_path); /* Replace "00" with version */ - zip_path[bufsz - 6] = VERSION[0]; - zip_path[bufsz - 5] = VERSION[2]; -@@ -695,7 +695,7 @@ calculate_path(void) - fprintf(stderr, - "Could not find platform dependent libraries \n"); - wcsncpy(exec_prefix, _exec_prefix, MAXPATHLEN); -- joinpath(exec_prefix, L"lib/lib-dynload"); -+ joinpath(exec_prefix, L"lib64/lib-dynload"); - } - /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ - -diff --git a/setup.py b/setup.py -index 0f2dfc4..da37896 100644 ---- a/setup.py -+++ b/setup.py -@@ -492,7 +492,7 @@ class PyBuildExt(build_ext): - # directories (i.e. '.' and 'Include') must be first. See issue - # 10520. - if not cross_compiling: -- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') -+ add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib64') - add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') - # only change this for cross builds for 3.3, issues on Mageia - if cross_compiling: -@@ -780,11 +780,11 @@ class PyBuildExt(build_ext): - elif curses_library: - readline_libs.append(curses_library) - elif self.compiler.find_library_file(lib_dirs + -- ['/usr/lib/termcap'], -+ ['/usr/lib64/termcap'], - 'termcap'): - readline_libs.append('termcap') - exts.append( Extension('readline', ['readline.c'], -- library_dirs=['/usr/lib/termcap'], -+ library_dirs=['/usr/lib64/termcap'], - extra_link_args=readline_extra_link_args, - libraries=readline_libs) ) - else: -@@ -821,8 +821,8 @@ class PyBuildExt(build_ext): - if krb5_h: - ssl_incs += krb5_h - ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs, -- ['/usr/local/ssl/lib', -- '/usr/contrib/ssl/lib/' -+ ['/usr/local/ssl/lib64', -+ '/usr/contrib/ssl/lib64/' - ] ) - - if (ssl_incs is not None and diff --git a/00104-lib64-fix-for-test_install.patch b/00104-lib64-fix-for-test_install.patch deleted file mode 100644 index 7ac1dbc..0000000 --- a/00104-lib64-fix-for-test_install.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- 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", "platform-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/00111-no-static-lib.patch b/00111-no-static-lib.patch deleted file mode 100644 index 9fbcc24..0000000 --- a/00111-no-static-lib.patch +++ /dev/null @@ -1,60 +0,0 @@ -diff --git a/Makefile.pre.in b/Makefile.pre.in -index 70e5927..04c8e3d 100644 ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -556,7 +556,7 @@ clinic: $(BUILDPYTHON) $(srcdir)/Modules/_blake2/blake2s_impl.c - $(RUNSHARED) $(PYTHON_FOR_BUILD) ./Tools/clinic/clinic.py --make - - # Build the interpreter --$(BUILDPYTHON): Programs/python.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) -+$(BUILDPYTHON): Programs/python.o $(LDLIBRARY) $(PY3LIBRARY) - $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) - - platform: $(BUILDPYTHON) pybuilddir.txt -@@ -601,18 +601,6 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o - $(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) Python/frozen.o -- $(AR) $(ARFLAGS) $@ $(MODULE_OBJS) -- $(AR) $(ARFLAGS) $@ $(MODOBJS) -- $(RANLIB) $@ -- - libplatform-python$(LDVERSION).so: $(LIBRARY_OBJS) - if test $(INSTSONAME) != $(LDLIBRARY); then \ - $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ -@@ -702,7 +690,7 @@ Modules/Setup: $(srcdir)/Modules/Setup.dist - echo "-----------------------------------------------"; \ - fi - --Programs/_testembed: Programs/_testembed.o $(LIBRARY) $(LDLIBRARY) $(PY3LIBRARY) -+Programs/_testembed: Programs/_testembed.o $(LDLIBRARY) $(PY3LIBRARY) - $(LINKCC) $(PY_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/_testembed.o $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) - - ############################################################################ -@@ -1382,18 +1370,6 @@ libainstall: all python-config - else true; \ - fi; \ - done -- @if test -d $(LIBRARY); then :; else \ -- if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ -- if test "$(SHLIB_SUFFIX)" = .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) Programs/python.o $(DESTDIR)$(LIBPL)/python.o - $(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in diff --git a/00132-add-rpmbuild-hooks-to-unittest.patch b/00132-add-rpmbuild-hooks-to-unittest.patch deleted file mode 100644 index 77dc6ec..0000000 --- a/00132-add-rpmbuild-hooks-to-unittest.patch +++ /dev/null @@ -1,46 +0,0 @@ -diff -up Python-3.2.2/Lib/unittest/case.py.add-rpmbuild-hooks-to-unittest Python-3.2.2/Lib/unittest/case.py ---- Python-3.2.2/Lib/unittest/case.py.add-rpmbuild-hooks-to-unittest 2011-09-03 12:16:44.000000000 -0400 -+++ Python-3.2.2/Lib/unittest/case.py 2011-09-09 06:35:16.365568382 -0400 -@@ -3,6 +3,7 @@ - import sys - import functools - import difflib -+import os - import logging - import pprint - import re -@@ -101,5 +102,21 @@ def expectedFailure(func): - raise self.test_case.failureException(msg) - -+# 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 -+ - class _AssertRaisesBaseContext(_BaseTestCaseContext): - - def __init__(self, expected, test_case, expected_regex=None): -diff -up Python-3.2.2/Lib/unittest/__init__.py.add-rpmbuild-hooks-to-unittest Python-3.2.2/Lib/unittest/__init__.py ---- Python-3.2.2/Lib/unittest/__init__.py.add-rpmbuild-hooks-to-unittest 2011-09-03 12:16:44.000000000 -0400 -+++ Python-3.2.2/Lib/unittest/__init__.py 2011-09-09 06:35:16.366568382 -0400 -@@ -57,7 +57,8 @@ __unittest = True - - from .result import TestResult - from .case import (TestCase, FunctionTestCase, SkipTest, skip, skipIf, -- skipUnless, expectedFailure) -+ skipUnless, expectedFailure, -+ _skipInRpmBuild) - from .suite import BaseTestSuite, TestSuite - from .loader import (TestLoader, defaultTestLoader, makeSuite, getTestCaseNames, - findTestCases) diff --git a/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch b/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch deleted file mode 100644 index 0457093..0000000 --- a/00137-skip-distutils-tests-that-fail-in-rpmbuild.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up Python-3.2.2/Lib/distutils/tests/test_bdist_rpm.py.skip-distutils-tests-that-fail-in-rpmbuild Python-3.2.2/Lib/distutils/tests/test_bdist_rpm.py ---- Python-3.2.2/Lib/distutils/tests/test_bdist_rpm.py.skip-distutils-tests-that-fail-in-rpmbuild 2011-09-03 12:16:40.000000000 -0400 -+++ Python-3.2.2/Lib/distutils/tests/test_bdist_rpm.py 2011-09-10 05:04:56.328852558 -0400 -@@ -23,6 +23,7 @@ setup(name='foo', version='0.1', py_modu - - """ - -+@unittest._skipInRpmBuild("don't try to nest one rpm build inside another rpm build") - class BuildRpmTestCase(support.TempdirManager, - support.EnvironGuard, - support.LoggingSilencer, -diff -up Python-3.2.2/Lib/distutils/tests/test_build_ext.py.skip-distutils-tests-that-fail-in-rpmbuild Python-3.2.2/Lib/distutils/tests/test_build_ext.py diff --git a/00146-hashlib-fips.patch b/00146-hashlib-fips.patch deleted file mode 100644 index e0cdce0..0000000 --- a/00146-hashlib-fips.patch +++ /dev/null @@ -1,640 +0,0 @@ -diff --git a/Lib/hashlib.py b/Lib/hashlib.py -index 316cece..b7ad879 100644 ---- a/Lib/hashlib.py -+++ b/Lib/hashlib.py -@@ -23,6 +23,16 @@ the zlib module. - Choose your hash function wisely. Some have known collision weaknesses. - sha384 and sha512 will be slow on 32 bit platforms. - -+If the underlying implementation supports "FIPS mode", and this is enabled, it -+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. -+ - Hash objects have these methods: - - update(arg): Update the hash object with the bytes in arg. Repeated calls - are equivalent to a single call with the concatenation of all -@@ -62,6 +72,18 @@ algorithms_available = set(__always_supported) - __all__ = __always_supported + ('new', 'algorithms_guaranteed', - 'algorithms_available', 'pbkdf2_hmac') - -+import functools -+def __ignore_usedforsecurity(func): -+ """Used for sha3_* functions. Until OpenSSL implements them, we want -+ to use them from Python _sha3 module, but we want them to accept -+ usedforsecurity argument too.""" -+ # TODO: remove this function when OpenSSL implements sha3 -+ @functools.wraps(func) -+ def inner(*args, **kwargs): -+ if 'usedforsecurity' in kwargs: -+ kwargs.pop('usedforsecurity') -+ return func(*args, **kwargs) -+ return inner - - __builtin_constructor_cache = {} - -@@ -100,31 +122,39 @@ def __get_openssl_constructor(name): - 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): -+ # TODO: We want to just raise here when OpenSSL implements sha3 -+ # because we want to make sure that Fedora uses everything from OpenSSL - return __get_builtin_constructor(name) - - --def __py_new(name, data=b''): -- """new(name, data=b'') - Return a new hashing object using the named algorithm; -- optionally initialized with data (which must be bytes). -+def __py_new(name, data=b'', usedforsecurity=True): -+ """new(name, data=b'', usedforsecurity=True) - Return a new hashing object using -+ the named algorithm; optionally initialized with data (which must be bytes). -+ The 'usedforsecurity' keyword argument does nothing, and is for compatibilty -+ with the OpenSSL implementation - """ - return __get_builtin_constructor(name)(data) - - --def __hash_new(name, data=b''): -- """new(name, data=b'') - Return a new hashing object using the named algorithm; -- optionally initialized with data (which must be bytes). -+def __hash_new(name, data=b'', usedforsecurity=True): -+ """new(name, data=b'', usedforsecurity=True) - Return a new hashing object using -+ the named algorithm; optionally initialized with data (which must be bytes). -+ -+ Override 'usedforsecurity' to False when using for non-security purposes in -+ a FIPS environment - """ - try: -- return _hashlib.new(name, data) -+ return _hashlib.new(name, data, 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. -+ # TODO: We want to just raise here when OpenSSL implements sha3 -+ # because we want to make sure that Fedora uses everything from OpenSSL - return __get_builtin_constructor(name)(data) - - -@@ -207,7 +237,10 @@ for __func_name in __always_supported: - # try them all, some may not work due to the OpenSSL - # version not supporting that algorithm. - try: -- globals()[__func_name] = __get_hash(__func_name) -+ func = __get_hash(__func_name) -+ if 'sha3_' in __func_name: -+ func = __ignore_usedforsecurity(func) -+ globals()[__func_name] = func - except ValueError: - import logging - logging.exception('code for hash %s was not found.', __func_name) -@@ -215,3 +248,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 __ignore_usedforsecurity -\ No newline at end of file -diff --git a/Lib/test/test_hashlib.py b/Lib/test/test_hashlib.py -index c9b113e..60e2392 100644 ---- a/Lib/test/test_hashlib.py -+++ b/Lib/test/test_hashlib.py -@@ -24,7 +24,22 @@ from test.support import _4G, bigmemtest, import_fresh_module - COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') - - c_hashlib = import_fresh_module('hashlib', fresh=['_hashlib']) --py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib']) -+# skipped on Fedora, since we always use OpenSSL implementation -+# py_hashlib = import_fresh_module('hashlib', blocked=['_hashlib']) -+ -+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() - - def hexstr(s): - assert isinstance(s, bytes), repr(s) -@@ -34,6 +49,16 @@ def hexstr(s): - r += h[(i >> 4) & 0xF] + h[i & 0xF] - return r - -+# hashlib and _hashlib-based functions support a "usedforsecurity" keyword -+# argument, and FIPS mode requires that it be used overridden with a False -+# value for these selftests to work. Other cryptographic code within Python -+# doesn't support this keyword. -+# Modify a function to one in which "usedforsecurity=False" is added to the -+# keyword arguments: -+def suppress_fips(f): -+ def g(*args, **kwargs): -+ return f(*args, usedforsecurity=False, **kwargs) -+ return g - - class HashLibTestCase(unittest.TestCase): - supported_hash_names = ( 'md5', 'MD5', 'sha1', 'SHA1', -@@ -63,11 +88,11 @@ class HashLibTestCase(unittest.TestCase): - # For each algorithm, test the direct constructor and the use - # of hashlib.new given the algorithm name. - for algorithm, constructors in self.constructors_to_test.items(): -- constructors.add(getattr(hashlib, algorithm)) -+ constructors.add(suppress_fips(getattr(hashlib, algorithm))) - def _test_algorithm_via_hashlib_new(data=None, _alg=algorithm): - if data is None: -- return hashlib.new(_alg) -- return hashlib.new(_alg, data) -+ return suppress_fips(hashlib.new)(_alg) -+ return suppress_fips(hashlib.new)(_alg, data) - constructors.add(_test_algorithm_via_hashlib_new) - - _hashlib = self._conditional_import_module('_hashlib') -@@ -79,27 +104,12 @@ class HashLibTestCase(unittest.TestCase): - for algorithm, constructors in self.constructors_to_test.items(): - constructor = getattr(_hashlib, 'openssl_'+algorithm, None) - if constructor: -- constructors.add(constructor) -+ constructors.add(suppress_fips(constructor)) - - def add_builtin_constructor(name): - constructor = getattr(hashlib, "__get_builtin_constructor")(name) - self.constructors_to_test[name].add(constructor) - -- _md5 = self._conditional_import_module('_md5') -- if _md5: -- add_builtin_constructor('md5') -- _sha1 = self._conditional_import_module('_sha1') -- if _sha1: -- add_builtin_constructor('sha1') -- _sha256 = self._conditional_import_module('_sha256') -- if _sha256: -- add_builtin_constructor('sha224') -- add_builtin_constructor('sha256') -- _sha512 = self._conditional_import_module('_sha512') -- if _sha512: -- add_builtin_constructor('sha384') -- add_builtin_constructor('sha512') -- - super(HashLibTestCase, self).__init__(*args, **kwargs) - - @property -@@ -148,9 +158,6 @@ class HashLibTestCase(unittest.TestCase): - else: - del sys.modules['_md5'] - self.assertRaises(TypeError, get_builtin_constructor, 3) -- constructor = get_builtin_constructor('md5') -- self.assertIs(constructor, _md5.md5) -- self.assertEqual(sorted(builtin_constructor_cache), ['MD5', 'md5']) - - def test_hexdigest(self): - for cons in self.hash_constructors: -@@ -433,6 +440,64 @@ 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") -+ -+ @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: -+ with self.assertRaisesRegexp(ValueError, '.*unknown cipher'): -+ m = hashlib.md5() -+ -+ if not self._conditional_import_module('_md5'): -+ with self.assertRaisesRegexp(ValueError, '.*unknown cipher'): -+ m = 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: -+ _hashlib = self._conditional_import_module('_hashlib') -+ if _hashlib: -+ assert hasattr(_hashlib, 'openssl_md5') -+ -+ # Ensure that _hashlib raises a ValueError on vanilla attempts to -+ # use MD5 in a FIPS-enforced setting: -+ with self.assertRaisesRegexp(ValueError, '.*unknown cipher'): -+ m = _hashlib.openssl_md5() -+ with self.assertRaisesRegexp(ValueError, '.*unknown cipher'): -+ m = _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(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.openssl_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") - - class KDFTests(unittest.TestCase): - -@@ -516,7 +581,7 @@ class KDFTests(unittest.TestCase): - out = pbkdf2(hash_name='sha1', password=b'password', salt=b'salt', - iterations=1, dklen=None) - self.assertEqual(out, self.pbkdf2_results['sha1'][0][0]) -- -+ @unittest.skip('skipped on Fedora, as we always use OpenSSL pbkdf2_hmac') - def test_pbkdf2_hmac_py(self): - self._test_pbkdf2_hmac(py_hashlib.pbkdf2_hmac) - -diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c -index 44765ac..b8cf490 100644 ---- a/Modules/_hashopenssl.c -+++ b/Modules/_hashopenssl.c -@@ -20,6 +20,8 @@ - - - /* EVP is the preferred interface to hashing in OpenSSL */ -+#include -+#include - #include - #include - /* We use the object interface to discover what hashes OpenSSL supports. */ -@@ -45,11 +47,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) -@@ -92,6 +102,48 @@ EVP_hash(EVPobject *self, const void *vp, Py_ssize_t len) - } - } - -+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 PyUnicode_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 -@@ -259,15 +311,16 @@ EVP_repr(EVPobject *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; - PyObject *data_obj = NULL; -+ int usedforsecurity = 1; - Py_buffer view; - char *nameStr; - const EVP_MD *digest; - -- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:HASH", kwlist, -- &name_obj, &data_obj)) { -+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|Oi:HASH", kwlist, -+ &name_obj, &data_obj, &usedforsecurity)) { - return -1; - } - -@@ -288,7 +341,12 @@ EVP_tp_init(EVPobject *self, PyObject *args, PyObject *kwds) - 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); -@@ -372,7 +430,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; - -@@ -387,7 +446,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) { -@@ -411,21 +475,29 @@ 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; - PyObject *data_obj = NULL; -+ int usedforsecurity = 1; - Py_buffer view = { 0 }; - PyObject *ret_obj; - char *name; - const EVP_MD *digest; - -- if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|O:new", kwlist, -- &name_obj, &data_obj)) { -+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, "O|Oi:new", kwlist, -+ &name_obj, &data_obj, &usedforsecurity)) { - return NULL; - } - -@@ -439,7 +511,8 @@ EVP_new(PyObject *self, PyObject *args, PyObject *kwdict) - - digest = EVP_get_digestbyname(name); - -- ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len); -+ ret_obj = EVPnew(name_obj, digest, NULL, (unsigned char*)view.buf, view.len, -+ usedforsecurity); - - if (data_obj) - PyBuffer_Release(&view); -@@ -722,57 +795,114 @@ generate_hash_name_list(void) - - - /* -- * 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) \ - { \ -- PyObject *data_obj = NULL; \ -- Py_buffer view = { 0 }; \ -- PyObject *ret_obj; \ -- \ -- if (!PyArg_ParseTuple(args, "|O:" #NAME , &data_obj)) { \ -- return NULL; \ -- } \ -- \ -- if (data_obj) \ -- GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); \ -- \ -- ret_obj = EVPnew( \ -- CONST_ ## NAME ## _name_obj, \ -- NULL, \ -- CONST_new_ ## NAME ## _ctx_p, \ -- (unsigned char*)view.buf, \ -- view.len); \ -- \ -- if (data_obj) \ -- PyBuffer_Release(&view); \ -- return ret_obj; \ -+ return implement_specific_EVP_new(self, args, kwdict, \ -+ "|Oi:" #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}; -+ PyObject *data_obj = NULL; -+ Py_buffer view = { 0 }; -+ int usedforsecurity = 1; -+ int idx; -+ PyObject *ret_obj = NULL; -+ -+ assert(cached_info); -+ -+ if (!PyArg_ParseTupleAndKeywords(args, kwdict, format, kwlist, -+ &data_obj, &usedforsecurity)) { -+ return NULL; -+ } -+ -+ if (data_obj) -+ GET_BUFFER_VIEW_OR_ERROUT(data_obj, &view); -+ -+ 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"); -+ } -+ } -+ -+ if (data_obj) -+ 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 = PyUnicode_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 with 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 = PyUnicode_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) -@@ -819,13 +949,10 @@ PyInit__hashlib(void) - { - PyObject *m, *openssl_md_meth_names; - -- OpenSSL_add_all_digests(); -- ERR_load_crypto_strings(); -+ SSL_load_error_strings(); -+ SSL_library_init(); - -- /* 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. */ -+ OpenSSL_add_all_digests(); - - Py_TYPE(&EVPtype) = &PyType_Type; - if (PyType_Ready(&EVPtype) < 0) diff --git a/00155-avoid-ctypes-thunks.patch b/00155-avoid-ctypes-thunks.patch deleted file mode 100644 index f03890e..0000000 --- a/00155-avoid-ctypes-thunks.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -up Python-3.2.3/Lib/ctypes/__init__.py.rhbz814391 Python-3.2.3/Lib/ctypes/__init__.py ---- Python-3.2.3/Lib/ctypes/__init__.py.rhbz814391 2012-04-20 15:12:49.017867692 -0400 -+++ Python-3.2.3/Lib/ctypes/__init__.py 2012-04-20 15:15:09.501111408 -0400 -@@ -275,11 +275,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) - - def create_unicode_buffer(init, size=None): - """create_unicode_buffer(aString) -> character array diff --git a/00157-uid-gid-overflows.patch b/00157-uid-gid-overflows.patch deleted file mode 100644 index 03f3e02..0000000 --- a/00157-uid-gid-overflows.patch +++ /dev/null @@ -1,68 +0,0 @@ -diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py -index e9fdb07..ea60e6e 100644 ---- a/Lib/test/test_os.py -+++ b/Lib/test/test_os.py -@@ -1723,30 +1723,36 @@ class PosixUidGidTests(unittest.TestCase): - def test_setuid(self): - if os.getuid() != 0: - self.assertRaises(OSError, os.setuid, 0) -+ self.assertRaises(TypeError, os.setuid, 'not an int') - self.assertRaises(OverflowError, os.setuid, 1<<32) - - @unittest.skipUnless(hasattr(os, 'setgid'), 'test needs os.setgid()') - def test_setgid(self): - if os.getuid() != 0 and not HAVE_WHEEL_GROUP: - self.assertRaises(OSError, os.setgid, 0) -+ self.assertRaises(TypeError, os.setgid, 'not an int') - self.assertRaises(OverflowError, os.setgid, 1<<32) - - @unittest.skipUnless(hasattr(os, 'seteuid'), 'test needs os.seteuid()') - def test_seteuid(self): - if os.getuid() != 0: - self.assertRaises(OSError, os.seteuid, 0) -+ self.assertRaises(TypeError, os.seteuid, 'not an int') - self.assertRaises(OverflowError, os.seteuid, 1<<32) - - @unittest.skipUnless(hasattr(os, 'setegid'), 'test needs os.setegid()') - def test_setegid(self): - if os.getuid() != 0 and not HAVE_WHEEL_GROUP: - self.assertRaises(OSError, os.setegid, 0) -+ self.assertRaises(TypeError, os.setegid, 'not an int') - self.assertRaises(OverflowError, os.setegid, 1<<32) - - @unittest.skipUnless(hasattr(os, 'setreuid'), 'test needs os.setreuid()') - def test_setreuid(self): - if os.getuid() != 0: - self.assertRaises(OSError, 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) - -@@ -1762,6 +1768,8 @@ class PosixUidGidTests(unittest.TestCase): - def test_setregid(self): - if os.getuid() != 0 and not HAVE_WHEEL_GROUP: - self.assertRaises(OSError, 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/Lib/test/test_pwd.py b/Lib/test/test_pwd.py -index ac9cff7..db98159 100644 ---- a/Lib/test/test_pwd.py -+++ b/Lib/test/test_pwd.py -@@ -104,11 +104,11 @@ class PwdTest(unittest.TestCase): - # In some cases, byuids isn't a complete list of all users in the - # system, so if we try to pick a value not in byuids (via a perturbing - # loop, say), pwd.getpwuid() might still be able to find data for that -- # uid. Using sys.maxint may provoke the same problems, but hopefully -+ # uid. Using 2**32 - 2 may provoke the same problems, but hopefully - # it will be a more repeatable failure. - # Android accepts a very large span of uids including sys.maxsize and - # -1; it raises KeyError with 1 or 2 for example. -- fakeuid = sys.maxsize -+ fakeuid = 2**32 - 2 - self.assertNotIn(fakeuid, byuids) - if not support.is_android: - self.assertRaises(KeyError, pwd.getpwuid, fakeuid) diff --git a/00160-disable-test_fs_holes-in-rpm-build.patch b/00160-disable-test_fs_holes-in-rpm-build.patch deleted file mode 100644 index 9fa91d5..0000000 --- a/00160-disable-test_fs_holes-in-rpm-build.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -up cpython-59223da36dec/Lib/test/test_posix.py.disable-test_fs_holes-in-rpm-build cpython-59223da36dec/Lib/test/test_posix.py ---- cpython-59223da36dec/Lib/test/test_posix.py.disable-test_fs_holes-in-rpm-build 2012-08-07 17:15:59.000000000 -0400 -+++ cpython-59223da36dec/Lib/test/test_posix.py 2012-08-07 17:16:53.528330330 -0400 -@@ -973,6 +973,7 @@ class PosixTester(unittest.TestCase): - posix.RTLD_GLOBAL - posix.RTLD_LOCAL - -+ @unittest._skipInRpmBuild('running kernel may not match kernel in chroot') - @unittest.skipUnless(hasattr(os, 'SEEK_HOLE'), - "test needs an OS that reports file holes") - def test_fs_holes(self): diff --git a/00163-disable-parts-of-test_socket-in-rpm-build.patch b/00163-disable-parts-of-test_socket-in-rpm-build.patch deleted file mode 100644 index 0e28036..0000000 --- a/00163-disable-parts-of-test_socket-in-rpm-build.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -up Python-3.3.0b1/Lib/test/test_socket.py.disable-test_socket-in-rpm-builds Python-3.3.0b1/Lib/test/test_socket.py ---- Python-3.3.0b1/Lib/test/test_socket.py.disable-test_socket-in-rpm-builds 2012-07-24 15:02:30.823355067 -0400 -+++ Python-3.3.0b1/Lib/test/test_socket.py 2012-07-24 15:08:13.021354999 -0400 -@@ -2188,6 +2188,7 @@ class RecvmsgGenericStreamTests(RecvmsgG - # Tests which require a stream socket and can use either recvmsg() - # or recvmsg_into(). - -+ @unittest._skipInRpmBuild('fails intermittently when run within Koji') - def testRecvmsgEOF(self): - # Receive end-of-stream indicator (b"", peer socket closed). - msg, ancdata, flags, addr = self.doRecvmsg(self.serv_sock, 1024) diff --git a/00170-gc-assertions.patch b/00170-gc-assertions.patch deleted file mode 100644 index f491733..0000000 --- a/00170-gc-assertions.patch +++ /dev/null @@ -1,310 +0,0 @@ -diff --git a/Include/object.h b/Include/object.h -index 0c88603..e3413e8 100644 ---- a/Include/object.h -+++ b/Include/object.h -@@ -1059,6 +1059,49 @@ PyAPI_FUNC(void) - _PyObject_DebugTypeStats(FILE *out); - #endif /* ifndef Py_LIMITED_API */ - -+/* -+ 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) -+ -+/* -+ Declare and define the entrypoint even when NDEBUG is defined, to avoid -+ causing compiler/linker errors when building extensions without NDEBUG -+ against a Python built with NDEBUG defined -+*/ -+PyAPI_FUNC(void) _PyObject_AssertFailed(PyObject *, const char *, -+ const char *, const char *, int, -+ const char *); -+ - #ifdef __cplusplus - } - #endif -diff --git a/Lib/test/test_gc.py b/Lib/test/test_gc.py -index e727499..6efcafb 100644 ---- a/Lib/test/test_gc.py -+++ b/Lib/test/test_gc.py -@@ -1,10 +1,11 @@ - import unittest - from test.support import (verbose, refcount_test, run_unittest, - strip_python_stderr, cpython_only, start_threads, -- temp_dir, requires_type_collecting) -+ temp_dir, import_module, requires_type_collecting) - from test.support.script_helper import assert_python_ok, make_script - - import sys -+import sysconfig - import time - import gc - import weakref -@@ -50,6 +51,8 @@ class GC_Detector(object): - # gc collects it. - self.wr = weakref.ref(C1055820(666), it_happened) - -+BUILD_WITH_NDEBUG = ('-DNDEBUG' in sysconfig.get_config_vars()['PY_CFLAGS']) -+ - @with_tp_del - class Uncollectable(object): - """Create a reference cycle with multiple __del__ methods. -@@ -862,6 +865,50 @@ class GCCallbackTests(unittest.TestCase): - self.assertEqual(len(gc.garbage), 0) - - -+ @unittest.skipIf(BUILD_WITH_NDEBUG, -+ 'built with -NDEBUG') -+ def test_refcount_errors(self): -+ self.preclean() -+ # 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.assertRegex(stderr, -+ b'Modules/gcmodule.c:[0-9]+: visit_decref: Assertion "\(\(gc\)->gc.gc_refs >> \(1\)\) != 0" failed.') -+ self.assertRegex(stderr, -+ b'refcount was too small') -+ self.assertRegex(stderr, -+ b'object : \[\]') -+ self.assertRegex(stderr, -+ b'type : list') -+ self.assertRegex(stderr, -+ b'refcount: 1') -+ self.assertRegex(stderr, -+ b'address : 0x[0-9a-f]+') -+ -+ - class GCTogglingTests(unittest.TestCase): - def setUp(self): - gc.enable() -diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c -index 0c6f444..87edd5a 100644 ---- a/Modules/gcmodule.c -+++ b/Modules/gcmodule.c -@@ -341,7 +341,8 @@ update_refs(PyGC_Head *containers) - { - PyGC_Head *gc = containers->gc.gc_next; - for (; gc != containers; gc = gc->gc.gc_next) { -- assert(_PyGCHead_REFS(gc) == GC_REACHABLE); -+ PyObject_ASSERT(FROM_GC(gc), -+ _PyGCHead_REFS(gc) == GC_REACHABLE); - _PyGCHead_SET_REFS(gc, 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 -@@ -361,7 +362,8 @@ update_refs(PyGC_Head *containers) - * so serious that maybe this should be a release-build - * check instead of an assert? - */ -- assert(_PyGCHead_REFS(gc) != 0); -+ PyObject_ASSERT(FROM_GC(gc), -+ _PyGCHead_REFS(gc) != 0); - } - } - -@@ -376,7 +378,9 @@ visit_decref(PyObject *op, void *data) - * generation being collected, which can be recognized - * because only they have positive gc_refs. - */ -- assert(_PyGCHead_REFS(gc) != 0); /* else refcount was too small */ -+ PyObject_ASSERT_WITH_MSG(FROM_GC(gc), -+ _PyGCHead_REFS(gc) != 0, -+ "refcount was too small"); /* else refcount was too small */ - if (_PyGCHead_REFS(gc) > 0) - _PyGCHead_DECREF(gc); - } -@@ -436,9 +440,10 @@ visit_reachable(PyObject *op, PyGC_Head *reachable) - * If gc_refs == GC_UNTRACKED, it must be ignored. - */ - else { -- assert(gc_refs > 0 -- || gc_refs == GC_REACHABLE -- || gc_refs == GC_UNTRACKED); -+ PyObject_ASSERT(FROM_GC(gc), -+ gc_refs > 0 -+ || gc_refs == GC_REACHABLE -+ || gc_refs == GC_UNTRACKED); - } - } - return 0; -@@ -480,7 +485,7 @@ move_unreachable(PyGC_Head *young, PyGC_Head *unreachable) - */ - PyObject *op = FROM_GC(gc); - traverseproc traverse = Py_TYPE(op)->tp_traverse; -- assert(_PyGCHead_REFS(gc) > 0); -+ PyObject_ASSERT(op, _PyGCHead_REFS(gc) > 0); - _PyGCHead_SET_REFS(gc, GC_REACHABLE); - (void) traverse(op, - (visitproc)visit_reachable, -@@ -543,7 +548,7 @@ move_legacy_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) - for (gc = unreachable->gc.gc_next; gc != unreachable; gc = next) { - PyObject *op = FROM_GC(gc); - -- assert(IS_TENTATIVELY_UNREACHABLE(op)); -+ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op)); - next = gc->gc.gc_next; - - if (has_legacy_finalizer(op)) { -@@ -619,7 +624,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) - PyWeakReference **wrlist; - - op = FROM_GC(gc); -- assert(IS_TENTATIVELY_UNREACHABLE(op)); -+ PyObject_ASSERT(op, IS_TENTATIVELY_UNREACHABLE(op)); - next = gc->gc.gc_next; - - if (! PyType_SUPPORTS_WEAKREFS(Py_TYPE(op))) -@@ -640,9 +645,9 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) - * the callback pointer intact. Obscure: it also - * changes *wrlist. - */ -- assert(wr->wr_object == op); -+ PyObject_ASSERT(wr->wr_object, wr->wr_object == op); - _PyWeakref_ClearRef(wr); -- assert(wr->wr_object == Py_None); -+ PyObject_ASSERT(wr->wr_object, wr->wr_object == Py_None); - if (wr->wr_callback == NULL) - continue; /* no callback */ - -@@ -676,7 +681,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) - */ - if (IS_TENTATIVELY_UNREACHABLE(wr)) - continue; -- assert(IS_REACHABLE(wr)); -+ PyObject_ASSERT(op, IS_REACHABLE(wr)); - - /* Create a new reference so that wr can't go away - * before we can process it again. -@@ -685,7 +690,8 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) - - /* Move wr to wrcb_to_call, for the next pass. */ - wrasgc = AS_GC(wr); -- assert(wrasgc != next); /* wrasgc is reachable, but -+ PyObject_ASSERT(op, wrasgc != next); -+ /* wrasgc is reachable, but - next isn't, so they can't - be the same */ - gc_list_move(wrasgc, &wrcb_to_call); -@@ -701,11 +707,11 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old) - - gc = wrcb_to_call.gc.gc_next; - op = FROM_GC(gc); -- assert(IS_REACHABLE(op)); -- assert(PyWeakref_Check(op)); -+ PyObject_ASSERT(op, IS_REACHABLE(op)); -+ PyObject_ASSERT(op, PyWeakref_Check(op)); - wr = (PyWeakReference *)op; - callback = wr->wr_callback; -- assert(callback != NULL); -+ PyObject_ASSERT(op, callback != NULL); - - /* copy-paste of weakrefobject.c's handle_callback() */ - temp = PyObject_CallFunctionObjArgs(callback, wr, NULL); -@@ -822,12 +828,14 @@ check_garbage(PyGC_Head *collectable) - for (gc = collectable->gc.gc_next; gc != collectable; - gc = gc->gc.gc_next) { - _PyGCHead_SET_REFS(gc, Py_REFCNT(FROM_GC(gc))); -- assert(_PyGCHead_REFS(gc) != 0); -+ PyObject_ASSERT(FROM_GC(gc), -+ _PyGCHead_REFS(gc) != 0); - } - subtract_refs(collectable); - for (gc = collectable->gc.gc_next; gc != collectable; - gc = gc->gc.gc_next) { -- assert(_PyGCHead_REFS(gc) >= 0); -+ PyObject_ASSERT(FROM_GC(gc), -+ _PyGCHead_REFS(gc) >= 0); - if (_PyGCHead_REFS(gc) != 0) - return -1; - } -diff --git a/Objects/object.c b/Objects/object.c -index 559794f..a47d47f 100644 ---- a/Objects/object.c -+++ b/Objects/object.c -@@ -2022,6 +2022,35 @@ _PyTrash_thread_destroy_chain(void) - } - } - -+PyAPI_FUNC(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(); -+} -+ - #ifndef Py_TRACE_REFS - /* For Py_LIMITED_API, we need an out-of-line version of _Py_Dealloc. - Define this here, so we can undefine the macro. */ diff --git a/00178-dont-duplicate-flags-in-sysconfig.patch b/00178-dont-duplicate-flags-in-sysconfig.patch deleted file mode 100644 index fc49b30..0000000 --- a/00178-dont-duplicate-flags-in-sysconfig.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff -r 39b9b05c3085 Lib/distutils/sysconfig.py ---- a/Lib/distutils/sysconfig.py Wed Apr 10 00:27:23 2013 +0200 -+++ b/Lib/distutils/sysconfig.py Wed Apr 10 10:14:18 2013 +0200 -@@ -362,7 +362,10 @@ - done[n] = item = "" - if found: - after = value[m.end():] -- value = value[:m.start()] + item + after -+ value = value[:m.start()] -+ if item.strip() not in value: -+ value += item -+ value += after - if "$" in after: - notdone[name] = value - else: -diff -r 39b9b05c3085 Lib/sysconfig.py ---- a/Lib/sysconfig.py Wed Apr 10 00:27:23 2013 +0200 -+++ b/Lib/sysconfig.py Wed Apr 10 10:14:18 2013 +0200 -@@ -296,7 +296,10 @@ - - if found: - after = value[m.end():] -- value = value[:m.start()] + item + after -+ value = value[:m.start()] -+ if item.strip() not in value: -+ value += item -+ value += after - if "$" in after: - notdone[name] = value - else: diff --git a/00180-python-add-support-for-ppc64p7.patch b/00180-python-add-support-for-ppc64p7.patch deleted file mode 100644 index 054f9f3..0000000 --- a/00180-python-add-support-for-ppc64p7.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/config.sub b/config.sub -index 40ea5df..932128b 100755 ---- a/config.sub -+++ b/config.sub -@@ -1045,7 +1045,7 @@ case $basic_machine in - ;; - ppc64) basic_machine=powerpc64-unknown - ;; -- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` -+ ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little) - basic_machine=powerpc64le-unknown diff --git a/00186-dont-raise-from-py_compile.patch b/00186-dont-raise-from-py_compile.patch deleted file mode 100644 index 25c4a9d..0000000 --- a/00186-dont-raise-from-py_compile.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -r 7fa3e824a4ee Lib/test/test_py_compile.py ---- a/Lib/test/test_py_compile.py Tue Oct 29 22:25:06 2013 -0400 -+++ b/Lib/test/test_py_compile.py Wed Oct 30 11:08:31 2013 +0100 -@@ -54,6 +54,10 @@ - self.assertTrue(os.path.exists(self.pyc_path)) - self.assertFalse(os.path.exists(self.cache_path)) - -+ def test_bad_coding(self): -+ bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py') -+ self.assertIsNone(py_compile.compile(bad_coding, doraise=False)) -+ - def test_relative_path(self): - py_compile.compile(os.path.relpath(self.source_path), - os.path.relpath(self.pyc_path)) diff --git a/00188-fix-lib2to3-tests-when-hashlib-doesnt-compile-properly.patch b/00188-fix-lib2to3-tests-when-hashlib-doesnt-compile-properly.patch deleted file mode 100644 index 90af30d..0000000 --- a/00188-fix-lib2to3-tests-when-hashlib-doesnt-compile-properly.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -r 28c04e954bb6 Lib/lib2to3/main.py ---- a/Lib/lib2to3/main.py Tue Oct 29 22:25:55 2013 -0400 -+++ b/Lib/lib2to3/main.py Wed Nov 06 14:33:07 2013 +0100 -@@ -213,6 +213,7 @@ - - # Set up logging handler - level = logging.DEBUG if options.verbose else logging.INFO -+ logging.root.handlers = [] - logging.basicConfig(format='%(name)s: %(message)s', level=level) - logger = logging.getLogger('lib2to3.main') - diff --git a/00205-make-libpl-respect-lib64.patch b/00205-make-libpl-respect-lib64.patch deleted file mode 100644 index 3e7c797..0000000 --- a/00205-make-libpl-respect-lib64.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up Python-3.5.0/Makefile.pre.in.lib Python-3.5.0/Makefile.pre.in ---- Python-3.5.0/Makefile.pre.in.lib 2015-09-21 15:39:47.928286620 +0200 -+++ Python-3.5.0/Makefile.pre.in 2015-09-21 15:42:58.004042762 +0200 -@@ -1340,7 +1340,7 @@ inclinstall: - - # Install the library and miscellaneous stuff needed for extending/embedding - # This goes into $(exec_prefix) --LIBPL= @LIBPL@ -+LIBPL= $(LIBDEST)/config-$(LDVERSION)-$(MULTIARCH) - - # pkgconfig directory - LIBPC= $(LIBDIR)/pkgconfig diff --git a/00206-remove-hf-from-arm-triplet.patch b/00206-remove-hf-from-arm-triplet.patch deleted file mode 100644 index c5f309c..0000000 --- a/00206-remove-hf-from-arm-triplet.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -up Python-3.5.0/configure.ac.eabi Python-3.5.0/configure.ac ---- Python-3.5.0/configure.eabi 2015-09-23 13:52:20.756909744 +0200 -+++ Python-3.5.0/configure 2015-09-23 13:52:46.859163629 +0200 -@@ -762,9 +762,9 @@ cat >> conftest.c <> conftest.c <> conftest.c <> conftest.c <> conftest.c < maxlen: -+ out = b'(... truncated stdout ...)' + out[-maxlen:] -+ if len(err) > maxlen: -+ err = b'(... truncated stderr ...)' + err[-maxlen:] -+ out = out.decode('ascii', 'replace').rstrip() -+ err = err.decode('ascii', 'replace').rstrip() -+ raise AssertionError("Process return code is %d\n" -+ "command line: %r\n" -+ "\n" -+ "stdout:\n" -+ "---\n" -+ "%s\n" -+ "---\n" -+ "\n" -+ "stderr:\n" -+ "---\n" -+ "%s\n" -+ "---" -+ % (self.rc, cmd_line, -+ out, -+ err)) - - - # Executing the interpreter in a subprocess -@@ -110,30 +137,7 @@ def run_python_until_end(*args, **env_vars): - def _assert_python(expected_success, *args, **env_vars): - res, cmd_line = run_python_until_end(*args, **env_vars) - if (res.rc and expected_success) or (not res.rc and not expected_success): -- # Limit to 80 lines to ASCII characters -- maxlen = 80 * 100 -- out, err = res.out, res.err -- if len(out) > maxlen: -- out = b'(... truncated stdout ...)' + out[-maxlen:] -- if len(err) > maxlen: -- err = b'(... truncated stderr ...)' + err[-maxlen:] -- out = out.decode('ascii', 'replace').rstrip() -- err = err.decode('ascii', 'replace').rstrip() -- raise AssertionError("Process return code is %d\n" -- "command line: %r\n" -- "\n" -- "stdout:\n" -- "---\n" -- "%s\n" -- "---\n" -- "\n" -- "stderr:\n" -- "---\n" -- "%s\n" -- "---" -- % (res.rc, cmd_line, -- out, -- err)) -+ res.fail(cmd_line) - return res - - def assert_python_ok(*args, **env_vars): -diff --git a/Lib/test/test_c_locale_coercion.py b/Lib/test/test_c_locale_coercion.py -new file mode 100644 -index 0000000..635c98f ---- /dev/null -+++ b/Lib/test/test_c_locale_coercion.py -@@ -0,0 +1,371 @@ -+# Tests the attempted automatic coercion of the C locale to a UTF-8 locale -+ -+import unittest -+import locale -+import os -+import sys -+import sysconfig -+import shutil -+import subprocess -+from collections import namedtuple -+ -+import test.support -+from test.support.script_helper import ( -+ run_python_until_end, -+ interpreter_requires_environment, -+) -+ -+# Set our expectation for the default encoding used in the C locale -+# for the filesystem encoding and the standard streams -+ -+# AIX uses iso8859-1 in the C locale, other *nix platforms use ASCII -+if sys.platform.startswith("aix"): -+ C_LOCALE_STREAM_ENCODING = "iso8859-1" -+else: -+ C_LOCALE_STREAM_ENCODING = "ascii" -+ -+# FS encoding is UTF-8 on macOS, other *nix platforms use the locale encoding -+if sys.platform == "darwin": -+ C_LOCALE_FS_ENCODING = "utf-8" -+else: -+ C_LOCALE_FS_ENCODING = C_LOCALE_STREAM_ENCODING -+ -+# Note that the above is probably still wrong in some cases, such as: -+# * Windows when PYTHONLEGACYWINDOWSFSENCODING is set -+# * AIX and any other platforms that use latin-1 in the C locale -+# -+# Options for dealing with this: -+# * Don't set PYTHON_COERCE_C_LOCALE on such platforms (e.g. Windows doesn't) -+# * Fix the test expectations to match the actual platform behaviour -+ -+# In order to get the warning messages to match up as expected, the candidate -+# order here must much the target locale order in Python/pylifecycle.c -+_C_UTF8_LOCALES = ("C.UTF-8", "C.utf8", "UTF-8") -+ -+# There's no reliable cross-platform way of checking locale alias -+# lists, so the only way of knowing which of these locales will work -+# is to try them with locale.setlocale(). We do that in a subprocess -+# to avoid altering the locale of the test runner. -+# -+# If the relevant locale module attributes exist, and we're not on a platform -+# where we expect it to always succeed, we also check that -+# `locale.nl_langinfo(locale.CODESET)` works, as if it fails, the interpreter -+# will skip locale coercion for that particular target locale -+_check_nl_langinfo_CODESET = bool( -+ sys.platform not in ("darwin", "linux") and -+ hasattr(locale, "nl_langinfo") and -+ hasattr(locale, "CODESET") -+) -+ -+def _set_locale_in_subprocess(locale_name): -+ cmd_fmt = "import locale; print(locale.setlocale(locale.LC_CTYPE, '{}'))" -+ if _check_nl_langinfo_CODESET: -+ # If there's no valid CODESET, we expect coercion to be skipped -+ cmd_fmt += "; import sys; sys.exit(not locale.nl_langinfo(locale.CODESET))" -+ cmd = cmd_fmt.format(locale_name) -+ result, py_cmd = run_python_until_end("-c", cmd, __isolated=True) -+ return result.rc == 0 -+ -+ -+ -+_fields = "fsencoding stdin_info stdout_info stderr_info lang lc_ctype lc_all" -+_EncodingDetails = namedtuple("EncodingDetails", _fields) -+ -+class EncodingDetails(_EncodingDetails): -+ # XXX (ncoghlan): Using JSON for child state reporting may be less fragile -+ CHILD_PROCESS_SCRIPT = ";".join([ -+ "import sys, os", -+ "print(sys.getfilesystemencoding())", -+ "print(sys.stdin.encoding + ':' + sys.stdin.errors)", -+ "print(sys.stdout.encoding + ':' + sys.stdout.errors)", -+ "print(sys.stderr.encoding + ':' + sys.stderr.errors)", -+ "print(os.environ.get('LANG', 'not set'))", -+ "print(os.environ.get('LC_CTYPE', 'not set'))", -+ "print(os.environ.get('LC_ALL', 'not set'))", -+ ]) -+ -+ @classmethod -+ def get_expected_details(cls, coercion_expected, fs_encoding, stream_encoding, env_vars): -+ """Returns expected child process details for a given encoding""" -+ _stream = stream_encoding + ":{}" -+ # stdin and stdout should use surrogateescape either because the -+ # coercion triggered, or because the C locale was detected -+ stream_info = 2*[_stream.format("surrogateescape")] -+ # stderr should always use backslashreplace -+ stream_info.append(_stream.format("backslashreplace")) -+ expected_lang = env_vars.get("LANG", "not set").lower() -+ if coercion_expected: -+ expected_lc_ctype = CLI_COERCION_TARGET.lower() -+ else: -+ expected_lc_ctype = env_vars.get("LC_CTYPE", "not set").lower() -+ expected_lc_all = env_vars.get("LC_ALL", "not set").lower() -+ env_info = expected_lang, expected_lc_ctype, expected_lc_all -+ return dict(cls(fs_encoding, *stream_info, *env_info)._asdict()) -+ -+ @staticmethod -+ def _handle_output_variations(data): -+ """Adjust the output to handle platform specific idiosyncrasies -+ -+ * Some platforms report ASCII as ANSI_X3.4-1968 -+ * Some platforms report ASCII as US-ASCII -+ * Some platforms report UTF-8 instead of utf-8 -+ """ -+ data = data.replace(b"ANSI_X3.4-1968", b"ascii") -+ data = data.replace(b"US-ASCII", b"ascii") -+ data = data.lower() -+ return data -+ -+ @classmethod -+ def get_child_details(cls, env_vars): -+ """Retrieves fsencoding and standard stream details from a child process -+ -+ Returns (encoding_details, stderr_lines): -+ -+ - encoding_details: EncodingDetails for eager decoding -+ - stderr_lines: result of calling splitlines() on the stderr output -+ -+ The child is run in isolated mode if the current interpreter supports -+ that. -+ """ -+ result, py_cmd = run_python_until_end( -+ "-c", cls.CHILD_PROCESS_SCRIPT, -+ __isolated=True, -+ **env_vars -+ ) -+ if not result.rc == 0: -+ result.fail(py_cmd) -+ # All subprocess outputs in this test case should be pure ASCII -+ adjusted_output = cls._handle_output_variations(result.out) -+ stdout_lines = adjusted_output.decode("ascii").splitlines() -+ child_encoding_details = dict(cls(*stdout_lines)._asdict()) -+ stderr_lines = result.err.decode("ascii").rstrip().splitlines() -+ return child_encoding_details, stderr_lines -+ -+ -+# Details of the shared library warning emitted at runtime -+LEGACY_LOCALE_WARNING = ( -+ "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII " -+ "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, " -+ "C.utf8, or UTF-8 (if available) as alternative Unicode-compatible " -+ "locales is recommended." -+) -+ -+# Details of the CLI locale coercion warning emitted at runtime -+CLI_COERCION_WARNING_FMT = ( -+ "Python detected LC_CTYPE=C: LC_CTYPE coerced to {} (set another locale " -+ "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior)." -+) -+ -+ -+AVAILABLE_TARGETS = None -+CLI_COERCION_TARGET = None -+CLI_COERCION_WARNING = None -+ -+def setUpModule(): -+ global AVAILABLE_TARGETS -+ global CLI_COERCION_TARGET -+ global CLI_COERCION_WARNING -+ -+ if AVAILABLE_TARGETS is not None: -+ # initialization already done -+ return -+ AVAILABLE_TARGETS = [] -+ -+ # Find the target locales available in the current system -+ for target_locale in _C_UTF8_LOCALES: -+ if _set_locale_in_subprocess(target_locale): -+ AVAILABLE_TARGETS.append(target_locale) -+ -+ if AVAILABLE_TARGETS: -+ # Coercion is expected to use the first available target locale -+ CLI_COERCION_TARGET = AVAILABLE_TARGETS[0] -+ CLI_COERCION_WARNING = CLI_COERCION_WARNING_FMT.format(CLI_COERCION_TARGET) -+ -+ -+class _LocaleHandlingTestCase(unittest.TestCase): -+ # Base class to check expected locale handling behaviour -+ -+ def _check_child_encoding_details(self, -+ env_vars, -+ expected_fs_encoding, -+ expected_stream_encoding, -+ expected_warnings, -+ coercion_expected): -+ """Check the C locale handling for the given process environment -+ -+ Parameters: -+ expected_fs_encoding: expected sys.getfilesystemencoding() result -+ expected_stream_encoding: expected encoding for standard streams -+ expected_warning: stderr output to expect (if any) -+ """ -+ result = EncodingDetails.get_child_details(env_vars) -+ encoding_details, stderr_lines = result -+ expected_details = EncodingDetails.get_expected_details( -+ coercion_expected, -+ expected_fs_encoding, -+ expected_stream_encoding, -+ env_vars -+ ) -+ self.assertEqual(encoding_details, expected_details) -+ if expected_warnings is None: -+ expected_warnings = [] -+ self.assertEqual(stderr_lines, expected_warnings) -+ -+ -+class LocaleConfigurationTests(_LocaleHandlingTestCase): -+ # Test explicit external configuration via the process environment -+ -+ def setUpClass(): -+ # This relies on setupModule() having been run, so it can't be -+ # handled via the @unittest.skipUnless decorator -+ if not AVAILABLE_TARGETS: -+ raise unittest.SkipTest("No C-with-UTF-8 locale available") -+ -+ def test_external_target_locale_configuration(self): -+ -+ # Explicitly setting a target locale should give the same behaviour as -+ # is seen when implicitly coercing to that target locale -+ self.maxDiff = None -+ -+ expected_fs_encoding = "utf-8" -+ expected_stream_encoding = "utf-8" -+ -+ base_var_dict = { -+ "LANG": "", -+ "LC_CTYPE": "", -+ "LC_ALL": "", -+ } -+ for env_var in ("LANG", "LC_CTYPE"): -+ for locale_to_set in AVAILABLE_TARGETS: -+ # XXX (ncoghlan): LANG=UTF-8 doesn't appear to work as -+ # expected, so skip that combination for now -+ # See https://bugs.python.org/issue30672 for discussion -+ if env_var == "LANG" and locale_to_set == "UTF-8": -+ continue -+ -+ with self.subTest(env_var=env_var, -+ configured_locale=locale_to_set): -+ var_dict = base_var_dict.copy() -+ var_dict[env_var] = locale_to_set -+ self._check_child_encoding_details(var_dict, -+ expected_fs_encoding, -+ expected_stream_encoding, -+ expected_warnings=None, -+ coercion_expected=False) -+ -+ -+ -+@test.support.cpython_only -+@unittest.skipUnless(sysconfig.get_config_var("PY_COERCE_C_LOCALE"), -+ "C locale coercion disabled at build time") -+class LocaleCoercionTests(_LocaleHandlingTestCase): -+ # Test implicit reconfiguration of the environment during CLI startup -+ -+ def _check_c_locale_coercion(self, -+ fs_encoding, stream_encoding, -+ coerce_c_locale, -+ expected_warnings=None, -+ coercion_expected=True, -+ **extra_vars): -+ """Check the C locale handling for various configurations -+ -+ Parameters: -+ fs_encoding: expected sys.getfilesystemencoding() result -+ stream_encoding: expected encoding for standard streams -+ coerce_c_locale: setting to use for PYTHONCOERCECLOCALE -+ None: don't set the variable at all -+ str: the value set in the child's environment -+ expected_warnings: expected warning lines on stderr -+ extra_vars: additional environment variables to set in subprocess -+ """ -+ self.maxDiff = None -+ -+ if not AVAILABLE_TARGETS: -+ # Locale coercion is disabled when there aren't any target locales -+ fs_encoding = C_LOCALE_FS_ENCODING -+ stream_encoding = C_LOCALE_STREAM_ENCODING -+ coercion_expected = False -+ if expected_warnings: -+ expected_warnings = [LEGACY_LOCALE_WARNING] -+ -+ base_var_dict = { -+ "LANG": "", -+ "LC_CTYPE": "", -+ "LC_ALL": "", -+ } -+ base_var_dict.update(extra_vars) -+ for env_var in ("LANG", "LC_CTYPE"): -+ for locale_to_set in ("", "C", "POSIX", "invalid.ascii"): -+ # XXX (ncoghlan): *BSD platforms don't behave as expected in the -+ # POSIX locale, so we skip that for now -+ # See https://bugs.python.org/issue30672 for discussion -+ if locale_to_set == "POSIX": -+ continue -+ with self.subTest(env_var=env_var, -+ nominal_locale=locale_to_set, -+ PYTHONCOERCECLOCALE=coerce_c_locale): -+ var_dict = base_var_dict.copy() -+ var_dict[env_var] = locale_to_set -+ if coerce_c_locale is not None: -+ var_dict["PYTHONCOERCECLOCALE"] = coerce_c_locale -+ # Check behaviour on successful coercion -+ self._check_child_encoding_details(var_dict, -+ fs_encoding, -+ stream_encoding, -+ expected_warnings, -+ coercion_expected) -+ -+ def test_test_PYTHONCOERCECLOCALE_not_set(self): -+ # This should coerce to the first available target locale by default -+ self._check_c_locale_coercion("utf-8", "utf-8", coerce_c_locale=None) -+ -+ def test_PYTHONCOERCECLOCALE_not_zero(self): -+ # *Any* string other than "0" is considered "set" for our purposes -+ # and hence should result in the locale coercion being enabled -+ for setting in ("", "1", "true", "false"): -+ self._check_c_locale_coercion("utf-8", "utf-8", coerce_c_locale=setting) -+ -+ def test_PYTHONCOERCECLOCALE_set_to_warn(self): -+ # PYTHONCOERCECLOCALE=warn enables runtime warnings for legacy locales -+ self._check_c_locale_coercion("utf-8", "utf-8", -+ coerce_c_locale="warn", -+ expected_warnings=[CLI_COERCION_WARNING]) -+ -+ -+ def test_PYTHONCOERCECLOCALE_set_to_zero(self): -+ # The setting "0" should result in the locale coercion being disabled -+ self._check_c_locale_coercion(C_LOCALE_FS_ENCODING, -+ C_LOCALE_STREAM_ENCODING, -+ coerce_c_locale="0", -+ coercion_expected=False) -+ # Setting LC_ALL=C shouldn't make any difference to the behaviour -+ self._check_c_locale_coercion(C_LOCALE_FS_ENCODING, -+ C_LOCALE_STREAM_ENCODING, -+ coerce_c_locale="0", -+ LC_ALL="C", -+ coercion_expected=False) -+ -+ def test_LC_ALL_set_to_C(self): -+ # Setting LC_ALL should render the locale coercion ineffective -+ self._check_c_locale_coercion(C_LOCALE_FS_ENCODING, -+ C_LOCALE_STREAM_ENCODING, -+ coerce_c_locale=None, -+ LC_ALL="C", -+ coercion_expected=False) -+ # And result in a warning about a lack of locale compatibility -+ self._check_c_locale_coercion(C_LOCALE_FS_ENCODING, -+ C_LOCALE_STREAM_ENCODING, -+ coerce_c_locale="warn", -+ LC_ALL="C", -+ expected_warnings=[LEGACY_LOCALE_WARNING], -+ coercion_expected=False) -+ -+def test_main(): -+ test.support.run_unittest( -+ LocaleConfigurationTests, -+ LocaleCoercionTests -+ ) -+ test.support.reap_children() -+ -+if __name__ == "__main__": -+ test_main() -diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py -index 6c3625d..009f542 100644 ---- a/Lib/test/test_capi.py -+++ b/Lib/test/test_capi.py -@@ -369,14 +369,21 @@ class EmbeddingTests(unittest.TestCase): - def tearDown(self): - os.chdir(self.oldcwd) - -- def run_embedded_interpreter(self, *args): -+ def run_embedded_interpreter(self, *args, env=None): - """Runs a test in the embedded interpreter""" - cmd = [self.test_exe] - cmd.extend(args) -+ if env is not None and sys.platform == 'win32': -+ # Windows requires at least the SYSTEMROOT environment variable to -+ # start Python. -+ env = env.copy() -+ env['SYSTEMROOT'] = os.environ['SYSTEMROOT'] -+ - p = subprocess.Popen(cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, -- universal_newlines=True) -+ universal_newlines=True, -+ env=env) - (out, err) = p.communicate() - self.assertEqual(p.returncode, 0, - "bad returncode %d, stderr is %r" % -@@ -386,31 +393,21 @@ class EmbeddingTests(unittest.TestCase): - def test_subinterps(self): - # This is just a "don't crash" test - out, err = self.run_embedded_interpreter() -- if support.verbose: -+ if support.verbose > 1: - print() - print(out) - print(err) - -- @staticmethod -- def _get_default_pipe_encoding(): -- rp, wp = os.pipe() -- try: -- with os.fdopen(wp, 'w') as w: -- default_pipe_encoding = w.encoding -- finally: -- os.close(rp) -- return default_pipe_encoding -- - def test_forced_io_encoding(self): - # Checks forced configuration of embedded interpreter IO streams -- out, err = self.run_embedded_interpreter("forced_io_encoding") -- if support.verbose: -+ env = dict(os.environ, PYTHONIOENCODING="utf-8:surrogateescape") -+ out, err = self.run_embedded_interpreter("forced_io_encoding", env=env) -+ if support.verbose > 1: - print() - print(out) - print(err) -- expected_errors = sys.__stdout__.errors -- expected_stdin_encoding = sys.__stdin__.encoding -- expected_pipe_encoding = self._get_default_pipe_encoding() -+ expected_stream_encoding = "utf-8" -+ expected_errors = "surrogateescape" - expected_output = '\n'.join([ - "--- Use defaults ---", - "Expected encoding: default", -@@ -437,8 +434,8 @@ class EmbeddingTests(unittest.TestCase): - "stdout: latin-1:replace", - "stderr: latin-1:backslashreplace"]) - expected_output = expected_output.format( -- in_encoding=expected_stdin_encoding, -- out_encoding=expected_pipe_encoding, -+ in_encoding=expected_stream_encoding, -+ out_encoding=expected_stream_encoding, - errors=expected_errors) - # This is useful if we ever trip over odd platform behaviour - self.maxDiff = None -diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py -index ae2bcd4..0a302ff 100644 ---- a/Lib/test/test_cmd_line.py -+++ b/Lib/test/test_cmd_line.py -@@ -9,8 +9,9 @@ import sys - import subprocess - import tempfile - from test.support import script_helper, is_android --from test.support.script_helper import (spawn_python, kill_python, assert_python_ok, -- assert_python_failure) -+from test.support.script_helper import ( -+ spawn_python, kill_python, assert_python_ok, assert_python_failure -+) - - - # XXX (ncoghlan): Move to script_helper and make consistent with run_python -@@ -151,6 +152,7 @@ class CmdLineTest(unittest.TestCase): - env = os.environ.copy() - # Use C locale to get ascii for the locale encoding - env['LC_ALL'] = 'C' -+ env['PYTHONCOERCECLOCALE'] = '0' - code = ( - b'import locale; ' - b'print(ascii("' + undecodable + b'"), ' -diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py -index df9ebd4..63145e4 100644 ---- a/Lib/test/test_sys.py -+++ b/Lib/test/test_sys.py -@@ -680,6 +680,7 @@ class SysModuleTest(unittest.TestCase): - # Force the POSIX locale - env = os.environ.copy() - env["LC_ALL"] = "C" -+ env["PYTHONCOERCECLOCALE"] = "0" - code = '\n'.join(( - 'import sys', - 'def dump(name):', -diff --git a/Modules/main.c b/Modules/main.c -index dd50211..f20cf24 100644 ---- a/Modules/main.c -+++ b/Modules/main.c -@@ -105,7 +105,11 @@ static const char usage_6[] = - " predictable seed.\n" - "PYTHONMALLOC: set the Python memory allocators and/or install debug hooks\n" - " on Python memory allocators. Use PYTHONMALLOC=debug to install debug\n" --" hooks.\n"; -+" hooks.\n" -+ -+"PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale\n" -+" coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of\n" -+" locale coercion and locale compatibility warnings on stderr.\n"; - - static int - usage(int exitcode, const wchar_t* program) -diff --git a/Programs/_testembed.c b/Programs/_testembed.c -index 3968399..1bd2bbf 100644 ---- a/Programs/_testembed.c -+++ b/Programs/_testembed.c -@@ -1,4 +1,5 @@ --#include -+#include "Python.h" -+#include "pyconfig.h" - #include - - /********************************************************* -diff --git a/Programs/python.c b/Programs/python.c -index a7afbc7..03f8295 100644 ---- a/Programs/python.c -+++ b/Programs/python.c -@@ -15,6 +15,21 @@ wmain(int argc, wchar_t **argv) - } - #else - -+/* Access private pylifecycle helper API to better handle the legacy C locale -+ * -+ * The legacy C locale assumes ASCII as the default text encoding, which -+ * causes problems not only for the CPython runtime, but also other -+ * components like GNU readline. -+ * -+ * Accordingly, when the CLI detects it, it attempts to coerce it to a -+ * more capable UTF-8 based alternative. -+ * -+ * See the documentation of the PYTHONCOERCECLOCALE setting for more details. -+ * -+ */ -+extern int _Py_LegacyLocaleDetected(void); -+extern void _Py_CoerceLegacyLocale(void); -+ - int - main(int argc, char **argv) - { -@@ -25,7 +40,11 @@ main(int argc, char **argv) - char *oldloc; - - /* Force malloc() allocator to bootstrap Python */ -+#ifdef Py_DEBUG -+ (void)_PyMem_SetupAllocators("malloc_debug"); -+# else - (void)_PyMem_SetupAllocators("malloc"); -+# endif - - argv_copy = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); - argv_copy2 = (wchar_t **)PyMem_RawMalloc(sizeof(wchar_t*) * (argc+1)); -@@ -49,7 +68,21 @@ main(int argc, char **argv) - return 1; - } - -+#ifdef __ANDROID__ -+ /* Passing "" to setlocale() on Android requests the C locale rather -+ * than checking environment variables, so request C.UTF-8 explicitly -+ */ -+ setlocale(LC_ALL, "C.UTF-8"); -+#else -+ /* Reconfigure the locale to the default for this process */ - setlocale(LC_ALL, ""); -+#endif -+ -+ if (_Py_LegacyLocaleDetected()) { -+ _Py_CoerceLegacyLocale(); -+ } -+ -+ /* Convert from char to wchar_t based on the locale settings */ - for (i = 0; i < argc; i++) { - argv_copy[i] = Py_DecodeLocale(argv[i], NULL); - if (!argv_copy[i]) { -@@ -70,7 +103,11 @@ main(int argc, char **argv) - - /* Force again malloc() allocator to release memory blocks allocated - before Py_Main() */ -+#ifdef Py_DEBUG -+ (void)_PyMem_SetupAllocators("malloc_debug"); -+# else - (void)_PyMem_SetupAllocators("malloc"); -+# endif - - for (i = 0; i < argc; i++) { - PyMem_RawFree(argv_copy2[i]); -diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c -index a4f7f82..3843297 100644 ---- a/Python/pylifecycle.c -+++ b/Python/pylifecycle.c -@@ -167,6 +167,7 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors) - return 0; - } - -+ - /* Global initializations. Can be undone by Py_FinalizeEx(). Don't - call this twice without an intervening Py_FinalizeEx() call. When - initializations fail, a fatal error is issued and the function does -@@ -301,6 +302,183 @@ import_init(PyInterpreterState *interp, PyObject *sysmod) - } - - -+/* Helper functions to better handle the legacy C locale -+ * -+ * The legacy C locale assumes ASCII as the default text encoding, which -+ * causes problems not only for the CPython runtime, but also other -+ * components like GNU readline. -+ * -+ * Accordingly, when the CLI detects it, it attempts to coerce it to a -+ * more capable UTF-8 based alternative as follows: -+ * -+ * if (_Py_LegacyLocaleDetected()) { -+ * _Py_CoerceLegacyLocale(); -+ * } -+ * -+ * See the documentation of the PYTHONCOERCECLOCALE setting for more details. -+ * -+ * Locale coercion also impacts the default error handler for the standard -+ * streams: while the usual default is "strict", the default for the legacy -+ * C locale and for any of the coercion target locales is "surrogateescape". -+ */ -+ -+int -+_Py_LegacyLocaleDetected(void) -+{ -+#ifndef MS_WINDOWS -+ /* On non-Windows systems, the C locale is considered a legacy locale */ -+ /* XXX (ncoghlan): some platforms (notably Mac OS X) don't appear to treat -+ * the POSIX locale as a simple alias for the C locale, so -+ * we may also want to check for that explicitly. -+ */ -+ const char *ctype_loc = setlocale(LC_CTYPE, NULL); -+ return ctype_loc != NULL && strcmp(ctype_loc, "C") == 0; -+#else -+ /* Windows uses code pages instead of locales, so no locale is legacy */ -+ return 0; -+#endif -+} -+ -+ -+static const char *_C_LOCALE_WARNING = -+ "Python runtime initialized with LC_CTYPE=C (a locale with default ASCII " -+ "encoding), which may cause Unicode compatibility problems. Using C.UTF-8, " -+ "C.utf8, or UTF-8 (if available) as alternative Unicode-compatible " -+ "locales is recommended.\n"; -+ -+static int -+_legacy_locale_warnings_enabled(void) -+{ -+ const char *coerce_c_locale = getenv("PYTHONCOERCECLOCALE"); -+ return (coerce_c_locale != NULL && -+ strncmp(coerce_c_locale, "warn", 5) == 0); -+} -+ -+static void -+_emit_stderr_warning_for_legacy_locale(void) -+{ -+ if (_legacy_locale_warnings_enabled()) { -+ if (_Py_LegacyLocaleDetected()) { -+ fprintf(stderr, "%s", _C_LOCALE_WARNING); -+ } -+ } -+} -+ -+typedef struct _CandidateLocale { -+ const char *locale_name; /* The locale to try as a coercion target */ -+} _LocaleCoercionTarget; -+ -+static _LocaleCoercionTarget _TARGET_LOCALES[] = { -+ {"C.UTF-8"}, -+ {"C.utf8"}, -+ {"UTF-8"}, -+ {NULL} -+}; -+ -+static char * -+get_default_standard_stream_error_handler(void) -+{ -+ const char *ctype_loc = setlocale(LC_CTYPE, NULL); -+ if (ctype_loc != NULL) { -+ /* "surrogateescape" is the default in the legacy C locale */ -+ if (strcmp(ctype_loc, "C") == 0) { -+ return "surrogateescape"; -+ } -+ -+#ifdef PY_COERCE_C_LOCALE -+ /* "surrogateescape" is the default in locale coercion target locales */ -+ const _LocaleCoercionTarget *target = NULL; -+ for (target = _TARGET_LOCALES; target->locale_name; target++) { -+ if (strcmp(ctype_loc, target->locale_name) == 0) { -+ return "surrogateescape"; -+ } -+ } -+#endif -+ } -+ -+ /* Otherwise return NULL to request the typical default error handler */ -+ return NULL; -+} -+ -+#ifdef PY_COERCE_C_LOCALE -+static const char *_C_LOCALE_COERCION_WARNING = -+ "Python detected LC_CTYPE=C: LC_CTYPE coerced to %.20s (set another locale " -+ "or PYTHONCOERCECLOCALE=0 to disable this locale coercion behavior).\n"; -+ -+static void -+_coerce_default_locale_settings(const _LocaleCoercionTarget *target) -+{ -+ -+ const char *newloc = target->locale_name; -+ -+ /* Reset locale back to currently configured defaults */ -+ setlocale(LC_ALL, ""); -+ -+ /* Set the relevant locale environment variable */ -+ if (setenv("LC_CTYPE", newloc, 1)) { -+ fprintf(stderr, -+ "Error setting LC_CTYPE, skipping C locale coercion\n"); -+ return; -+ } -+ if (_legacy_locale_warnings_enabled()) { -+ fprintf(stderr, _C_LOCALE_COERCION_WARNING, newloc); -+ } -+ -+ /* Reconfigure with the overridden environment variables */ -+ setlocale(LC_ALL, ""); -+} -+#endif -+ -+ -+void -+_Py_CoerceLegacyLocale(void) -+{ -+#ifdef PY_COERCE_C_LOCALE -+ /* We ignore the Python -E and -I flags here, as the CLI needs to sort out -+ * the locale settings *before* we try to do anything with the command -+ * line arguments. For cross-platform debugging purposes, we also need -+ * to give end users a way to force even scripts that are otherwise -+ * isolated from their environment to use the legacy ASCII-centric C -+ * locale. -+ * -+ * Ignoring -E and -I is safe from a security perspective, as we only use -+ * the setting to turn *off* the implicit locale coercion, and anyone with -+ * access to the process environment already has the ability to set -+ * `LC_ALL=C` to override the C level locale settings anyway. -+ */ -+ const char *coerce_c_locale = getenv("PYTHONCOERCECLOCALE"); -+ if (coerce_c_locale == NULL || strncmp(coerce_c_locale, "0", 2) != 0) { -+ /* PYTHONCOERCECLOCALE is not set, or is set to something other than "0" */ -+ const char *locale_override = getenv("LC_ALL"); -+ if (locale_override == NULL || *locale_override == '\0') { -+ /* LC_ALL is also not set (or is set to an empty string) */ -+ const _LocaleCoercionTarget *target = NULL; -+ for (target = _TARGET_LOCALES; target->locale_name; target++) { -+ const char *new_locale = setlocale(LC_CTYPE, -+ target->locale_name); -+ if (new_locale != NULL) { -+#if !defined(__APPLE__) && defined(HAVE_LANGINFO_H) && defined(CODESET) -+ /* Also ensure that nl_langinfo works in this locale */ -+ char *codeset = nl_langinfo(CODESET); -+ if (!codeset || *codeset == '\0') { -+ /* CODESET is not set or empty, so skip coercion */ -+ new_locale = NULL; -+ setlocale(LC_CTYPE, ""); -+ continue; -+ } -+#endif -+ /* Successfully configured locale, so make it the default */ -+ _coerce_default_locale_settings(target); -+ return; -+ } -+ } -+ } -+ } -+ /* No C locale warning here, as Py_Initialize will emit one later */ -+#endif -+} -+ -+ - void - _Py_InitializeEx_Private(int install_sigs, int install_importlib) - { -@@ -315,11 +493,19 @@ _Py_InitializeEx_Private(int install_sigs, int install_importlib) - initialized = 1; - _Py_Finalizing = NULL; - --#ifdef HAVE_SETLOCALE -+#ifdef __ANDROID__ -+ /* Passing "" to setlocale() on Android requests the C locale rather -+ * than checking environment variables, so request C.UTF-8 explicitly -+ */ -+ setlocale(LC_CTYPE, "C.UTF-8"); -+#else -+#ifndef MS_WINDOWS - /* Set up the LC_CTYPE locale, so we can obtain - the locale's charset without having to switch - locales. */ - setlocale(LC_CTYPE, ""); -+ _emit_stderr_warning_for_legacy_locale(); -+#endif - #endif - - if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0') -@@ -1242,12 +1428,8 @@ initstdio(void) - } - } - if (!errors && !(pythonioencoding && *pythonioencoding)) { -- /* When the LC_CTYPE locale is the POSIX locale ("C locale"), -- stdin and stdout use the surrogateescape error handler by -- default, instead of the strict error handler. */ -- char *loc = setlocale(LC_CTYPE, NULL); -- if (loc != NULL && strcmp(loc, "C") == 0) -- errors = "surrogateescape"; -+ /* Choose the default error handler based on the current locale */ -+ errors = get_default_standard_stream_error_handler(); - } - } - -diff --git a/configure b/configure -index 2915246..39e5a27 100755 ---- a/configure -+++ b/configure -@@ -834,6 +834,8 @@ with_thread - enable_ipv6 - with_doc_strings - with_pymalloc -+with_c_locale_coercion -+with_c_locale_warning - with_valgrind - with_dtrace - with_fpectl -@@ -1527,6 +1529,12 @@ Optional Packages: - deprecated; use --with(out)-threads - --with(out)-doc-strings disable/enable documentation strings - --with(out)-pymalloc disable/enable specialized mallocs -+ --with(out)-c-locale-coercion -+ disable/enable C locale coercion to a UTF-8 based -+ locale -+ --with(out)-c-locale-warning -+ disable/enable locale compatibility warning in the C -+ locale - --with-valgrind Enable Valgrind support - --with(out)-dtrace disable/enable DTrace support - --with-fpectl enable SIGFPE catching -@@ -11010,6 +11018,52 @@ fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_pymalloc" >&5 - $as_echo "$with_pymalloc" >&6; } - -+# Check for --with-c-locale-coercion -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-c-locale-coercion" >&5 -+$as_echo_n "checking for --with-c-locale-coercion... " >&6; } -+ -+# Check whether --with-c-locale-coercion was given. -+if test "${with_c_locale_coercion+set}" = set; then : -+ withval=$with_c_locale_coercion; -+fi -+ -+ -+if test -z "$with_c_locale_coercion" -+then -+ with_c_locale_coercion="yes" -+fi -+if test "$with_c_locale_coercion" != "no" -+then -+ -+$as_echo "#define PY_COERCE_C_LOCALE 1" >>confdefs.h -+ -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_c_locale_coercion" >&5 -+$as_echo "$with_c_locale_coercion" >&6; } -+ -+# Check for --with-c-locale-warning -+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-c-locale-warning" >&5 -+$as_echo_n "checking for --with-c-locale-warning... " >&6; } -+ -+# Check whether --with-c-locale-warning was given. -+if test "${with_c_locale_warning+set}" = set; then : -+ withval=$with_c_locale_warning; -+fi -+ -+ -+if test -z "$with_c_locale_warning" -+then -+ with_c_locale_warning="yes" -+fi -+if test "$with_c_locale_warning" != "no" -+then -+ -+$as_echo "#define PY_WARN_ON_C_LOCALE 1" >>confdefs.h -+ -+fi -+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_c_locale_warning" >&5 -+$as_echo "$with_c_locale_warning" >&6; } -+ - # Check for Valgrind support - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for --with-valgrind" >&5 - $as_echo_n "checking for --with-valgrind... " >&6; } -diff --git a/configure.ac b/configure.ac -index 67dfba3..b9c9f04 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3279,6 +3279,40 @@ then - fi - AC_MSG_RESULT($with_pymalloc) - -+# Check for --with-c-locale-coercion -+AC_MSG_CHECKING(for --with-c-locale-coercion) -+AC_ARG_WITH(c-locale-coercion, -+ AS_HELP_STRING([--with(out)-c-locale-coercion], -+ [disable/enable C locale coercion to a UTF-8 based locale])) -+ -+if test -z "$with_c_locale_coercion" -+then -+ with_c_locale_coercion="yes" -+fi -+if test "$with_c_locale_coercion" != "no" -+then -+ AC_DEFINE(PY_COERCE_C_LOCALE, 1, -+ [Define if you want to coerce the C locale to a UTF-8 based locale]) -+fi -+AC_MSG_RESULT($with_c_locale_coercion) -+ -+# Check for --with-c-locale-warning -+AC_MSG_CHECKING(for --with-c-locale-warning) -+AC_ARG_WITH(c-locale-warning, -+ AS_HELP_STRING([--with(out)-c-locale-warning], -+ [disable/enable locale compatibility warning in the C locale])) -+ -+if test -z "$with_c_locale_warning" -+then -+ with_c_locale_warning="yes" -+fi -+if test "$with_c_locale_warning" != "no" -+then -+ AC_DEFINE(PY_WARN_ON_C_LOCALE, 1, -+ [Define to emit a locale compatibility warning in the C locale]) -+fi -+AC_MSG_RESULT($with_c_locale_warning) -+ - # Check for Valgrind support - AC_MSG_CHECKING([for --with-valgrind]) - AC_ARG_WITH([valgrind], -diff --git a/pyconfig.h.in b/pyconfig.h.in -index b10c57f..0a6f3e2 100644 ---- a/pyconfig.h.in -+++ b/pyconfig.h.in -@@ -1244,9 +1244,15 @@ - /* Define as the preferred size in bits of long digits */ - #undef PYLONG_BITS_IN_DIGIT - -+/* Define if you want to coerce the C locale to a UTF-8 based locale */ -+#undef PY_COERCE_C_LOCALE -+ - /* Define to printf format modifier for Py_ssize_t */ - #undef PY_FORMAT_SIZE_T - -+/* Define to emit a locale compatibility warning in the C locale */ -+#undef PY_WARN_ON_C_LOCALE -+ - /* Define if you want to build an interpreter with many run-time checks. */ - #undef Py_DEBUG - diff --git a/00264-skip-test-failing-on-aarch64.patch b/00264-skip-test-failing-on-aarch64.patch deleted file mode 100644 index edda219..0000000 --- a/00264-skip-test-failing-on-aarch64.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py -index 3eded77..ad7859a 100644 ---- a/Lib/ctypes/test/test_structures.py -+++ b/Lib/ctypes/test/test_structures.py -@@ -392,6 +392,7 @@ class StructureTestCase(unittest.TestCase): - (1, 0, 0, 0, 0, 0)) - self.assertRaises(TypeError, lambda: Z(1, 2, 3, 4, 5, 6, 7)) - -+ @unittest.skip('Fails on aarch64: http://bugs.python.org/issue29804') - def test_pass_by_value(self): - # This should mirror the structure in Modules/_ctypes/_ctypes_test.c - class X(Structure): diff --git a/00270-fix-ssl-alpn-hook-test.patch b/00270-fix-ssl-alpn-hook-test.patch deleted file mode 100644 index 97b433e..0000000 --- a/00270-fix-ssl-alpn-hook-test.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py -index d203cdd..c128dae 100644 ---- a/Lib/test/test_ssl.py -+++ b/Lib/test/test_ssl.py -@@ -3256,8 +3256,9 @@ if _have_threads: - except ssl.SSLError as e: - stats = e - -- if expected is None and IS_OPENSSL_1_1: -- # OpenSSL 1.1.0 raises handshake error -+ if (expected is None and IS_OPENSSL_1_1 -+ and ssl.OPENSSL_VERSION_INFO < (1, 1, 0, 6)): -+ # OpenSSL 1.1.0 to 1.1.0e raises handshake error - self.assertIsInstance(stats, ssl.SSLError) - else: - msg = "failed trying %s (s) and %s (c).\n" \ diff --git a/00271-asyncio-get-default-signal-handler.patch b/00271-asyncio-get-default-signal-handler.patch deleted file mode 100644 index 8b1bf77..0000000 --- a/00271-asyncio-get-default-signal-handler.patch +++ /dev/null @@ -1,99 +0,0 @@ -diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py -index 492a84a2313..9746678607c 100644 ---- a/Lib/test/test_asyncio/test_events.py -+++ b/Lib/test/test_asyncio/test_events.py -@@ -1980,19 +1980,26 @@ def test_subprocess_terminate(self): - - @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") - def test_subprocess_send_signal(self): -- prog = os.path.join(os.path.dirname(__file__), 'echo.py') -- -- connect = self.loop.subprocess_exec( -- functools.partial(MySubprocessProtocol, self.loop), -- sys.executable, prog) -- transp, proto = self.loop.run_until_complete(connect) -- self.assertIsInstance(proto, MySubprocessProtocol) -- self.loop.run_until_complete(proto.connected) -- -- transp.send_signal(signal.SIGHUP) -- self.loop.run_until_complete(proto.completed) -- self.assertEqual(-signal.SIGHUP, proto.returncode) -- transp.close() -+ # bpo-31034: Make sure that we get the default signal handler (killing -+ # the process). The parent process may have decided to ignore SIGHUP, -+ # and signal handlers are inherited. -+ old_handler = signal.signal(signal.SIGHUP, signal.SIG_DFL) -+ try: -+ prog = os.path.join(os.path.dirname(__file__), 'echo.py') -+ -+ connect = self.loop.subprocess_exec( -+ functools.partial(MySubprocessProtocol, self.loop), -+ sys.executable, prog) -+ transp, proto = self.loop.run_until_complete(connect) -+ self.assertIsInstance(proto, MySubprocessProtocol) -+ self.loop.run_until_complete(proto.connected) -+ -+ transp.send_signal(signal.SIGHUP) -+ self.loop.run_until_complete(proto.completed) -+ self.assertEqual(-signal.SIGHUP, proto.returncode) -+ transp.close() -+ finally: -+ signal.signal(signal.SIGHUP, old_handler) - - def test_subprocess_stderr(self): - prog = os.path.join(os.path.dirname(__file__), 'echo2.py') -diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py -index 2e14a8a9735..e8822c36698 100644 ---- a/Lib/test/test_asyncio/test_subprocess.py -+++ b/Lib/test/test_asyncio/test_subprocess.py -@@ -166,25 +166,32 @@ def test_terminate(self): - - @unittest.skipIf(sys.platform == 'win32', "Don't have SIGHUP") - def test_send_signal(self): -- code = 'import time; print("sleeping", flush=True); time.sleep(3600)' -- args = [sys.executable, '-c', code] -- create = asyncio.create_subprocess_exec(*args, -- stdout=subprocess.PIPE, -- loop=self.loop) -- proc = self.loop.run_until_complete(create) -- -- @asyncio.coroutine -- def send_signal(proc): -- # basic synchronization to wait until the program is sleeping -- line = yield from proc.stdout.readline() -- self.assertEqual(line, b'sleeping\n') -+ # bpo-31034: Make sure that we get the default signal handler (killing -+ # the process). The parent process may have decided to ignore SIGHUP, -+ # and signal handlers are inherited. -+ old_handler = signal.signal(signal.SIGHUP, signal.SIG_DFL) -+ try: -+ code = 'import time; print("sleeping", flush=True); time.sleep(3600)' -+ args = [sys.executable, '-c', code] -+ create = asyncio.create_subprocess_exec(*args, -+ stdout=subprocess.PIPE, -+ loop=self.loop) -+ proc = self.loop.run_until_complete(create) - -- proc.send_signal(signal.SIGHUP) -- returncode = (yield from proc.wait()) -- return returncode -- -- returncode = self.loop.run_until_complete(send_signal(proc)) -- self.assertEqual(-signal.SIGHUP, returncode) -+ @asyncio.coroutine -+ def send_signal(proc): -+ # basic synchronization to wait until the program is sleeping -+ line = yield from proc.stdout.readline() -+ self.assertEqual(line, b'sleeping\n') -+ -+ proc.send_signal(signal.SIGHUP) -+ returncode = (yield from proc.wait()) -+ return returncode -+ -+ returncode = self.loop.run_until_complete(send_signal(proc)) -+ self.assertEqual(-signal.SIGHUP, returncode) -+ finally: -+ signal.signal(signal.SIGHUP, old_handler) - - def prepare_broken_pipe_test(self): - # buffer large enough to feed the whole pipe buffer diff --git a/00272-fix-ftplib-to-reject-newlines.patch b/00272-fix-ftplib-to-reject-newlines.patch deleted file mode 100644 index 66486a8..0000000 --- a/00272-fix-ftplib-to-reject-newlines.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 8c2d4cf092c5f0335e7982392a33927579c4d512 Mon Sep 17 00:00:00 2001 -From: Dong-hee Na -Date: Wed, 26 Jul 2017 21:11:25 +0900 -Subject: [PATCH] [3.6] bpo-30119: fix ftplib.FTP.putline() to throw an error - for a illegal command (#1214) (#2886) - ---- - Lib/ftplib.py | 2 ++ - Lib/test/test_ftplib.py | 6 +++++- - Misc/NEWS.d/next/Library/2017-07-26-15-15-00.bpo-30119.DZ6C_S.rst | 2 ++ - 3 files changed, 9 insertions(+), 1 deletion(-) - create mode 100644 Misc/NEWS.d/next/Library/2017-07-26-15-15-00.bpo-30119.DZ6C_S.rst - -diff --git a/Lib/ftplib.py b/Lib/ftplib.py -index 8f36f537e8a..a02e595cb02 100644 ---- a/Lib/ftplib.py -+++ b/Lib/ftplib.py -@@ -186,6 +186,8 @@ def sanitize(self, s): - - # Internal: send one line to the server, appending CRLF - def putline(self, line): -+ if '\r' in line or '\n' in line: -+ raise ValueError('an illegal newline character should not be contained') - line = line + CRLF - if self.debugging > 1: - print('*put*', self.sanitize(line)) -diff --git a/Lib/test/test_ftplib.py b/Lib/test/test_ftplib.py -index 12fabc5e8be..a561e9efa03 100644 ---- a/Lib/test/test_ftplib.py -+++ b/Lib/test/test_ftplib.py -@@ -484,6 +484,9 @@ def test_sanitize(self): - self.assertEqual(self.client.sanitize('PASS 12345'), repr('PASS *****')) - - def test_exceptions(self): -+ self.assertRaises(ValueError, self.client.sendcmd, 'echo 40\r\n0') -+ self.assertRaises(ValueError, self.client.sendcmd, 'echo 40\n0') -+ self.assertRaises(ValueError, self.client.sendcmd, 'echo 40\r0') - self.assertRaises(ftplib.error_temp, self.client.sendcmd, 'echo 400') - self.assertRaises(ftplib.error_temp, self.client.sendcmd, 'echo 499') - self.assertRaises(ftplib.error_perm, self.client.sendcmd, 'echo 500') -@@ -492,7 +495,8 @@ def test_exceptions(self): - - def test_all_errors(self): - exceptions = (ftplib.error_reply, ftplib.error_temp, ftplib.error_perm, -- ftplib.error_proto, ftplib.Error, OSError, EOFError) -+ ftplib.error_proto, ftplib.Error, OSError, -+ EOFError) - for x in exceptions: - try: - raise x('exception not included in all_errors set') -diff --git a/Misc/NEWS.d/next/Library/2017-07-26-15-15-00.bpo-30119.DZ6C_S.rst b/Misc/NEWS.d/next/Library/2017-07-26-15-15-00.bpo-30119.DZ6C_S.rst -new file mode 100644 -index 00000000000..a37d3703842 ---- /dev/null -+++ b/Misc/NEWS.d/next/Library/2017-07-26-15-15-00.bpo-30119.DZ6C_S.rst -@@ -0,0 +1,2 @@ -+ftplib.FTP.putline() now throws ValueError on commands that contains CR or -+LF. Patch by Dong-hee Na. diff --git a/Python-3.1.1-rpath.patch b/Python-3.1.1-rpath.patch deleted file mode 100644 index 1493af2..0000000 --- a/Python-3.1.1-rpath.patch +++ /dev/null @@ -1,20 +0,0 @@ -diff -up Python-3.1.1/Lib/distutils/unixccompiler.py.rpath Python-3.1.1/Lib/distutils/unixccompiler.py ---- Python-3.1.1/Lib/distutils/unixccompiler.py.rpath 2009-09-04 17:29:34.000000000 -0400 -+++ Python-3.1.1/Lib/distutils/unixccompiler.py 2009-09-04 17:49:54.000000000 -0400 -@@ -141,6 +141,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 = super( -+ self.__class__, self)._fix_lib_args(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): - fixed_args = self._fix_compile_args(None, macros, include_dirs) diff --git a/README b/README new file mode 120000 index 0000000..ad2d282 --- /dev/null +++ b/README @@ -0,0 +1 @@ +dead.package \ No newline at end of file diff --git a/check-pyc-and-pyo-timestamps.py b/check-pyc-and-pyo-timestamps.py deleted file mode 100644 index aab0cc1..0000000 --- a/check-pyc-and-pyo-timestamps.py +++ /dev/null @@ -1,59 +0,0 @@ -"""Checks if all *.pyc and *.pyo files have later mtime than their *.py files.""" - -import imp -import os -import sys - -# list of test and other files that we expect not to have bytecode -not_compiled = [ - 'test/bad_coding.py', - 'test/bad_coding2.py', - 'test/badsyntax_3131.py', - 'test/badsyntax_future3.py', - 'test/badsyntax_future4.py', - 'test/badsyntax_future5.py', - 'test/badsyntax_future6.py', - 'test/badsyntax_future7.py', - 'test/badsyntax_future8.py', - 'test/badsyntax_future9.py', - 'test/badsyntax_future10.py', - 'test/badsyntax_async1.py', - 'test/badsyntax_async2.py', - 'test/badsyntax_async3.py', - 'test/badsyntax_async4.py', - 'test/badsyntax_async5.py', - 'test/badsyntax_async6.py', - 'test/badsyntax_async7.py', - 'test/badsyntax_async8.py', - 'test/badsyntax_async9.py', - 'test/badsyntax_pep3120.py', - 'lib2to3/tests/data/bom.py', - 'lib2to3/tests/data/crlf.py', - 'lib2to3/tests/data/different_encoding.py', - 'lib2to3/tests/data/false_encoding.py', - 'lib2to3/tests/data/py2_test_grammar.py', - '.debug-gdb.py', -] -failed = 0 - -def bytecode_expected(source): - for f in not_compiled: - if source.endswith(f): - return False - return True - -compiled = filter(lambda f: bytecode_expected(f), sys.argv[1:]) -for f in compiled: - # check both pyo and pyc - to_check = map(lambda b: imp.cache_from_source(f, b), (True, False)) - f_mtime = os.path.getmtime(f) - for c in to_check: - c_mtime = os.path.getmtime(c) - if c_mtime < f_mtime: - sys.stderr.write('Failed bytecompilation timestamps check: ') - sys.stderr.write('Bytecode file {} is older than source file {}.\n'.format(c, f)) - failed += 1 - -if failed: - sys.stderr.write('\n{} files failed bytecompilation timestamps check.\n'.format(failed)) - sys.exit(1) diff --git a/dead.package b/dead.package new file mode 100644 index 0000000..0f1d9b5 --- /dev/null +++ b/dead.package @@ -0,0 +1 @@ +This branch was pushed by mistake. Please ignore it. diff --git a/macros.pybytecompile-platform-python b/macros.pybytecompile-platform-python deleted file mode 100644 index 3968c6e..0000000 --- a/macros.pybytecompile-platform-python +++ /dev/null @@ -1,10 +0,0 @@ -# Note that the path could itself be a python file, or a directory - -# Python's compile_all module only works on directories, and requires a max -# recursion depth - -%py_byte_compile()\ -python_binary="%1"\ -bytecode_compilation_path="%2"\ -find $bytecode_compilation_path -type f -a -name "*.py" -print0 | xargs -0 $python_binary -O -c 'import py_compile, sys; [py_compile.compile(f, dfile=f.partition("$RPM_BUILD_ROOT")[2], optimize=opt) for opt in range(2) for f in sys.argv[1:]]' || :\ -%{nil} diff --git a/platform-python-3.6.2-10.fc27.src.rpm b/platform-python-3.6.2-10.fc27.src.rpm deleted file mode 100644 index b25cabc..0000000 Binary files a/platform-python-3.6.2-10.fc27.src.rpm and /dev/null differ diff --git a/platform-python.patch b/platform-python.patch deleted file mode 100644 index f92ac48..0000000 --- a/platform-python.patch +++ /dev/null @@ -1,471 +0,0 @@ -diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py -index 74de782..8ca9d6d 100644 ---- a/Lib/distutils/command/build_ext.py -+++ b/Lib/distutils/command/build_ext.py -@@ -747,7 +747,7 @@ class build_ext(Command): - else: - from distutils import sysconfig - if sysconfig.get_config_var('Py_ENABLE_SHARED'): -- pythonlib = 'python{}.{}{}'.format( -+ pythonlib = 'platform-python{}.{}{}'.format( - sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff, - sysconfig.get_config_var('ABIFLAGS')) - return ext.libraries + [pythonlib] -diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py -index ec135d4..60c3a18 100644 ---- a/Lib/distutils/command/install.py -+++ b/Lib/distutils/command/install.py -@@ -29,9 +29,9 @@ WINDOWS_SCHEME = { - - INSTALL_SCHEMES = { - 'unix_prefix': { -- 'purelib': '$base/lib/python$py_version_short/site-packages', -- 'platlib': '$platbase/lib/python$py_version_short/site-packages', -- 'headers': '$base/include/python$py_version_short$abiflags/$dist_name', -+ 'purelib': '$base/lib/platform-python$py_version_short/site-packages', -+ 'platlib': '$platbase/lib/platform-python$py_version_short/site-packages', -+ 'headers': '$base/include/platform-python$py_version_short$abiflags/$dist_name', - 'scripts': '$base/bin', - 'data' : '$base', - }, -@@ -59,7 +59,7 @@ if HAS_USER_SITE: - 'purelib': '$usersite', - 'platlib': '$usersite', - 'headers': -- '$userbase/include/python$py_version_short$abiflags/$dist_name', -+ '$userbase/include/platform-python$py_version_short$abiflags/$dist_name', - 'scripts': '$userbase/bin', - 'data' : '$userbase', - } -diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py -index 5c2670f..6e90b40 100644 ---- a/Lib/distutils/sysconfig.py -+++ b/Lib/distutils/sysconfig.py -@@ -130,7 +130,7 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): - - if os.name == "posix": - libpython = os.path.join(prefix, -- "lib", "python" + get_python_version()) -+ "lib", "platform-python" + get_python_version()) - if standard_lib: - return libpython - else: -diff --git a/Lib/site.py b/Lib/site.py -index 386d2ad..cfef02b 100644 ---- a/Lib/site.py -+++ b/Lib/site.py -@@ -305,7 +305,7 @@ def getsitepackages(prefixes=None): - - if os.sep == '/': - sitepackages.append(os.path.join(prefix, "lib", -- "python%d.%d" % sys.version_info[:2], -+ "platform-python%d.%d" % sys.version_info[:2], - "site-packages")) - else: - sitepackages.append(prefix) -diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py -index d35b5eb..25059e4 100644 ---- a/Lib/sysconfig.py -+++ b/Lib/sysconfig.py -@@ -20,14 +20,14 @@ __all__ = [ - - _INSTALL_SCHEMES = { - 'posix_prefix': { -- 'stdlib': '{installed_base}/lib/python{py_version_short}', -- 'platstdlib': '{platbase}/lib/python{py_version_short}', -- 'purelib': '{base}/lib/python{py_version_short}/site-packages', -- 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', -+ 'stdlib': '{installed_base}/lib/platform-python{py_version_short}', -+ 'platstdlib': '{platbase}/lib/platform-python{py_version_short}', -+ 'purelib': '{base}/lib/platform-python{py_version_short}/site-packages', -+ 'platlib': '{platbase}/lib/platform-python{py_version_short}/site-packages', - 'include': -- '{installed_base}/include/python{py_version_short}{abiflags}', -+ '{installed_base}/include/platform-python{py_version_short}{abiflags}', - 'platinclude': -- '{installed_platbase}/include/python{py_version_short}{abiflags}', -+ '{installed_platbase}/include/platform-python{py_version_short}{abiflags}', - 'scripts': '{base}/bin', - 'data': '{base}', - }, -@@ -61,13 +61,13 @@ _INSTALL_SCHEMES = { - 'data': '{userbase}', - }, - 'posix_user': { -- 'stdlib': '{userbase}/lib/python{py_version_short}', -- 'platstdlib': '{userbase}/lib/python{py_version_short}', -- 'purelib': '{userbase}/lib/python{py_version_short}/site-packages', -- 'platlib': '{userbase}/lib/python{py_version_short}/site-packages', -- 'include': '{userbase}/include/python{py_version_short}', -- 'scripts': '{userbase}/bin', -- 'data': '{userbase}', -+ 'stdlib': '{installed_base}/lib/platform-python{py_version_short}', -+ 'platstdlib': '{platbase}/lib/platform-python{py_version_short}', -+ 'purelib': '{base}/lib/platform-python{py_version_short}/site-packages', -+ 'platlib': '{platbase}/lib/platform-python{py_version_short}/site-packages', -+ 'include': '{installed_base}/include/platform-python{py_version_short}{abiflags}', -+ 'scripts': '{base}/bin', -+ 'data': '{base}', - }, - 'osx_framework_user': { - 'stdlib': '{userbase}/lib/python', -diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py -index a29ca96..fea10e3 100644 ---- a/Lib/test/test_sysconfig.py -+++ b/Lib/test/test_sysconfig.py -@@ -260,7 +260,7 @@ class TestSysConfig(unittest.TestCase): - self.assertEqual(get(real), get(link)) - finally: - unlink(link) -- -+ @unittest.skip('posix_prefix and posix_user schemes are the same so skipping the test') - def test_user_similar(self): - # Issue #8759: make sure the posix scheme for the users - # is similar to the global posix_prefix one -diff --git a/Makefile.pre.in b/Makefile.pre.in -index 8b6454f..bf83e4f 100644 ---- a/Makefile.pre.in -+++ b/Makefile.pre.in -@@ -137,10 +137,10 @@ SCRIPTDIR= $(prefix)/lib - ABIFLAGS= @ABIFLAGS@ - - # Detailed destination directories --BINLIBDEST= $(LIBDIR)/python$(VERSION) --LIBDEST= $(SCRIPTDIR)/python$(VERSION) --INCLUDEPY= $(INCLUDEDIR)/python$(LDVERSION) --CONFINCLUDEPY= $(CONFINCLUDEDIR)/python$(LDVERSION) -+BINLIBDEST= $(LIBDIR)/platform-python$(VERSION) -+LIBDEST= $(SCRIPTDIR)/platform-python$(VERSION) -+INCLUDEPY= $(INCLUDEDIR)/platform-python$(LDVERSION) -+CONFINCLUDEPY= $(CONFINCLUDEDIR)/platform-python$(LDVERSION) - - # Symbols used for using shared libraries - SHLIB_SUFFIX= @SHLIB_SUFFIX@ -@@ -590,7 +590,7 @@ $(LIBRARY): $(LIBRARY_OBJS) - $(AR) $(ARFLAGS) $@ $(MODOBJS) - $(RANLIB) $@ - --libpython$(LDVERSION).so: $(LIBRARY_OBJS) -+libplatform-python$(LDVERSION).so: $(LIBRARY_OBJS) - if test $(INSTSONAME) != $(LDLIBRARY); then \ - $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ - $(LN) -f $(INSTSONAME) $@; \ -@@ -598,14 +598,14 @@ libpython$(LDVERSION).so: $(LIBRARY_OBJS) - $(BLDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ - fi - --libpython3.so: libpython$(LDVERSION).so -+libplatform-python3.so: libplatform-python$(LDVERSION).so - $(BLDSHARED) $(NO_AS_NEEDED) -o $@ -Wl,-h$@ $^ - --libpython$(LDVERSION).dylib: $(LIBRARY_OBJS) -- $(CC) -dynamiclib -Wl,-single_module $(PY_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ -+libplatform-python$(LDVERSION).dylib: $(LIBRARY_OBJS) -+ $(CC) -dynamiclib -Wl,-single_module $(PY_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libplatform-python$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ - - --libpython$(VERSION).sl: $(LIBRARY_OBJS) -+libplatform-python$(VERSION).sl: $(LIBRARY_OBJS) - $(LDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST) - - # Copy up the gdb python hooks into a position where they can be automatically -@@ -643,7 +643,7 @@ $(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK): \ - - # This rule builds the Cygwin Python DLL and import library if configured - # for a shared core library; otherwise, this rule is a noop. --$(DLLLIBRARY) libpython$(VERSION).dll.a: $(LIBRARY_OBJS) -+$(DLLLIBRARY) libplatform-python$(VERSION).dll.a: $(LIBRARY_OBJS) - if test -n "$(DLLLIBRARY)"; then \ - $(LDSHARED) -Wl,--out-implib=$@ -o $(DLLLIBRARY) $^ \ - $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST); \ -@@ -1346,7 +1346,7 @@ - python-config: $(srcdir)/Misc/python-config.in Misc/python-config.sh - # Substitution happens here, as the completely-expanded BINDIR - # is not available in configure -- sed -e "s,@EXENAME@,$(BINDIR)/python$(LDVERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config.py -+ sed -e "s,@EXENAME@,/usr/libexec/platform-python$(LDVERSION)$(EXE)," < $(srcdir)/Misc/python-config.in >python-config.py - # Replace makefile compat. variable references with shell script compat. ones; $(VAR) -> ${VAR} - LC_ALL=C sed -e 's,\$$(\([A-Za-z0-9_]*\)),\$$\{\1\},g' < Misc/python-config.sh >python-config - # On Darwin, always use the python version of the script, the shell -@@ -1485,12 +1485,12 @@ frameworkinstallstructure: $(LDLIBRARY) - # Install a number of symlinks to keep software that expects a normal unix - # install (which includes python-config) happy. - frameworkinstallmaclib: -- $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(LDVERSION).a" -- $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(LDVERSION).dylib" -- $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(VERSION).a" -- $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libpython$(VERSION).dylib" -- $(LN) -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(LDVERSION).dylib" -- $(LN) -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libpython$(VERSION).dylib" -+ $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libplatform-python$(LDVERSION).a" -+ $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libplatform-python$(LDVERSION).dylib" -+ $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libplatform-python$(VERSION).a" -+ $(LN) -fs "../../../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(LIBPL)/libplatform-python$(VERSION).dylib" -+ $(LN) -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libplatformp-ython$(LDVERSION).dylib" -+ $(LN) -fs "../$(PYTHONFRAMEWORK)" "$(DESTDIR)$(prefix)/lib/libplatformp-ython$(VERSION).dylib" - - # This installs the IDE, the Launcher and other apps into /Applications - frameworkinstallapps: -diff --git a/Misc/python-config.in b/Misc/python-config.in -index e13da75..a72893c 100644 ---- a/Misc/python-config.in -+++ b/Misc/python-config.in -@@ -47,7 +47,7 @@ for opt in opt_flags: - print(' '.join(flags)) - - elif opt in ('--libs', '--ldflags'): -- libs = ['-lpython' + pyver + sys.abiflags] -+ libs = ['-lplatform-python' + pyver + sys.abiflags] - libs += getvar('LIBS').split() - libs += getvar('SYSLIBS').split() - # add the prefix/lib/pythonX.Y/config dir, but only if there is no -diff --git a/Misc/python-config.sh.in b/Misc/python-config.sh.in -index 30c6927..33ea82f 100644 ---- a/Misc/python-config.sh.in -+++ b/Misc/python-config.sh.in -@@ -40,7 +40,7 @@ LIBM="@LIBM@" - LIBC="@LIBC@" - SYSLIBS="$LIBM $LIBC" - ABIFLAGS="@ABIFLAGS@" --LIBS="-lpython${VERSION}${ABIFLAGS} @LIBS@ $SYSLIBS" -+LIBS="-lplatform-python${VERSION}${ABIFLAGS} @LIBS@ $SYSLIBS" - BASECFLAGS="@BASECFLAGS@" - LDLIBRARY="@LDLIBRARY@" - LINKFORSHARED="@LINKFORSHARED@" -@@ -51,8 +51,8 @@ LIBDEST=${prefix}/lib/python${VERSION} - LIBPL=$(echo "@LIBPL@" | sed "s#$prefix_build#$prefix_real#") - SO="@EXT_SUFFIX@" - PYTHONFRAMEWORK="@PYTHONFRAMEWORK@" --INCDIR="-I$includedir/python${VERSION}${ABIFLAGS}" --PLATINCDIR="-I$includedir/python${VERSION}${ABIFLAGS}" -+INCDIR="-I$includedir/platform-python${VERSION}${ABIFLAGS}" -+PLATINCDIR="-I$includedir/platform-python${VERSION}${ABIFLAGS}" - - # Scan for --help or unknown argument. - for ARG in $* -diff --git a/Misc/python.pc.in b/Misc/python.pc.in -index ae69867..38405a1 100644 ---- a/Misc/python.pc.in -+++ b/Misc/python.pc.in -@@ -9,5 +9,5 @@ Description: Python library - Requires: - Version: @VERSION@ - Libs.private: @LIBS@ --Libs: -L${libdir} -lpython@VERSION@@ABIFLAGS@ --Cflags: -I${includedir}/python@VERSION@@ABIFLAGS@ -+Libs: -L${libdir} -lplatform-python@VERSION@@ABIFLAGS@ -+Cflags: -I${includedir}/platform-python@VERSION@@ABIFLAGS@ -diff --git a/Modules/getpath.c b/Modules/getpath.c -index 0f91643..8d7b675 100644 ---- a/Modules/getpath.c -+++ b/Modules/getpath.c -@@ -494,7 +494,7 @@ calculate_path(void) - _pythonpath = Py_DecodeLocale(PYTHONPATH, NULL); - _prefix = Py_DecodeLocale(PREFIX, NULL); - _exec_prefix = Py_DecodeLocale(EXEC_PREFIX, NULL); -- lib_python = Py_DecodeLocale("lib/python" VERSION, NULL); -+ lib_python = Py_DecodeLocale("lib/platform-python" VERSION, NULL); - - if (!_pythonpath || !_prefix || !_exec_prefix || !lib_python) { - Py_FatalError( -diff --git a/Modules/makesetup b/Modules/makesetup -index 8db8de8..430e323 100755 ---- a/Modules/makesetup -+++ b/Modules/makesetup -@@ -92,7 +92,7 @@ CYGWIN*) if test $libdir = . - else - ExtraLibDir='$(LIBPL)' - fi -- ExtraLibs="-L$ExtraLibDir -lpython\$(VERSION)";; -+ ExtraLibs="-L$ExtraLibDir -lplatform-python\$(VERSION)";; - esac - - # Main loop -diff --git a/configure b/configure -index eea17a4..76b3d3a 100755 ---- a/configure -+++ b/configure -@@ -5741,7 +5741,7 @@ esac - $as_echo_n "checking LIBRARY... " >&6; } - if test -z "$LIBRARY" - then -- LIBRARY='libpython$(VERSION)$(ABIFLAGS).a' -+ LIBRARY='libplatform-python$(VERSION)$(ABIFLAGS).a' - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBRARY" >&5 - $as_echo "$LIBRARY" >&6; } -@@ -5957,48 +5957,48 @@ $as_echo "#define Py_ENABLE_SHARED 1" >>confdefs.h - - case $ac_sys_system in - CYGWIN*) -- LDLIBRARY='libpython$(LDVERSION).dll.a' -- DLLLIBRARY='libpython$(LDVERSION).dll' -+ LDLIBRARY='libplatform-python$(LDVERSION).dll.a' -+ DLLLIBRARY='libplatfor-mpython$(LDVERSION).dll' - ;; - SunOS*) -- LDLIBRARY='libpython$(LDVERSION).so' -- BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)' -+ LDLIBRARY='libplatform-python$(LDVERSION).so' -+ BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lplatform-python$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} - INSTSONAME="$LDLIBRARY".$SOVERSION - if test "$with_pydebug" != yes - then -- PY3LIBRARY=libpython3.so -+ PY3LIBRARY=libplatform-python3.so - fi - ;; - Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*) -- LDLIBRARY='libpython$(LDVERSION).so' -- BLDLIBRARY='-L. -lpython$(LDVERSION)' -+ LDLIBRARY='libplatform-python$(LDVERSION).so' -+ BLDLIBRARY='-L. -lplatform-python$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} - INSTSONAME="$LDLIBRARY".$SOVERSION - if test "$with_pydebug" != yes - then -- PY3LIBRARY=libpython3.so -+ PY3LIBRARY=libplatform-python3.so - fi - ;; - hp*|HP*) - case `uname -m` in - ia64) -- LDLIBRARY='libpython$(LDVERSION).so' -+ LDLIBRARY='libplatform-python$(LDVERSION).so' - ;; - *) -- LDLIBRARY='libpython$(LDVERSION).sl' -+ LDLIBRARY='libplatform-python$(LDVERSION).sl' - ;; - esac -- BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)' -+ BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lplatform-python$(LDVERSION)' - RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}} - ;; - Darwin*) -- LDLIBRARY='libpython$(LDVERSION).dylib' -- BLDLIBRARY='-L. -lpython$(LDVERSION)' -+ LDLIBRARY='libplatform-python$(LDVERSION).dylib' -+ BLDLIBRARY='-L. -lplatform-python$(LDVERSION)' - RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}} - ;; - AIX*) -- LDLIBRARY='libpython$(LDVERSION).so' -+ LDLIBRARY='libplatform-python$(LDVERSION).so' - RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}} - ;; - -@@ -6008,7 +6008,7 @@ else # shared is disabled - case $ac_sys_system in - CYGWIN*) - BLDLIBRARY='$(LIBRARY)' -- LDLIBRARY='libpython$(LDVERSION).dll.a' -+ LDLIBRARY='libplatform-python$(LDVERSION).dll.a' - ;; - esac - fi -@@ -9448,7 +9448,7 @@ $as_echo "$CFLAGSFORSHARED" >&6; } - # For platforms on which shared libraries are not allowed to have unresolved - # symbols, this must be set to $(LIBS) (expanded by make). We do this even - # if it is not required, since it creates a dependency of the shared library --# to LIBS. This, in turn, means that applications linking the shared libpython -+# to LIBS. This, in turn, means that applications linking the shared libplatformpython - # don't need to link LIBS explicitly. The default should be only changed - # on systems where this approach causes problems. - -diff --git a/configure.ac b/configure.ac -index 74b0e57..ce28eeb 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -987,7 +987,7 @@ AC_SUBST(LIBRARY) - AC_MSG_CHECKING(LIBRARY) - if test -z "$LIBRARY" - then -- LIBRARY='libpython$(VERSION)$(ABIFLAGS).a' -+ LIBRARY='libplatform-python$(VERSION)$(ABIFLAGS).a' - fi - AC_MSG_RESULT($LIBRARY) - -@@ -1134,48 +1134,48 @@ if test $enable_shared = "yes"; then - AC_DEFINE(Py_ENABLE_SHARED, 1, [Defined if Python is built as a shared library.]) - case $ac_sys_system in - CYGWIN*) -- LDLIBRARY='libpython$(LDVERSION).dll.a' -- DLLLIBRARY='libpython$(LDVERSION).dll' -+ LDLIBRARY='libplatform-python$(LDVERSION).dll.a' -+ DLLLIBRARY='libplatform-python$(LDVERSION).dll' - ;; - SunOS*) -- LDLIBRARY='libpython$(LDVERSION).so' -- BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lpython$(LDVERSION)' -+ LDLIBRARY='libplatform-python$(LDVERSION).so' -+ BLDLIBRARY='-Wl,-R,$(LIBDIR) -L. -lplatform-python$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} - INSTSONAME="$LDLIBRARY".$SOVERSION - if test "$with_pydebug" != yes - then -- PY3LIBRARY=libpython3.so -+ PY3LIBRARY=libplatform-python3.so - fi - ;; - Linux*|GNU*|NetBSD*|FreeBSD*|DragonFly*|OpenBSD*) -- LDLIBRARY='libpython$(LDVERSION).so' -- BLDLIBRARY='-L. -lpython$(LDVERSION)' -+ LDLIBRARY='libplatform-python$(LDVERSION).so' -+ BLDLIBRARY='-L. -lplatform-python$(LDVERSION)' - RUNSHARED=LD_LIBRARY_PATH=`pwd`${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} - INSTSONAME="$LDLIBRARY".$SOVERSION - if test "$with_pydebug" != yes - then -- PY3LIBRARY=libpython3.so -+ PY3LIBRARY=libplatform-python3.so - fi - ;; - hp*|HP*) - case `uname -m` in - ia64) -- LDLIBRARY='libpython$(LDVERSION).so' -+ LDLIBRARY='libplatform-python$(LDVERSION).so' - ;; - *) -- LDLIBRARY='libpython$(LDVERSION).sl' -+ LDLIBRARY='libplatform-python$(LDVERSION).sl' - ;; - esac -- BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lpython$(LDVERSION)' -+ BLDLIBRARY='-Wl,+b,$(LIBDIR) -L. -lplatform-python$(LDVERSION)' - RUNSHARED=SHLIB_PATH=`pwd`${SHLIB_PATH:+:${SHLIB_PATH}} - ;; - Darwin*) -- LDLIBRARY='libpython$(LDVERSION).dylib' -- BLDLIBRARY='-L. -lpython$(LDVERSION)' -+ LDLIBRARY='libplatform-python$(LDVERSION).dylib' -+ BLDLIBRARY='-L. -lplatform-python$(LDVERSION)' - RUNSHARED=DYLD_LIBRARY_PATH=`pwd`${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}} - ;; - AIX*) -- LDLIBRARY='libpython$(LDVERSION).so' -+ LDLIBRARY='libplatform-python$(LDVERSION).so' - RUNSHARED=LIBPATH=`pwd`${LIBPATH:+:${LIBPATH}} - ;; - -@@ -1185,7 +1185,7 @@ else # shared is disabled - case $ac_sys_system in - CYGWIN*) - BLDLIBRARY='$(LIBRARY)' -- LDLIBRARY='libpython$(LDVERSION).dll.a' -+ LDLIBRARY='libplatform-python$(LDVERSION).dll.a' - ;; - esac - fi -@@ -2679,7 +2679,7 @@ AC_MSG_RESULT($CFLAGSFORSHARED) - # For platforms on which shared libraries are not allowed to have unresolved - # symbols, this must be set to $(LIBS) (expanded by make). We do this even - # if it is not required, since it creates a dependency of the shared library --# to LIBS. This, in turn, means that applications linking the shared libpython -+# to LIBS. This, in turn, means that applications linking the shared libplatformpython - # don't need to link LIBS explicitly. The default should be only changed - # on systems where this approach causes problems. - AC_SUBST(SHLIBS) diff --git a/platform-python.spec b/platform-python.spec deleted file mode 100644 index 597d532..0000000 --- a/platform-python.spec +++ /dev/null @@ -1,2204 +0,0 @@ -# ====================================================== -# Conditionals and other variables controlling the build -# ====================================================== - -%global pybasever 3.6 - -# pybasever without the dot: -%global pyshortver 36 - -%global pylibdir %{_libdir}/%{name}%{pybasever} -%global dynload_dir %{pylibdir}/lib-dynload - -# SOABI is defined in the upstream configure.in from Python-3.2a2 onwards, -# for PEP 3149: -# http://www.python.org/dev/peps/pep-3149/ - -# ("configure.in" became "configure.ac" in Python 3.3 onwards, and in -# backports) - -# ABIFLAGS, LDVERSION and SOABI are in the upstream Makefile -# With Python 3.3, we lose the "u" suffix due to PEP 393 -%global ABIFLAGS_optimized m -%global ABIFLAGS_debug dm - -%global LDVERSION_optimized %{pybasever}%{ABIFLAGS_optimized} -%global LDVERSION_debug %{pybasever}%{ABIFLAGS_debug} - -%global SOABI_optimized cpython-%{pyshortver}%{ABIFLAGS_optimized}-%{_arch}-linux%{_gnu} -%global SOABI_debug cpython-%{pyshortver}%{ABIFLAGS_debug}-%{_arch}-linux%{_gnu} - -# All bytecode files are now in a __pycache__ subdirectory, with a name -# reflecting the version of the bytecode (to permit sharing of python libraries -# between different runtimes) -# See http://www.python.org/dev/peps/pep-3147/ -# For example, -# foo/bar.py -# now has bytecode at: -# foo/__pycache__/bar.cpython-36.pyc -# foo/__pycache__/bar.cpython-36.opt-1.pyc -# foo/__pycache__/bar.cpython-36.opt-2.pyc -%global bytecode_suffixes .cpython-36*.pyc - -# 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 libplatform-python%{LDVERSION_optimized}.so.%{py_SOVERSION} - -%global with_gdb_hooks 0 - -# some arches don't have valgrind so we need to disable its support on them -%ifnarch s390 %{mips} riscv64 -%global with_valgrind 1 -%else -%global with_valgrind 0 -%endif - -%global with_gdbm 1 - -# Change from yes to no to turn this off -%global with_computed_gotos yes - -# Turn this to 0 to turn off the "check" phase: -%global run_selftest_suite 1 - -# We want to byte-compile the .py files within the packages using the new -# python3 binary. -# -# Unfortunately, rpmbuild's infrastructure requires us to jump through some -# hoops to avoid byte-compiling with the system python 2 version: -# /usr/lib/rpm/redhat/macros sets up build policy that (amongst other things) -# defines __os_install_post. In particular, "brp-python-bytecompile" is -# invoked without an argument thus using the wrong version of python -# (/usr/bin/python, rather than the freshly built python), thus leading to -# numerous syntax errors, and incorrect magic numbers in the .pyc files. We -# thus override __os_install_post to avoid invoking this script: -%global __os_install_post /usr/lib/rpm/brp-compress \ - %{!?__debug_package:/usr/lib/rpm/brp-strip %{__strip}} \ - /usr/lib/rpm/brp-strip-static-archive %{__strip} \ - /usr/lib/rpm/brp-strip-comment-note %{__strip} %{__objdump} \ - /usr/lib/rpm/brp-python-hardlink -# to remove the invocation of brp-python-bytecompile, whilst keeping the -# invocation of brp-python-hardlink (since this should still work for python3 -# pyc/pyo files) - - -# ================== -# Top-level metadata -# ================== -Summary: A Python interpreter for basic system tools -Name: platform-python -Version: %{pybasever}.2 -Release: 10%{?dist} -License: Python - - -# ======================= -# 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-3.2.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: libffi-devel -BuildRequires: libGL-devel -BuildRequires: libX11-devel -BuildRequires: ncurses-devel -# workaround http://bugs.python.org/issue19804 (test_uuid requires ifconfig) -BuildRequires: net-tools -BuildRequires: openssl-devel -BuildRequires: pkgconfig -BuildRequires: readline-devel -BuildRequires: sqlite-devel - - -BuildRequires: tar -BuildRequires: tcl-devel -BuildRequires: tix-devel -BuildRequires: tk-devel - -%if 0%{?with_valgrind} -BuildRequires: valgrind-devel -%endif - -BuildRequires: xz-devel -BuildRequires: zlib-devel - -# ======================= -# Source code and patches -# ======================= - -Source: https://www.python.org/ftp/python/%{version}/Python-%{version}.tar.xz - -# Supply an RPM macro "py_byte_compile" for the python3-devel subpackage -# to enable specfiles to selectively byte-compile individual files and paths -# with different Python runtimes as necessary: -Source3: macros.pybytecompile-%{name} - -# A simple script to check timestamps of bytecode files -# Run in check section with Python that is currently being built -# Written by bkabrda -Source8: check-pyc-and-pyo-timestamps.py - -# Platform python patch -# https://fedoraproject.org/wiki/Changes/Platform_Python_Stack -Patch0: platform-python.patch - -# Fixup distutils/unixccompiler.py to remove standard library path from rpath: -# Was Patch0 in ivazquez' python3000 specfile: -Patch1: Python-3.1.1-rpath.patch - -Patch102: 00102-lib64.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 - -# 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 # -# 00133-skip-test_dl.patch is not relevant for python3: the "dl" module no -# longer exists - -# 00137 # -# Some tests within distutils fail when run in an rpmbuild: -Patch137: 00137-skip-distutils-tests-that-fail-in-rpmbuild.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 ; see RHEL6 -# python 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 -# (rhbz#563986) -# Note: Up to Python 3.4.0.b1, upstream had their own implementation of what -# they assumed would become sha3. This patch was adapted to give it the -# usedforsecurity argument, even though it did nothing (OpenSSL didn't have -# sha3 implementation at that time).In 3.4.0.b2, sha3 implementation was reverted -# (see http://bugs.python.org/issue16113), but the alterations were left in the -# patch, since they may be useful again if upstream decides to rerevert sha3 -# implementation and OpenSSL still doesn't support it. For now, they're harmless. -Patch146: 00146-hashlib-fips.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 - -# 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 - -# 00160 # -# Python 3.3 added os.SEEK_DATA and os.SEEK_HOLE, which may be present in the -# header files in the build chroot, but may not be supported in the running -# kernel, hence we disable this test in an rpm build. -# Adding these was upstream issue http://bugs.python.org/issue10142 -# Not yet sent upstream -Patch160: 00160-disable-test_fs_holes-in-rpm-build.patch - -# 00163 # -# Some tests within test_socket fail intermittently when run inside Koji; -# disable them using unittest._skipInRpmBuild -# Not yet sent upstream -Patch163: 00163-disable-parts-of-test_socket-in-rpm-build.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 - -# 00178 # -# Don't duplicate various FLAGS in sysconfig values -# http://bugs.python.org/issue17679 -# Does not affect python2 AFAICS (different sysconfig values initialization) -Patch178: 00178-dont-duplicate-flags-in-sysconfig.patch - -# 00180 # -# Enable building on ppc64p7 -# Not appropriate for upstream, Fedora-specific naming -Patch180: 00180-python-add-support-for-ppc64p7.patch - -# 00186 # -# Fix for https://bugzilla.redhat.com/show_bug.cgi?id=1023607 -# Previously, this fixed a problem where some *.py files were not being -# bytecompiled properly during build. This was result of py_compile.compile -# raising exception when trying to convert test file with bad encoding, and -# thus not continuing bytecompilation for other files. -# This was fixed upstream, but the test hasn't been merged yet, so we keep it -Patch186: 00186-dont-raise-from-py_compile.patch - -# 00188 # -# Downstream only patch that should be removed when we compile all guaranteed -# hashlib algorithms properly. The problem is this: -# - during tests, test_hashlib is imported and executed before test_lib2to3 -# - if at least one hash function has failed, trying to import it triggers an -# exception that is being caught and exception is logged: -# http://hg.python.org/cpython/file/2de806c8b070/Lib/hashlib.py#l217 -# - logging the exception makes logging module run basicConfig -# - when lib2to3 tests are run again, lib2to3 runs basicConfig again, which -# doesn't do anything, because it was run previously -# (logging.root.handlers != []), which means that the default setup -# (most importantly logging level) is not overriden. That means that a test -# relying on this will fail (test_filename_changing_on_output_single_dir) -Patch188: 00188-fix-lib2to3-tests-when-hashlib-doesnt-compile-properly.patch - -# 00205 # -# LIBPL variable in makefile takes LIBPL from configure.ac -# but the LIBPL variable defined there doesn't respect libdir macro -Patch205: 00205-make-libpl-respect-lib64.patch - -# 00206 # -# Remove hf flag from arm triplet which is used -# by debian but fedora infra uses only eabi without hf -Patch206: 00206-remove-hf-from-arm-triplet.patch - -# 00243 # -# Fix the triplet used on 64-bit MIPS -# rhbz#1322526: https://bugzilla.redhat.com/show_bug.cgi?id=1322526 -# Upstream uses Debian-like style mips64-linux-gnuabi64 -# Fedora needs the default mips64-linux-gnu -Patch243: 00243-fix-mips64-triplet.patch - -# 00251 -# Set values of prefix and exec_prefix in distutils install command -# to /usr/local if executable is /usr/bin/python* and RPM build -# is not detected to make pip and distutils install into separate location -# Fedora Change: https://fedoraproject.org/wiki/Changes/Making_sudo_pip_safe -Patch251: 00251-change-user-install-location.patch - -# 00262 # -# Backport of PEP 538: Coercing the legacy C locale to a UTF-8 based locale -# https://www.python.org/dev/peps/pep-0538/ -# Fedora Change: https://fedoraproject.org/wiki/Changes/python3_c.utf-8_locale -# Original proposal: https://bugzilla.redhat.com/show_bug.cgi?id=1404918 -Patch262: 00262-pep538_coerce_legacy_c_locale.patch - -# 00264 # -# test_pass_by_value was added in Python 3.6.1 and on aarch64 -# it is catching an error that was there, but wasn't tested before. -# Therefore skipping the test on aarch64 until fixed upstream. -# Reported upstream: http://bugs.python.org/issue29804 -Patch264: 00264-skip-test-failing-on-aarch64.patch - -# 00270 # -# Fix test_alpn_protocols from test_ssl as openssl > 1.1.0f -# changed the behaviour of the ALPN hook. -# Fixed upstream: http://bugs.python.org/issue30714 -Patch270: 00270-fix-ssl-alpn-hook-test.patch - -# 00271 # -# Make test_asyncio to not depend on the current signal handler -# as this can make it hang on koji, since it ignores SIGHUP. -# Reported upstream: http://bugs.python.org/issue31034 -Patch271: 00271-asyncio-get-default-signal-handler.patch - -# 00272 # -# Reject newline characters in ftplib.FTP.putline() arguments to -# avoid FTP protocol stream injection via malicious URLs. -# rhbz#1478916 -# Fixed upstream: http://bugs.python.org/issue30119 -Patch272: 00272-fix-ftplib-to-reject-newlines.patch - -# (New patches go here ^^^) -# -# When adding new patches to "python" and "python3" in Fedora, EL, etc., -# please try to keep the patch numbers in-sync between all specfiles. -# -# More information, and a patch number catalog, is at: -# -# https://fedoraproject.org/wiki/SIGs/Python/PythonPatches - -# add correct arch for ppc64/ppc64le -# it should be ppc64le-linux-gnu/ppc64-linux-gnu instead powerpc64le-linux-gnu/powerpc64-linux-gnu -Patch5001: python3-powerppc-arch.patch - -BuildRoot: %{_tmppath}/%{name}-%{version}-root - -# ====================================================== -# Additional metadata, and subpackages -# ====================================================== - -URL: https://www.python.org/ - -# See notes in bug 532118: -Provides: platform-python(abi) = %{pybasever} - -Requires: %{name}-libs%{?_isa} = %{version}-%{release} - -%description -Python interpreter for low-level system tools, designed to work with -the Platform module. - -%package libs -Summary: Platform Python runtime libraries - -# expat 2.1.0 added the symbol XML_SetHashSalt without bumping SONAME. We use -# this symbol (in pyexpat), so we must explicitly state this dependency to -# prevent "import pyexpat" from failing with a linker error if someone hasn't -# yet upgraded expat: -Requires: expat >= 2.1.0 - -# Python 3 built with glibc >= 2.24.90-26 needs to require it (rhbz#1410644). -Requires: glibc%{?_isa} >= 2.24.90-26 - -%description libs -This package contains runtime libraries for use by Platform Python: -- the libpython dynamic library for embedding Platform Python as -a scripting language, and the main platform-python executable -- the Python standard library - -%package libs-devel -Summary: Platform Python runtime libraries - -# 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-devel -This package contains runtime libraries for use by Platform Python: -- the libpython dynamic library for embedding Platform Python as -a scripting language, and the main platform-python executable -- the Python standard library - -%package devel -Summary: Libraries and header files needed for Platform Python development -Requires: %{name} = %{version}-%{release} -Requires: %{name}-libs%{?_isa} = %{version}-%{release} -Requires: %{name}-libs-devel%{?_isa} = %{version}-%{release} -BuildRequires: platform-python-rpm-macros -Requires: python-rpm-macros -Requires: platform-python-rpm-macros -Requires: python3-rpm-generators - -%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 build tools -that extend or embed Platform Python. - -%package tools -Summary: A collection of tools included with Platform Python -Requires: %{name} = %{version}-%{release} -Requires: %{name}-tkinter = %{version}-%{release} - -%description tools -This package contains several tools included with Python - -%package tkinter -Summary: A GUI toolkit for Platform Python -Requires: %{name} = %{version}-%{release} - -%description tkinter -The Tkinter (Tk interface) program is a graphical user interface for -Platform Python. - -%package test -Summary: Self-test suite form Platform Python -Requires: %{name} = %{version}-%{release} -Requires: %{name}-tools = %{version}-%{release} - -%description test -The test modules from the main %{name} package. -These are in a separate package to save space, as they are almost never used -in production. - - -# ====================================================== -# The prep phase of the build: -# ====================================================== - -%prep -%setup -q -n Python-%{version}%{?prerel} - -# 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 zlib: -rm -r Modules/zlib || exit 1 - -## Disabling hashlib patch for now as it needs to be reimplemented -## for OpenSSL 1.1.0. -# Don't build upstream Python's implementation of these crypto algorithms; -# instead rely on _hashlib and OpenSSL. -# -# For example, in our builds hashlib.md5 is implemented within _hashlib via -# OpenSSL (and thus respects FIPS mode), and does not fall back to _md5 -# TODO: there seems to be no OpenSSL support in Python for sha3 so far -# when it is there, also remove _sha3/ dir -#for f in md5module.c sha1module.c sha256module.c sha512module.c; do -# rm Modules/$f -#done - -# -# Apply patches: -# - -%patch0 -p1 - -%patch1 -p1 - -%if "%{_lib}" == "lib64" -%patch102 -p1 -%patch104 -p1 -%endif -%patch111 -p1 -%patch132 -p1 -%patch137 -p1 -#patch146 -p1 -%patch155 -p1 -%patch157 -p1 -%patch160 -p1 -%patch163 -p1 -%patch170 -p1 -%patch178 -p1 -%patch180 -p1 -%patch186 -p1 -%patch188 -p1 - -%patch205 -p1 -%patch206 -p1 -%patch243 -p1 -%patch251 -p1 -%patch262 -p1 - -%ifarch aarch64 -%patch264 -p1 -%endif - -%patch270 -p1 -%patch271 -p1 -%patch272 -p1 - -# Currently (2010-01-15), http://docs.python.org/library is for 2.6, and there -# are many differences between 2.6 and the Python 3 library. -# -# Fix up the URLs within pydoc to point at the documentation for this -# MAJOR.MINOR version: -# -sed --in-place \ - --expression="s|http://docs.python.org/library|http://docs.python.org/%{pybasever}/library|g" \ - Lib/pydoc.py || exit 1 - -%patch5001 -p1 - -# ====================================================== -# 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 CFLAGS="$CFLAGS `pkg-config --cflags openssl`" -export LDFLAGS="$RPM_LD_FLAGS `pkg-config --libs-only-L openssl`" - - -# 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 - MoreCFlags=$6 - - 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 \ - --with-computed-gotos=%{with_computed_gotos} \ - --with-dbmliborder=gdbm:ndbm:bdb \ - --with-system-expat \ - --with-system-ffi \ - --enable-loadable-sqlite-extensions \ - --with-lto \ -%if 0%{?with_valgrind} - --with-valgrind \ -%endif - $ExtraConfigArgs \ - %{nil} - - # Set EXTRA_CFLAGS to our CFLAGS (rather than overriding OPT, as we've done - # in the past). - # This should fix a problem with --with-valgrind where it adds - # -DDYNAMIC_ANNOTATIONS_ENABLED=1 - # to OPT which must be passed to all compilation units in the build, - # otherwise leading to linker errors, e.g. - # missing symbol AnnotateRWLockDestroy - # - # Invoke the build: - make EXTRA_CFLAGS="$CFLAGS $MoreCFlags" %{?_smp_mflags} - - popd - echo FINISHED: BUILD OF PYTHON FOR CONFIGURATION: $ConfDir -} - -# Use "BuildPython" to support building with different configurations: - -BuildPython optimized \ - python \ - python%{pybasever} \ -%ifarch %{ix86} x86_64 - "--without-ensurepip --enable-optimizations" \ -%else - "--without-ensurepip" \ -%endif - true - -# ====================================================== -# Installing the built code: -# ====================================================== - -%install -topdir=$(pwd) -rm -fr %{buildroot} -mkdir -p %{buildroot}%{_prefix} %{buildroot}%{_mandir} - -InstallPython() { - - ConfName=$1 - PyInstSoName=$2 - MoreCFlags=$3 - - ConfDir=build/$ConfName - - echo STARTING: INSTALL OF PYTHON FOR CONFIGURATION: $ConfName - mkdir -p $ConfDir - - pushd $ConfDir - -make install DESTDIR=%{buildroot} INSTALL="install -p" EXTRA_CFLAGS="$MoreCFlags" - - popd - - # We install a collection of hooks for gdb that make it easier to debug - # executables linked against libpython3* (such as /usr/bin/python3 itself) - # - # These hooks are implemented in Python itself (though they are for the version - # of python that gdb is linked with, in this case Python 2.7) - # - # 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/libpython3.2.so.1.0.debug-gdb.py - # - # See https://fedoraproject.org/wiki/Features/EasierPythonDebugging for more - # information - # - # Copy up the gdb hooks into place; the python file will be autoloaded by gdb - # when visiting libpython.so, provided that the python file is installed to the - # same path as the library (or its .debug file) plus a "-gdb.py" suffix, e.g: - # /usr/lib/debug/usr/lib64/libpython3.2.so.1.0.debug-gdb.py - # (note that the debug path is /usr/lib/debug for both 32/64 bit) - # - # Initially I tried: - # /usr/lib/libpython3.1.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-%{version}-%{release}.%{_arch}.debug-gdb.py - - mkdir -p %{buildroot}$DirHoldingGdbPy - cp Tools/gdb/libpython.py %{buildroot}$PathOfGdbPy -%endif # with_gdb_hooks - - echo FINISHED: INSTALL OF PYTHON FOR CONFIGURATION: $ConfName -} - -# Use "InstallPython" to support building with different configurations: - -# Now the optimized build: -InstallPython optimized \ - %{py_INSTSONAME_optimized} - -install -d -m 0755 ${RPM_BUILD_ROOT}%{pylibdir}/site-packages/__pycache__ - -# Development tools -install -m755 -d ${RPM_BUILD_ROOT}%{pylibdir}/Tools -install Tools/README ${RPM_BUILD_ROOT}%{pylibdir}/Tools/ -cp -ar Tools/freeze ${RPM_BUILD_ROOT}%{pylibdir}/Tools/ -cp -ar Tools/i18n ${RPM_BUILD_ROOT}%{pylibdir}/Tools/ -cp -ar Tools/pynche ${RPM_BUILD_ROOT}%{pylibdir}/Tools/ -cp -ar Tools/scripts ${RPM_BUILD_ROOT}%{pylibdir}/Tools/ - -# Documentation tools -install -m755 -d %{buildroot}%{pylibdir}/Doc -cp -ar Doc/tools %{buildroot}%{pylibdir}/Doc/ - -# Demo scripts -cp -ar Tools/demo %{buildroot}%{pylibdir}/Tools/ - -# Fix for bug #136654 -rm -f %{buildroot}%{pylibdir}/email/test/data/audiotest.au %{buildroot}%{pylibdir}/test/audiotest.au - -%if "%{_lib}" == "lib64" -install -d -m 0755 %{buildroot}/%{_prefix}/lib/%{name}%{pybasever}/site-packages/__pycache__ -%endif - -# Make python3-devel multilib-ready (bug #192747, #139911) -%global _pyconfig32_h pyconfig-32.h -%global _pyconfig64_h pyconfig-64.h - -%ifarch %{power64} s390x x86_64 ia64 alpha sparc64 aarch64 %{mips64} riscv64 -%global _pyconfig_h %{_pyconfig64_h} -%else -%global _pyconfig_h %{_pyconfig32_h} -%endif - -# ABIFLAGS, LDVERSION and SOABI are in the upstream Makefile -%global ABIFLAGS_optimized m - -%global LDVERSION_optimized %{pybasever}%{ABIFLAGS_optimized} - -%global SOABI_optimized cpython-%{pyshortver}%{ABIFLAGS_optimized}-%{_arch}-linux%{_gnu} - -%global PyIncludeDirs platform-python%{LDVERSION_optimized} - -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 - -# 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 (bug 653058) -# -# 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 - -# Platform Python: Copy the executable to libexec -mkdir -p %{buildroot}%{_libexecdir} -cp %{buildroot}%{_bindir}/python%{pybasever} %{buildroot}%{_libexecdir}/platform-python%{pybasever} - -# Create symlinks of the platform-python binary - -ln -s platform-python%{pybasever} %{buildroot}%{_libexecdir}/platform-python3 -ln -s platform-python3 %{buildroot}%{_libexecdir}/platform-python - -# Switch all shebangs to refer to the specific Python version. -LD_LIBRARY_PATH=./build/optimized ./build/optimized/python \ - Tools/scripts/pathfix.py \ - -i "%{_libexecdir}/platform-python" \ - %{buildroot} - -# Remove shebang lines from .py files that aren't executable, and -# remove executability from .py files that don't have a shebang line: -find %{buildroot} -name \*.py \ - \( \( \! -perm /u+x,g+x,o+x -exec sed -e '/^#!/Q 0' -e 'Q 1' {} \; \ - -print -exec sed -i '1d' {} \; \) -o \( \ - -perm /u+x,g+x,o+x ! -exec grep -m 1 -q '^#!' {} \; \ - -exec chmod a-x {} \; \) \) - -# .xpm and .xbm files should not be executable: -find %{buildroot} \ - \( -name \*.xbm -o -name \*.xpm -o -name \*.xpm.1 \) \ - -exec chmod a-x {} \; - -# Remove executable flag from files that shouldn't have it: -chmod a-x \ - %{buildroot}%{pylibdir}/distutils/tests/Setup.sample \ - %{buildroot}%{pylibdir}/Tools/README - -# Get rid of DOS batch files: -find %{buildroot} -name \*.bat -exec rm {} \; - -# Get rid of backup files: -find %{buildroot}/ -name "*~" -exec rm -f {} \; -find . -name "*~" -exec rm -f {} \; -rm -f %{buildroot}%{pylibdir}/LICENSE.txt -# Junk, no point in putting in -test sub-pkg -rm -f ${RPM_BUILD_ROOT}/%{pylibdir}/idlelib/testcode.py* - -# Get rid of stray patch file from buildroot: -rm -f %{buildroot}%{pylibdir}/test/test_imp.py.apply-our-changes-to-expected-shebang # from patch 4 - -# Fix end-of-line encodings: -find %{buildroot}/ -name \*.py -exec sed -i 's/\r//' {} \; - -# Fix an encoding: -iconv -f iso8859-1 -t utf-8 %{buildroot}/%{pylibdir}/Demo/rpc/README > README.conv && mv -f README.conv %{buildroot}/%{pylibdir}/Demo/rpc/README - -# Note that -# %{pylibdir}/Demo/distutils/test2to3/setup.py -# is in iso-8859-1 encoding, and that this is deliberate; this is test data -# for the 2to3 tool, and one of the functions of the 2to3 tool is to fixup -# character encodings within python source code - -# Do bytecompilation with the newly installed interpreter. -# This is similar to the script in macros.pybytecompile -# compile *.pyc -find %{buildroot} -type f -a -name "*.py" -print0 | \ - LD_LIBRARY_PATH="%{buildroot}%{dynload_dir}/:%{buildroot}%{_libdir}" \ - PYTHONPATH="%{buildroot}%{_libdir}/%{name} %{buildroot}%{_libdir}/%{name}/site-packages" \ - xargs -0 %{buildroot}%{_libexecdir}/platform-python -O -c 'import py_compile, sys; [py_compile.compile(f, dfile=f.partition("%{buildroot}")[2], optimize=opt) for opt in range(3) for f in sys.argv[1:]]' || : - -# Fixup permissions for shared libraries from non-standard 555 to standard 755: -find %{buildroot} \ - -perm 555 -exec chmod 755 {} \; - -# Install macros for rpm: -mkdir -p %{buildroot}/%{_rpmconfigdir}/macros.d/ -install -m 644 %{SOURCE3} %{buildroot}/%{_rpmconfigdir}/macros.d/ - -# 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 - *.%{SOABI_debug}) - ldd $Module | grep %{py_INSTSONAME_optimized} && - (echo Debug module $Module linked against optimized %{py_INSTSONAME_optimized} ; exit 1) - - ;; - *.%{SOABI_optimized}) - ldd $Module | grep %{py_INSTSONAME_debug} && - (echo Optimized module $Module linked against debug %{py_INSTSONAME_debug} ; exit 1) - ;; - esac -done - -# Rename the -devel script that differs on different arches to arch specific name -mv %{buildroot}%{_bindir}/python%{LDVERSION_optimized}-{,`uname -m`-}config -echo -e '#!/bin/sh\nexec `dirname $0`/python%{LDVERSION_optimized}-`uname -m`-config "$@"' > \ - %{buildroot}%{_bindir}/python%{LDVERSION_optimized}-config -echo '[ $? -eq 127 ] && echo "Could not find python%{LDVERSION_optimized}-`uname -m`-config. Look around to see available arches." >&2' >> \ - %{buildroot}%{_bindir}/python%{LDVERSION_optimized}-config - chmod +x %{buildroot}%{_bindir}/python%{LDVERSION_optimized}-config - - -# ====================================================== -# Running the upstream test suite -# ====================================================== - -%check - -# first of all, check timestamps of bytecode files -find %{buildroot} -type f -a -name "*.py" -print0 | \ - LD_LIBRARY_PATH="%{buildroot}%{dynload_dir}/:%{buildroot}%{_libdir}" \ - PYTHONPATH="%{buildroot}%{_libdir}/%{name} %{buildroot}%{_libdir}/%{name}/site-packages" \ - xargs -0 %{buildroot}%{_libexecdir}/platform-python %{SOURCE8} - -# For ppc64 we need a larger stack than default (rhbz#1292462) -%ifarch %{power64} - ulimit -a - ulimit -s 16384 -%endif - -topdir=$(pwd) -CheckPython() { - ConfName=$1 - 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. - - # 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 - # test_faulthandler.test_register_chain currently fails on ppc64le and - # aarch64, see upstream bug http://bugs.python.org/issue21131 - WITHIN_PYTHON_RPM_BUILD= \ - LD_LIBRARY_PATH=$ConfDir $ConfDir/python -m test \ - -wW --slowest --findleaks \ - -x test_distutils \ - -x test_resource \ - %ifarch ppc64le aarch64 - -x test_faulthandler \ - %endif - %ifarch %{mips64} - -x test_ctypes \ - %endif - %ifarch %{power64} s390 s390x armv7hl aarch64 %{mips} - -x test_gdb - %endif - - echo FINISHED: CHECKING OF PYTHON FOR CONFIGURATION: $ConfName - -} - -%if 0%{run_selftest_suite} - -# Check each of the configurations: -CheckPython optimized - -%endif # run_selftest_suite - - -# ====================================================== -# Cleaning up -# ====================================================== - -%clean - - -# ====================================================== -# Scriptlets -# ====================================================== - -%post libs -p /sbin/ldconfig - -%postun libs -p /sbin/ldconfig - -# ====================================================== -# Files -# ====================================================== - -%files -%license LICENSE -%doc README.rst -%exclude %{_bindir} -%{_libexecdir}/platform-python* -%exclude %{_mandir}/*/* - -%files libs -%license LICENSE -%doc README.rst -%dir %{pylibdir} -%dir %{dynload_dir} - -%{dynload_dir}/_blake2.%{SOABI_optimized}.so -%{dynload_dir}/_md5.%{SOABI_optimized}.so -%{dynload_dir}/_sha1.%{SOABI_optimized}.so -%{dynload_dir}/_sha256.%{SOABI_optimized}.so -%{dynload_dir}/_sha3.%{SOABI_optimized}.so -%{dynload_dir}/_sha512.%{SOABI_optimized}.so - -%{dynload_dir}/_asyncio.%{SOABI_optimized}.so -%{dynload_dir}/_bisect.%{SOABI_optimized}.so -%{dynload_dir}/_bz2.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_cn.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_hk.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_iso2022.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_jp.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_kr.%{SOABI_optimized}.so -%{dynload_dir}/_codecs_tw.%{SOABI_optimized}.so -%{dynload_dir}/_crypt.%{SOABI_optimized}.so -%{dynload_dir}/_csv.%{SOABI_optimized}.so -%{dynload_dir}/_ctypes.%{SOABI_optimized}.so -%{dynload_dir}/_curses.%{SOABI_optimized}.so -%{dynload_dir}/_curses_panel.%{SOABI_optimized}.so -%{dynload_dir}/_dbm.%{SOABI_optimized}.so -%{dynload_dir}/_decimal.%{SOABI_optimized}.so -%{dynload_dir}/_elementtree.%{SOABI_optimized}.so -%if %{with_gdbm} -%{dynload_dir}/_gdbm.%{SOABI_optimized}.so -%endif -%{dynload_dir}/_hashlib.%{SOABI_optimized}.so -%{dynload_dir}/_heapq.%{SOABI_optimized}.so -%{dynload_dir}/_json.%{SOABI_optimized}.so -%{dynload_dir}/_lsprof.%{SOABI_optimized}.so -%{dynload_dir}/_lzma.%{SOABI_optimized}.so -%{dynload_dir}/_multibytecodec.%{SOABI_optimized}.so -%{dynload_dir}/_multiprocessing.%{SOABI_optimized}.so -%{dynload_dir}/_opcode.%{SOABI_optimized}.so -%{dynload_dir}/_pickle.%{SOABI_optimized}.so -%{dynload_dir}/_posixsubprocess.%{SOABI_optimized}.so -%{dynload_dir}/_random.%{SOABI_optimized}.so -%{dynload_dir}/_socket.%{SOABI_optimized}.so -%{dynload_dir}/_sqlite3.%{SOABI_optimized}.so -%{dynload_dir}/_ssl.%{SOABI_optimized}.so -%{dynload_dir}/_struct.%{SOABI_optimized}.so -%{dynload_dir}/array.%{SOABI_optimized}.so -%{dynload_dir}/audioop.%{SOABI_optimized}.so -%{dynload_dir}/binascii.%{SOABI_optimized}.so -%{dynload_dir}/cmath.%{SOABI_optimized}.so -%{dynload_dir}/_datetime.%{SOABI_optimized}.so -%{dynload_dir}/fcntl.%{SOABI_optimized}.so -%{dynload_dir}/grp.%{SOABI_optimized}.so -%{dynload_dir}/math.%{SOABI_optimized}.so -%{dynload_dir}/mmap.%{SOABI_optimized}.so -%{dynload_dir}/nis.%{SOABI_optimized}.so -%{dynload_dir}/ossaudiodev.%{SOABI_optimized}.so -%{dynload_dir}/parser.%{SOABI_optimized}.so -%{dynload_dir}/pyexpat.%{SOABI_optimized}.so -%{dynload_dir}/readline.%{SOABI_optimized}.so -%{dynload_dir}/resource.%{SOABI_optimized}.so -%{dynload_dir}/select.%{SOABI_optimized}.so -%{dynload_dir}/spwd.%{SOABI_optimized}.so -%{dynload_dir}/syslog.%{SOABI_optimized}.so -%{dynload_dir}/termios.%{SOABI_optimized}.so -#%{dynload_dir}/time.%{SOABI_optimized}.so -%{dynload_dir}/_testmultiphase.%{SOABI_optimized}.so -%{dynload_dir}/unicodedata.%{SOABI_optimized}.so -%{dynload_dir}/xxlimited.%{SOABI_optimized}.so -%{dynload_dir}/zlib.%{SOABI_optimized}.so - -%dir %{pylibdir}/site-packages/ -%dir %{pylibdir}/site-packages/__pycache__/ -%{pylibdir}/site-packages/README.txt -%{pylibdir}/*.py -%dir %{pylibdir}/__pycache__/ -%{pylibdir}/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/collections/ -%dir %{pylibdir}/collections/__pycache__/ -%{pylibdir}/collections/*.py -%{pylibdir}/collections/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/ctypes/ -%dir %{pylibdir}/ctypes/__pycache__/ -%{pylibdir}/ctypes/*.py -%{pylibdir}/ctypes/__pycache__/*%{bytecode_suffixes} -%{pylibdir}/ctypes/macholib - -%{pylibdir}/curses - -%dir %{pylibdir}/dbm/ -%dir %{pylibdir}/dbm/__pycache__/ -%{pylibdir}/dbm/*.py -%{pylibdir}/dbm/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/distutils/ -%dir %{pylibdir}/distutils/__pycache__/ -%{pylibdir}/distutils/*.py -%{pylibdir}/distutils/__pycache__/*%{bytecode_suffixes} -%{pylibdir}/distutils/README -%{pylibdir}/distutils/command -%exclude %{pylibdir}/distutils/command/wininst-*.exe - -%dir %{pylibdir}/email/ -%dir %{pylibdir}/email/__pycache__/ -%{pylibdir}/email/*.py -%{pylibdir}/email/__pycache__/*%{bytecode_suffixes} -%{pylibdir}/email/mime -%doc %{pylibdir}/email/architecture.rst - -%{pylibdir}/encodings - -%{pylibdir}/html -%{pylibdir}/http - -%dir %{pylibdir}/importlib/ -%dir %{pylibdir}/importlib/__pycache__/ -%{pylibdir}/importlib/*.py -%{pylibdir}/importlib/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/json/ -%dir %{pylibdir}/json/__pycache__/ -%{pylibdir}/json/*.py -%{pylibdir}/json/__pycache__/*%{bytecode_suffixes} - -%{pylibdir}/logging -%{pylibdir}/multiprocessing - -%dir %{pylibdir}/sqlite3/ -%dir %{pylibdir}/sqlite3/__pycache__/ -%{pylibdir}/sqlite3/*.py -%{pylibdir}/sqlite3/__pycache__/*%{bytecode_suffixes} - -%exclude %{pylibdir}/turtle.py -%exclude %{pylibdir}/__pycache__/turtle*%{bytecode_suffixes} - -%{pylibdir}/urllib -%{pylibdir}/xml - -%if "%{_lib}" == "lib64" -%attr(0755,root,root) %dir %{_prefix}/lib/%{name}%{pybasever} -%attr(0755,root,root) %dir %{_prefix}/lib/%{name}%{pybasever}/site-packages -%attr(0755,root,root) %dir %{_prefix}/lib/%{name}%{pybasever}/site-packages/__pycache__/ -%endif - -# "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): -%dir %{pylibdir}/config-%{LDVERSION_optimized}-%{_arch}-linux%{_gnu}/ -%{pylibdir}/config-%{LDVERSION_optimized}-%{_arch}-linux%{_gnu}/Makefile -%dir %{_includedir}/platform-python%{LDVERSION_optimized}/ -%{_includedir}/platform-python%{LDVERSION_optimized}/%{_pyconfig_h} - -%{_libdir}/%{py_INSTSONAME_optimized} -%{_libdir}/libplatform-python3.so - -%files libs-devel -%license LICENSE -%doc README.rst - -%{pylibdir}/lib2to3 -%exclude %{pylibdir}/lib2to3/tests - -%dir %{pylibdir}/unittest/ -%dir %{pylibdir}/unittest/__pycache__/ -%{pylibdir}/unittest/*.py -%{pylibdir}/unittest/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/asyncio/ -%dir %{pylibdir}/asyncio/__pycache__/ -%{pylibdir}/asyncio/*.py -%{pylibdir}/asyncio/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/venv/ -%dir %{pylibdir}/venv/__pycache__/ -%{pylibdir}/venv/*.py -%{pylibdir}/venv/__pycache__/*%{bytecode_suffixes} -%{pylibdir}/venv/scripts - -%{pylibdir}/wsgiref -%{pylibdir}/xmlrpc - -%exclude %{pylibdir}/ensurepip/ - - -%{pylibdir}/idlelib - -%dir %{pylibdir}/test/ -%dir %{pylibdir}/test/__pycache__/ -%dir %{pylibdir}/test/support/ -%dir %{pylibdir}/test/support/__pycache__/ -%{pylibdir}/test/__init__.py -%{pylibdir}/test/__pycache__/__init__%{bytecode_suffixes} -%{pylibdir}/test/support/__init__.py -%{pylibdir}/test/support/__pycache__/__init__%{bytecode_suffixes} - -%dir %{pylibdir}/concurrent/ -%dir %{pylibdir}/concurrent/__pycache__/ -%{pylibdir}/concurrent/*.py -%{pylibdir}/concurrent/__pycache__/*%{bytecode_suffixes} - -%dir %{pylibdir}/concurrent/futures/ -%dir %{pylibdir}/concurrent/futures/__pycache__/ -%{pylibdir}/concurrent/futures/*.py -%{pylibdir}/concurrent/futures/__pycache__/*%{bytecode_suffixes} - -%{pylibdir}/pydoc_data - - -%files devel -%{pylibdir}/config-%{LDVERSION_optimized}-%{_arch}-linux%{_gnu}/* -%exclude %{pylibdir}/config-%{LDVERSION_optimized}-%{_arch}-linux%{_gnu}/Makefile -%{pylibdir}/distutils/command/wininst-*.exe -%{_includedir}/platform-python%{LDVERSION_optimized}/*.h -%exclude %{_includedir}/platform-python%{LDVERSION_optimized}/%{_pyconfig_h} -%doc Misc/README.valgrind Misc/valgrind-python.supp Misc/gdbinit -# %%{_bindir} is excluded in the main package -%{_libdir}/libplatform-python%{LDVERSION_optimized}.so -%exclude %{_libdir}/pkgconfig/python-%{LDVERSION_optimized}.pc -%exclude %{_libdir}/pkgconfig/python-%{pybasever}.pc -%exclude %{_libdir}/pkgconfig/python3.pc -%{_rpmconfigdir}/macros.d/macros.pybytecompile-%{name} - -%files tools -# %%{_bindir} is excluded in the main package -%{pylibdir}/Tools -%doc %{pylibdir}/Doc - -%files tkinter -%{pylibdir}/tkinter -%exclude %{pylibdir}/tkinter/test -%{dynload_dir}/_tkinter.%{SOABI_optimized}.so -%{pylibdir}/turtle.py -%{pylibdir}/__pycache__/turtle*%{bytecode_suffixes} -%dir %{pylibdir}/turtledemo -%{pylibdir}/turtledemo/*.py -%{pylibdir}/turtledemo/*.cfg -%dir %{pylibdir}/turtledemo/__pycache__/ -%{pylibdir}/turtledemo/__pycache__/*%{bytecode_suffixes} - -%files test -%{pylibdir}/ctypes/test -%{pylibdir}/distutils/tests -%{pylibdir}/sqlite3/test -%{pylibdir}/test -%{dynload_dir}/_ctypes_test.%{SOABI_optimized}.so -%{dynload_dir}/_testbuffer.%{SOABI_optimized}.so -%{dynload_dir}/_testcapi.%{SOABI_optimized}.so -%{dynload_dir}/_testimportmultiple.%{SOABI_optimized}.so -%{pylibdir}/lib2to3/tests -%{pylibdir}/tkinter/test -%{pylibdir}/unittest/test - -# 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 %__debug_package to use -# debugfiles.list, and it appears that everything below /usr/lib/debug and -# (/usr/src/debug) gets added to this file (via LISTFILES) in -# /usr/lib/rpm/find-debuginfo.sh -# -# Hence by installing it below /usr/lib/debug we ensure it is added to the -# -debuginfo subpackage -# (if it doesn't, then the rpmbuild ought to fail since the debug-gdb.py -# payload file would be unpackaged) - -# Workaround for rhbz#1476593 -%undefine _debuginfo_subpackages - -# ====================================================== -# Finally, the changelog: -# ====================================================== - -%changelog -* Mon Aug 14 2017 Petr Viktorin - 3.6.2-10 -- Remove bundled setuptools, pip, ensurepip -- Have /usr/libexec symlink point from generic to specific version binaries -- Adjust summaries and descriptions for platfrom-python -- Remove __requires_exclude -- Remove scriptlets for libs-devel -- Use one %%excludes for _bindir -- Specfile cleanup - -* Thu Aug 10 2017 Tomas Orsava - 3.6.2-9 -- Re-add runtime dependency on python-rpm-macros - -* Tue Aug 08 2017 Charalampos Stratakis - 3.6.2-8 -- Make platform-python-devel depend on platform-python-libs-devel - and platform-python-rpm-macros - -* Tue Aug 08 2017 Charalampos Stratakis - 3.6.2-7 -- Create the platform-python package - -* Mon Aug 07 2017 Iryna Shcherbina - 3.6.2-6 -- Fix the "urllib FTP protocol stream injection" vulnerability -Resolves: rhbz#1478916 - -* Tue Aug 01 2017 Tomas Orsava - 3.6.2-5 -- Dropped BuildRequires on db4-devel which was useful for Python 2 (module - bsddb), however, no longer needod for Python 3 -- Tested building Python 3 with and without the dependency, all tests pass and - filelists of resulting RPMs are identical - -* Sun Jul 30 2017 Florian Weimer - 3.6.2-4 -- Do not generate debuginfo subpackages (#1476593) -- Rebuild with binutils fix for ppc64le (#1475636) - -* Thu Jul 27 2017 Fedora Release Engineering - 3.6.2-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild - -* Tue Jul 25 2017 Charalampos Stratakis - 3.6.2-2 -- Make test_asyncio to not depend on the current SIGHUP signal handler. - -* Tue Jul 18 2017 Charalampos Stratakis - 3.6.2-1 -- Update to Python 3.6.2 - -* Tue Jun 27 2017 Charalampos Stratakis - 3.6.1-10 -- Update to the latest upstream implementation of PEP 538 - -* Mon Jun 26 2017 Michal Cyprian - 3.6.1-9 -- Make pip and distutils in user environment install into separate location - -* Fri Jun 23 2017 Charalampos Stratakis - 3.6.1-8 -- Fix test_alpn_protocols from test_ssl -- Do not require rebundled setuptools dependencies - -* Tue May 16 2017 Tomas Orsava - 3.6.1-7 -- Added a dependency to the devel subpackage on python3-rpm-generators which - have been excised out of rpm-build -- Updated notes on bootstrapping Python on top of this specfile accordingly -- Involves: rhbz#1410631, rhbz#1444925 - -* Tue May 09 2017 Charalampos Stratakis - 3.6.1-6 -- Enable profile guided optimizations for x86_64 and i686 architectures -- Update to a newer implementation of PEP 538 -- Update description to reflect that Python 3 is now the default Python - -* Fri May 05 2017 Charalampos Stratakis - 3.6.1-5 -- Update PEP 538 to the latest upstream implementation - -* Tue Apr 18 2017 Charalampos Stratakis - 3.6.1-4 -- Enable link time optimizations -- Move windows executables to the devel subpackage (rhbz#1426257) - -* Thu Apr 13 2017 Tomas Orsava - 3.6.1-3 -- Rename python3.Xdm-config script from -debug to be arch specific -Resolves: rhbz#1179073 - -* Wed Apr 05 2017 Charalampos Stratakis - 3.6.1-2 -- Install the Makefile in its proper location (rhbz#1438219) - -* Wed Mar 22 2017 Iryna Shcherbina - 3.6.1-1 -- Update to version 3.6.1 final - -* Tue Mar 21 2017 Tomas Orsava - 3.6.1-0.2.rc1 -- Fix syntax error in %%py_byte_compile macro (rhbz#1433569) - -* Thu Mar 16 2017 Iryna Shcherbina - 3.6.1-0.1.rc1 -- Update to Python 3.6.1 release candidate 1 -- Add patch 264 to skip a known test failure on aarch64 - -* Fri Mar 10 2017 Charalampos Stratakis - 3.6.0-21 -- Use proper command line parsing in _testembed -- Backport of PEP 538: Coercing the legacy C locale to a UTF-8 based locale - https://fedoraproject.org/wiki/Changes/python3_c.utf-8_locale - -* Mon Feb 27 2017 Charalampos Stratakis - 3.6.0-20 -- Add desktop entry and appdata.xml file for IDLE 3 (rhbz#1392049) - -* Fri Feb 24 2017 Michal Cyprian - 3.6.0-19 -- Revert "Set values of prefix and exec_prefix to /usr/local for - /usr/bin/python* executables..." to prevent build failures - of packages using alternate build tools - -* Tue Feb 21 2017 Michal Cyprian - 3.6.0-18 -- Set values of prefix and exec_prefix to /usr/local for - /usr/bin/python* executables -- Use new %%_module_build macro - -* Fri Feb 17 2017 Michal Cyprian - 3.6.0-13 -- Add --executable option to install.py command - -* Wed Feb 15 2017 Charalampos Stratakis - 3.6.0-12 -- BuildRequire the new dependencies of setuptools when rewheel mode is enabled -in order for the virtualenvs to work properly - -* Sat Feb 11 2017 Fedora Release Engineering - 3.6.0-11 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild - -* Wed Feb 01 2017 Stephen Gallagher - 3.6.0-10 -- Add missing %%license macro - -* Thu Jan 26 2017 Tomas Orsava - 3.6.0-9 -- Modify the runtime dependency of python3-libs on system-python-libs again, - because previous attempt didn't work properly with dnf resolving mechanism - -* Wed Jan 25 2017 Tomas Orsava - 3.6.0-8 -- Modify the runtime dependency of python3-libs on system-python-libs to use - just the version and release number, but not the dist tag due to Modularity - -* Mon Jan 16 2017 Charalampos Stratakis - 3.6.0-7 -- Fix error check, so that Random.seed actually uses OS randomness (rhbz#1412275) -- Skip test_aead_aes_gcm during rpmbuild - -* Thu Jan 12 2017 Igor Gnatenko - 3.6.0-6 -- Rebuild for readline 7.x - -* Tue Jan 10 2017 Charalampos Stratakis - 3.6.0-5 -- Require glibc >= 2.24.90-26 for system-python-libs (rhbz#1410644) - -* Mon Jan 09 2017 Charalampos Stratakis - 3.6.0-4 -- Define HAVE_LONG_LONG as 1 for backwards compatibility - -* Thu Jan 05 2017 Miro Hrončok - 3.6.0-3 -- Don't blow up on EL7 kernel (random generator) (rhbz#1410175) - -* Tue Dec 27 2016 Charalampos Stratakis - 3.6.0-1 -- Update to Python 3.6.0 final - -* Fri Dec 09 2016 Charalampos Stratakis - 3.6.0-0.6.rc1 -- Enable rewheel - -* Wed Dec 07 2016 Charalampos Stratakis - 3.6.0-0.5.rc1 -- Update to Python 3.6.0 release candidate 1 - -* Mon Dec 05 2016 Charalampos Stratakis - 3.6.0-0.4.b4 -- Update to Python 3.6.0 beta 4 - -* Mon Dec 05 2016 Charalampos Stratakis - 3.5.2-7 -- Set to work with pip version 9.0.1 - -* Wed Oct 12 2016 Charalampos Stratakis - 3.5.2-6 -- Use proper patch numbering and base upstream branch for -porting ssl and hashlib modules to OpenSSL 1.1.0 -- Drop hashlib patch for now -- Add riscv64 arch to 64bit and no-valgrind arches - -* Tue Oct 11 2016 Tomáš Mráz - 3.5.2-5 -- Make it build with OpenSSL-1.1.0 based on upstream patch - -* Wed Sep 14 2016 Charalampos Stratakis - 3.5.2-4 -- Obsolete and Provide python35 package - -* Mon Sep 12 2016 Charalampos Stratakis - 3.5.2-3 -- Update %py_byte_compile macro -- Remove unused configure flags (rhbz#1374357) - -* Fri Sep 09 2016 Tomas Orsava - 3.5.2-2 -- Updated .pyc 'bytecompilation with the newly installed interpreter' to also - recompile optimized .pyc files -- Removed .pyo 'bytecompilation with the newly installed interpreter', as .pyo - files are no more -- Resolves rhbz#1373635 - -* Mon Aug 15 2016 Tomas Orsava - 3.5.2-1 -- Rebased to version 3.5.2 -- Set to work with pip version 8.1.2 -- Removed patches 207, 237, 241 as fixes are already contained in Python 3.5.2 -- Removed arch or environment specific patches 194, 196, 203, and 208 - as test builds indicate they are no longer needed -- Updated patches 102, 146, and 242 to work with the new Python codebase -- Removed patches 200, 201, 5000 which weren't even being applied - -* Tue Aug 09 2016 Charalampos Stratakis - 3.5.1-15 -- Fix for CVE-2016-1000110 HTTPoxy attack -- SPEC file cleanup - -* Mon Aug 01 2016 Michal Toman - 3.5.1-14 -- Build properly on MIPS - -* Tue Jul 19 2016 Fedora Release Engineering - 3.5.1-13 -- https://fedoraproject.org/wiki/Changes/Automatic_Provides_for_Python_RPM_Packages - -* Fri Jul 08 2016 Charalampos Stratakis - 3.5.1-12 -- Refactor patch for properly fixing CVE-2016-5636 - -* Fri Jul 08 2016 Charalampos Stratakis - 3.5.1-11 -- Fix test_pyexpat failure with Expat version of 2.2.0 - -* Fri Jul 08 2016 Miro Hrončok - 3.5.1-10 -- Move xml module to system-python-libs - -* Thu Jun 16 2016 Tomas Orsava - 3.5.1-9 -- Fix for: CVE-2016-0772 python: smtplib StartTLS stripping attack -- Raise an error when STARTTLS fails -- rhbz#1303647: https://bugzilla.redhat.com/show_bug.cgi?id=1303647 -- rhbz#1346345: https://bugzilla.redhat.com/show_bug.cgi?id=1346345 -- Fixed upstream: https://hg.python.org/cpython/rev/d590114c2394 - -* Mon Jun 13 2016 Charalampos Stratakis - 3.5.1-8 -- Added patch for fixing possible integer overflow and heap corruption in zipimporter.get_data() - -* Fri Mar 04 2016 Miro Hrončok - 3.5.1-7 -- Move distutils to system-python-libs - -* Wed Feb 24 2016 Robert Kuska - 3.5.1-6 -- Provide python3-enum34 - -* Fri Feb 19 2016 Miro Hrončok - 3.5.1-5 -- Provide System Python packages and macros - -* Thu Feb 04 2016 Fedora Release Engineering - 3.5.1-4 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild - -* Wed Jan 13 2016 Orion Poplwski - 3.5.1-2 -- Drop python3 macros, require python/python3-rpm-macros - -* Mon Dec 14 2015 Robert Kuska - 3.5.1-1 -- Update to 3.5.1 -- Removed patch 199 and 207 (upstream) - -* Sun Nov 15 2015 Robert Kuska - 3.5.0-5 -- Remove versioned libpython from devel package - -* Fri Nov 13 2015 Than Ngo 3.5.0-4 -- add correct arch for ppc64/ppc64le to fix build failure - -* Wed Nov 11 2015 Robert Kuska - 3.5.0-3 -- Hide the private _Py_atomic_xxx symbols from public header - -* Wed Oct 14 2015 Robert Kuska - 3.5.0-2 -- Rebuild with wheel set to 1 - -* Tue Sep 15 2015 Matej Stuchlik - 3.5.0-1 -- Update to 3.5.0 - -* Mon Jun 29 2015 Thomas Spura - 3.4.3-4 -- python3-devel: Require python-macros for version independant macros such as - python_provide. See fpc#281 and fpc#534. - -* Thu Jun 18 2015 Fedora Release Engineering - 3.4.3-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild - -* Wed Jun 17 2015 Matej Stuchlik - 3.4.3-4 -- Use 1024bit DH key in test_ssl -- Use -O0 when compiling -debug build -- Update pip version variable to the version we actually ship - -* Wed Jun 17 2015 Matej Stuchlik - 3.4.3-3 -- Make relocating Python by changing _prefix actually work -Resolves: rhbz#1231801 - -* Mon May 4 2015 Peter Robinson 3.4.3-2 -- Disable test_gdb on aarch64 (rhbz#1196181), it joins all other non x86 arches - -* Thu Mar 12 2015 Matej Stuchlik - 3.4.3-1 -- Updated to 3.4.3 -- BuildPython now accepts additional build options -- Temporarily disabled test_gdb on arm (rhbz#1196181) - -* Wed Feb 25 2015 Matej Stuchlik - 3.4.2-7 -- Fixed undefined behaviour in faulthandler which caused test to hang on x86_64 - (http://bugs.python.org/issue23433) - -* Sat Feb 21 2015 Till Maas - 3.4.2-6 -- Rebuilt for Fedora 23 Change - https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code - -* Tue Feb 17 2015 Ville Skyttä - 3.4.2-5 -- Own systemtap dirs (#710733) - -* Mon Jan 12 2015 Dan Horák - 3.4.2-4 -- build with valgrind on ppc64le -- disable test_gdb on s390(x) until rhbz#1181034 is resolved - -* Tue Dec 16 2014 Robert Kuska - 3.4.2-3 -- New patches: 170 (gc asserts), 200 (gettext headers), - 201 (gdbm memory leak) - -* Thu Dec 11 2014 Robert Kuska - 3.4.2-2 -- OpenSSL disabled SSLv3 in SSLv23 method - -* Thu Nov 13 2014 Matej Stuchlik - 3.4.2-1 -- Update to 3.4.2 -- Refreshed patches: 156 (gdb autoload) -- Removed: 195 (Werror declaration), 197 (CVE-2014-4650) - -* Mon Nov 03 2014 Slavek Kabrda - 3.4.1-16 -- Fix CVE-2014-4650 - CGIHTTPServer URL handling -Resolves: rhbz#1113529 - -* Sun Sep 07 2014 Karsten Hopp 3.4.1-15 -- exclude test_gdb on ppc* (rhbz#1132488) - -* Thu Aug 21 2014 Slavek Kabrda - 3.4.1-14 -- Update rewheel patch with fix from https://github.com/bkabrda/rewheel/pull/1 - -* Sun Aug 17 2014 Fedora Release Engineering - 3.4.1-13 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild - -* Sun Jun 8 2014 Peter Robinson 3.4.1-12 -- aarch64 has valgrind, just list those that don't support it - -* Sun Jun 08 2014 Fedora Release Engineering - 3.4.1-11 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild - -* Wed Jun 04 2014 Karsten Hopp 3.4.1-10 -- bump release and rebuild to link with the correct tcl/tk libs on ppcle - -* Tue Jun 03 2014 Matej Stuchlik - 3.4.1-9 -- Change paths to bundled projects in rewheel patch - -* Fri May 30 2014 Miro Hrončok - 3.4.1-8 -- In config script, use uname -m to write the arch - -* Thu May 29 2014 Dan Horák - 3.4.1-7 -- update the arch list where valgrind exists - %%power64 includes also - ppc64le which is not supported yet - -* Thu May 29 2014 Miro Hrončok - 3.4.1-6 -- Forward arguments to the arch specific config script -Resolves: rhbz#1102683 - -* Wed May 28 2014 Miro Hrončok - 3.4.1-5 -- Rename python3.Xm-config script to arch specific. -Resolves: rhbz#1091815 - -* Tue May 27 2014 Bohuslav Kabrda - 3.4.1-4 -- Use python3-*, not python-* runtime requires on setuptools and pip -- rebuild for tcl-8.6 - -* Tue May 27 2014 Matej Stuchlik - 3.4.1-3 -- Update the rewheel module - -* Mon May 26 2014 Miro Hrončok - 3.4.1-2 -- Fix multilib dependencies. -Resolves: rhbz#1091815 - -* Sun May 25 2014 Matej Stuchlik - 3.4.1-1 -- Update to Python 3.4.1 - -* Sun May 25 2014 Matej Stuchlik - 3.4.0-8 -- Fix test_gdb failure on ppc64le -Resolves: rhbz#1095355 - -* Thu May 22 2014 Miro Hrončok - 3.4.0-7 -- Add macro %%python3_version_nodots - -* Sun May 18 2014 Matej Stuchlik - 3.4.0-6 -- Disable test_faulthandler, test_gdb on aarch64 -Resolves: rhbz#1045193 - -* Fri May 16 2014 Matej Stuchlik - 3.4.0-5 -- Don't add Werror=declaration-after-statement for extension - modules through setup.py (PyBT#21121) - -* Mon May 12 2014 Matej Stuchlik - 3.4.0-4 -- Add setuptools and pip to Requires - -* Tue Apr 29 2014 Matej Stuchlik - 3.4.0-3 -- Point __os_install_post to correct brp-* files - -* Tue Apr 15 2014 Matej Stuchlik - 3.4.0-2 -- Temporarily disable tests requiring SIGHUP (rhbz#1088233) - -* Tue Apr 15 2014 Matej Stuchlik - 3.4.0-1 -- Update to Python 3.4 final -- Add patch adding the rewheel module -- Merge patches from master - -* Wed Jan 08 2014 Bohuslav Kabrda - 3.4.0-0.1.b2 -- Update to Python 3.4 beta 2. -- Refreshed patches: 55 (systemtap), 146 (hashlib-fips), 154 (test_gdb noise) -- Dropped patches: 114 (statvfs constants), 177 (platform unicode) - -* Mon Nov 25 2013 Bohuslav Kabrda - 3.4.0-0.1.b1 -- Update to Python 3.4 beta 1. -- Refreshed patches: 102 (lib64), 111 (no static lib), 125 (less verbose COUNT -ALLOCS), 141 (fix COUNT_ALLOCS in test_module), 146 (hashlib fips), -157 (UID+GID overflows), 173 (ENOPROTOOPT in bind_port) -- Removed patch 00187 (remove pthread atfork; upstreamed) - -* Mon Nov 04 2013 Bohuslav Kabrda - 3.4.0-0.1.a4 -- Update to Python 3.4 alpha 4. -- Refreshed patches: 55 (systemtap), 102 (lib64), 111 (no static lib), -114 (statvfs flags), 132 (unittest rpmbuild hooks), 134 (fix COUNT_ALLOCS in -test_sys), 143 (tsc on ppc64), 146 (hashlib fips), 153 (test gdb noise), -157 (UID+GID overflows), 173 (ENOPROTOOPT in bind_port), 186 (dont raise -from py_compile) -- Removed patches: 129 (test_subprocess nonreadable dir - no longer fails in -Koji), 142 (the mock issue that caused this is fixed) -- Added patch 187 (remove thread atfork) - will be in next version -- Refreshed script for checking pyc and pyo timestamps with new ignored files. -- The fips patch is disabled for now until upstream makes a final decision -what to do with sha3 implementation for 3.4.0. - -* Wed Oct 30 2013 Bohuslav Kabrda - 3.3.2-7 -- Bytecompile all *.py files properly during build (rhbz#1023607) - -* Fri Aug 23 2013 Matej Stuchlik - 3.3.2-6 -- Added fix for CVE-2013-4238 (rhbz#996399) - -* Fri Jul 26 2013 Dennis Gilmore - 3.3.2-5 -- fix up indentation in arm patch - -* Fri Jul 26 2013 Dennis Gilmore - 3.3.2-4 -- disable a test that fails on arm -- enable valgrind support on arm arches - -* Tue Jul 02 2013 Bohuslav Kabrda - 3.3.2-3 -- Fix build with libffi containing multilib wrapper for ffi.h (rhbz#979696). - -* Mon May 20 2013 Bohuslav Kabrda - 3.3.2-2 -- Add patch for CVE-2013-2099 (rhbz#963261). - -* Thu May 16 2013 Bohuslav Kabrda - 3.3.2-1 -- Updated to Python 3.3.2. -- Refreshed patches: 153 (gdb test noise) -- Dropped patches: 175 (configure -Wformat, fixed upstream), 182 (gdb -test threads) -- Synced patch numbers with python.spec. - -* Thu May 9 2013 David Malcolm - 3.3.1-4 -- fix test.test_gdb.PyBtTests.test_threads on ppc64 (patch 181; rhbz#960010) - -* Thu May 02 2013 Bohuslav Kabrda - 3.3.1-3 -- Add patch that enables building on ppc64p7 (replace the sed, so that -we get consistent with python2 spec and it's more obvious that we're doing it. - -* Wed Apr 24 2013 Bohuslav Kabrda - 3.3.1-2 -- Add fix for gdb tests failing on arm, rhbz#951802. - -* Tue Apr 09 2013 Bohuslav Kabrda - 3.3.1-1 -- Updated to Python 3.3.1. -- Refreshed patches: 55 (systemtap), 111 (no static lib), 146 (hashlib fips), -153 (fix test_gdb noise), 157 (uid, gid overflow - fixed upstream, just -keeping few more downstream tests) -- Removed patches: 3 (audiotest.au made it to upstream tarball) -- Removed workaround for http://bugs.python.org/issue14774, discussed in -http://bugs.python.org/issue15298 and fixed in revision 24d52d3060e8. - -* Mon Mar 25 2013 David Malcolm - 3.3.0-10 -- fix gcc 4.8 incompatibility (rhbz#927358); regenerate autotool intermediates - -* Mon Mar 25 2013 David Malcolm - 3.3.0-9 -- renumber patches to keep them in sync with python.spec - -* Fri Mar 15 2013 Toshio Kuratomi - 3.3.0-8 -- Fix error in platform.platform() when non-ascii byte strings are decoded to - unicode (rhbz#922149) - -* Thu Mar 14 2013 Toshio Kuratomi - 3.3.0-7 -- Fix up shared library extension (rhbz#889784) - -* Thu Mar 07 2013 Karsten Hopp 3.3.0-6 -- add ppc64p7 build target, optimized for Power7 - -* Mon Mar 4 2013 David Malcolm - 3.3.0-5 -- add workaround for ENOPROTOOPT seen running selftests in Koji -(rhbz#913732) - -* Mon Mar 4 2013 David Malcolm - 3.3.0-4 -- remove config flag from /etc/rpm/macros.{python3|pybytecompile} - -* Mon Feb 11 2013 David Malcolm - 3.3.0-3 -- add aarch64 (rhbz#909783) - -* Thu Nov 29 2012 David Malcolm - 3.3.0-2 -- add BR on bluez-libs-devel (rhbz#879720) - -* Sat Sep 29 2012 David Malcolm - 3.3.0-1 -- 3.3.0rc3 -> 3.3.0; drop alphatag - -* Mon Sep 24 2012 David Malcolm - 3.3.0-0.6.rc3 -- 3.3.0rc2 -> 3.3.0rc3 - -* Mon Sep 10 2012 David Malcolm - 3.3.0-0.5.rc2 -- 3.3.0rc1 -> 3.3.0rc2; refresh patch 55 - -* Mon Aug 27 2012 David Malcolm - 3.3.0-0.4.rc1 -- 3.3.0b2 -> 3.3.0rc1; refresh patches 3, 55 - -* Mon Aug 13 2012 David Malcolm - 3.3.0-0.3.b2 -- 3.3b1 -> 3.3b2; drop upstreamed patch 152; refresh patches 3, 102, 111, -134, 153, 160; regenenerate autotools patch; rework systemtap patch to work -correctly when LANG=C (patch 55); importlib.test was moved to -test.test_importlib upstream - -* Mon Aug 13 2012 Karsten Hopp 3.3.0-0.2.b1 -- disable some failing checks on PPC* (rhbz#846849) - -* Fri Aug 3 2012 David Malcolm - 3.3.0-0.1.b1 -- 3.2 -> 3.3: https://fedoraproject.org/wiki/Features/Python_3.3 -- 3.3.0b1: refresh patches 3, 55, 102, 111, 113, 114, 134, 157; drop upstream -patch 147; regenenerate autotools patch; drop "--with-wide-unicode" from -configure (PEP 393); "plat-linux2" -> "plat-linux" (upstream issue 12326); -"bz2" -> "_bz2" and "crypt" -> "_crypt"; egg-info files are no longer shipped -for stdlib (upstream issues 10645 and 12218); email/test moved to -test/test_email; add /usr/bin/pyvenv[-3.3] and venv module (PEP 405); add -_decimal and _lzma modules; make collections modules explicit in payload again -(upstream issue 11085); add _testbuffer module to tests subpackage (added in -upstream commit 3f9b3b6f7ff0); fix test failures (patches 160 and 161); -workaround erroneously shared _sysconfigdata.py upstream issue #14774; fix -distutils.sysconfig traceback (patch 162); add BuildRequires: xz-devel (for -_lzma module); skip some tests within test_socket (patch 163) - -* Sat Jul 21 2012 Fedora Release Engineering - 3.2.3-11 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild - -* Fri Jul 20 2012 David Malcolm - 3.3.0-0.1.b1 - -* Fri Jun 22 2012 David Malcolm - 3.2.3-10 -- use macro for power64 (rhbz#834653) - -* Mon Jun 18 2012 David Malcolm - 3.2.3-9 -- fix missing include in uid/gid handling patch (patch 157; rhbz#830405) - -* Wed May 30 2012 Bohuslav Kabrda - 3.2.3-8 -- fix tapset for debug build - -* Tue May 15 2012 David Malcolm - 3.2.3-7 -- 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 - 3.2.3-6 -- renumber autotools patch from 300 to 5000 -- specfile cleanups - -* Mon Apr 30 2012 David Malcolm - 3.2.3-5 -- fix test_gdb.py (patch 156; rhbz#817072) - -* Fri Apr 20 2012 David Malcolm - 3.2.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) - -* Fri Apr 20 2012 David Malcolm - 3.2.3-3 -- add explicit version requirements on expat to avoid linkage problems with -XML_SetHashSalt - -* Thu Apr 12 2012 David Malcolm - 3.2.3-2 -- fix test_gdb (patch 153) - -* Wed Apr 11 2012 David Malcolm - 3.2.3-1 -- 3.2.3; refresh patch 102 (lib64); drop upstream patches 148 (gdbm magic -values), 149 (__pycache__ fix); add patch 152 (test_gdb regex) - -* Thu Feb 9 2012 Thomas Spura - 3.2.2-13 -- use newly installed python for byte compiling (now for real) - -* Sun Feb 5 2012 Thomas Spura - 3.2.2-12 -- use newly installed python for byte compiling (#787498) - -* Wed Jan 4 2012 Ville Skyttä - 3.2.2-11 -- Build with $RPM_LD_FLAGS (#756863). -- Use xz-compressed source tarball. - -* Wed Dec 07 2011 Karsten Hopp 3.2.2-10 -- disable rAssertAlmostEqual in test_cmath on PPC (#750811) - -* Mon Oct 17 2011 Rex Dieter - 3.2.2-9 -- python3-devel missing autogenerated pkgconfig() provides (#746751) - -* Mon Oct 10 2011 David Malcolm - 3.2.2-8 -- cherrypick fix for distutils not using __pycache__ when byte-compiling -files (rhbz#722578) - -* Fri Sep 30 2011 David Malcolm - 3.2.2-7 -- re-enable gdbm (patch 148; rhbz#742242) - -* Fri Sep 16 2011 David Malcolm - 3.2.2-6 -- add a sys._debugmallocstats() function (patch 147) - -* Wed Sep 14 2011 David Malcolm - 3.2.2-5 -- support OpenSSL FIPS mode in _hashlib and hashlib; don't build the _md5 and -_sha* modules, relying on _hashlib in hashlib (rhbz#563986; patch 146) - -* Tue Sep 13 2011 David Malcolm - 3.2.2-4 -- disable gdbm module to prepare for gdbm soname bump - -* Mon Sep 12 2011 David Malcolm - 3.2.2-3 -- renumber and rename patches for consistency with python.spec (8 to 55, 106 -to 104, 6 to 111, 104 to 113, 105 to 114, 125, 131, 130 to 143) - -* Sat Sep 10 2011 David Malcolm - 3.2.2-2 -- 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 106, 133-142 sparsely, moving -patches for consistency with python.spec: 128 to 134, 126 to 135, 127 to 141) - -* Tue Sep 6 2011 David Malcolm - 3.2.2-1 -- 3.2.2 - -* Thu Sep 1 2011 David Malcolm - 3.2.1-7 -- run selftests with "--verbose" -- disable parts of test_io on ppc (rhbz#732998) - -* Wed Aug 31 2011 David Malcolm - 3.2.1-6 -- use "--findleaks --verbose3" when running test suite - -* Tue Aug 23 2011 David Malcolm - 3.2.1-5 -- re-enable and fix the --with-tsc option on ppc64, and rework it on 32-bit -ppc to avoid aliasing violations (patch 130; rhbz#698726) - -* Tue Aug 23 2011 David Malcolm - 3.2.1-4 -- don't use --with-tsc on ppc64 debug builds (rhbz#698726) - -* Thu Aug 18 2011 David Malcolm - 3.2.1-3 -- add %%python3_version to the rpm macros (rhbz#719082) - -* Mon Jul 11 2011 Dennis Gilmore - 3.2.1-2 -- disable some tests on sparc arches - -* Mon Jul 11 2011 David Malcolm - 3.2.1-1 -- 3.2.1; refresh lib64 patch (102), subprocess unit test patch (129), disabling -of static library build (due to Modules/_testembed; patch 6), autotool -intermediates (patch 300) - -* Fri Jul 8 2011 David Malcolm - 3.2-5 -- use the gdb hooks from the upstream tarball, rather than keeping our own copy - -* Fri Jul 8 2011 David Malcolm - 3.2-4 -- don't run test_openpty and test_pty in %%check - -* Fri Jul 8 2011 David Malcolm - 3.2-3 -- cleanup of BuildRequires; add comment headings to specfile sections - -* Tue Apr 19 2011 David Malcolm - 3.2-2 -- fix the libpython.stp systemtap tapset (rhbz#697730) - -* Mon Feb 21 2011 David Malcolm - 3.2-1 -- 3.2 -- drop alphatag -- regenerate autotool patch - -* Mon Feb 14 2011 David Malcolm - 3.2-0.13.rc3 -- add a /usr/bin/python3-debug symlink within the debug subpackage - -* Mon Feb 14 2011 David Malcolm - 3.2-0.12.rc3 -- 3.2rc3 -- regenerate autotool patch - -* Wed Feb 09 2011 Fedora Release Engineering - 3.2-0.11.rc2 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild - -* Mon Jan 31 2011 David Malcolm - 3.2-0.10.rc2 -- 3.2rc2 - -* Mon Jan 17 2011 David Malcolm - 3.2-0.9.rc1 -- 3.2rc1 -- rework patch 6 (static lib removal) -- remove upstreamed patch 130 (ppc debug build) -- regenerate patch 300 (autotool intermediates) -- updated packaging to reflect upstream rewrite of "Demo" (issue 7962) -- added libpython3.so and 2to3-3.2 - -* Wed Jan 5 2011 David Malcolm - 3.2-0.8.b2 -- set EXTRA_CFLAGS to our CFLAGS, rather than overriding OPT, fixing a linker -error with dynamic annotations (when configured using --with-valgrind) -- fix the ppc build of the debug configuration (patch 130; rhbz#661510) - -* Tue Jan 4 2011 David Malcolm - 3.2-0.7.b2 -- add --with-valgrind to configuration (on architectures that support this) - -* Wed Dec 29 2010 David Malcolm - 3.2-0.6.b2 -- work around test_subprocess failure seen in koji (patch 129) - -* Tue Dec 28 2010 David Malcolm - 3.2-0.5.b2 -- 3.2b2 -- rework patch 3 (removal of mimeaudio tests), patch 6 (no static libs), -patch 8 (systemtap), patch 102 (lib64) -- remove patch 4 (rendered redundant by upstream r85537), patch 103 (PEP 3149), -patch 110 (upstreamed expat fix), patch 111 (parallel build fix for grammar -fixed upstream) -- regenerate patch 300 (autotool intermediates) -- workaround COUNT_ALLOCS weakref issues in test suite (patch 126, patch 127, -patch 128) -- stop using runtest.sh in %%check (dropped by upstream), replacing with -regrtest; fixup list of failing tests -- introduce "pyshortver", "SOABI_optimized" and "SOABI_debug" macros -- rework manifests of shared libraries to use "SOABI_" macros, reflecting -PEP 3149 -- drop itertools, operator and _collections modules from the manifests as py3k -commit r84058 moved these inside libpython; json/tests moved to test/json_tests -- move turtle code into the tkinter subpackage - -* Wed Nov 17 2010 David Malcolm - 3.2-0.5.a1 -- fix sysconfig to not rely on the -devel subpackage (rhbz#653058) - -* Thu Sep 9 2010 David Malcolm - 3.2-0.4.a1 -- move most of the content of the core package to the libs subpackage, given -that the libs aren't meaningfully usable without the standard libraries - -* Wed Sep 8 2010 David Malcolm - 3.2-0.3.a1 -- Move test.support to core package (rhbz#596258) -- Add various missing __pycache__ directories to payload - -* Sun Aug 22 2010 Toshio Kuratomi - 3.2-0.2.a1 -- Add __pycache__ directory for site-packages - -* Sun Aug 22 2010 Thomas Spura - 3.2-0.1.a1 -- on 64bit "stdlib" was still "/usr/lib/python*" (modify *lib64.patch) -- make find-provides-without-python-sonames.sh 64bit aware - -* Sat Aug 21 2010 David Malcolm - 3.2-0.0.a1 -- 3.2a1; add alphatag -- rework %%files in the light of PEP 3147 (__pycache__) -- drop our configuration patch to Setup.dist (patch 0): setup.py should do a -better job of things, and the %%files explicitly lists our modules (r82746 -appears to break the old way of doing things). This leads to various modules -changing from "foomodule.so" to "foo.so". It also leads to the optimized build -dropping the _sha1, _sha256 and _sha512 modules, but these are provided by -_hashlib; _weakref becomes a builtin module; xxsubtype goes away (it's only for -testing/devel purposes) -- fixup patches 3, 4, 6, 8, 102, 103, 105, 111 for the rebase -- remove upstream patches: 7 (system expat), 106, 107, 108 (audioop reformat -plus CVE-2010-1634 and CVE-2010-2089), 109 (CVE-2008-5983) -- add machinery for rebuilding "configure" and friends, using the correct -version of autoconf (patch 300) -- patch the debug build's usage of COUNT_ALLOCS to be less verbose (patch 125) -- "modulator" was removed upstream -- drop "-b" from patch applications affecting .py files to avoid littering the -installation tree - -* Thu Aug 19 2010 Toshio Kuratomi - 3.1.2-13 -- Turn on computed-gotos. -- Fix for parallel make and graminit.c - -* Fri Jul 2 2010 David Malcolm - 3.1.2-12 -- rebuild - -* Fri Jul 2 2010 David Malcolm - 3.1.2-11 -- Fix an incompatibility between pyexpat and the system expat-2.0.1 that led to -a segfault running test_pyexpat.py (patch 110; upstream issue 9054; rhbz#610312) - -* Fri Jun 4 2010 David Malcolm - 3.1.2-10 -- ensure that the compiler is invoked with "-fwrapv" (rhbz#594819) -- reformat whitespace in audioop.c (patch 106) -- CVE-2010-1634: fix various integer overflow checks in the audioop -module (patch 107) -- CVE-2010-2089: further checks within the audioop module (patch 108) -- CVE-2008-5983: the new PySys_SetArgvEx entry point from r81399 (patch 109) - -* Thu May 27 2010 Dan Horák - 3.1.2-9 -- reading the timestamp counter is available only on some arches (see Python/ceval.c) - -* Wed May 26 2010 David Malcolm - 3.1.2-8 -- add flags for statvfs.f_flag to the constant list in posixmodule (i.e. "os") -(patch 105) - -* Tue May 25 2010 David Malcolm - 3.1.2-7 -- add configure-time support for COUNT_ALLOCS and CALL_PROFILE debug options -(patch 104); enable them and the WITH_TSC option within the debug build - -* Mon May 24 2010 David Malcolm - 3.1.2-6 -- build and install two different configurations of Python 3: debug and -standard, packaging the debug build in a new "python3-debug" subpackage -(patch 103) - -* Tue Apr 13 2010 David Malcolm - 3.1.2-5 -- exclude test_http_cookies when running selftests, due to hang seen on -http://koji.fedoraproject.org/koji/taskinfo?taskID=2088463 (cancelled after -11 hours) -- update python-gdb.py from v5 to py3k version submitted upstream - -* Wed Mar 31 2010 David Malcolm - 3.1.2-4 -- update python-gdb.py from v4 to v5 (improving performance and stability, -adding commands) - -* Thu Mar 25 2010 David Malcolm - 3.1.2-3 -- 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 - 3.1.2-2 -- refresh gdb hooks to v3 (reworking how they are packaged) - -* Sun Mar 21 2010 David Malcolm - 3.1.2-1 -- update to 3.1.2: http://www.python.org/download/releases/3.1.2/ -- drop upstreamed patch 2 (.pyc permissions handling) -- drop upstream patch 5 (fix for the test_tk and test_ttk_* selftests) -- drop upstreamed patch 200 (path-fixing script) - -* Sat Mar 20 2010 David Malcolm - 3.1.1-28 -- fix typo in libpython.stp (rhbz:575336) - -* Fri Mar 12 2010 David Malcolm - 3.1.1-27 -- add pyfuntop.stp example (source 7) -- convert usage of $$RPM_BUILD_ROOT to %%{buildroot} throughout, for -consistency with python.spec - -* Mon Feb 15 2010 Thomas Spura - 3.1.1-26 -- rebuild for new package of redhat-rpm-config (rhbz:564527) -- use 'install -p' when running 'make install' - -* Fri Feb 12 2010 David Malcolm - 3.1.1-25 -- split configure options into multiple lines for easy of editing -- add systemtap static markers (wcohen, mjw, dmalcolm; patch 8), a systemtap -tapset defining "python.function.entry" and "python.function.return" to make -the markers easy to use (dmalcolm; source 5), and an example of using the -tapset to the docs (dmalcolm; source 6) (rhbz:545179) - -* Mon Feb 8 2010 David Malcolm - 3.1.1-24 -- 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 - 3.1.1-23 -- add gdb hooks for easier debugging (Source 4) - -* Thu Jan 28 2010 David Malcolm - 3.1.1-22 -- update python-3.1.1-config.patch to remove downstream customization of build -of pyexpat and elementtree modules -- add patch adapted from upstream (patch 7) to add support for building against -system expat; add --with-system-expat to "configure" invocation -- remove embedded copies of expat and zlib from source tree during "prep" - -* Mon Jan 25 2010 David Malcolm - 3.1.1-21 -- introduce %%{dynload_dir} macro -- 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 -- introduce a macros.pybytecompile source file, to help with packaging python3 -modules (Source3; written by Toshio) -- rename "2to3-3" to "python3-2to3" to better reflect python 3 module packaging -plans - -* Mon Jan 25 2010 David Malcolm - 3.1.1-20 -- change python-3.1.1-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 - 3.1.1-19 -- add %%py3dir macro to macros.python3 (to be used during unified python 2/3 -builds for setting up the python3 copy of the source tree) - -* Wed Jan 20 2010 David Malcolm - 3.1.1-18 -- move lib2to3 from -tools subpackage to main package (bug 556667) - -* Sun Jan 17 2010 David Malcolm - 3.1.1-17 -- patch Makefile.pre.in to avoid building static library (patch 6, bug 556092) - -* Fri Jan 15 2010 David Malcolm - 3.1.1-16 -- 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 - -* Fri Jan 15 2010 David Malcolm - 3.1.1-15 -- fix the URLs output by pydoc so they point at python.org's 3.1 build of the -docs, rather than the 2.6 build - -* Wed Jan 13 2010 David Malcolm - 3.1.1-14 -- replace references to /usr with %%{_prefix}; replace references to -/usr/include with %%{_includedir} (Toshio) - -* Mon Jan 11 2010 David Malcolm - 3.1.1-13 -- fix permission on find-provides-without-python-sonames.sh from 775 to 755 - -* Mon Jan 11 2010 David Malcolm - 3.1.1-12 -- remove build-time requirements on tix and tk, since we already have -build-time requirements on the -devel subpackages for each of these (Thomas -Spura) -- replace usage of %%define with %%global (Thomas Spura) -- remove forcing of CC=gcc as this old workaround for bug 109268 appears to -longer be necessary -- move various test files from the "tools"/"tkinter" subpackages to the "test" -subpackage - -* Thu Jan 7 2010 David Malcolm - 3.1.1-11 -- add %%check section (thanks to Thomas Spura) -- update patch 4 to use correct shebang line -- get rid of stray patch file from buildroot - -* Tue Nov 17 2009 Andrew McNabb - 3.1.1-10 -- switched a few instances of "find |xargs" to "find -exec" for consistency. -- made the description of __os_install_post more accurate. - -* Wed Nov 4 2009 David Malcolm - 3.1.1-9 -- add macros.python3 to the -devel subpackage, containing common macros for use -when packaging python3 modules - -* Tue Nov 3 2009 David Malcolm - 3.1.1-8 -- add a provides of "python(abi)" (see bug 532118) -- fix issues identified by a.badger in package review (bug 526126, comment 39): - - use "3" thoughout metadata, rather than "3.*" - - remove conditional around "pkg-config openssl" - - use standard cleanup of RPM_BUILD_ROOT - - replace hardcoded references to /usr with _prefix macro - - stop removing egg-info files - - use /usr/bin/python3.1 rather than /use/bin/env python3.1 when fixing -up shebang lines - - stop attempting to remove no-longer-present .cvsignore files - - move the post/postun sections above the "files" sections - -* Thu Oct 29 2009 David Malcolm - 3.1.1-7 -- remove commented-away patch 51 (python-2.6-distutils_rpm.patch): the -O1 -flag is used by default in the upstream code -- "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) - -* Tue Oct 27 2009 David Malcolm - 3.1.1-6 -- reword description, based on suggestion by amcnabb -- fix the test_email and test_imp selftests (patch 3 and patch 4 respectively) -- fix the test_tk and test_ttk_* selftests (patch 5) -- fix up the specfile's handling of shebang/perms to avoid corrupting -test_httpservers.py (sed command suggested by amcnabb) - -* Thu Oct 22 2009 David Malcolm - 3.1.1-5 -- fixup importlib/_bootstrap.py so that it correctly handles being unable to -open .pyc files for writing (patch 2, upstream issue 7187) -- actually apply the rpath patch (patch 1) - -* Thu Oct 22 2009 David Malcolm - 3.1.1-4 -- update patch0's setup of the crypt module to link it against libcrypt -- update patch0 to comment "datetimemodule" back out, so that it is built -using setup.py (see Setup, option 3), thus linking it statically against -timemodule.c and thus avoiding a run-time "undefined symbol: -_PyTime_DoubleToTimet" failure on "import datetime" - -* Wed Oct 21 2009 David Malcolm - 3.1.1-3 -- remove executable flag from various files that shouldn't have it -- fix end-of-line encodings -- fix a character encoding - -* Tue Oct 20 2009 David Malcolm - 3.1.1-2 -- disable invocation of brp-python-bytecompile in postprocessing, since -it would be with the wrong version of python (adapted from ivazquez' -python3000 specfile) -- use a custom implementation of __find_provides in order to filter out bogus -provides lines for the various .so modules -- fixup distutils/unixccompiler.py to remove standard library path from rpath -(patch 1, was Patch0 in ivazquez' python3000 specfile) -- split out libraries into a -libs subpackage -- update summaries and descriptions, basing content on ivazquez' specfile -- fixup executable permissions on .py, .xpm and .xbm files, based on work in -ivazquez's specfile -- get rid of DOS batch files -- fixup permissions for shared libraries from non-standard 555 to standard 755 -- move /usr/bin/python*-config to the -devel subpackage -- mark various directories as being documentation - -* Thu Sep 24 2009 Andrew McNabb 3.1.1-1 -- Initial package for Python 3. - diff --git a/python-gdb.py b/python-gdb.py deleted file mode 100644 index dd6d462..0000000 --- a/python-gdb.py +++ /dev/null @@ -1,1380 +0,0 @@ -#!/usr/bin/python -''' -From gdb 7 onwards, gdb's build can be configured --with-python, allowing gdb -to be extended with Python code e.g. for library-specific data visualizations, -such as for the C++ STL types. Documentation on this API can be seen at: -http://sourceware.org/gdb/current/onlinedocs/gdb/Python-API.html - - -This python module deals with the case when the process being debugged (the -"inferior process" in gdb parlance) is itself python, or more specifically, -linked against libpython. In this situation, almost every item of data is a -(PyObject*), and having the debugger merely print their addresses is not very -enlightening. - -This module embeds knowledge about the implementation details of libpython so -that we can emit useful visualizations e.g. a string, a list, a dict, a frame -giving file/line information and the state of local variables - -In particular, given a gdb.Value corresponding to a PyObject* in the inferior -process, we can generate a "proxy value" within the gdb process. For example, -given a PyObject* in the inferior process that is in fact a PyListObject* -holding three PyObject* that turn out to be PyBytesObject* instances, we can -generate a proxy value within the gdb process that is a list of bytes -instances: - [b"foo", b"bar", b"baz"] - -Doing so can be expensive for complicated graphs of objects, and could take -some time, so we also have a "write_repr" method that writes a representation -of the data to a file-like object. This allows us to stop the traversal by -having the file-like object raise an exception if it gets too much data. - -With both "proxyval" and "write_repr" we keep track of the set of all addresses -visited so far in the traversal, to avoid infinite recursion due to cycles in -the graph of object references. - -We try to defer gdb.lookup_type() invocations for python types until as late as -possible: for a dynamically linked python binary, when the process starts in -the debugger, the libpython.so hasn't been dynamically loaded yet, so none of -the type names are known to the debugger - -The module also extends gdb with some python-specific commands. -''' -from __future__ import with_statement -import gdb - -# Look up the gdb.Type for some standard types: -_type_char_ptr = gdb.lookup_type('char').pointer() # char* -_type_unsigned_char_ptr = gdb.lookup_type('unsigned char').pointer() # unsigned char* -_type_void_ptr = gdb.lookup_type('void').pointer() # void* -_type_size_t = gdb.lookup_type('size_t') - -SIZEOF_VOID_P = _type_void_ptr.sizeof - - -Py_TPFLAGS_HEAPTYPE = (1L << 9) - -Py_TPFLAGS_INT_SUBCLASS = (1L << 23) -Py_TPFLAGS_LONG_SUBCLASS = (1L << 24) -Py_TPFLAGS_LIST_SUBCLASS = (1L << 25) -Py_TPFLAGS_TUPLE_SUBCLASS = (1L << 26) -Py_TPFLAGS_BYTES_SUBCLASS = (1L << 27) -Py_TPFLAGS_UNICODE_SUBCLASS = (1L << 28) -Py_TPFLAGS_DICT_SUBCLASS = (1L << 29) -Py_TPFLAGS_BASE_EXC_SUBCLASS = (1L << 30) -Py_TPFLAGS_TYPE_SUBCLASS = (1L << 31) - - -MAX_OUTPUT_LEN=1024 - -class NullPyObjectPtr(RuntimeError): - pass - - -def safety_limit(val): - # Given a integer value from the process being debugged, limit it to some - # safety threshold so that arbitrary breakage within said process doesn't - # break the gdb process too much (e.g. sizes of iterations, sizes of lists) - return min(val, 1000) - - -def safe_range(val): - # As per range, but don't trust the value too much: cap it to a safety - # threshold in case the data was corrupted - return xrange(safety_limit(val)) - - -class StringTruncated(RuntimeError): - pass - -class TruncatedStringIO(object): - '''Similar to cStringIO, but can truncate the output by raising a - StringTruncated exception''' - def __init__(self, maxlen=None): - self._val = '' - self.maxlen = maxlen - - def write(self, data): - if self.maxlen: - if len(data) + len(self._val) > self.maxlen: - # Truncation: - self._val += data[0:self.maxlen - len(self._val)] - raise StringTruncated() - - self._val += data - - def getvalue(self): - return self._val - -class PyObjectPtr(object): - """ - Class wrapping a gdb.Value that's a either a (PyObject*) within the - inferior process, or some subclass pointer e.g. (PyBytesObject*) - - There will be a subclass for every refined PyObject type that we care - about. - - Note that at every stage the underlying pointer could be NULL, point - to corrupt data, etc; this is the debugger, after all. - """ - _typename = 'PyObject' - - def __init__(self, gdbval, cast_to=None): - if cast_to: - self._gdbval = gdbval.cast(cast_to) - else: - self._gdbval = gdbval - - def field(self, name): - ''' - Get the gdb.Value for the given field within the PyObject, coping with - some python 2 versus python 3 differences. - - Various libpython types are defined using the "PyObject_HEAD" and - "PyObject_VAR_HEAD" macros. - - In Python 2, this these are defined so that "ob_type" and (for a var - object) "ob_size" are fields of the type in question. - - In Python 3, this is defined as an embedded PyVarObject type thus: - PyVarObject ob_base; - so that the "ob_size" field is located insize the "ob_base" field, and - the "ob_type" is most easily accessed by casting back to a (PyObject*). - ''' - if self.is_null(): - raise NullPyObjectPtr(self) - - if name == 'ob_type': - pyo_ptr = self._gdbval.cast(PyObjectPtr.get_gdb_type()) - return pyo_ptr.dereference()[name] - - if name == 'ob_size': - pyo_ptr = self._gdbval.cast(PyVarObjectPtr.get_gdb_type()) - return pyo_ptr.dereference()[name] - - # General case: look it up inside the object: - return self._gdbval.dereference()[name] - - def pyop_field(self, name): - ''' - Get a PyObjectPtr for the given PyObject* field within this PyObject, - coping with some python 2 versus python 3 differences. - ''' - return PyObjectPtr.from_pyobject_ptr(self.field(name)) - - def write_field_repr(self, name, out, visited): - ''' - Extract the PyObject* field named "name", and write its representation - to file-like object "out" - ''' - field_obj = self.pyop_field(name) - field_obj.write_repr(out, visited) - - def get_truncated_repr(self, maxlen): - ''' - Get a repr-like string for the data, but truncate it at "maxlen" bytes - (ending the object graph traversal as soon as you do) - ''' - out = TruncatedStringIO(maxlen) - try: - self.write_repr(out, set()) - except StringTruncated: - # Truncation occurred: - return out.getvalue() + '...(truncated)' - - # No truncation occurred: - return out.getvalue() - - def type(self): - return PyTypeObjectPtr(self.field('ob_type')) - - def is_null(self): - return 0 == long(self._gdbval) - - def is_optimized_out(self): - ''' - Is the value of the underlying PyObject* visible to the debugger? - - This can vary with the precise version of the compiler used to build - Python, and the precise version of gdb. - - See e.g. https://bugzilla.redhat.com/show_bug.cgi?id=556975 with - PyEval_EvalFrameEx's "f" - ''' - return self._gdbval.is_optimized_out - - def safe_tp_name(self): - try: - return self.type().field('tp_name').string() - except NullPyObjectPtr: - # NULL tp_name? - return 'unknown' - except RuntimeError: - # Can't even read the object at all? - return 'unknown' - - def proxyval(self, visited): - ''' - Scrape a value from the inferior process, and try to represent it - within the gdb process, whilst (hopefully) avoiding crashes when - the remote data is corrupt. - - Derived classes will override this. - - For example, a PyIntObject* with ob_ival 42 in the inferior process - should result in an int(42) in this process. - - visited: a set of all gdb.Value pyobject pointers already visited - whilst generating this value (to guard against infinite recursion when - 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)) - - def write_repr(self, out, visited): - ''' - Write a string representation of the value scraped from the inferior - process to "out", a file-like object. - ''' - # Default implementation: generate a proxy value and write its repr - # However, this could involve a lot of work for complicated objects, - # so for derived classes we specialize this - return out.write(repr(self.proxyval(visited))) - - @classmethod - def subclass_from_type(cls, t): - ''' - Given a PyTypeObjectPtr instance wrapping a gdb.Value that's a - (PyTypeObject*), determine the corresponding subclass of PyObjectPtr - to use - - Ideally, we would look up the symbols for the global types, but that - isn't working yet: - (gdb) python print gdb.lookup_symbol('PyList_Type')[0].value - Traceback (most recent call last): - File "", line 1, in - NotImplementedError: Symbol type not yet supported in Python scripts. - Error while executing Python code. - - For now, we use tp_flags, after doing some string comparisons on the - tp_name for some special-cases that don't seem to be visible through - flags - ''' - try: - tp_name = t.field('tp_name').string() - tp_flags = int(t.field('tp_flags')) - except RuntimeError: - # Handle any kind of error e.g. NULL ptrs by simply using the base - # class - return cls - - #print 'tp_flags = 0x%08x' % tp_flags - #print 'tp_name = %r' % tp_name - - name_map = {'bool': PyBoolObjectPtr, - 'classobj': PyClassObjectPtr, - 'instance': PyInstanceObjectPtr, - 'NoneType': PyNoneStructPtr, - 'frame': PyFrameObjectPtr, - 'set' : PySetObjectPtr, - 'frozenset' : PySetObjectPtr, - 'builtin_function_or_method' : PyCFunctionObjectPtr, - } - if tp_name in name_map: - return name_map[tp_name] - - if tp_flags & Py_TPFLAGS_HEAPTYPE: - return HeapTypeObjectPtr - - if tp_flags & Py_TPFLAGS_INT_SUBCLASS: - return PyIntObjectPtr - if tp_flags & Py_TPFLAGS_LONG_SUBCLASS: - return PyLongObjectPtr - if tp_flags & Py_TPFLAGS_LIST_SUBCLASS: - return PyListObjectPtr - if tp_flags & Py_TPFLAGS_TUPLE_SUBCLASS: - return PyTupleObjectPtr - if tp_flags & Py_TPFLAGS_BYTES_SUBCLASS: - return PyBytesObjectPtr - if tp_flags & Py_TPFLAGS_UNICODE_SUBCLASS: - return PyUnicodeObjectPtr - if tp_flags & Py_TPFLAGS_DICT_SUBCLASS: - return PyDictObjectPtr - if tp_flags & Py_TPFLAGS_BASE_EXC_SUBCLASS: - return PyBaseExceptionObjectPtr - #if tp_flags & Py_TPFLAGS_TYPE_SUBCLASS: - # return PyTypeObjectPtr - - # Use the base class: - return cls - - @classmethod - def from_pyobject_ptr(cls, gdbval): - ''' - Try to locate the appropriate derived class dynamically, and cast - the pointer accordingly. - ''' - try: - p = PyObjectPtr(gdbval) - cls = cls.subclass_from_type(p.type()) - return cls(gdbval, cast_to=cls.get_gdb_type()) - except RuntimeError: - # Handle any kind of error e.g. NULL ptrs by simply using the base - # class - pass - return cls(gdbval) - - @classmethod - def get_gdb_type(cls): - return gdb.lookup_type(cls._typename).pointer() - - def as_address(self): - return long(self._gdbval) - -class PyVarObjectPtr(PyObjectPtr): - _typename = 'PyVarObject' - -class ProxyAlreadyVisited(object): - ''' - Placeholder proxy to use when protecting against infinite recursion due to - loops in the object graph. - - Analogous to the values emitted by the users of Py_ReprEnter and Py_ReprLeave - ''' - def __init__(self, rep): - self._rep = rep - - def __repr__(self): - return self._rep - - -def _write_instance_repr(out, visited, name, pyop_attrdict, address): - '''Shared code for use by old-style and new-style classes: - write a representation to file-like object "out"''' - out.write('<') - out.write(name) - - # Write dictionary of instance attributes: - if isinstance(pyop_attrdict, PyDictObjectPtr): - out.write('(') - first = True - for pyop_arg, pyop_val in pyop_attrdict.iteritems(): - if not first: - out.write(', ') - first = False - out.write(pyop_arg.proxyval(visited)) - out.write('=') - pyop_val.write_repr(out, visited) - out.write(')') - out.write(' at remote 0x%x>' % address) - - -class InstanceProxy(object): - - def __init__(self, cl_name, attrdict, address): - self.cl_name = cl_name - self.attrdict = attrdict - self.address = address - - def __repr__(self): - if isinstance(self.attrdict, dict): - kwargs = ', '.join(["%s=%r" % (arg, val) - for arg, val in self.attrdict.iteritems()]) - return '<%s(%s) at remote 0x%x>' % (self.cl_name, - kwargs, self.address) - else: - return '<%s at remote 0x%x>' % (self.cl_name, - self.address) - -def _PyObject_VAR_SIZE(typeobj, nitems): - return ( ( typeobj.field('tp_basicsize') + - nitems * typeobj.field('tp_itemsize') + - (SIZEOF_VOID_P - 1) - ) & ~(SIZEOF_VOID_P - 1) - ).cast(_type_size_t) - -class HeapTypeObjectPtr(PyObjectPtr): - _typename = 'PyObject' - - def get_attr_dict(self): - ''' - Get the PyDictObject ptr representing the attribute dictionary - (or None if there's a problem) - ''' - try: - typeobj = self.type() - dictoffset = int_from_int(typeobj.field('tp_dictoffset')) - if dictoffset != 0: - if dictoffset < 0: - type_PyVarObject_ptr = gdb.lookup_type('PyVarObject').pointer() - tsize = int_from_int(self._gdbval.cast(type_PyVarObject_ptr)['ob_size']) - if tsize < 0: - tsize = -tsize - size = _PyObject_VAR_SIZE(typeobj, tsize) - dictoffset += size - assert dictoffset > 0 - assert dictoffset % SIZEOF_VOID_P == 0 - - dictptr = self._gdbval.cast(_type_char_ptr) + dictoffset - PyObjectPtrPtr = PyObjectPtr.get_gdb_type().pointer() - dictptr = dictptr.cast(PyObjectPtrPtr) - return PyObjectPtr.from_pyobject_ptr(dictptr.dereference()) - except RuntimeError: - # Corrupt data somewhere; fail safe - pass - - # Not found, or some kind of error: - return None - - def proxyval(self, visited): - ''' - Support for new-style classes. - - Currently we just locate the dictionary using a transliteration to - python of _PyObject_GetDictPtr, ignoring descriptors - ''' - # Guard against infinite loops: - if self.as_address() in visited: - return ProxyAlreadyVisited('<...>') - visited.add(self.as_address()) - - pyop_attr_dict = self.get_attr_dict() - if pyop_attr_dict: - attr_dict = pyop_attr_dict.proxyval(visited) - else: - attr_dict = {} - tp_name = self.safe_tp_name() - - # New-style class: - return InstanceProxy(tp_name, attr_dict, long(self._gdbval)) - - def write_repr(self, out, visited): - # Guard against infinite loops: - if self.as_address() in visited: - out.write('<...>') - return - visited.add(self.as_address()) - - pyop_attrdict = self.get_attr_dict() - _write_instance_repr(out, visited, - self.safe_tp_name(), pyop_attrdict, self.as_address()) - -class ProxyException(Exception): - def __init__(self, tp_name, args): - self.tp_name = tp_name - self.args = args - - def __repr__(self): - return '%s%r' % (self.tp_name, self.args) - -class PyBaseExceptionObjectPtr(PyObjectPtr): - """ - Class wrapping a gdb.Value that's a PyBaseExceptionObject* i.e. an exception - within the process being debugged. - """ - _typename = 'PyBaseExceptionObject' - - def proxyval(self, visited): - # Guard against infinite loops: - if self.as_address() in visited: - return ProxyAlreadyVisited('(...)') - visited.add(self.as_address()) - arg_proxy = self.pyop_field('args').proxyval(visited) - return ProxyException(self.safe_tp_name(), - arg_proxy) - - def write_repr(self, out, visited): - # Guard against infinite loops: - if self.as_address() in visited: - out.write('(...)') - return - visited.add(self.as_address()) - - out.write(self.safe_tp_name()) - self.write_field_repr('args', out, visited) - -class PyClassObjectPtr(PyObjectPtr): - """ - Class wrapping a gdb.Value that's a PyClassObject* i.e. a - instance within the process being debugged. - """ - _typename = 'PyClassObject' - - -class BuiltInFunctionProxy(object): - def __init__(self, ml_name): - self.ml_name = ml_name - - def __repr__(self): - return "" % self.ml_name - -class BuiltInMethodProxy(object): - def __init__(self, ml_name, pyop_m_self): - self.ml_name = ml_name - self.pyop_m_self = pyop_m_self - - def __repr__(self): - return ('' - % (self.ml_name, - self.pyop_m_self.safe_tp_name(), - self.pyop_m_self.as_address()) - ) - -class PyCFunctionObjectPtr(PyObjectPtr): - """ - Class wrapping a gdb.Value that's a PyCFunctionObject* - (see Include/methodobject.h and Objects/methodobject.c) - """ - _typename = 'PyCFunctionObject' - - def proxyval(self, visited): - m_ml = self.field('m_ml') # m_ml is a (PyMethodDef*) - ml_name = m_ml['ml_name'].string() - - pyop_m_self = self.pyop_field('m_self') - if pyop_m_self.is_null(): - return BuiltInFunctionProxy(ml_name) - else: - return BuiltInMethodProxy(ml_name, pyop_m_self) - - -class PyCodeObjectPtr(PyObjectPtr): - """ - Class wrapping a gdb.Value that's a PyCodeObject* i.e. a instance - within the process being debugged. - """ - _typename = 'PyCodeObject' - - def addr2line(self, addrq): - ''' - Get the line number for a given bytecode offset - - Analogous to PyCode_Addr2Line; translated from pseudocode in - Objects/lnotab_notes.txt - ''' - co_lnotab = self.pyop_field('co_lnotab').proxyval(set()) - - # Initialize lineno to co_firstlineno as per PyCode_Addr2Line - # not 0, as lnotab_notes.txt has it: - lineno = int_from_int(self.field('co_firstlineno')) - - addr = 0 - for addr_incr, line_incr in zip(co_lnotab[::2], co_lnotab[1::2]): - addr += ord(addr_incr) - if addr > addrq: - return lineno - lineno += ord(line_incr) - return lineno - - -class PyDictObjectPtr(PyObjectPtr): - """ - Class wrapping a gdb.Value that's a PyDictObject* i.e. a dict instance - within the process being debugged. - """ - _typename = 'PyDictObject' - - def iteritems(self): - ''' - Yields a sequence of (PyObjectPtr key, PyObjectPtr value) pairs, - analagous to dict.iteritems() - ''' - for i in safe_range(self.field('ma_mask') + 1): - ep = self.field('ma_table') + i - pyop_value = PyObjectPtr.from_pyobject_ptr(ep['me_value']) - if not pyop_value.is_null(): - pyop_key = PyObjectPtr.from_pyobject_ptr(ep['me_key']) - yield (pyop_key, pyop_value) - - def proxyval(self, visited): - # Guard against infinite loops: - if self.as_address() in visited: - return ProxyAlreadyVisited('{...}') - visited.add(self.as_address()) - - result = {} - for pyop_key, pyop_value in self.iteritems(): - proxy_key = pyop_key.proxyval(visited) - proxy_value = pyop_value.proxyval(visited) - result[proxy_key] = proxy_value - return result - - def write_repr(self, out, visited): - # Guard against infinite loops: - if self.as_address() in visited: - out.write('{...}') - return - visited.add(self.as_address()) - - out.write('{') - first = True - for pyop_key, pyop_value in self.iteritems(): - if not first: - out.write(', ') - first = False - pyop_key.write_repr(out, visited) - out.write(': ') - pyop_value.write_repr(out, visited) - out.write('}') - -class PyInstanceObjectPtr(PyObjectPtr): - _typename = 'PyInstanceObject' - - def proxyval(self, visited): - # Guard against infinite loops: - if self.as_address() in visited: - return ProxyAlreadyVisited('<...>') - visited.add(self.as_address()) - - # Get name of class: - in_class = self.pyop_field('in_class') - cl_name = in_class.pyop_field('cl_name').proxyval(visited) - - # Get dictionary of instance attributes: - in_dict = self.pyop_field('in_dict').proxyval(visited) - - # Old-style class: - return InstanceProxy(cl_name, in_dict, long(self._gdbval)) - - def write_repr(self, out, visited): - # Guard against infinite loops: - if self.as_address() in visited: - out.write('<...>') - return - visited.add(self.as_address()) - - # Old-style class: - - # Get name of class: - in_class = self.pyop_field('in_class') - cl_name = in_class.pyop_field('cl_name').proxyval(visited) - - # Get dictionary of instance attributes: - pyop_in_dict = self.pyop_field('in_dict') - - _write_instance_repr(out, visited, - cl_name, pyop_in_dict, self.as_address()) - -class PyListObjectPtr(PyObjectPtr): - _typename = 'PyListObject' - - def __getitem__(self, i): - # Get the gdb.Value for the (PyObject*) with the given index: - field_ob_item = self.field('ob_item') - return field_ob_item[i] - - def proxyval(self, visited): - # Guard against infinite loops: - if self.as_address() in visited: - return ProxyAlreadyVisited('[...]') - visited.add(self.as_address()) - - result = [PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited) - for i in safe_range(int_from_int(self.field('ob_size')))] - return result - - def write_repr(self, out, visited): - # Guard against infinite loops: - if self.as_address() in visited: - out.write('[...]') - return - visited.add(self.as_address()) - - out.write('[') - for i in safe_range(int_from_int(self.field('ob_size'))): - if i > 0: - out.write(', ') - element = PyObjectPtr.from_pyobject_ptr(self[i]) - element.write_repr(out, visited) - out.write(']') - -class PyLongObjectPtr(PyObjectPtr): - _typename = 'PyLongObject' - - def proxyval(self, visited): - ''' - Python's Include/longobjrep.h has this declaration: - struct _longobject { - PyObject_VAR_HEAD - digit ob_digit[1]; - }; - - with this description: - The absolute value of a number is equal to - SUM(for i=0 through abs(ob_size)-1) ob_digit[i] * 2**(SHIFT*i) - Negative numbers are represented with ob_size < 0; - zero is represented by ob_size == 0. - - where SHIFT can be either: - #define PyLong_SHIFT 30 - #define PyLong_SHIFT 15 - ''' - ob_size = long(self.field('ob_size')) - if ob_size == 0: - return 0L - - ob_digit = self.field('ob_digit') - - if gdb.lookup_type('digit').sizeof == 2: - SHIFT = 15L - else: - SHIFT = 30L - - digits = [long(ob_digit[i]) * 2**(SHIFT*i) - for i in safe_range(abs(ob_size))] - result = sum(digits) - if ob_size < 0: - result = -result - return result - -class PyBoolObjectPtr(PyLongObjectPtr): - """ - Class wrapping a gdb.Value that's a PyBoolObject* i.e. one of the two - instances (Py_True/Py_False) within the process being debugged. - """ - def proxyval(self, visited): - if PyLongObjectPtr.proxyval(self, visited): - return True - else: - return False - -class PyNoneStructPtr(PyObjectPtr): - """ - Class wrapping a gdb.Value that's a PyObject* pointing to the - singleton (we hope) _Py_NoneStruct with ob_type PyNone_Type - """ - _typename = 'PyObject' - - def proxyval(self, visited): - return None - - -class PyFrameObjectPtr(PyObjectPtr): - _typename = 'PyFrameObject' - - def __init__(self, gdbval, cast_to): - PyObjectPtr.__init__(self, gdbval, cast_to) - - if not self.is_optimized_out(): - self.co = PyCodeObjectPtr.from_pyobject_ptr(self.field('f_code')) - self.co_name = self.co.pyop_field('co_name') - self.co_filename = self.co.pyop_field('co_filename') - - self.f_lineno = int_from_int(self.field('f_lineno')) - self.f_lasti = int_from_int(self.field('f_lasti')) - self.co_nlocals = int_from_int(self.co.field('co_nlocals')) - self.co_varnames = PyTupleObjectPtr.from_pyobject_ptr(self.co.field('co_varnames')) - - def iter_locals(self): - ''' - Yield a sequence of (name,value) pairs of PyObjectPtr instances, for - the local variables of this frame - ''' - if self.is_optimized_out(): - return - - f_localsplus = self.field('f_localsplus') - for i in safe_range(self.co_nlocals): - pyop_value = PyObjectPtr.from_pyobject_ptr(f_localsplus[i]) - if not pyop_value.is_null(): - pyop_name = PyObjectPtr.from_pyobject_ptr(self.co_varnames[i]) - yield (pyop_name, pyop_value) - - def iter_globals(self): - ''' - Yield a sequence of (name,value) pairs of PyObjectPtr instances, for - the global variables of this frame - ''' - if self.is_optimized_out(): - return - - pyop_globals = self.pyop_field('f_globals') - return pyop_globals.iteritems() - - def iter_builtins(self): - ''' - Yield a sequence of (name,value) pairs of PyObjectPtr instances, for - the builtin variables - ''' - if self.is_optimized_out(): - return - - pyop_builtins = self.pyop_field('f_builtins') - return pyop_builtins.iteritems() - - def get_var_by_name(self, name): - ''' - Look for the named local variable, returning a (PyObjectPtr, scope) pair - where scope is a string 'local', 'global', 'builtin' - - If not found, return (None, None) - ''' - for pyop_name, pyop_value in self.iter_locals(): - if name == pyop_name.proxyval(set()): - return pyop_value, 'local' - for pyop_name, pyop_value in self.iter_globals(): - if name == pyop_name.proxyval(set()): - return pyop_value, 'global' - for pyop_name, pyop_value in self.iter_builtins(): - if name == pyop_name.proxyval(set()): - return pyop_value, 'builtin' - return None, None - - def filename(self): - '''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()) - - def current_line_num(self): - '''Get current line number as an integer (1-based) - - Translated from PyFrame_GetLineNumber and PyCode_Addr2Line - - See Objects/lnotab_notes.txt - ''' - if self.is_optimized_out(): - return None - f_trace = self.field('f_trace') - if long(f_trace) != 0: - # we have a non-NULL f_trace: - return self.f_lineno - else: - #try: - return self.co.addr2line(self.f_lasti) - #except ValueError: - # return self.f_lineno - - def current_line(self): - '''Get the text of the current source line as a string, with a trailing - newline character''' - if self.is_optimized_out(): - return '(frame information optimized out)' - with open(self.filename(), 'r') as f: - all_lines = f.readlines() - # Convert from 1-based current_line_num to 0-based list offset: - return all_lines[self.current_line_num()-1] - - def write_repr(self, out, visited): - if self.is_optimized_out(): - out.write('(frame information optimized out)') - return - out.write('Frame 0x%x, for file %s, line %i, in %s (' - % (self.as_address(), - self.co_filename.proxyval(visited), - self.current_line_num(), - self.co_name.proxyval(visited))) - first = True - for pyop_name, pyop_value in self.iter_locals(): - if not first: - out.write(', ') - first = False - - out.write(pyop_name.proxyval(visited)) - out.write('=') - pyop_value.write_repr(out, visited) - - out.write(')') - -class PySetObjectPtr(PyObjectPtr): - _typename = 'PySetObject' - - def proxyval(self, visited): - # Guard against infinite loops: - if self.as_address() in visited: - return ProxyAlreadyVisited('%s(...)' % self.safe_tp_name()) - visited.add(self.as_address()) - - members = [] - table = self.field('table') - for i in safe_range(self.field('mask')+1): - setentry = table[i] - key = setentry['key'] - if key != 0: - key_proxy = PyObjectPtr.from_pyobject_ptr(key).proxyval(visited) - if key_proxy != '': - members.append(key_proxy) - if self.safe_tp_name() == 'frozenset': - return frozenset(members) - else: - return set(members) - - def write_repr(self, out, visited): - out.write(self.safe_tp_name()) - - # Guard against infinite loops: - if self.as_address() in visited: - out.write('(...)') - return - visited.add(self.as_address()) - - out.write('([') - first = True - table = self.field('table') - for i in safe_range(self.field('mask')+1): - setentry = table[i] - key = setentry['key'] - if key != 0: - pyop_key = PyObjectPtr.from_pyobject_ptr(key) - key_proxy = pyop_key.proxyval(visited) # FIXME! - if key_proxy != '': - if not first: - out.write(', ') - first = False - pyop_key.write_repr(out, visited) - out.write('])') - - -class PyBytesObjectPtr(PyObjectPtr): - _typename = 'PyBytesObject' - - def __str__(self): - field_ob_size = self.field('ob_size') - field_ob_sval = self.field('ob_sval') - char_ptr = field_ob_sval.address.cast(_type_unsigned_char_ptr) - return ''.join([chr(char_ptr[i]) for i in safe_range(field_ob_size)]) - - def proxyval(self, visited): - return str(self) - -class PyTupleObjectPtr(PyObjectPtr): - _typename = 'PyTupleObject' - - def __getitem__(self, i): - # Get the gdb.Value for the (PyObject*) with the given index: - field_ob_item = self.field('ob_item') - return field_ob_item[i] - - def proxyval(self, visited): - # Guard against infinite loops: - if self.as_address() in visited: - return ProxyAlreadyVisited('(...)') - visited.add(self.as_address()) - - result = tuple([PyObjectPtr.from_pyobject_ptr(self[i]).proxyval(visited) - for i in safe_range(int_from_int(self.field('ob_size')))]) - return result - - def write_repr(self, out, visited): - # Guard against infinite loops: - if self.as_address() in visited: - out.write('(...)') - return - visited.add(self.as_address()) - - out.write('(') - for i in safe_range(int_from_int(self.field('ob_size'))): - if i > 0: - out.write(', ') - element = PyObjectPtr.from_pyobject_ptr(self[i]) - element.write_repr(out, visited) - if self.field('ob_size') == 1: - out.write(',)') - else: - out.write(')') - -class PyTypeObjectPtr(PyObjectPtr): - _typename = 'PyTypeObject' - - -class PyUnicodeObjectPtr(PyObjectPtr): - _typename = 'PyUnicodeObject' - - def proxyval(self, visited): - # From unicodeobject.h: - # Py_ssize_t length; /* Length of raw Unicode data in buffer */ - # Py_UNICODE *str; /* Raw Unicode buffer */ - field_length = long(self.field('length')) - field_str = self.field('str') - - # Gather a list of ints from the Py_UNICODE array; these are either - # UCS-2 or UCS-4 code points: - Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)] - - # Convert the int code points to unicode characters, and generate a - # local unicode instance: - result = u''.join([unichr(ucs) for ucs in Py_UNICODEs]) - return result - - -def int_from_int(gdbval): - return int(str(gdbval)) - - -def stringify(val): - # TODO: repr() puts everything on one line; pformat can be nicer, but - # can lead to v.long results; this function isolates the choice - if True: - return repr(val) - else: - from pprint import pformat - return pformat(val) - - -class PyObjectPtrPrinter: - "Prints a (PyObject*)" - - def __init__ (self, gdbval): - self.gdbval = gdbval - - def to_string (self): - pyop = PyObjectPtr.from_pyobject_ptr(self.gdbval) - if True: - return pyop.get_truncated_repr(MAX_OUTPUT_LEN) - else: - # Generate full proxy value then stringify it. - # Doing so could be expensive - proxyval = pyop.proxyval(set()) - return stringify(proxyval) - -def pretty_printer_lookup(gdbval): - type = gdbval.type.unqualified() - if type.code == gdb.TYPE_CODE_PTR: - type = type.target().unqualified() - t = str(type) - if t in ("PyObject", "PyFrameObject", "PyUnicodeObject"): - return PyObjectPtrPrinter(gdbval) - -""" -During development, I've been manually invoking the code in this way: -(gdb) python - -import sys -sys.path.append('/home/david/coding/python-gdb') -import libpython -end - -then reloading it after each edit like this: -(gdb) python reload(libpython) - -The following code should ensure that the prettyprinter is registered -if the code is autoloaded by gdb when visiting libpython.so, provided -that this python file is installed to the same path as the library (or its -.debug file) plus a "-gdb.py" suffix, e.g: - /usr/lib/libpython2.6.so.1.0-gdb.py - /usr/lib/debug/usr/lib/libpython2.6.so.1.0.debug-gdb.py -""" -def register (obj): - if obj == None: - obj = gdb - - # Wire up the pretty-printer - obj.pretty_printers.append(pretty_printer_lookup) - -register (gdb.current_objfile ()) - - -class Frame(object): - ''' - Wrapper for gdb.Frame, adding various methods - ''' - def __init__(self, gdbframe): - self._gdbframe = gdbframe - - def older(self): - older = self._gdbframe.older() - if older: - return Frame(older) - else: - return None - - def newer(self): - newer = self._gdbframe.newer() - if newer: - return Frame(newer) - else: - return None - - def select(self): - self._gdbframe.select() - - def get_index(self): - '''Calculate index of frame, starting at 0 for the newest frame within - this thread''' - index = 0 - # Go down until you reach the newest frame: - iter_frame = self - while iter_frame.newer(): - index += 1 - iter_frame = iter_frame.newer() - return index - - def is_evalframeex(self): - 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 get_pyop(self): - try: - f = self._gdbframe.read_var('f') - return PyFrameObjectPtr.from_pyobject_ptr(f) - except ValueError: - return None - - @classmethod - def get_selected_frame(cls): - _gdbframe = gdb.selected_frame() - if _gdbframe: - return Frame(_gdbframe) - return None - - @classmethod - def get_selected_python_frame(cls): - '''Try to obtain the Frame for the python code in the selected frame, - or None''' - frame = cls.get_selected_frame() - - while frame: - if frame.is_evalframeex(): - return frame - frame = frame.older() - - # Not found: - return None - - def print_summary(self): - if self.is_evalframeex(): - pyop = self.get_pyop() - if pyop: - sys.stdout.write('#%i %s\n' % (self.get_index(), pyop.get_truncated_repr(MAX_OUTPUT_LEN))) - sys.stdout.write(pyop.current_line()) - else: - sys.stdout.write('#%i (unable to read python frame information)\n' % self.get_index()) - else: - sys.stdout.write('#%i\n' % self.get_index()) - -class PyList(gdb.Command): - '''List the current Python source code, if any - - Use - py-list START - to list at a different line number within the python source. - - Use - py-list START, END - to list a specific range of lines within the python source. - ''' - - def __init__(self): - gdb.Command.__init__ (self, - "py-list", - gdb.COMMAND_FILES, - gdb.COMPLETE_NONE) - - - def invoke(self, args, from_tty): - import re - - start = None - end = None - - m = re.match(r'\s*(\d+)\s*', args) - if m: - start = int(m.group(0)) - end = start + 10 - - m = re.match(r'\s*(\d+)\s*,\s*(\d+)\s*', args) - if m: - start, end = map(int, m.groups()) - - frame = Frame.get_selected_python_frame() - if not frame: - print 'Unable to locate python frame' - return - - pyop = frame.get_pyop() - if not pyop: - print 'Unable to read information on python frame' - return - - filename = pyop.filename() - lineno = pyop.current_line_num() - - if start is None: - start = lineno - 5 - end = lineno + 5 - - if start<1: - start = 1 - - with open(filename, 'r') as f: - all_lines = f.readlines() - # start and end are 1-based, all_lines is 0-based; - # so [start-1:end] as a python slice gives us [start, end] as a - # closed interval - for i, line in enumerate(all_lines[start-1:end]): - linestr = str(i+start) - # Highlight current line: - if i + start == lineno: - linestr = '>' + linestr - sys.stdout.write('%4s %s' % (linestr, line)) - - -# ...and register the command: -PyList() - -def move_in_stack(move_up): - '''Move up or down the stack (for the py-up/py-down command)''' - frame = Frame.get_selected_python_frame() - while frame: - if move_up: - iter_frame = frame.older() - else: - iter_frame = frame.newer() - - if not iter_frame: - break - - if iter_frame.is_evalframeex(): - # Result: - iter_frame.select() - iter_frame.print_summary() - return - - frame = iter_frame - - if move_up: - print 'Unable to find an older python frame' - else: - print 'Unable to find a newer python frame' - -class PyUp(gdb.Command): - 'Select and print the python stack frame that called this one (if any)' - def __init__(self): - gdb.Command.__init__ (self, - "py-up", - gdb.COMMAND_STACK, - gdb.COMPLETE_NONE) - - - def invoke(self, args, from_tty): - move_in_stack(move_up=True) - -PyUp() - -class PyDown(gdb.Command): - 'Select and print the python stack frame called by this one (if any)' - def __init__(self): - gdb.Command.__init__ (self, - "py-down", - gdb.COMMAND_STACK, - gdb.COMPLETE_NONE) - - - def invoke(self, args, from_tty): - move_in_stack(move_up=False) - -PyDown() - -class PyBacktrace(gdb.Command): - 'Display the current python frame and all the frames within its call stack (if any)' - def __init__(self): - gdb.Command.__init__ (self, - "py-bt", - gdb.COMMAND_STACK, - gdb.COMPLETE_NONE) - - - def invoke(self, args, from_tty): - frame = Frame.get_selected_python_frame() - while frame: - if frame.is_evalframeex(): - frame.print_summary() - frame = frame.older() - -PyBacktrace() - -class PyPrint(gdb.Command): - 'Look up the given python variable name, and print it' - def __init__(self): - gdb.Command.__init__ (self, - "py-print", - gdb.COMMAND_DATA, - gdb.COMPLETE_NONE) - - - def invoke(self, args, from_tty): - name = str(args) - - frame = Frame.get_selected_python_frame() - if not frame: - print 'Unable to locate python frame' - return - - pyop_frame = frame.get_pyop() - if not pyop_frame: - print 'Unable to read information on python frame' - return - - pyop_var, scope = pyop_frame.get_var_by_name(name) - - if pyop_var: - print ('%s %r = %s' - % (scope, - name, - pyop_var.get_truncated_repr(MAX_OUTPUT_LEN))) - else: - print '%r not found' % name - -PyPrint() - -class PyLocals(gdb.Command): - 'Look up the given python variable name, and print it' - def __init__(self): - gdb.Command.__init__ (self, - "py-locals", - gdb.COMMAND_DATA, - gdb.COMPLETE_NONE) - - - def invoke(self, args, from_tty): - name = str(args) - - frame = Frame.get_selected_python_frame() - if not frame: - print 'Unable to locate python frame' - return - - pyop_frame = frame.get_pyop() - if not pyop_frame: - print 'Unable to read information on python frame' - return - - for pyop_name, pyop_value in pyop_frame.iter_locals(): - print ('%s = %s' - % (pyop_name.proxyval(set()), - pyop_value.get_truncated_repr(MAX_OUTPUT_LEN))) - -PyLocals() diff --git a/python3-powerppc-arch.patch b/python3-powerppc-arch.patch deleted file mode 100644 index 10f0201..0000000 --- a/python3-powerppc-arch.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff -up Python-3.5.0/configure.ac.than Python-3.5.0/configure.ac ---- Python-3.5.0/configure.ac.than 2015-11-13 11:51:32.039560172 -0500 -+++ Python-3.5.0/configure.ac 2015-11-13 11:52:11.670168157 -0500 -@@ -804,9 +804,9 @@ cat >> conftest.c <> conftest.c <