classification
Title: platform.libc_ver() returns incorrect version number
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.8, Python 3.7, Python 3.6, Python 2.7
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Thomas.Waldmann, benjamin.peterson, doko, lemburg, ned.deily, njs, serhiy.storchaka, vstinner
Priority: release blocker Keywords: 3.6regression, 3.7regression, patch

Created on 2016-03-12 00:36 by Thomas.Waldmann, last changed 2018-08-21 07:48 by doko.

Files
File name Uploaded Description Edit
results-20160709-224820.csv njs, 2016-07-10 06:00
platform-no-distutils.diff doko, 2018-08-20 16:00 platform-not-using-distutils
Pull Requests
URL Status Linked Edit
PR 7684 merged serhiy.storchaka, 2018-06-13 17:51
PR 8193 merged serhiy.storchaka, 2018-07-09 08:55
PR 8195 merged miss-islington, 2018-07-09 09:56
PR 8196 merged serhiy.storchaka, 2018-07-09 10:17
PR 8356 open serhiy.storchaka, 2018-07-20 17:42
Messages (22)
msg261624 - (view) Author: Thomas Waldmann (Thomas.Waldmann) Date: 2016-03-12 00:36
platform.libc_ver() is trivially broken as it uses string comparison internally to determine the maximum libc version number (which is obviously broken as "2.9" > "2.10").
msg261648 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2016-03-12 13:34
True. At the time the code was written, this was not an issue :-)

Is the libc version information documented somewhere ? If so, we could probably add a better parser for it.
msg261649 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2016-03-12 13:35
Adding other Python versions as well, since this is a bug.
msg270073 - (view) Author: Nathaniel Smith (njs) * (Python committer) Date: 2016-07-10 06:00
We just ran into this in pip -- https://github.com/pypa/pip/pull/3836

I'd really recommend dropping the current "grovel through the binary doing a regex search" strategy -- it's incredibly error prone, and AFAICT doesn't really give any value. This code OTOH reliably lets you detect glibc and gives the exact version number with no fuss:
   https://github.com/pypa/pip/blob/master/pip/utils/glibc.py#L9

What about non-glibc systems? Unfortunately the current libc_ver() turns out not to work well for those either. Attached is a CSV file showing the return value of ~1.2 billion calls to platform.libc_ver() by the last 6 months of pip users. You can see that the current code basically never returns anything useful for non-glibc platforms. (The one exception is that it seems to be able to detect uclibc 0.9.32 and label it as "libc 0.9.32".)

Don't get me wrong: it'd be really really useful if there were some way to detect and distinguish between the common non-glibc libcs like musl/bionic/uclibc/..., but I'm not sure how to do that -- and unfortunately the current code definitely doesn't do the job :-(.
msg270080 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2016-07-10 10:37
At the time the code was written, libc and glibc were in wide spread use, so it's not surprising that it doesn't work well for other C libs.

Note that the routine returns the highest libc version number used and required by the executable (usually the Python interpreter). This does not necessarily correspond to the version installed on the system. The purpose of the function was to determine the minimum libc compatibility requirements of the executable.

The routine you quote uses ctypes and only works for glibc, so parsing needs to be kept around as fallback solution. It also returns the libc version that is currently used on the system; not necessarily the minimum version required, so semantics are different.
msg270089 - (view) Author: Nathaniel Smith (njs) * (Python committer) Date: 2016-07-10 15:14
> The purpose of the function was to determine the minimum libc compatibility requirements of the executable.

For what it's worth, I didn't know this, the pip authors obviously didn't know this, and after rereading the docs just now I still can't quite tell that this was intended. I'm not sure why one would want these semantics either, but at a minimum it would help to document the intended semantics much more clearly.

> parsing needs to be kept around as fallback solution

The point of the data I attached was that AFAICT there don't exist any currently-in-use, non-glibc systems where "parsing" returns a meaningful result.
msg319456 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-06-13 12:34
I need the glibc version for skipping a test if run with glibc containing a bug (see issue31630 and issue33630). platform.libc_ver() is not usable, it always returns '2.9' (the version that has bugs), while the actual version on my computer is '2.25' (the version that doesn't have these bugs).
msg319479 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-06-13 17:50
I agree that the strategy used for platform.libc_ver() is not perfect. But the implementation has bugs that make it useless. The following PR fixes two bugs in the implementation:

1) Version numbers compared as strings.
2) Versions that are located on the border of 16 KiB blocks were not recognized or were recognized incorrectly.
msg321301 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-07-09 08:47
New changeset 2a9b8babf0d09946ebebfdb2931cc0d3db5a1d3d by Serhiy Storchaka in branch 'master':
bpo-26544: Fixed implementation of platform.libc_ver(). (GH-7684)
https://github.com/python/cpython/commit/2a9b8babf0d09946ebebfdb2931cc0d3db5a1d3d
msg321308 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-07-09 09:55
New changeset 7c43b801503c802ed6ea4b811f5bc73791249d94 by Serhiy Storchaka in branch '3.7':
[3.7] bpo-26544: Fixed implementation of platform.libc_ver(). (GH-7684). (GH-8193)
https://github.com/python/cpython/commit/7c43b801503c802ed6ea4b811f5bc73791249d94
msg321310 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-07-09 11:38
New changeset d73497ba52171bc8f786a70ecf50d3104b596221 by Serhiy Storchaka (Miss Islington (bot)) in branch '3.6':
bpo-26544: Fixed implementation of platform.libc_ver(). (GH-7684). (GH-8193) (GH-8195)
https://github.com/python/cpython/commit/d73497ba52171bc8f786a70ecf50d3104b596221
msg321311 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-07-09 11:39
New changeset b1e6e5615a8e82fcf569368fac5c5b0385929855 by Serhiy Storchaka in branch '2.7':
bpo-26544: Fixed implementation of platform.libc_ver(). (GH-7684). (GH-8193) (GH-8196)
https://github.com/python/cpython/commit/b1e6e5615a8e82fcf569368fac5c5b0385929855
msg321462 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2018-07-11 14:39
Can we close this issue? It seems like the bug has been fixed, no?
msg322021 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2018-07-20 15:46
please don't close this yet.  the patch introduces a dependency on the distutils package.  I don't see any reason to compare the libc version as a python egg version, so please avoid that.

if we need to have a module to compare arbitrary version strings, then we should think about adding one in the standard library, but I think that's what the packaging module is for.
msg322023 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2018-07-20 15:55
a tuple comparison should be good enough
msg323795 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2018-08-20 15:33
no, it's not fixed at all. Setting as a release blocker for 3.6 and 3.7.
msg323796 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2018-08-20 16:00
proposed patch attached
msg323802 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-08-20 17:22
platform-no-distutils.diff restores the original bug: "2.9" > "2.10".

PR 8356 removes the dependency from distutils and use a sophisticated function for parsing versions.
msg323805 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2018-08-20 17:57
fine! what prevents merging and backporting this issue?
msg323816 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2018-08-21 03:38
I'll merge it if it looks good to you.
msg323823 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2018-08-21 07:26
I added a comment to the PR, but other than that I think it's good to go.
msg323825 - (view) Author: Matthias Klose (doko) * (Python committer) Date: 2018-08-21 07:48
+1
History
Date User Action Args
2018-08-21 07:48:33dokosetmessages: + msg323825
2018-08-21 07:26:53lemburgsetmessages: + msg323823
2018-08-21 03:38:31serhiy.storchakasetmessages: + msg323816
2018-08-20 17:57:12dokosetmessages: + msg323805
2018-08-20 17:22:27serhiy.storchakasetmessages: + msg323802
2018-08-20 16:00:56dokosetmessages: + msg323796
2018-08-20 16:00:30dokosetfiles: + platform-no-distutils.diff
2018-08-20 15:33:06dokosetpriority: normal -> release blocker

nosy: + ned.deily, benjamin.peterson
messages: + msg323795

keywords: + 3.6regression, 3.7regression
2018-07-20 17:42:05serhiy.storchakasetpull_requests: + pull_request7891
2018-07-20 15:55:14dokosetmessages: + msg322023
2018-07-20 15:46:14dokosetnosy: + doko
messages: + msg322021
2018-07-11 14:39:39vstinnersetnosy: + vstinner
messages: + msg321462
2018-07-09 11:39:09serhiy.storchakasetmessages: + msg321311
2018-07-09 11:38:30serhiy.storchakasetmessages: + msg321310
2018-07-09 10:17:15serhiy.storchakasetpull_requests: + pull_request7748
2018-07-09 09:56:47miss-islingtonsetpull_requests: + pull_request7747
2018-07-09 09:55:38serhiy.storchakasetmessages: + msg321308
2018-07-09 08:55:29serhiy.storchakasetpull_requests: + pull_request7745
2018-07-09 08:47:49serhiy.storchakasetmessages: + msg321301
2018-06-13 17:51:27serhiy.storchakasetversions: + Python 3.7, Python 3.8, - Python 3.4, Python 3.5
2018-06-13 17:51:06serhiy.storchakasetkeywords: + patch
stage: patch review
pull_requests: + pull_request7297
2018-06-13 17:50:38serhiy.storchakasetmessages: + msg319479
2018-06-13 12:34:53serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg319456
2016-07-10 15:14:08njssetmessages: + msg270089
2016-07-10 10:37:00lemburgsetmessages: + msg270080
2016-07-10 06:00:48njssetfiles: + results-20160709-224820.csv
nosy: + njs
messages: + msg270073

2016-03-12 13:35:18lemburgsetmessages: + msg261649
versions: + Python 2.7, Python 3.4, Python 3.6
2016-03-12 13:34:39lemburgsetmessages: + msg261648
2016-03-12 00:39:49ned.deilysetnosy: + lemburg
2016-03-12 00:36:03Thomas.Waldmanncreate