diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-09 17:34:45 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2019-12-09 17:35:06 +0900 |
commit | 914ebab220639c3ab7ddf0901ad3adad76348626 (patch) | |
tree | b9cfa1366c7193fa2c9d55315b0eb41c4ba10058 | |
parent | aa06267fd1871884bae60bd9f1af2dbbf4f4b29f (diff) | |
download | python-accepted/tizen_4.0_base.tar.gz python-accepted/tizen_4.0_base.tar.bz2 python-accepted/tizen_4.0_base.zip |
Bump to python 2.7.17submit/tizen_4.0_base/20191219.072806submit/tizen_4.0_base/20191217.021530submit/tizen_4.0_base/20191209.231008accepted/tizen/4.0/base/20191223.013429tizen_4.0_baseaccepted/tizen_4.0_base
Change-Id: I893f9018e0c18b5843c6a17d1b4aab3b18e1eb61
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
44 files changed, 581 insertions, 534 deletions
diff --git a/Doc/library/xmlrpclib.rst b/Doc/library/xmlrpclib.rst index 27777d9..e818c3d 100644 --- a/Doc/library/xmlrpclib.rst +++ b/Doc/library/xmlrpclib.rst @@ -139,15 +139,9 @@ between conformable Python objects and XML on the wire. *__dict__* attribute and don't have a base class that is marshalled in a special way. -.. data:: MAX_GZIP_DECODE + .. versionchanged:: 2.7.9 + Added the *context* argument. - The module constant specifies the amount of bytes that are decompressed by - :func:`gzip_decode`. The default value is *20 MB*. A value of *-1* disables - the protection. - - .. versionadded:: 2.7.4 - The constant was added to strengthen the module against gzip bomb - attacks. .. seealso:: diff --git a/Include/pythonrun.h b/Include/pythonrun.h index a3d2ed8..f0f4e38 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -108,8 +108,6 @@ PyAPI_FUNC(char *) Py_GetPath(void); /* In their own files */ PyAPI_FUNC(const char *) Py_GetVersion(void); PyAPI_FUNC(const char *) Py_GetPlatform(void); -PyAPI_FUNC(const char *) Py_GetArch(void); -PyAPI_FUNC(const char *) Py_GetLib(void); PyAPI_FUNC(const char *) Py_GetCopyright(void); PyAPI_FUNC(const char *) Py_GetCompiler(void); PyAPI_FUNC(const char *) Py_GetBuildInfo(void); diff --git a/Lib/bsddb/test/test_all.py b/Lib/bsddb/test/test_all.py index 57e96bc..529dfad 100644 --- a/Lib/bsddb/test/test_all.py +++ b/Lib/bsddb/test/test_all.py @@ -74,9 +74,8 @@ if sys.version_info[0] >= 3 : key = key.decode(charset) return (key, value.decode(charset)) - def __next__(self, flags=0, dlen=-1, doff=-1) : - v = getattr(self._dbcursor, "next")(flags=flags, dlen=dlen, - doff=doff) + def __next__(self) : + v = getattr(self._dbcursor, "next")() return self._fix(v) next = __next__ @@ -129,8 +128,8 @@ if sys.version_info[0] >= 3 : v = self._dbcursor.current(flags=flags, dlen=dlen, doff=doff) return self._fix(v) - def first(self, flags=0, dlen=-1, doff=-1) : - v = self._dbcursor.first(flags=flags, dlen=dlen, doff=doff) + def first(self) : + v = self._dbcursor.first() return self._fix(v) def pget(self, key=None, data=None, flags=0) : @@ -490,11 +489,7 @@ def print_versions(): print 'py module: %s' % getattr(bsddb, "__file"+suffix) print 'extension module: %s' % getattr(bsddb, "__file"+suffix) - print 'Test working dir: %s' % get_test_path_prefix() - import platform - print 'python version: %s %s' % \ - (sys.version.replace("\r", "").replace("\n", ""), \ - platform.architecture()[0]) + print 'python version: %s' % sys.version print 'My pid: %s' % os.getpid() print '-=' * 38 diff --git a/Lib/bsddb/test/test_misc.py b/Lib/bsddb/test/test_misc.py index 20872e1..e2ff2af 100644 --- a/Lib/bsddb/test/test_misc.py +++ b/Lib/bsddb/test/test_misc.py @@ -46,9 +46,8 @@ class MiscTestCase(unittest.TestCase): d[repr(i)] = repr(100*i) db.close() db = hashopen(self.filename) - rp = repr(sorted(db.items())) - rd = repr(sorted(d.items())) - self.assertEqual(rp, rd) + rp = repr(db) + self.assertEqual(rp, repr(d)) db.close() # http://sourceforge.net/tracker/index.php?func=detail&aid=1708868&group_id=13900&atid=313900 diff --git a/Lib/bsddb/test/test_replication.py b/Lib/bsddb/test/test_replication.py index 0ee3112..536d25d 100644 --- a/Lib/bsddb/test/test_replication.py +++ b/Lib/bsddb/test/test_replication.py @@ -165,10 +165,21 @@ class DBReplicationManager(DBReplication) : # is not generated if the master has no new transactions. # This is solved in BDB 4.6 (#15542). import time - timeout = time.time()+10 + timeout = time.time()+60 while (time.time()<timeout) and not (self.confirmed_master and self.client_startupdone) : time.sleep(0.02) - self.assertTrue(time.time()<timeout) + # self.client_startupdone does not always get set to True within + # the timeout. On windows this may be a deep issue, on other + # platforms it is likely just a timing issue, especially on slow + # virthost buildbots (see issue 3892 for more). Even though + # the timeout triggers, the rest of this test method usually passes + # (but not all of it always, see below). So we just note the + # timeout on stderr and keep soldering on. + if time.time()>timeout: + import sys + print >> sys.stderr, ("XXX: timeout happened before" + "startup was confirmed - see issue 3892") + startup_timeout = True d = self.dbenvMaster.repmgr_site_list() self.assertEqual(len(d), 1) @@ -226,7 +237,15 @@ class DBReplicationManager(DBReplication) : txn.commit() if v is None : time.sleep(0.02) - self.assertTrue(time.time()<timeout) + # If startup did not happen before the timeout above, then this test + # sometimes fails. This happens randomly, which causes buildbot + # instability, but all the other bsddb tests pass. Since bsddb3 in the + # stdlib is currently not getting active maintenance, and is gone in + # py3k, we just skip the end of the test in that case. + if time.time()>=timeout and startup_timeout: + self.skipTest("replication test skipped due to random failure, " + "see issue 3892") + self.assertLess(time.time(), timeout) self.assertEqual("123", v) txn=self.dbenvMaster.txn_begin() @@ -356,7 +375,7 @@ class DBBaseReplication(DBReplication) : # is not generated if the master has no new transactions. # This is solved in BDB 4.6 (#15542). import time - timeout = time.time()+10 + timeout = time.time()+60 while (time.time()<timeout) and not (self.confirmed_master and self.client_startupdone) : time.sleep(0.02) diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py index 0423e9f..b9f1c6c 100644 --- a/Lib/distutils/command/install.py +++ b/Lib/distutils/command/install.py @@ -22,8 +22,6 @@ from site import USER_BASE from site import USER_SITE -libname = sys.lib - if sys.version < "2.2": WINDOWS_SCHEME = { 'purelib': '$base', @@ -44,7 +42,7 @@ else: INSTALL_SCHEMES = { 'unix_prefix': { 'purelib': '$base/lib/python$py_version_short/site-packages', - 'platlib': '$platbase/'+libname+'/python$py_version_short/site-packages', + 'platlib': '$platbase/lib/python$py_version_short/site-packages', 'headers': '$base/include/python$py_version_short/$dist_name', 'scripts': '$base/bin', 'data' : '$base', @@ -156,8 +154,6 @@ class install (Command): ('record=', None, "filename in which to record list of installed files"), - ('record-rpm=', None, - "filename in which to record list of installed files and directories suitable as filelist for rpm"), ] boolean_options = ['compile', 'force', 'skip-build', 'user'] @@ -233,7 +229,6 @@ class install (Command): #self.install_info = None self.record = None - self.record_rpm = None # -- Option finalizing methods ------------------------------------- @@ -583,61 +578,12 @@ class install (Command): self.create_path_file() # write list of installed files, if requested. - if self.record or self.record_rpm: + if self.record: outputs = self.get_outputs() if self.root: # strip any package prefix root_len = len(self.root) for counter in xrange(len(outputs)): outputs[counter] = outputs[counter][root_len:] - if self.record_rpm: # add directories - self.record = self.record_rpm - dirs = [] - # directories to reject: - rejectdirs = [ - '/etc', - '/', - '', - self.prefix, - self.exec_prefix, - self.install_base, - self.install_platbase, - self.install_purelib, - self.install_platlib, - self.install_headers[:len(self.install_headers) - len(self.distribution.get_name()) - 1], - self.install_libbase, - self.install_scripts, - self.install_data, - os.path.join(self.install_data, 'share'), - os.path.join(self.install_data, 'share', 'doc'), - ] - # directories whose childs reject: - rejectdirs2 = [ - os.path.join(self.install_data, 'share', 'man'), - ] - # directories whose grandsons reject: - rejectdirs3 = [ - os.path.join(self.install_data, 'share', 'man'), - os.path.join(self.install_data, 'share', 'locale'), - ] - for counter in xrange(len(rejectdirs)): - if len(rejectdirs[counter]) > root_len: - rejectdirs[counter] = rejectdirs[counter][root_len:] - for counter in xrange(len(rejectdirs2)): - if len(rejectdirs2[counter]) > root_len: - rejectdirs2[counter] = rejectdirs2[counter][root_len:] - for counter in xrange(len(rejectdirs3)): - if len(rejectdirs3[counter]) > root_len: - rejectdirs3[counter] = rejectdirs3[counter][root_len:] - for counter in xrange(len(outputs)): - directory = os.path.dirname(outputs[counter]) - while directory not in rejectdirs and \ - os.path.dirname(directory) not in rejectdirs2 and \ - os.path.dirname(os.path.dirname(directory)) not in rejectdirs3: - dirname = '%dir ' + directory - if dirname not in dirs: - dirs.append(dirname) - directory = os.path.dirname(directory) - outputs += dirs self.execute(write_file, (self.record, outputs), "writing list of installed files to '%s'" % diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py index f4c3823..1a4b792 100644 --- a/Lib/distutils/sysconfig.py +++ b/Lib/distutils/sysconfig.py @@ -129,11 +129,8 @@ 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 = sys.lib - else: - lib = "lib" - libpython = os.path.join(prefix, lib, "python" + get_python_version()) + libpython = os.path.join(prefix, + "lib", "python" + get_python_version()) if standard_lib: return libpython else: diff --git a/Lib/distutils/tests/test_build_ext.py b/Lib/distutils/tests/test_build_ext.py index 4776c18..a6d2d2e 100644 --- a/Lib/distutils/tests/test_build_ext.py +++ b/Lib/distutils/tests/test_build_ext.py @@ -285,14 +285,20 @@ class BuildExtTestCase(support.TempdirManager, # issue #5977 : distutils build_ext.get_outputs # returns wrong result with --inplace - cmd.inplace = 1 - cmd.run() - so_file = cmd.get_outputs()[0] + other_tmp_dir = os.path.realpath(self.mkdtemp()) + old_wd = os.getcwd() + os.chdir(other_tmp_dir) + try: + cmd.inplace = 1 + cmd.run() + so_file = cmd.get_outputs()[0] + finally: + os.chdir(old_wd) self.assertTrue(os.path.exists(so_file)) self.assertEqual(os.path.splitext(so_file)[-1], sysconfig.get_config_var('SO')) so_dir = os.path.dirname(so_file) - self.assertEqual(so_dir, os.getcwd()) + self.assertEqual(so_dir, other_tmp_dir) cmd.compiler = None cmd.inplace = 0 cmd.run() diff --git a/Lib/gettext.py b/Lib/gettext.py index 95b41d2..765cc8c 100644 --- a/Lib/gettext.py +++ b/Lib/gettext.py @@ -387,9 +387,8 @@ class GNUTranslations(NullTranslations): self._charset = v.split('charset=')[1] elif k == 'plural-forms': v = v.split(';') - if len(v) > 1: - plural = v[1].split('plural=')[1] - self.plural = c2py(plural) + plural = v[1].split('plural=')[1] + self.plural = c2py(plural) # Note: we unconditionally convert both msgids and msgstrs to # Unicode using the character encoding specified in the charset # parameter of the Content-Type header. The gettext documentation diff --git a/Lib/httplib.py b/Lib/httplib.py index 05e4fb7..79532b9 100644 --- a/Lib/httplib.py +++ b/Lib/httplib.py @@ -216,6 +216,9 @@ MAXAMOUNT = 1048576 # maximal line length when calling readline(). _MAXLINE = 65536 +# maximum amount of headers accepted +_MAXHEADERS = 100 + # Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2) # # VCHAR = %x21-7E @@ -239,11 +242,25 @@ _MAXLINE = 65536 # # VCHAR defined in http://tools.ietf.org/html/rfc5234#appendix-B.1 -# the patterns for both name and value are more leniant than RFC +# the patterns for both name and value are more lenient than RFC # definitions to allow for backwards compatibility _is_legal_header_name = re.compile(r'\A[^:\s][^:\r\n]*\Z').match _is_illegal_header_value = re.compile(r'\n(?![ \t])|\r(?![ \t\n])').search +# These characters are not allowed within HTTP URL paths. +# See https://tools.ietf.org/html/rfc3986#section-3.3 and the +# https://tools.ietf.org/html/rfc3986#appendix-A pchar definition. +# Prevents CVE-2019-9740. Includes control characters such as \r\n. +# Restrict non-ASCII characters above \x7f (0x80-0xff). +_contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f-\xff]') +# Arguably only these _should_ allowed: +# _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$") +# We are more lenient for assumed real world compatibility purposes. + +# We always set the Content-Length header for these methods because some +# servers will otherwise respond with a 411 +_METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'} + class HTTPMessage(mimetools.Message): diff --git a/Lib/mhlib.py b/Lib/mhlib.py index b6efdf9..46311fc 100644 --- a/Lib/mhlib.py +++ b/Lib/mhlib.py @@ -156,6 +156,11 @@ class MH: """Return the names of the subfolders in a given folder (prefixed with the given folder name).""" fullname = os.path.join(self.path, name) + # Get the link count so we can avoid listing folders + # that have no subfolders. + nlinks = os.stat(fullname).st_nlink + if nlinks == 2: + return [] subfolders = [] subnames = os.listdir(fullname) for subname in subnames: @@ -163,6 +168,11 @@ class MH: if os.path.isdir(fullsubname): name_subname = os.path.join(name, subname) subfolders.append(name_subname) + # Stop looking for subfolders when + # we've seen them all + nlinks = nlinks - 1 + if nlinks == 2: + break subfolders.sort() return subfolders @@ -173,6 +183,11 @@ class MH: def listallsubfolders(self, name): """Return the names of subfolders in a given folder, recursively.""" fullname = os.path.join(self.path, name) + # Get the link count so we can avoid listing folders + # that have no subfolders. + nlinks = os.stat(fullname).st_nlink + if nlinks == 2: + return [] subfolders = [] subnames = os.listdir(fullname) for subname in subnames: @@ -185,6 +200,11 @@ class MH: subsubfolders = self.listallsubfolders( name_subname) subfolders = subfolders + subsubfolders + # Stop looking for subfolders when + # we've seen them all + nlinks = nlinks - 1 + if nlinks == 2: + break subfolders.sort() return subfolders diff --git a/Lib/poplib.py b/Lib/poplib.py index e890ed2..a238510 100644 --- a/Lib/poplib.py +++ b/Lib/poplib.py @@ -33,7 +33,7 @@ LF = '\n' CRLF = CR+LF # maximal line length when calling readline(). This is to prevent -# reading arbitrary lenght lines. RFC 1939 limits POP3 line length to +# reading arbitrary length lines. RFC 1939 limits POP3 line length to # 512 characters, including CRLF. We have selected 2048 just to be on # the safe side. _MAXLINE = 2048 @@ -112,7 +112,6 @@ class POP3: line = self.file.readline(_MAXLINE + 1) if len(line) > _MAXLINE: raise error_proto('line too long') - if self._debugging > 1: print '*get*', repr(line) if not line: raise error_proto('-ERR EOF') octets = len(line) diff --git a/Lib/pydoc.py b/Lib/pydoc.py index 267cd71..62cc262 100755 --- a/Lib/pydoc.py +++ b/Lib/pydoc.py @@ -385,9 +385,8 @@ class Doc: file = '(built-in)' docloc = os.environ.get("PYTHONDOCS", - "http://docs.python.org/library") - basedir = os.path.join(sys.exec_prefix, sys.lib, - "python"+sys.version[0:3]) + "https://docs.python.org/library") + basedir = os.path.normcase(basedir) if (isinstance(object, type(os)) and (object.__name__ in ('errno', 'exceptions', 'gc', 'imp', 'marshal', 'posix', 'signal', 'sys', diff --git a/Lib/site.py b/Lib/site.py index 40b0352..3b51e81 100644 --- a/Lib/site.py +++ b/Lib/site.py @@ -231,38 +231,29 @@ def getuserbase(): USER_BASE = get_config_var('userbase') return USER_BASE -def getusersitepackages(lib_kind = 'purelib'): +def getusersitepackages(): """Returns the user-specific site-packages directory path. If the global variable ``USER_SITE`` is not initialized yet, this function will also set it. """ - - set_user_site = (lib_kind == 'purelib') - global USER_SITE user_base = getuserbase() # this will also set USER_BASE - if USER_SITE is not None and set_user_site: + if USER_SITE is not None: return USER_SITE from sysconfig import get_path import os - user_site = None - if sys.platform == 'darwin': from sysconfig import get_config_var if get_config_var('PYTHONFRAMEWORK'): - user_site = get_path(lib_kind, 'osx_framework_user') + USER_SITE = get_path('purelib', 'osx_framework_user') + return USER_SITE - if user_site is None: - user_site = get_path(lib_kind, '%s_user' % os.name) - - if set_user_site: - USER_SITE = user_site - - return user_site + USER_SITE = get_path('purelib', '%s_user' % os.name) + return USER_SITE def addusersitepackages(known_paths): """Add a per user site-package to sys.path @@ -272,12 +263,10 @@ def addusersitepackages(known_paths): """ # get the per user site-package path # this call will also make sure USER_BASE and USER_SITE are set - for kind in ('purelib', 'platlib'): - user_site = getusersitepackages(kind) - - if ENABLE_USER_SITE and os.path.isdir(user_site): - addsitedir(user_site, known_paths) + user_site = getusersitepackages() + if ENABLE_USER_SITE and os.path.isdir(user_site): + addsitedir(user_site, known_paths) return known_paths def getsitepackages(): @@ -299,27 +288,13 @@ def getsitepackages(): if sys.platform in ('os2emx', 'riscos'): sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) elif os.sep == '/': - sitepackages.append(os.path.join(prefix, sys.lib, + sitepackages.append(os.path.join(prefix, "lib", "python" + sys.version[:3], "site-packages")) - sitepackages.append(os.path.join(prefix, sys.lib, "site-python")) - if sys.lib != "lib": - sitepackages.append(os.path.join(prefix, "lib", - "python" + sys.version[:3], - "site-packages")) - sitepackages.append(os.path.join(prefix, "lib", "site-python")) + sitepackages.append(os.path.join(prefix, "lib", "site-python")) else: sitepackages.append(prefix) - sitepackages.append(os.path.join(prefix, sys.lib, "site-packages")) - if sys.platform == "darwin": - # for framework builds *only* we add the standard Apple - # locations. - from sysconfig import get_config_var - framework = get_config_var("PYTHONFRAMEWORK") - if framework: - sitepackages.append( - os.path.join("/Library", framework, - sys.version[:3], "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", "site-packages")) return sitepackages def addsitepackages(known_paths): diff --git a/Lib/sysconfig.py b/Lib/sysconfig.py index 67a1299..9c8350d 100644 --- a/Lib/sysconfig.py +++ b/Lib/sysconfig.py @@ -7,10 +7,10 @@ from os.path import pardir, realpath _INSTALL_SCHEMES = { 'posix_prefix': { - 'stdlib': '{base}/'+sys.lib+'/python{py_version_short}', - 'platstdlib': '{platbase}/'+sys.lib+'/python{py_version_short}', + 'stdlib': '{base}/lib/python{py_version_short}', + 'platstdlib': '{platbase}/lib/python{py_version_short}', 'purelib': '{base}/lib/python{py_version_short}/site-packages', - 'platlib': '{platbase}/'+sys.lib+'/python{py_version_short}/site-packages', + 'platlib': '{platbase}/lib/python{py_version_short}/site-packages', 'include': '{base}/include/python{py_version_short}', 'platinclude': '{platbase}/include/python{py_version_short}', 'scripts': '{base}/bin', @@ -65,10 +65,10 @@ _INSTALL_SCHEMES = { 'data' : '{userbase}', }, 'posix_user': { - 'stdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', - 'platstdlib': '{userbase}/'+sys.lib+'/python{py_version_short}', + '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}/'+sys.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}', diff --git a/Lib/test/regrtest.py b/Lib/test/regrtest.py index f9d89a4..5b0b3e4 100755 --- a/Lib/test/regrtest.py +++ b/Lib/test/regrtest.py @@ -2172,5 +2172,29 @@ def main_in_temp_cwd(): if not os.path.exists(TEMPDIR): os.mkdir(TEMPDIR) - # do not change directory, because it breaks distutils tests - main() + # Define a writable temp dir that will be used as cwd while running + # the tests. The name of the dir includes the pid to allow parallel + # testing (see the -j option). + TESTCWD = 'test_python_{}'.format(os.getpid()) + + TESTCWD = os.path.join(TEMPDIR, TESTCWD) + + # Run the tests in a context manager that temporary changes the CWD to a + # temporary and writable directory. If it's not possible to create or + # change the CWD, the original CWD will be used. The original CWD is + # available from support.SAVEDCWD. + with support.temp_cwd(TESTCWD, quiet=True): + main() + +if __name__ == '__main__': + # findtestdir() gets the dirname out of __file__, so we have to make it + # absolute before changing the working directory. + # For example __file__ may be relative when running trace or profile. + # See issue #9323. + global __file__ + __file__ = os.path.abspath(__file__) + + # sanity check + assert __file__ == os.path.abspath(sys.argv[0]) + + main_in_temp_cwd() diff --git a/Lib/test/test_dl.py b/Lib/test/test_dl.py index c010ef2..da9730f 100644 --- a/Lib/test/test_dl.py +++ b/Lib/test/test_dl.py @@ -4,11 +4,10 @@ import unittest from test.test_support import verbose, import_module dl = import_module('dl', deprecated=True) -import sys sharedlibs = [ - ('/usr/'+sys.lib+'/libc.so', 'getpid'), - ('/'+sys.lib+'/libc.so.6', 'getpid'), + ('/usr/lib/libc.so', 'getpid'), + ('/lib/libc.so.6', 'getpid'), ('/usr/bin/cygwin1.dll', 'getpid'), ('/usr/lib/libc.dylib', 'getpid'), ] diff --git a/Lib/test/test_httplib.py b/Lib/test/test_httplib.py index 7800d2b..5462fdd 100644 --- a/Lib/test/test_httplib.py +++ b/Lib/test/test_httplib.py @@ -231,6 +231,130 @@ class HeaderTests(TestCase): conn.request('GET', '/foo') self.assertTrue(sock.data.startswith(expected)) + def test_malformed_headers_coped_with(self): + # Issue 19996 + body = "HTTP/1.1 200 OK\r\nFirst: val\r\n: nval\r\nSecond: val\r\n\r\n" + sock = FakeSocket(body) + resp = httplib.HTTPResponse(sock) + resp.begin() + + self.assertEqual(resp.getheader('First'), 'val') + self.assertEqual(resp.getheader('Second'), 'val') + + def test_malformed_truncation(self): + # Other malformed header lines, especially without colons, used to + # cause the rest of the header section to be truncated + resp = ( + b'HTTP/1.1 200 OK\r\n' + b'Public-Key-Pins: \n' + b'pin-sha256="xxx=";\n' + b'report-uri="https://..."\r\n' + b'Transfer-Encoding: chunked\r\n' + b'\r\n' + b'4\r\nbody\r\n0\r\n\r\n' + ) + resp = httplib.HTTPResponse(FakeSocket(resp)) + resp.begin() + self.assertIsNotNone(resp.getheader('Public-Key-Pins')) + self.assertEqual(resp.getheader('Transfer-Encoding'), 'chunked') + self.assertEqual(resp.read(), b'body') + + def test_blank_line_forms(self): + # Test that both CRLF and LF blank lines can terminate the header + # section and start the body + for blank in (b'\r\n', b'\n'): + resp = b'HTTP/1.1 200 OK\r\n' b'Transfer-Encoding: chunked\r\n' + resp += blank + resp += b'4\r\nbody\r\n0\r\n\r\n' + resp = httplib.HTTPResponse(FakeSocket(resp)) + resp.begin() + self.assertEqual(resp.getheader('Transfer-Encoding'), 'chunked') + self.assertEqual(resp.read(), b'body') + + resp = b'HTTP/1.0 200 OK\r\n' + blank + b'body' + resp = httplib.HTTPResponse(FakeSocket(resp)) + resp.begin() + self.assertEqual(resp.read(), b'body') + + # A blank line ending in CR is not treated as the end of the HTTP + # header section, therefore header fields following it should be + # parsed if possible + resp = ( + b'HTTP/1.1 200 OK\r\n' + b'\r' + b'Name: value\r\n' + b'Transfer-Encoding: chunked\r\n' + b'\r\n' + b'4\r\nbody\r\n0\r\n\r\n' + ) + resp = httplib.HTTPResponse(FakeSocket(resp)) + resp.begin() + self.assertEqual(resp.getheader('Transfer-Encoding'), 'chunked') + self.assertEqual(resp.read(), b'body') + + # No header fields nor blank line + resp = b'HTTP/1.0 200 OK\r\n' + resp = httplib.HTTPResponse(FakeSocket(resp)) + resp.begin() + self.assertEqual(resp.read(), b'') + + def test_from_line(self): + # The parser handles "From" lines specially, so test this does not + # affect parsing the rest of the header section + resp = ( + b'HTTP/1.1 200 OK\r\n' + b'From start\r\n' + b' continued\r\n' + b'Name: value\r\n' + b'From middle\r\n' + b' continued\r\n' + b'Transfer-Encoding: chunked\r\n' + b'From end\r\n' + b'\r\n' + b'4\r\nbody\r\n0\r\n\r\n' + ) + resp = httplib.HTTPResponse(FakeSocket(resp)) + resp.begin() + self.assertIsNotNone(resp.getheader('Name')) + self.assertEqual(resp.getheader('Transfer-Encoding'), 'chunked') + self.assertEqual(resp.read(), b'body') + + resp = ( + b'HTTP/1.0 200 OK\r\n' + b'From alone\r\n' + b'\r\n' + b'body' + ) + resp = httplib.HTTPResponse(FakeSocket(resp)) + resp.begin() + self.assertEqual(resp.read(), b'body') + + def test_parse_all_octets(self): + # Ensure no valid header field octet breaks the parser + body = ( + b'HTTP/1.1 200 OK\r\n' + b"!#$%&'*+-.^_`|~: value\r\n" # Special token characters + b'VCHAR: ' + bytearray(range(0x21, 0x7E + 1)) + b'\r\n' + b'obs-text: ' + bytearray(range(0x80, 0xFF + 1)) + b'\r\n' + b'obs-fold: text\r\n' + b' folded with space\r\n' + b'\tfolded with tab\r\n' + b'Content-Length: 0\r\n' + b'\r\n' + ) + sock = FakeSocket(body) + resp = httplib.HTTPResponse(sock) + resp.begin() + self.assertEqual(resp.getheader('Content-Length'), '0') + self.assertEqual(resp.getheader("!#$%&'*+-.^_`|~"), 'value') + vchar = ''.join(map(chr, range(0x21, 0x7E + 1))) + self.assertEqual(resp.getheader('VCHAR'), vchar) + self.assertIsNotNone(resp.getheader('obs-text')) + folded = resp.getheader('obs-fold') + self.assertTrue(folded.startswith('text')) + self.assertIn(' folded with space', folded) + self.assertTrue(folded.endswith('folded with tab')) + def test_invalid_headers(self): conn = httplib.HTTPConnection('example.com') conn.sock = FakeSocket('') diff --git a/Lib/test/test_poplib.py b/Lib/test/test_poplib.py index d10b612..d214375 100644 --- a/Lib/test/test_poplib.py +++ b/Lib/test/test_poplib.py @@ -81,7 +81,7 @@ class DummyPOP3Handler(asynchat.async_chat): def cmd_list(self, arg): if arg: - self.push('+OK %s %s' % (arg, arg)) + self.push('+OK %s %s' %(arg, arg)) else: self.push('+OK') asynchat.async_chat.push(self, LIST_RESP) diff --git a/Lib/test/test_site.py b/Lib/test/test_site.py index 445b109..b4384ee 100644 --- a/Lib/test/test_site.py +++ b/Lib/test/test_site.py @@ -253,17 +253,13 @@ class HelperFunctionsTests(unittest.TestCase): wanted = os.path.join('xoxo', 'Lib', 'site-packages') self.assertEqual(dirs[0], wanted) elif os.sep == '/': - # OS X non-framwework builds, Linux, FreeBSD, etc + # OS X, Linux, FreeBSD, etc + self.assertEqual(len(dirs), 2) wanted = os.path.join('xoxo', 'lib', 'python' + sys.version[:3], 'site-packages') - self.assertTrue(wanted in dirs) + self.assertEqual(dirs[0], wanted) wanted = os.path.join('xoxo', 'lib', 'site-python') - self.assertTrue(wanted in dirs) - wanted = os.path.join('xoxo', sys.lib, 'python' + sys.version[:3], - 'site-packages') - self.assertTrue(wanted in dirs) - wanted = os.path.join('xoxo', sys.lib, 'site-python') - self.assertTrue(wanted in dirs) + self.assertEqual(dirs[1], wanted) else: # other platforms self.assertEqual(len(dirs), 2) diff --git a/Lib/test/test_smtplib.py b/Lib/test/test_smtplib.py index 1bb6690..703b631 100644 --- a/Lib/test/test_smtplib.py +++ b/Lib/test/test_smtplib.py @@ -306,12 +306,14 @@ class TooLongLineTests(unittest.TestCase): self.sock.settimeout(15) self.port = test_support.bind_port(self.sock) servargs = (self.evt, self.respdata, self.sock) - threading.Thread(target=server, args=servargs).start() + self.thread = threading.Thread(target=server, args=servargs) + self.thread.start() self.evt.wait() self.evt.clear() def tearDown(self): self.evt.wait() + self.thread.join() sys.stdout = self.old_stdout def testLineTooLong(self): diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index 73b0228..86c4a05 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -641,12 +641,29 @@ class UrlParseTestCase(unittest.TestCase): self.assertIn(u'\u2100', denorm_chars) self.assertIn(u'\uFF03', denorm_chars) + # bpo-36742: Verify port separators are ignored when they + # existed prior to decomposition + urlparse.urlsplit(u'http://\u30d5\u309a:80') + with self.assertRaises(ValueError): + urlparse.urlsplit(u'http://\u30d5\u309a\ufe1380') + for scheme in [u"http", u"https", u"ftp"]: - for c in denorm_chars: - url = u"{}://netloc{}false.netloc/path".format(scheme, c) - print "Checking %r" % url - with self.assertRaises(ValueError): - urlparse.urlsplit(url) + for netloc in [u"netloc{}false.netloc", u"n{}user@netloc"]: + for c in denorm_chars: + url = u"{}://{}/path".format(scheme, netloc.format(c)) + if test_support.verbose: + print "Checking %r" % url + with self.assertRaises(ValueError): + urlparse.urlsplit(url) + + # check error message: invalid netloc must be formated with repr() + # to get an ASCII error message + with self.assertRaises(ValueError) as cm: + urlparse.urlsplit(u'http://example.com\uFF03@bing.com') + self.assertEqual(str(cm.exception), + "netloc u'example.com\\uff03@bing.com' contains invalid characters " + "under NFKC normalization") + self.assertIsInstance(cm.exception.args[0], str) def test_main(): test_support.run_unittest(UrlParseTestCase) diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py index 945d481..90ccb30 100644 --- a/Lib/test/test_xmlrpc.py +++ b/Lib/test/test_xmlrpc.py @@ -23,18 +23,6 @@ try: except ImportError: gzip = None -try: - import gzip -except ImportError: - gzip = None - -try: - unicode -except NameError: - have_unicode = False -else: - have_unicode = True - alist = [{'astring': 'foo@bar.baz.spam', 'afloat': 7283.43, 'anint': 2**20, @@ -852,24 +840,20 @@ class GzipServerTestCase(BaseServerTestCase): self.assertTrue(a>b) def test_gzip_decode_limit(self): - data = '\0' * xmlrpclib.MAX_GZIP_DECODE + max_gzip_decode = 20 * 1024 * 1024 + data = '\0' * max_gzip_decode encoded = xmlrpclib.gzip_encode(data) decoded = xmlrpclib.gzip_decode(encoded) - self.assertEqual(len(decoded), xmlrpclib.MAX_GZIP_DECODE) + self.assertEqual(len(decoded), max_gzip_decode) - data = '\0' * (xmlrpclib.MAX_GZIP_DECODE + 1) + data = '\0' * (max_gzip_decode + 1) encoded = xmlrpclib.gzip_encode(data) with self.assertRaisesRegexp(ValueError, "max gzipped payload length exceeded"): xmlrpclib.gzip_decode(encoded) - oldmax = xmlrpclib.MAX_GZIP_DECODE - try: - xmlrpclib.MAX_GZIP_DECODE = -1 - xmlrpclib.gzip_decode(encoded) - finally: - xmlrpclib.MAX_GZIP_DECODE = oldmax + xmlrpclib.gzip_decode(encoded, max_decode=-1) #Test special attributes of the ServerProxy object diff --git a/Lib/trace.py b/Lib/trace.py index a40fd24..96af260 100755 --- a/Lib/trace.py +++ b/Lib/trace.py @@ -754,10 +754,10 @@ def main(argv=None): # should I also call expanduser? (after all, could use $HOME) s = s.replace("$prefix", - os.path.join(sys.prefix, sys.lib, + os.path.join(sys.prefix, "lib", "python" + sys.version[:3])) s = s.replace("$exec_prefix", - os.path.join(sys.exec_prefix, sys.lib, + os.path.join(sys.exec_prefix, "lib", "python" + sys.version[:3])) s = os.path.normpath(s) ignore_dirs.append(s) diff --git a/Lib/urlparse.py b/Lib/urlparse.py index 54eda08..798b467 100644 --- a/Lib/urlparse.py +++ b/Lib/urlparse.py @@ -171,14 +171,18 @@ def _checknetloc(netloc): # looking for characters like \u2100 that expand to 'a/c' # IDNA uses NFKC equivalence, so normalize for this check import unicodedata - netloc2 = unicodedata.normalize('NFKC', netloc) - if netloc == netloc2: + n = netloc.replace(u'@', u'') # ignore characters already included + n = n.replace(u':', u'') # but not the surrounding text + n = n.replace(u'#', u'') + n = n.replace(u'?', u'') + netloc2 = unicodedata.normalize('NFKC', n) + if n == netloc2: return - _, _, netloc = netloc.rpartition('@') # anything to the left of '@' is okay for c in '/?#@:': if c in netloc2: - raise ValueError("netloc '" + netloc2 + "' contains invalid " + - "characters under NFKC normalization") + raise ValueError("netloc %r contains invalid characters " + "under NFKC normalization" + % netloc) def urlsplit(url, scheme='', allow_fragments=True): """Parse a URL into 5 components: diff --git a/Lib/xmlrpclib.py b/Lib/xmlrpclib.py index 152ed1b..b0e7485 100644 --- a/Lib/xmlrpclib.py +++ b/Lib/xmlrpclib.py @@ -49,7 +49,7 @@ # 2003-07-12 gp Correct marshalling of Faults # 2003-10-31 mvl Add multicall support # 2004-08-20 mvl Bump minimum supported Python version to 2.1 -# 2013-01-20 ch Add workaround for gzip bomb vulnerability +# 2014-12-02 ch/doko Add workaround for gzip bomb vulnerability # # Copyright (c) 1999-2002 by Secret Labs AB. # Copyright (c) 1999-2002 by Fredrik Lundh. @@ -148,10 +148,6 @@ try: except ImportError: gzip = None #python can be built without zlib/gzip support -# Limit the maximum amount of decoded data that is decompressed. The -# limit prevents gzip bomb attacks. -MAX_GZIP_DECODE = 20 * 1024 * 1024 # 20 MB - # -------------------------------------------------------------------- # Internal stuff @@ -1194,15 +1190,15 @@ def gzip_decode(data, max_decode=20971520): f = StringIO.StringIO(data) gzf = gzip.GzipFile(mode="rb", fileobj=f) try: - if MAX_GZIP_DECODE < 0: # no limit + if max_decode < 0: # no limit decoded = gzf.read() else: - decoded = gzf.read(MAX_GZIP_DECODE + 1) + decoded = gzf.read(max_decode + 1) except IOError: raise ValueError("invalid data") f.close() gzf.close() - if MAX_GZIP_DECODE >= 0 and len(decoded) > MAX_GZIP_DECODE: + if max_decode >= 0 and len(decoded) > max_decode: raise ValueError("max gzipped payload length exceeded") return decoded diff --git a/Makefile.pre.in b/Makefile.pre.in index 7ba03a7..f2154e5 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -91,8 +91,6 @@ PY_CFLAGS= $(CFLAGS) $(CPPFLAGS) $(CFLAGSFORSHARED) -DPy_BUILD_CORE # Machine-dependent subdirectories MACHDEP= @MACHDEP@ -LIB= @LIB@ -ARCH= @ARCH@ # Multiarch directory (may be empty) MULTIARCH= @MULTIARCH@ @@ -112,7 +110,7 @@ LIBDIR= @libdir@ MANDIR= @mandir@ INCLUDEDIR= @includedir@ CONFINCLUDEDIR= $(exec_prefix)/include -SCRIPTDIR= @libdir@ +SCRIPTDIR= $(prefix)/lib # Detailed destination directories BINLIBDEST= $(LIBDIR)/python$(VERSION) @@ -211,9 +209,14 @@ TCLTK_INCLUDES= @TCLTK_INCLUDES@ TCLTK_LIBS= @TCLTK_LIBS@ # The task to run while instrument when building the profile-opt target -PROFILE_TASK= -#PROFILE_TASK= $(srcdir)/Tools/pybench/pybench.py -n 2 --with-gc --with-syscheck -#PROFILE_TASK= $(srcdir)/Lib/test/regrtest.py +# We exclude unittests with -x that take a rediculious amount of time to +# run in the instrumented training build or do not provide much value. +#PROFILE_TASK=-m test.regrtest --pgo -x test_asyncore test_gdb test_multiprocessing test_subprocess + +# report files for gcov / lcov coverage report +COVERAGE_INFO= $(abs_builddir)/coverage.info +COVERAGE_REPORT=$(abs_builddir)/lcov-report +COVERAGE_REPORT_OPTIONS=--no-branch-coverage --title "CPython lcov report" # === Definitions added by makesetup === @@ -483,7 +486,7 @@ coverage-report: regen-grammar # Build the interpreter -$(BUILDPYTHON): Modules/python.o $(LDLIBRARY) +$(BUILDPYTHON): Modules/python.o $(LIBRARY) $(LDLIBRARY) $(LINKCC) $(LDFLAGS) $(LINKFORSHARED) -pie -o $@ \ Modules/python.o \ $(BLDLIBRARY) $(LIBS) $(MODLIBS) $(SYSLIBS) $(LDLAST) @@ -524,6 +527,18 @@ sharedmods: $(BUILDPYTHON) pybuilddir.txt Modules/_math.o _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build +# Build static library +# avoid long command lines, same as LIBRARY_OBJS +$(LIBRARY): $(LIBRARY_OBJS) + -rm -f $@ + $(AR) $(ARFLAGS) $@ Modules/getbuildinfo.o + $(AR) $(ARFLAGS) $@ $(PARSER_OBJS) + $(AR) $(ARFLAGS) $@ $(OBJECT_OBJS) + $(AR) $(ARFLAGS) $@ $(PYTHON_OBJS) + $(AR) $(ARFLAGS) $@ $(MODULE_OBJS) $(SIGNAL_OBJS) + $(AR) $(ARFLAGS) $@ $(MODOBJS) + $(RANLIB) $@ + libpython$(VERSION).so: $(LIBRARY_OBJS) if test $(INSTSONAME) != $(LDLIBRARY); then \ $(BLDSHARED) -Wl,-h$(INSTSONAME) -o $(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM) $(LDLAST); \ @@ -627,26 +642,17 @@ Modules/getbuildinfo.o: $(PARSER_OBJS) \ $(MODOBJS) \ $(srcdir)/Modules/getbuildinfo.c $(CC) -c $(PY_CFLAGS) \ - -DSVNVERSION="\"`LC_ALL=C $(SVNVERSION)`\"" \ - -DHGVERSION="\"`LC_ALL=C $(HGVERSION)`\"" \ - -DHGTAG="\"`LC_ALL=C $(HGTAG)`\"" \ - -DHGBRANCH="\"`LC_ALL=C $(HGBRANCH)`\"" \ - -DDATE="\"`LC_ALL=C date -u -r Makefile.pre.in +"%b %d %Y"`\"" \ - -DTIME="\"`LC_ALL=C date -u -r Makefile.pre.in +"%T"`\"" \ + -DGITVERSION="\"`LC_ALL=C $(GITVERSION)`\"" \ + -DGITTAG="\"`LC_ALL=C $(GITTAG)`\"" \ + -DGITBRANCH="\"`LC_ALL=C $(GITBRANCH)`\"" \ -o $@ $(srcdir)/Modules/getbuildinfo.c -Python/getcompiler.o: $(srcdir)/Python/getcompiler.c Makefile - $(CC) -c $(PY_CFLAGS) \ - -DCOMPILER='"[GCC]"' \ - -o $@ $(srcdir)/Python/getcompiler.c - Modules/getpath.o: $(srcdir)/Modules/getpath.c Makefile $(CC) -c $(PY_CFLAGS) -DPYTHONPATH='"$(PYTHONPATH)"' \ -DPREFIX='"$(prefix)"' \ -DEXEC_PREFIX='"$(exec_prefix)"' \ -DVERSION='"$(VERSION)"' \ -DVPATH='"$(VPATH)"' \ - -DARCH='"$(ARCH)"' -DLIB='"$(LIB)"' \ -o $@ $(srcdir)/Modules/getpath.c Modules/python.o: $(srcdir)/Modules/python.c @@ -695,7 +701,7 @@ regen-ast: Python/compile.o Python/symtable.o Python/ast.o: $(srcdir)/Include/graminit.h $(srcdir)/Include/Python-ast.h Python/getplatform.o: $(srcdir)/Python/getplatform.c - $(CC) -c $(PY_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -DARCH='"$(ARCH)"' -DLIB='"$(LIB)"' -o $@ $(srcdir)/Python/getplatform.c + $(CC) -c $(PY_CFLAGS) -DPLATFORM='"$(MACHDEP)"' -o $@ $(srcdir)/Python/getplatform.c Python/importdl.o: $(srcdir)/Python/importdl.c $(CC) -c $(PY_CFLAGS) -I$(DLINCLDIR) -o $@ $(srcdir)/Python/importdl.c @@ -1210,6 +1216,18 @@ libainstall: @DEF_MAKE_RULE@ python-config else true; \ fi; \ done + @if test -d $(LIBRARY); then :; else \ + if test "$(PYTHONFRAMEWORKDIR)" = no-framework; then \ + if test "$(SO)" = .dll; then \ + $(INSTALL_DATA) $(LDLIBRARY) $(DESTDIR)$(LIBPL) ; \ + else \ + $(INSTALL_DATA) $(LIBRARY) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ + $(RANLIB) $(DESTDIR)$(LIBPL)/$(LIBRARY) ; \ + fi; \ + else \ + echo Skip install of $(LIBRARY) - use make frameworkinstall; \ + fi; \ + fi $(INSTALL_DATA) Modules/config.c $(DESTDIR)$(LIBPL)/config.c $(INSTALL_DATA) Modules/python.o $(DESTDIR)$(LIBPL)/python.o $(INSTALL_DATA) $(srcdir)/Modules/config.c.in $(DESTDIR)$(LIBPL)/config.c.in diff --git a/Modules/Setup.dist b/Modules/Setup.dist index 2118cae..bbc9222 100644 --- a/Modules/Setup.dist +++ b/Modules/Setup.dist @@ -252,14 +252,14 @@ GLHACK=-Dclear=__GLclear # Message-Digest Algorithm, described in RFC 1321. The necessary files # md5.c and md5.h are included here. -_md5 md5module.c md5.c +#_md5 md5module.c md5.c # The _sha module implements the SHA checksum algorithms. # (NIST's Secure Hash Algorithms.) -_sha shamodule.c -_sha256 sha256module.c -_sha512 sha512module.c +#_sha shamodule.c +#_sha256 sha256module.c +#_sha512 sha512module.c # SGI IRIX specific modules -- off by default. diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c index e5cdb2e..cee447b 100644 --- a/Modules/_bsddb.c +++ b/Modules/_bsddb.c @@ -124,14 +124,10 @@ typedef int Py_ssize_t; #define NUMBER_Check PyLong_Check #define NUMBER_AsLong PyLong_AsLong #define NUMBER_FromLong PyLong_FromLong -#define NUMBER_FromUnsignedLong PyLong_FromUnsignedLong #else #define NUMBER_Check PyInt_Check #define NUMBER_AsLong PyInt_AsLong #define NUMBER_FromLong PyInt_FromLong -#if (PY_VERSION_HEX >= 0x02050000) -#define NUMBER_FromUnsignedLong PyInt_FromSize_t -#endif #endif #ifdef WITH_THREAD @@ -857,18 +853,6 @@ static void _addIntToDict(PyObject* dict, char *name, int value) Py_XDECREF(v); } -#if (DBVER >= 60) && (PY_VERSION_HEX >= 0x02050000) -/* add an unsigned integer to a dictionary using the given name as a key */ -static void _addUnsignedIntToDict(PyObject* dict, char *name, unsigned int value) -{ - PyObject* v = NUMBER_FromUnsignedLong((unsigned long) value); - if (!v || PyDict_SetItemString(dict, name, v)) - PyErr_Clear(); - - Py_XDECREF(v); -} -#endif - /* The same, when the value is a time_t */ static void _addTimeTToDict(PyObject* dict, char *name, time_t value) { @@ -2693,21 +2677,13 @@ _default_cmp(const DBT *leftKey, static int _db_compareCallback(DB* db, const DBT *leftKey, - const DBT *rightKey -#if (DBVER >= 60) - , size_t *locp -#endif - ) + const DBT *rightKey) { int res = 0; PyObject *args; PyObject *result = NULL; DBObject *self = (DBObject *)db->app_private; -# if (DBVER >= 60) - locp = NULL; /* As required by documentation */ -#endif - if (self == NULL || self->btCompareCallback == NULL) { MYDB_BEGIN_BLOCK_THREADS; PyErr_SetString(PyExc_TypeError, @@ -2815,21 +2791,13 @@ DB_set_bt_compare(DBObject* self, PyObject* comparator) static int _db_dupCompareCallback(DB* db, const DBT *leftKey, - const DBT *rightKey -#if (DBVER >= 60) - , size_t *locp -#endif - ) + const DBT *rightKey) { int res = 0; PyObject *args; PyObject *result = NULL; DBObject *self = (DBObject *)db->app_private; -#if (DBVER >= 60) - locp = NULL; /* As required by documentation */ -#endif - if (self == NULL || self->dupCompareCallback == NULL) { MYDB_BEGIN_BLOCK_THREADS; PyErr_SetString(PyExc_TypeError, @@ -3608,14 +3576,13 @@ Py_ssize_t DB_length(PyObject* _self) err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0); MYDB_END_ALLOW_THREADS; - if (makeDBError(err)) { - return -1; - } - /* All the stat structures have matching fields upto the ndata field, so we can use any of them for the type cast */ size = ((DB_BTREE_STAT*)sp)->bt_ndata; + if (err) + return -1; + free(sp); return size; } @@ -8453,22 +8420,12 @@ static PyObject* DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs) { int err, flags = 0; -#if (DBVER >= 60) - unsigned -#endif int delta = 1; db_seq_t value; PyObject *txnobj = NULL; DB_TXN *txn = NULL; static char* kwnames[] = {"delta", "txn", "flags", NULL }; - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, -#if (DBVER >=60) - "|IOi:get", -#else - "|iOi:get", -#endif - kwnames, &delta, &txnobj, &flags)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags)) return NULL; CHECK_SEQUENCE_NOT_CLOSED(self) @@ -8598,19 +8555,8 @@ DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs) static PyObject* DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args) { - int err; -#if (DBVER >= 60) - unsigned -#endif - int size; - - if (!PyArg_ParseTuple(args, -#if (DBVER >= 60) - "I:set_cachesize", -#else - "i:set_cachesize", -#endif - &size)) + int err, size; + if (!PyArg_ParseTuple(args,"i:set_cachesize", &size)) return NULL; CHECK_SEQUENCE_NOT_CLOSED(self) @@ -8625,11 +8571,7 @@ DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args) static PyObject* DBSequence_get_cachesize(DBSequenceObject* self) { - int err; -#if (DBVER >= 60) - unsigned -#endif - int size; + int err, size; CHECK_SEQUENCE_NOT_CLOSED(self) @@ -8758,9 +8700,6 @@ DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs) #define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name) -#if (DBVER >= 60) && (PY_VERSION_HEX >= 0x02050000) -#define MAKE_UNSIGNED_INT_ENTRY(name) _addUnsignedIntToDict(dict_stat, #name, sp->st_##name) -#endif #define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name) MAKE_INT_ENTRY(wait); @@ -8770,15 +8709,10 @@ DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs) MAKE_LONG_LONG_ENTRY(last_value); MAKE_LONG_LONG_ENTRY(min); MAKE_LONG_LONG_ENTRY(max); -#if (DBVER >= 60) && (PY_VERSION_HEX >= 0x02050000) - MAKE_UNSIGNED_INT_ENTRY(cache_size); -#else MAKE_INT_ENTRY(cache_size); -#endif MAKE_INT_ENTRY(flags); #undef MAKE_INT_ENTRY -#undef MAKE_UNSIGNED_INT_ENTRY #undef MAKE_LONG_LONG_ENTRY free(sp); @@ -9080,7 +9014,7 @@ static PyMethodDef DBEnv_methods[] = { {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS}, #if (DBVER < 48) {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server, - METH_VARARGS||METH_KEYWORDS}, + METH_VARARGS|METH_KEYWORDS}, #endif {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS}, {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS}, @@ -10052,10 +9986,6 @@ PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */ ADD_INT(d, DB_LOG_ZERO); #endif -#if (DBVER >= 60) - ADD_INT(d, DB_LOG_BLOB); -#endif - #if (DBVER >= 44) ADD_INT(d, DB_DSYNC_DB); #endif @@ -10116,10 +10046,6 @@ PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */ ADD_INT(d, DB_EVENT_REG_PANIC); #endif -#if (DBVER >= 60) - ADD_INT(d, DB_EVENT_REP_AUTOTAKEOVER_FAILED); -#endif - #if (DBVER >=52) ADD_INT(d, DB_EVENT_REP_SITE_ADDED); ADD_INT(d, DB_EVENT_REP_SITE_REMOVED); @@ -10224,20 +10150,6 @@ PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */ ADD_INT(d, DB_REP_CONF_INMEM); #endif -#if (DBVER >= 60) - ADD_INT(d, DB_REPMGR_ISVIEW); -#endif - -#if (DBVER >= 60) - ADD_INT(d, DB_DBT_BLOB); -#endif - -#if (DBVER >= 60) - ADD_INT(d, DB_STREAM_READ); - ADD_INT(d, DB_STREAM_WRITE); - ADD_INT(d, DB_STREAM_SYNC_WRITE); -#endif - ADD_INT(d, DB_TIMEOUT); #if (DBVER >= 50) diff --git a/Modules/_ctypes/libffi/fficonfig.py.in b/Modules/_ctypes/libffi/fficonfig.py.in index 3828b2d..d102498 100644 --- a/Modules/_ctypes/libffi/fficonfig.py.in +++ b/Modules/_ctypes/libffi/fficonfig.py.in @@ -28,7 +28,6 @@ ffi_platforms = { 'PA': ['src/pa/linux.S', 'src/pa/ffi.c'], 'PA_LINUX': ['src/pa/linux.S', 'src/pa/ffi.c'], 'PA_HPUX': ['src/pa/hpux32.S', 'src/pa/ffi.c'], - 'AARCH64' : ['src/aarch64/ffi.c', 'src/aarch64/sysv.S'], } ffi_sources += ffi_platforms['@TARGET@'] diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 1c2f3ed..e5cd721 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -829,9 +829,6 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) goto error; } - if (! statement) - break; - /* execute statement, and ignore results of SELECT statements */ rc = SQLITE_ROW; while (rc == SQLITE_ROW) { diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 504baf3..98c8a5a 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -574,12 +574,9 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, enum py_ssl_server_or_client socket_type, char *server_hostname, PyObject *ssl_sock) { - PySSLObject *self; - char *errstr = NULL; - int ret; - int verification_mode; - long options; - struct stat stat_buf; + PySSLSocket *self; + SSL_CTX *ctx = sslctx->ctx; + long mode; self = PyObject_New(PySSLSocket, &PySSLSocket_Type); if (self == NULL) @@ -622,27 +619,8 @@ newPySSLSocket(PySSLContext *sslctx, PySocketSockObject *sock, send_sni = 1; ERR_clear_error(); } else { - /* If cacerts_file is a directory-based cert store, pass it as the - third parameter, CApath, instead - */ - if (stat(cacerts_file, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode)) { - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_CTX_load_verify_locations(self->ctx, - NULL, - cacerts_file); - PySSL_END_ALLOW_THREADS - } else { - PySSL_BEGIN_ALLOW_THREADS - ret = SSL_CTX_load_verify_locations(self->ctx, - cacerts_file, - NULL); - PySSL_END_ALLOW_THREADS - } - - if (ret != 1) { - _setSSLError(NULL, 0, __FILE__, __LINE__); - goto fail; - } + send_sni = 0; + ASN1_OCTET_STRING_free(ip); } #elif defined(HAVE_INET_PTON) #ifdef ENABLE_IPV6 diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 998da85..af93d00 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5,7 +5,6 @@ * standard Python regression test, via Lib/test/test_capi.py. */ -#define PY_SSIZE_T_CLEAN #include "Python.h" #include <float.h> #include "structmember.h" @@ -1675,7 +1674,7 @@ test_u_code(PyObject *self) { PyObject *tuple, *obj; Py_UNICODE *value; - Py_ssize_t len; + int len; /* issue4122: Undefined reference to _Py_ascii_whitespace on Windows */ /* Just use the macro and check that it compiles */ diff --git a/Modules/bsddb.h b/Modules/bsddb.h index c0b587f..8405afa 100644 --- a/Modules/bsddb.h +++ b/Modules/bsddb.h @@ -110,7 +110,7 @@ #error "eek! DBVER can't handle minor versions > 9" #endif -#define PY_BSDDB_VERSION "6.0.0" +#define PY_BSDDB_VERSION "5.3.0" /* Python object definitions */ diff --git a/Modules/getpath.c b/Modules/getpath.c index 6dbe37f..c42ce31 100644 --- a/Modules/getpath.c +++ b/Modules/getpath.c @@ -96,31 +96,8 @@ #endif -#ifndef VERSION -#define VERSION "2.1" -#endif - -#ifndef VPATH -#define VPATH "." -#endif - -#ifndef PREFIX -# ifdef __VMS -# define PREFIX "" -# else -# define PREFIX "/usr/local" -# endif -#endif - -#ifndef EXEC_PREFIX -#define EXEC_PREFIX PREFIX -#endif - -#define LIB_PYTHON LIB "/python" VERSION - -#ifndef PYTHONPATH -#define PYTHONPATH PREFIX "/" LIB_PYTHON ":" \ - EXEC_PREFIX "/" LIB_PYTHON "/lib-dynload" +#if !defined(PREFIX) || !defined(EXEC_PREFIX) || !defined(VERSION) || !defined(VPATH) +#error "PREFIX, EXEC_PREFIX, VERSION, and VPATH must be constant defined" #endif #ifndef LANDMARK @@ -131,7 +108,7 @@ static char prefix[MAXPATHLEN+1]; static char exec_prefix[MAXPATHLEN+1]; static char progpath[MAXPATHLEN+1]; static char *module_search_path = NULL; -static char lib_python[] = LIB_PYTHON; +static char lib_python[] = "lib/python" VERSION; static void reduce(char *dir) diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c index 3552a87..2067cf5 100644 --- a/Objects/obmalloc.c +++ b/Objects/obmalloc.c @@ -3,20 +3,16 @@ #if defined(__has_feature) /* Clang */ #if __has_feature(address_sanitizer) /* is ASAN enabled? */ #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \ - __attribute__ ((no_sanitize_address)) \ + __attribute__((no_address_safety_analysis)) \ __attribute__ ((noinline)) - #define SANITIZED_BUILD - #define RUNNING_ON_VALGRIND 1 #else #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS #endif #else - #if defined(__SANITIZE_ADDRESS__) /* GCC, is ASAN enabled? */ + #if defined(__SANITIZE_ADDRESS__) /* GCC 4.8.x, is ASAN enabled? */ #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \ - __attribute__ ((no_sanitize_address)) \ + __attribute__((no_address_safety_analysis)) \ __attribute__ ((noinline)) - #define SANITIZED_BUILD - #define RUNNING_ON_VALGRIND 1 #else #define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS #endif @@ -31,10 +27,8 @@ #endif #endif -#if defined(WITH_VALGRIND) || defined(SANITIZED_BUILD) #ifdef WITH_VALGRIND #include <valgrind/valgrind.h> -#endif /* If we're using GCC, use __builtin_expect() to reduce overhead of the valgrind checks */ @@ -806,7 +800,7 @@ PyObject_Malloc(size_t nbytes) poolp next; uint size; -#if defined(WITH_VALGRIND) || defined(SANITIZED_BUILD) +#ifdef WITH_VALGRIND if (UNLIKELY(running_on_valgrind == -1)) running_on_valgrind = RUNNING_ON_VALGRIND; if (UNLIKELY(running_on_valgrind)) @@ -1016,7 +1010,7 @@ PyObject_Free(void *p) if (p == NULL) /* free(NULL) has no effect */ return; -#if defined(WITH_VALGRIND) || defined(SANITIZED_BUILD) +#ifdef WITH_VALGRIND if (UNLIKELY(running_on_valgrind > 0)) goto redirect; #endif @@ -1219,7 +1213,7 @@ PyObject_Free(void *p) return; } -#if defined(WITH_VALGRIND) || defined(SANITIZED_BUILD) +#ifdef WITH_VALGRIND redirect: #endif /* We didn't allocate this address. */ @@ -1255,7 +1249,7 @@ PyObject_Realloc(void *p, size_t nbytes) if (nbytes > PY_SSIZE_T_MAX) return NULL; -#if defined(WITH_VALGRIND) || defined(SANITIZED_BUILD) +#ifdef WITH_VALGRIND /* Treat running_on_valgrind == -1 the same as 0 */ if (UNLIKELY(running_on_valgrind > 0)) goto redirect; @@ -1288,7 +1282,7 @@ PyObject_Realloc(void *p, size_t nbytes) } return bp; } -#if defined(WITH_VALGRIND) || defined(SANITIZED_BUILD) +#ifdef WITH_VALGRIND redirect: #endif /* We're not managing this block. If nbytes <= diff --git a/Python/getplatform.c b/Python/getplatform.c index 66a49c6..6899140 100644 --- a/Python/getplatform.c +++ b/Python/getplatform.c @@ -10,23 +10,3 @@ Py_GetPlatform(void) { return PLATFORM; } - -#ifndef ARCH -#define ARCH "unknown" -#endif - -const char * -Py_GetArch(void) -{ - return ARCH; -} - -#ifndef LIB -#define LIB "lib" -#endif - -const char * -Py_GetLib(void) -{ - return LIB; -} diff --git a/Python/sysmodule.c b/Python/sysmodule.c index f200e6b..fdb7af2 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1437,10 +1437,6 @@ _PySys_Init(void) PyString_FromString(Py_GetCopyright())); SET_SYS_FROM_STRING("platform", PyString_FromString(Py_GetPlatform())); - SET_SYS_FROM_STRING("arch", - PyString_FromString(Py_GetArch())); - SET_SYS_FROM_STRING("lib", - PyString_FromString(Py_GetLib())); SET_SYS_FROM_STRING("executable", PyString_FromString(Py_GetProgramFullPath())); SET_SYS_FROM_STRING("prefix", @@ -1638,20 +1634,7 @@ PySys_SetArgvEx(int argc, char **argv, int updatepath) char *p = NULL; Py_ssize_t n = 0; PyObject *a; -#ifdef HAVE_CANONICALIZE_FILE_NAME - int errnum; - - if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { - argv0 = canonicalize_file_name(argv0); - if (argv0 == NULL) argv0 = strdup(argv[0]); - } -#elif defined(HAVE_REALPATH) - if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { - if (realpath(argv0, fullpath)) { - argv0 = fullpath; - } - } -#elif defined(HAVE_READLINK) +#ifdef HAVE_READLINK char link[MAXPATHLEN+1]; char argv0copy[2*MAXPATHLEN+1]; int nr = 0; @@ -1678,8 +1661,7 @@ PySys_SetArgvEx(int argc, char **argv, int updatepath) } } } -#endif /* resolve method selection */ - +#endif /* HAVE_READLINK */ #if SEP == '\\' /* Special case for MS filename syntax */ if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { char *q; @@ -1708,6 +1690,11 @@ PySys_SetArgvEx(int argc, char **argv, int updatepath) } #else /* All other filename syntaxes */ if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) { +#if defined(HAVE_REALPATH) + if (realpath(argv0, fullpath)) { + argv0 = fullpath; + } +#endif p = strrchr(argv0, SEP); } if (p != NULL) { @@ -1725,9 +1712,6 @@ PySys_SetArgvEx(int argc, char **argv, int updatepath) a = PyString_FromStringAndSize(argv0, n); if (a == NULL) Py_FatalError("no mem for sys.path insertion"); -#ifdef HAVE_CANONICALIZE_FILE_NAME - if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) free(argv0); -#endif /* HAVE_CANONICALIZE_FILE_NAME */ if (PyList_Insert(path, 0, a) < 0) Py_FatalError("sys.path.insert(0) failed"); Py_DECREF(a); diff --git a/configure.ac b/configure.ac index aeac42a..efe6922 100644 --- a/configure.ac +++ b/configure.ac @@ -773,41 +773,6 @@ SunOS*) ;; esac -AC_SUBST(ARCH) -AC_MSG_CHECKING(ARCH) -ARCH=`uname -m` -case $ARCH in -i?86) ARCH=i386;; -esac -AC_MSG_RESULT($ARCH) - -AC_SUBST(LIB) -AC_MSG_CHECKING(LIB) -case $ac_sys_system in -Linux*) - # Test if the compiler is 64bit - echo 'int i;' > conftest.$ac_ext - python_cv_cc_64bit_output=no - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *"ELF 64"*) - python_cv_cc_64bit_output=yes - ;; - esac - fi - rm -rf conftest* - ;; -esac - -case $ARCH:$python_cv_cc_64bit_output in -aarch64:yes | ppc64:yes | ppc64le:yes | powerpc64:yes | s390x:yes | sparc64:yes | x86_64:yes) - LIB="lib64" - ;; -*:*) - LIB="lib" - ;; -esac -AC_MSG_RESULT($LIB) AC_SUBST(LIBRARY) AC_MSG_CHECKING(LIBRARY) @@ -3165,7 +3130,7 @@ AC_CHECK_FUNCS(alarm setitimer getitimer chown \ getpriority getresuid getresgid getpwent getspnam getspent getsid getwd \ initgroups kill killpg lchown lstat mkfifo mknod mktime mmap \ mremap nice pathconf pause plock poll pthread_init \ - putenv readlink realpath canonicalize_file_name \ + putenv readlink realpath \ select sem_open sem_timedwait sem_getvalue sem_unlink setegid seteuid \ setgid \ setlocale setregid setreuid setsid setpgid setpgrp setuid setvbuf snprintf \ @@ -4367,18 +4332,9 @@ then fi # check for readline 4.0 -AC_MSG_CHECKING([for rl_pre_input_hook in -lreadline]) -AC_CACHE_VAL(ac_cv_have_rl_re_input_hook, [ -AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <stdio.h> -#include <readline/readline.h>], - [return rl_pre_input_hook != 0])], - ac_cv_have_rl_re_input_hook=yes, - ac_cv_have_rl_re_input_hook=no)]) -AC_MSG_RESULT($ac_cv_have_rl_re_input_hook) -if test "$ac_cv_have_rl_re_input_hook" = yes; then - AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK, 1, - [Define if you have readline 4.0]) -fi +AC_CHECK_LIB(readline, rl_pre_input_hook, + AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK, 1, + [Define if you have readline 4.0]), ,$READLINE_LIBS) # also in 4.0 AC_CHECK_LIB(readline, rl_completion_display_matches_hook, diff --git a/packaging/_local.pth b/packaging/_local.pth deleted file mode 100644 index 75ea69d..0000000 --- a/packaging/_local.pth +++ /dev/null @@ -1 +0,0 @@ -import site; import sys; site.addsitedir("/usr/local/" + sys.lib + "/python"+sys.version[:3]+"/site-packages", set()); sys.lib != "lib" and site.addsitedir("/usr/local/lib/python"+sys.version[:3]+"/site-packages", set()) diff --git a/packaging/python.spec b/packaging/python.spec index 028615d..3e8732a 100644 --- a/packaging/python.spec +++ b/packaging/python.spec @@ -1,6 +1,6 @@ Name: python -Version: 2.7.8 -Release: 1 +Version: 2.7.17 +Release: 0 License: Python-2.0 Summary: Python Interpreter Url: http://www.python.org/ @@ -12,13 +12,15 @@ Source1: macros.python Source2: pythonstart Source3: python.sh Source4: python.csh -Source5: _local.pth +Source6: python_lib64.patch Source1001: %name.manifest + + BuildRequires: automake BuildRequires: db4-devel BuildRequires: fdupes BuildRequires: bzip2-devel -BuildRequires: openssl-devel +BuildRequires: pkgconfig(openssl) BuildRequires: ncurses-devel BuildRequires: readline-devel BuildRequires: sqlite-devel @@ -90,16 +92,17 @@ other applications. %prep %setup -q -n %{tarname} +%ifarch x86_64 aarch64 +%{__patch} -p1 < %{SOURCE6} +%endif + # drop Autoconf version requirement sed -i 's/^version_required/dnl version_required/' configure.ac -# remove newslist.py because of bad license -rm Demo/scripts/newslist.* - %build cp %{S:1001} . export OPT=$(echo $RPM_OPT_FLAGS | sed -s "s/--param=ssp-buffer-size=32//g") -export CFLAGS+=" -fPIC" +export CFLAGS+=" -fPIC -DNCURSES_INTERNALS" export LDFLAGS+=" -Wl,-z,relro" autoreconf -f -i . # Modules/_ctypes/libffi @@ -115,7 +118,7 @@ touch Parser/asdl* Python/Python-ast.c Include/Python-ast.h --enable-unicode=ucs4 LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH \ - make %{?_smp_mflags} profile-opt + make %{?_smp_mflags} BASE_LIB=%{_lib} profile-opt %install # replace rest of /usr/local/bin/python or /usr/bin/python2.x with /usr/bin/python @@ -125,11 +128,9 @@ find . -wholename "./Parser" -prune -o -name '*.py' -type f -print0 | xargs -0 g # install it ######################################## export OPT=$(echo $RPM_OPT_FLAGS | sed -s "s/--param=ssp-buffer-size=32//g") -%make_install +%make_install # install site-specific tweaks -#ln -s python%{python_version} %{buildroot}%{_bindir}/python2 install -m 644 %{SOURCE4} %{buildroot}%{_libdir}/python%{python_version}/distutils -install -m 644 %{SOURCE5} %{buildroot}%{_libdir}/python%{python_version}/site-packages install -d -m 755 %{buildroot}%{_sysconfdir}/rpm install -m 644 %{SOURCE1} %{buildroot}%{_sysconfdir}/rpm # make sure /usr/lib/python/site-packages exists even on lib64 machines @@ -188,39 +189,33 @@ rm -rf %{buildroot}%{_libdir}/python%{python_version}/lib-tk %defattr(644, root, root, 755) %dir %{_docdir}/%{name} %doc %{_docdir}/%{name}/README + %license LICENSE + %config %{_sysconfdir}/pythonstart %config %{_sysconfdir}/profile.d/python.* + +%dir %{_usr}/lib/python%{python_version}/site-packages %dir %{_libdir}/python%{python_version} -%{_libdir}/python%{python_version}/ssl.py* -%{_libdir}/python%{python_version}/bsddb -%{_libdir}/python%{python_version}/sqlite3 +%dir %{_prefix}/lib/python%{python_version} %dir %{_libdir}/python%{python_version}/lib-dynload -%{_libdir}/python%{python_version}/lib-dynload/_bsddb.so -%{_libdir}/python%{python_version}/lib-dynload/_hashlib.so -%{_libdir}/python%{python_version}/lib-dynload/_sqlite3.so -%{_libdir}/python%{python_version}/lib-dynload/_ssl.so -%{_libdir}/python%{python_version}/lib-dynload/readline.so -%defattr(644, root, root, 755) -%config %{_sysconfdir}/rpm/macros.python -%doc %{_mandir}/man1/python.1* -%doc %{_mandir}/man1/python2.* -%doc %{_mandir}/man1/python%{python_version}.1* +%dir %{_libdir}/python%{python_version}/config %dir %{_includedir}/python%{python_version} -%{_includedir}/python%{python_version}/pyconfig.h + %{_libdir}/python -%dir %{_prefix}/lib/python%{python_version} -%dir %{_prefix}/lib/python%{python_version}/site-packages -%dir %{_libdir}/python%{python_version} -%dir %{_libdir}/python%{python_version}/config %{_libdir}/python%{python_version}/config/Setup %{_libdir}/python%{python_version}/config/Makefile + %{_libdir}/python%{python_version}/*.* + +%{_libdir}/python%{python_version}/bsddb +%{_libdir}/python%{python_version}/sqlite3 %{_libdir}/python%{python_version}/compiler %{_libdir}/python%{python_version}/ctypes %{_libdir}/python%{python_version}/distutils %{_libdir}/python%{python_version}/email %{_libdir}/python%{python_version}/encodings +%{_libdir}/python%{python_version}/ensurepip %{_libdir}/python%{python_version}/hotshot %{_libdir}/python%{python_version}/importlib %{_libdir}/python%{python_version}/json @@ -231,10 +226,15 @@ rm -rf %{buildroot}%{_libdir}/python%{python_version}/lib-tk %{_libdir}/python%{python_version}/pydoc_data %{_libdir}/python%{python_version}/unittest %{_libdir}/python%{python_version}/wsgiref -%dir %{_libdir}/python%{python_version}/site-packages %{_libdir}/python%{python_version}/site-packages/README -%{_libdir}/python%{python_version}/site-packages/_local.pth -%dir %{_libdir}/python%{python_version}/lib-dynload + +%{_includedir}/python%{python_version}/pyconfig.h + +%{_libdir}/python%{python_version}/lib-dynload/_bsddb.so +%{_libdir}/python%{python_version}/lib-dynload/_hashlib.so +%{_libdir}/python%{python_version}/lib-dynload/_sqlite3.so +%{_libdir}/python%{python_version}/lib-dynload/_ssl.so +%{_libdir}/python%{python_version}/lib-dynload/readline.so %{_libdir}/python%{python_version}/lib-dynload/_bisect.so %{_libdir}/python%{python_version}/lib-dynload/_csv.so %{_libdir}/python%{python_version}/lib-dynload/_collections.so @@ -295,6 +295,13 @@ rm -rf %{buildroot}%{_libdir}/python%{python_version}/lib-tk # requires sizeof(int) == sizeof(long) == sizeof(char*) %{_libdir}/python%{python_version}/lib-dynload/dl.so %endif + +%defattr(644, root, root, 755) +%config %{_sysconfdir}/rpm/macros.python + +%doc %{_mandir}/man1/python.1* +%doc %{_mandir}/man1/python2.* +%doc %{_mandir}/man1/python%{python_version}.1* %attr(755, root, root) %{_bindir}/pydoc %attr(755, root, root) %{_bindir}/python %attr(755, root, root) %{_bindir}/python%{python_version} diff --git a/packaging/python_lib64.patch b/packaging/python_lib64.patch new file mode 100644 index 0000000..22159fc --- /dev/null +++ b/packaging/python_lib64.patch @@ -0,0 +1,142 @@ +diff --git a/Lib/distutils/command/install.py b/Lib/distutils/command/install.py +index b9f1c6c..7b23714 100644 +--- a/Lib/distutils/command/install.py ++++ b/Lib/distutils/command/install.py +@@ -42,14 +42,14 @@ else: + INSTALL_SCHEMES = { + 'unix_prefix': { + 'purelib': '$base/lib/python$py_version_short/site-packages', +- 'platlib': '$platbase/lib/python$py_version_short/site-packages', ++ 'platlib': '$platbase/lib64/python$py_version_short/site-packages', + 'headers': '$base/include/python$py_version_short/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', + }, + 'unix_home': { + 'purelib': '$base/lib/python', +- 'platlib': '$base/lib/python', ++ 'platlib': '$base/lib64/python', + 'headers': '$base/include/python/$dist_name', + 'scripts': '$base/bin', + 'data' : '$base', +diff --git a/Lib/distutils/sysconfig.py b/Lib/distutils/sysconfig.py +index de7da1d..5333b06 100644 +--- a/Lib/distutils/sysconfig.py ++++ b/Lib/distutils/sysconfig.py +@@ -119,8 +119,11 @@ def get_python_lib(plat_specific=0, standard_lib=0, prefix=None): + prefix = plat_specific and EXEC_PREFIX or PREFIX + + if os.name == "posix": +- libpython = os.path.join(prefix, +- "lib", "python" + get_python_version()) ++ if plat_specific or standard_lib: ++ lib = "lib64" ++ else: ++ lib = "lib" ++ libpython = os.path.join(prefix, lib, "python" + get_python_version()) + if standard_lib: + return libpython + else: +diff --git a/Lib/site.py b/Lib/site.py +index 3b51e81..9fd76c8 100644 +--- a/Lib/site.py ++++ b/Lib/site.py +@@ -288,12 +288,16 @@ def getsitepackages(): + if sys.platform in ('os2emx', 'riscos'): + sitepackages.append(os.path.join(prefix, "Lib", "site-packages")) + elif os.sep == '/': ++ sitepackages.append(os.path.join(prefix, "lib64", ++ "python" + sys.version[:3], ++ "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", + "python" + sys.version[:3], + "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", "site-python")) + else: + sitepackages.append(prefix) ++ sitepackages.append(os.path.join(prefix, "lib64", "site-packages")) + sitepackages.append(os.path.join(prefix, "lib", "site-packages")) + return sitepackages + +diff --git a/Makefile.pre.in b/Makefile.pre.in +index 9297e7f..773f15d 100644 +--- a/Makefile.pre.in ++++ b/Makefile.pre.in +@@ -110,7 +110,7 @@ LIBDIR= @libdir@ + MANDIR= @mandir@ + INCLUDEDIR= @includedir@ + CONFINCLUDEDIR= $(exec_prefix)/include +-SCRIPTDIR= $(prefix)/lib ++SCRIPTDIR= $(prefix)/lib64 + + # Detailed destination directories + BINLIBDEST= $(LIBDIR)/python$(VERSION) +diff --git a/Modules/getpath.c b/Modules/getpath.c +index c42ce31..2d68cb4 100644 +--- a/Modules/getpath.c ++++ b/Modules/getpath.c +@@ -108,7 +108,7 @@ static char prefix[MAXPATHLEN+1]; + static char exec_prefix[MAXPATHLEN+1]; + static char progpath[MAXPATHLEN+1]; + static char *module_search_path = NULL; +-static char lib_python[] = "lib/python" VERSION; ++static char lib_python[] = "lib64/python" VERSION; + + static void + reduce(char *dir) +@@ -520,7 +520,7 @@ calculate_path(void) + } + else + strncpy(zip_path, PREFIX, MAXPATHLEN); +- joinpath(zip_path, "lib/python00.zip"); ++ joinpath(zip_path, "lib64/python00.zip"); + bufsz = strlen(zip_path); /* Replace "00" with version */ + zip_path[bufsz - 6] = VERSION[0]; + zip_path[bufsz - 5] = VERSION[2]; +@@ -530,7 +530,7 @@ calculate_path(void) + fprintf(stderr, + "Could not find platform dependent libraries <exec_prefix>\n"); + strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); +- joinpath(exec_prefix, "lib/lib-dynload"); ++ joinpath(exec_prefix, "lib64/lib-dynload"); + } + /* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */ + +diff --git a/setup.py b/setup.py +index 33cecc6..b787487 100644 +--- a/setup.py ++++ b/setup.py +@@ -456,7 +456,7 @@ class PyBuildExt(build_ext): + def detect_modules(self): + # Ensure that /usr/local is always used + if not cross_compiling: +- add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') ++ add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib64') + add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') + if cross_compiling: + self.add_gcc_paths() +@@ -782,11 +782,11 @@ class PyBuildExt(build_ext): + elif curses_library: + readline_libs.append(curses_library) + elif self.compiler.find_library_file(lib_dirs + +- ['/usr/lib/termcap'], ++ ['/usr/lib64/termcap'], + 'termcap'): + readline_libs.append('termcap') + exts.append( Extension('readline', ['readline.c'], +- library_dirs=['/usr/lib/termcap'], ++ library_dirs=['/usr/lib64/termcap'], + extra_link_args=readline_extra_link_args, + libraries=readline_libs) ) + else: +@@ -821,8 +821,8 @@ class PyBuildExt(build_ext): + if krb5_h: + ssl_incs += krb5_h + ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs, +- ['/usr/local/ssl/lib', +- '/usr/contrib/ssl/lib/' ++ ['/usr/local/ssl/lib64', ++ '/usr/contrib/ssl/lib64/' + ] ) + + if (ssl_incs is not None and diff --git a/pyconfig.h.in b/pyconfig.h.in index 99f2bb0..4da6e71 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -109,9 +109,6 @@ /* Define to 1 if you have the 'chflags' function. */ #undef HAVE_CHFLAGS -/* Define to 1 if you have the `canonicalize_file_name' function. */ -#undef HAVE_CANONICALIZE_FILE_NAME - /* Define to 1 if you have the `chown' function. */ #undef HAVE_CHOWN @@ -502,7 +502,7 @@ class PyBuildExt(build_ext): def detect_modules(self): # Ensure that /usr/local is always used if not cross_compiling: - add_dir_to_list(self.compiler.library_dirs, '/usr/local/' + sys.lib) + add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') if cross_compiling: self.add_gcc_paths() @@ -828,11 +828,11 @@ class PyBuildExt(build_ext): elif curses_library: readline_libs.append(curses_library) elif self.compiler.find_library_file(lib_dirs + - ['/usr/'+sys.lib+'/termcap'], + ['/usr/lib/termcap'], 'termcap'): readline_libs.append('termcap') exts.append( Extension('readline', ['readline.c'], - library_dirs=['/usr/'+sys.lib+'/termcap'], + library_dirs=['/usr/lib/termcap'], extra_link_args=readline_extra_link_args, libraries=readline_libs) ) else: @@ -951,7 +951,7 @@ class PyBuildExt(build_ext): # a release. Most open source OSes come with one or more # versions of BerkeleyDB already installed. - max_db_ver = (6, 0) + max_db_ver = (5, 3) min_db_ver = (4, 3) db_setup_debug = False # verbose debug prints from this script? @@ -991,7 +991,6 @@ class PyBuildExt(build_ext): # construct a list of paths to look for the header file in on # top of the normal inc_dirs. db_inc_paths = [ - '/usr/include/db6', '/usr/include/db4', '/usr/local/include/db4', '/opt/sfw/include/db4', @@ -1031,7 +1030,6 @@ class PyBuildExt(build_ext): for dn in inc_dirs: std_variants.append(os.path.join(dn, 'db3')) std_variants.append(os.path.join(dn, 'db4')) - std_variants.append(os.path.join(dn, 'db6')) for x in gen_db_minor_ver_nums(4): std_variants.append(os.path.join(dn, "db4%d"%x)) std_variants.append(os.path.join(dn, "db4.%d"%x)) @@ -1981,17 +1979,18 @@ class PyBuildExt(build_ext): # Check for various platform-specific directories if host_platform == 'sunos5': include_dirs.append('/usr/openwin/include') - added_lib_dirs.append('/usr/openwin/' + sys.lib) + added_lib_dirs.append('/usr/openwin/lib') elif os.path.exists('/usr/X11R6/include'): include_dirs.append('/usr/X11R6/include') - added_lib_dirs.append('/usr/X11R6/' + sys.lib) + added_lib_dirs.append('/usr/X11R6/lib64') + added_lib_dirs.append('/usr/X11R6/lib') elif os.path.exists('/usr/X11R5/include'): include_dirs.append('/usr/X11R5/include') - added_lib_dirs.append('/usr/X11R5/' + sys.lib) + added_lib_dirs.append('/usr/X11R5/lib') else: # Assume default location for X11 include_dirs.append('/usr/X11/include') - added_lib_dirs.append('/usr/X11/' + sys.lib) + added_lib_dirs.append('/usr/X11/lib') # If Cygwin, then verify that X is installed before proceeding if host_platform == 'cygwin': |