Let us walk on the 3-isogeny graph
Loading...
Searching...
No Matches
glibc.py
Go to the documentation of this file.
1
import
os
2
import
sys
3
from
typing
import
Optional, Tuple
4
5
6
def
glibc_version_string
() -> Optional[str]:
7
"Returns glibc version string, or None if not using glibc."
8
return
glibc_version_string_confstr
()
or
glibc_version_string_ctypes
()
9
10
11
def
glibc_version_string_confstr
() -> Optional[str]:
12
"Primary implementation of glibc_version_string using os.confstr."
13
# os.confstr is quite a bit faster than ctypes.DLL. It's also less likely
14
# to be broken or missing. This strategy is used in the standard library
15
# platform module:
16
# https://github.com/python/cpython/blob/fcf1d003bf4f0100c9d0921ff3d70e1127ca1b71/Lib/platform.py#L175-L183
17
if
sys.platform
==
"win32"
:
18
return
None
19
try
:
20
gnu_libc_version =
os.confstr
(
"CS_GNU_LIBC_VERSION"
)
21
if
gnu_libc_version
is
None
:
22
return
None
23
# os.confstr("CS_GNU_LIBC_VERSION") returns a string like "glibc 2.17":
24
_, version =
gnu_libc_version.split
()
25
except
(AttributeError, OSError, ValueError):
26
# os.confstr() or CS_GNU_LIBC_VERSION not available (or a bad value)...
27
return
None
28
return
version
29
30
31
def
glibc_version_string_ctypes
() -> Optional[str]:
32
"Fallback implementation of glibc_version_string using ctypes."
33
34
try
:
35
import
ctypes
36
except
ImportError:
37
return
None
38
39
# ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen
40
# manpage says, "If filename is NULL, then the returned handle is for the
41
# main program". This way we can let the linker do the work to figure out
42
# which libc our process is actually using.
43
process_namespace =
ctypes.CDLL
(
None
)
44
try
:
45
gnu_get_libc_version =
process_namespace.gnu_get_libc_version
46
except
AttributeError:
47
# Symbol doesn't exist -> therefore, we are not linked to
48
# glibc.
49
return
None
50
51
# Call gnu_get_libc_version, which returns a string like "2.5"
52
gnu_get_libc_version.restype
=
ctypes.c_char_p
53
version_str =
gnu_get_libc_version
()
54
# py2 / py3 compatibility:
55
if
not
isinstance
(version_str, str):
56
version_str =
version_str.decode
(
"ascii"
)
57
58
return
version_str
59
60
61
# platform.libc_ver regularly returns completely nonsensical glibc
62
# versions. E.g. on my computer, platform says:
63
#
64
# ~$ python2.7 -c 'import platform; print(platform.libc_ver())'
65
# ('glibc', '2.7')
66
# ~$ python3.5 -c 'import platform; print(platform.libc_ver())'
67
# ('glibc', '2.9')
68
#
69
# But the truth is:
70
#
71
# ~$ ldd --version
72
# ldd (Debian GLIBC 2.22-11) 2.22
73
#
74
# This is unfortunate, because it means that the linehaul data on libc
75
# versions that was generated by pip 8.1.2 and earlier is useless and
76
# misleading. Solution: instead of using platform, use our code that actually
77
# works.
78
def
libc_ver
() -> Tuple[str, str]:
79
"""Try to determine the glibc version
80
81
Returns a tuple of strings (lib, version) which default to empty strings
82
in case the lookup fails.
83
"""
84
glibc_version =
glibc_version_string
()
85
if
glibc_version
is
None
:
86
return
(
""
,
""
)
87
else
:
88
return
(
"glibc"
, glibc_version)
pip._internal.utils.glibc.glibc_version_string_ctypes
Optional[str] glibc_version_string_ctypes()
Definition
glibc.py:31
pip._internal.utils.glibc.glibc_version_string_confstr
Optional[str] glibc_version_string_confstr()
Definition
glibc.py:11
pip._internal.utils.glibc.libc_ver
Tuple[str, str] libc_ver()
Definition
glibc.py:78
pip._internal.utils.glibc.glibc_version_string
Optional[str] glibc_version_string()
Definition
glibc.py:6
i
for i
Definition
prime_search.m:10
venv
lib
python3.12
site-packages
pip
_internal
utils
glibc.py
Generated by
1.9.8