[Python-checkins] bpo-26544: Fixed implementation of platform.libc_ver(). (GH-7684). (GH-8193) (GH-8196)
Serhiy Storchaka
webhook-mailer at python.org
Mon Jul 9 07:39:10 EDT 2018
https://github.com/python/cpython/commit/b1e6e5615a8e82fcf569368fac5c5b0385929855
commit: b1e6e5615a8e82fcf569368fac5c5b0385929855
branch: 2.7
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018-07-09T14:39:06+03:00
summary:
bpo-26544: Fixed implementation of platform.libc_ver(). (GH-7684). (GH-8193) (GH-8196)
(cherry picked from commit 2a9b8babf0d09946ebebfdb2931cc0d3db5a1d3d).
(cherry picked from commit 7c43b801503c802ed6ea4b811f5bc73791249d94)
files:
A Misc/NEWS.d/next/Library/2018-06-13-20-33-29.bpo-26544.hQ1oMt.rst
M Lib/platform.py
M Lib/test/test_platform.py
diff --git a/Lib/platform.py b/Lib/platform.py
index 55f2fa89957f..44a612b28fce 100755
--- a/Lib/platform.py
+++ b/Lib/platform.py
@@ -140,9 +140,7 @@
'|'
'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)')
-def libc_ver(executable=sys.executable,lib='',version='',
-
- chunksize=2048):
+def libc_ver(executable=sys.executable,lib='',version='', chunksize=2048):
""" Tries to determine the libc version that the file executable
(which defaults to the Python interpreter) is linked against.
@@ -157,40 +155,42 @@ def libc_ver(executable=sys.executable,lib='',version='',
The file is read and scanned in chunks of chunksize bytes.
"""
+ from distutils.version import LooseVersion as V
if hasattr(os.path, 'realpath'):
# Python 2.2 introduced os.path.realpath(); it is used
# here to work around problems with Cygwin not being
# able to open symlinks for reading
executable = os.path.realpath(executable)
- f = open(executable,'rb')
- binary = f.read(chunksize)
- pos = 0
- while 1:
- m = _libc_search.search(binary,pos)
- if not m:
- binary = f.read(chunksize)
- if not binary:
- break
- pos = 0
- continue
- libcinit,glibc,glibcversion,so,threads,soversion = m.groups()
- if libcinit and not lib:
- lib = 'libc'
- elif glibc:
- if lib != 'glibc':
- lib = 'glibc'
- version = glibcversion
- elif glibcversion > version:
- version = glibcversion
- elif so:
- if lib != 'glibc':
+ with open(executable, 'rb') as f:
+ binary = f.read(chunksize)
+ pos = 0
+ while pos < len(binary):
+ m = _libc_search.search(binary,pos)
+ if not m or m.end() == len(binary):
+ chunk = f.read(chunksize)
+ if chunk:
+ binary = binary[max(pos, len(binary) - 1000):] + chunk
+ pos = 0
+ continue
+ if not m:
+ break
+ libcinit,glibc,glibcversion,so,threads,soversion = m.groups()
+ if libcinit and not lib:
lib = 'libc'
- if soversion and soversion > version:
- version = soversion
- if threads and version[-len(threads):] != threads:
- version = version + threads
- pos = m.end()
- f.close()
+ elif glibc:
+ if lib != 'glibc':
+ lib = 'glibc'
+ version = glibcversion
+ elif V(glibcversion) > V(version):
+ version = glibcversion
+ elif so:
+ if lib != 'glibc':
+ lib = 'libc'
+ if soversion and (not version or V(soversion) > V(version)):
+ version = soversion
+ if threads and version[-len(threads):] != threads:
+ version = version + threads
+ pos = m.end()
return lib,version
def _dist_try_harder(distname,version,id):
@@ -451,6 +451,7 @@ def popen(cmd, mode='r', bufsize=None):
else:
return popen(cmd,mode,bufsize)
+
def _norm_version(version, build=''):
""" Normalize the version and build strings and return a single
diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py
index f754550f95d5..542763d46dfd 100644
--- a/Lib/test/test_platform.py
+++ b/Lib/test/test_platform.py
@@ -4,7 +4,7 @@
import platform
import subprocess
-from test import test_support
+from test import support
class PlatformTest(unittest.TestCase):
def test_architecture(self):
@@ -18,7 +18,7 @@ def get(python):
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
return p.communicate()
real = os.path.realpath(sys.executable)
- link = os.path.abspath(test_support.TESTFN)
+ link = os.path.abspath(support.TESTFN)
os.symlink(real, link)
try:
self.assertEqual(get(real), get(link))
@@ -163,7 +163,7 @@ def test_uname_win32_ARCHITEW6432(self):
# using it, per
# http://blogs.msdn.com/david.wang/archive/2006/03/26/HOWTO-Detect-Process-Bitness.aspx
try:
- with test_support.EnvironmentVarGuard() as environ:
+ with support.EnvironmentVarGuard() as environ:
if 'PROCESSOR_ARCHITEW6432' in environ:
del environ['PROCESSOR_ARCHITEW6432']
environ['PROCESSOR_ARCHITECTURE'] = 'foo'
@@ -247,7 +247,6 @@ def test_dist(self):
res = platform.dist()
def test_libc_ver(self):
- import os
if os.path.isdir(sys.executable) and \
os.path.exists(sys.executable+'.exe'):
# Cygwin horror
@@ -256,6 +255,13 @@ def test_libc_ver(self):
executable = sys.executable
res = platform.libc_ver(executable)
+ self.addCleanup(support.unlink, support.TESTFN)
+ with open(support.TESTFN, 'wb') as f:
+ f.write(b'x'*(16384-10))
+ f.write(b'GLIBC_1.23.4\0GLIBC_1.9\0GLIBC_1.21\0')
+ self.assertEqual(platform.libc_ver(support.TESTFN),
+ ('glibc', '1.23.4'))
+
def test_parse_release_file(self):
for input, output in (
@@ -275,7 +281,7 @@ def test_parse_release_file(self):
def test_main():
- test_support.run_unittest(
+ support.run_unittest(
PlatformTest
)
diff --git a/Misc/NEWS.d/next/Library/2018-06-13-20-33-29.bpo-26544.hQ1oMt.rst b/Misc/NEWS.d/next/Library/2018-06-13-20-33-29.bpo-26544.hQ1oMt.rst
new file mode 100644
index 000000000000..e2cd0bad6e2c
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-06-13-20-33-29.bpo-26544.hQ1oMt.rst
@@ -0,0 +1,2 @@
+Fixed implementation of :func:`platform.libc_ver`. It almost always returned
+version '2.9' for glibc.
More information about the Python-checkins
mailing list