[Python-checkins] [3.7] bpo-26544: Fixed implementation of platform.libc_ver(). (GH-7684). (GH-8193)

Serhiy Storchaka webhook-mailer at python.org
Mon Jul 9 05:55:38 EDT 2018


https://github.com/python/cpython/commit/7c43b801503c802ed6ea4b811f5bc73791249d94
commit: 7c43b801503c802ed6ea4b811f5bc73791249d94
branch: 3.7
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018年07月09日T12:55:35+03:00
summary:
[3.7] bpo-26544: Fixed implementation of platform.libc_ver(). (GH-7684). (GH-8193)
(cherry picked from commit 2a9b8babf0d09946ebebfdb2931cc0d3db5a1d3d)
files:
A Misc/NEWS.d/next/Library/2018-06-13-20-33-29.bpo-26544.hQ1oMt.rst
M Doc/library/platform.rst
M Lib/platform.py
M Lib/test/test_platform.py
diff --git a/Doc/library/platform.rst b/Doc/library/platform.rst
index f5cb52cb4745..7d29dc186b67 100644
--- a/Doc/library/platform.rst
+++ b/Doc/library/platform.rst
@@ -270,7 +270,7 @@ Unix Platforms
 .. deprecated-removed:: 3.5 3.8
 See alternative like the `distro <https://pypi.org/project/distro>`_ package.
 
-.. function:: libc_ver(executable=sys.executable, lib='', version='', chunksize=2048)
+.. function:: libc_ver(executable=sys.executable, lib='', version='', chunksize=16384)
 
 Tries to determine the libc version against which the file executable (defaults
 to the Python interpreter) is linked. Returns a tuple of strings ``(lib,
diff --git a/Lib/platform.py b/Lib/platform.py
index 20f9817f4ffb..e22734850786 100755
--- a/Lib/platform.py
+++ b/Lib/platform.py
@@ -144,9 +144,7 @@
 b'|'
 br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII)
 
-def libc_ver(executable=sys.executable, lib='', version='',
-
- chunksize=16384):
+def libc_ver(executable=sys.executable, lib='', version='', chunksize=16384):
 
 """ Tries to determine the libc version that the file executable
 (which defaults to the Python interpreter) is linked against.
@@ -161,6 +159,7 @@ 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
@@ -169,17 +168,19 @@ def libc_ver(executable=sys.executable, lib='', version='',
 with open(executable, 'rb') as f:
 binary = f.read(chunksize)
 pos = 0
- while 1:
+ while pos < len(binary):
 if b'libc' in binary or b'GLIBC' in binary:
 m = _libc_search.search(binary, pos)
 else:
 m = None
- if not m:
- binary = f.read(chunksize)
- if not binary:
+ 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
- pos = 0
- continue
 libcinit, glibc, glibcversion, so, threads, soversion = [
 s.decode('latin1') if s is not None else s
 for s in m.groups()]
@@ -189,12 +190,12 @@ def libc_ver(executable=sys.executable, lib='', version='',
 if lib != 'glibc':
 lib = 'glibc'
 version = glibcversion
- elif glibcversion > version:
+ elif V(glibcversion) > V(version):
 version = glibcversion
 elif so:
 if lib != 'glibc':
 lib = 'libc'
- if soversion and soversion > version:
+ if soversion and (not version or V(soversion) > V(version)):
 version = soversion
 if threads and version[-len(threads):] != threads:
 version = version + threads
@@ -389,6 +390,7 @@ def popen(cmd, mode='r', bufsize=-1):
 warnings.warn('use os.popen instead', DeprecationWarning, stacklevel=2)
 return os.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 d3b77eb5a610..eaf14e0f18ad 100644
--- a/Lib/test/test_platform.py
+++ b/Lib/test/test_platform.py
@@ -270,7 +270,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
@@ -279,6 +278,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.40円GLIBC_1.90円GLIBC_1.210円')
+ self.assertEqual(platform.libc_ver(support.TESTFN),
+ ('glibc', '1.23.4'))
+
 def test_parse_release_file(self):
 
 for input, output in (
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

AltStyle によって変換されたページ (->オリジナル) /