mirror of https://github.com/python/cpython
gh-103977: compile re expressions in platform.py only if required (#103981)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
This commit is contained in:
parent
ed95e8cbd4
commit
f186557dc3
|
@ -136,11 +136,11 @@ _ver_stages = {
|
||||||
'pl': 200, 'p': 200,
|
'pl': 200, 'p': 200,
|
||||||
}
|
}
|
||||||
|
|
||||||
_component_re = re.compile(r'([0-9]+|[._+-])')
|
|
||||||
|
|
||||||
def _comparable_version(version):
|
def _comparable_version(version):
|
||||||
|
component_re = re.compile(r'([0-9]+|[._+-])')
|
||||||
result = []
|
result = []
|
||||||
for v in _component_re.split(version):
|
for v in component_re.split(version):
|
||||||
if v not in '._+-':
|
if v not in '._+-':
|
||||||
try:
|
try:
|
||||||
v = int(v, 10)
|
v = int(v, 10)
|
||||||
|
@ -152,11 +152,6 @@ def _comparable_version(version):
|
||||||
|
|
||||||
### Platform specific APIs
|
### Platform specific APIs
|
||||||
|
|
||||||
_libc_search = re.compile(b'(__libc_init)'
|
|
||||||
b'|'
|
|
||||||
b'(GLIBC_([0-9.]+))'
|
|
||||||
b'|'
|
|
||||||
br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII)
|
|
||||||
|
|
||||||
def libc_ver(executable=None, lib='', version='', chunksize=16384):
|
def libc_ver(executable=None, lib='', version='', chunksize=16384):
|
||||||
|
|
||||||
|
@ -190,6 +185,12 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384):
|
||||||
# sys.executable is not set.
|
# sys.executable is not set.
|
||||||
return lib, version
|
return lib, version
|
||||||
|
|
||||||
|
libc_search = re.compile(b'(__libc_init)'
|
||||||
|
b'|'
|
||||||
|
b'(GLIBC_([0-9.]+))'
|
||||||
|
b'|'
|
||||||
|
br'(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)', re.ASCII)
|
||||||
|
|
||||||
V = _comparable_version
|
V = _comparable_version
|
||||||
# We use os.path.realpath()
|
# We use os.path.realpath()
|
||||||
# here to work around problems with Cygwin not being
|
# here to work around problems with Cygwin not being
|
||||||
|
@ -200,7 +201,7 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384):
|
||||||
pos = 0
|
pos = 0
|
||||||
while pos < len(binary):
|
while pos < len(binary):
|
||||||
if b'libc' in binary or b'GLIBC' in binary:
|
if b'libc' in binary or b'GLIBC' in binary:
|
||||||
m = _libc_search.search(binary, pos)
|
m = libc_search.search(binary, pos)
|
||||||
else:
|
else:
|
||||||
m = None
|
m = None
|
||||||
if not m or m.end() == len(binary):
|
if not m or m.end() == len(binary):
|
||||||
|
@ -247,9 +248,6 @@ def _norm_version(version, build=''):
|
||||||
version = '.'.join(strings[:3])
|
version = '.'.join(strings[:3])
|
||||||
return version
|
return version
|
||||||
|
|
||||||
_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) '
|
|
||||||
r'.*'
|
|
||||||
r'\[.* ([\d.]+)\])')
|
|
||||||
|
|
||||||
# Examples of VER command output:
|
# Examples of VER command output:
|
||||||
#
|
#
|
||||||
|
@ -295,9 +293,13 @@ def _syscmd_ver(system='', release='', version='',
|
||||||
else:
|
else:
|
||||||
return system, release, version
|
return system, release, version
|
||||||
|
|
||||||
|
ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) '
|
||||||
|
r'.*'
|
||||||
|
r'\[.* ([\d.]+)\])')
|
||||||
|
|
||||||
# Parse the output
|
# Parse the output
|
||||||
info = info.strip()
|
info = info.strip()
|
||||||
m = _ver_output.match(info)
|
m = ver_output.match(info)
|
||||||
if m is not None:
|
if m is not None:
|
||||||
system, release, version = m.groups()
|
system, release, version = m.groups()
|
||||||
# Strip trailing dots from version and release
|
# Strip trailing dots from version and release
|
||||||
|
@ -1033,18 +1035,6 @@ def processor():
|
||||||
|
|
||||||
### Various APIs for extracting information from sys.version
|
### Various APIs for extracting information from sys.version
|
||||||
|
|
||||||
_sys_version_parser = re.compile(
|
|
||||||
r'([\w.+]+)\s*' # "version<space>"
|
|
||||||
r'\(#?([^,]+)' # "(#buildno"
|
|
||||||
r'(?:,\s*([\w ]*)' # ", builddate"
|
|
||||||
r'(?:,\s*([\w :]*))?)?\)\s*' # ", buildtime)<space>"
|
|
||||||
r'\[([^\]]+)\]?', re.ASCII) # "[compiler]"
|
|
||||||
|
|
||||||
_pypy_sys_version_parser = re.compile(
|
|
||||||
r'([\w.+]+)\s*'
|
|
||||||
r'\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
|
|
||||||
r'\[PyPy [^\]]+\]?')
|
|
||||||
|
|
||||||
_sys_version_cache = {}
|
_sys_version_cache = {}
|
||||||
|
|
||||||
def _sys_version(sys_version=None):
|
def _sys_version(sys_version=None):
|
||||||
|
@ -1076,10 +1066,17 @@ def _sys_version(sys_version=None):
|
||||||
if result is not None:
|
if result is not None:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
sys_version_parser = re.compile(
|
||||||
|
r'([\w.+]+)\s*' # "version<space>"
|
||||||
|
r'\(#?([^,]+)' # "(#buildno"
|
||||||
|
r'(?:,\s*([\w ]*)' # ", builddate"
|
||||||
|
r'(?:,\s*([\w :]*))?)?\)\s*' # ", buildtime)<space>"
|
||||||
|
r'\[([^\]]+)\]?', re.ASCII) # "[compiler]"
|
||||||
|
|
||||||
if sys.platform.startswith('java'):
|
if sys.platform.startswith('java'):
|
||||||
# Jython
|
# Jython
|
||||||
name = 'Jython'
|
name = 'Jython'
|
||||||
match = _sys_version_parser.match(sys_version)
|
match = sys_version_parser.match(sys_version)
|
||||||
if match is None:
|
if match is None:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'failed to parse Jython sys.version: %s' %
|
'failed to parse Jython sys.version: %s' %
|
||||||
|
@ -1091,8 +1088,13 @@ def _sys_version(sys_version=None):
|
||||||
|
|
||||||
elif "PyPy" in sys_version:
|
elif "PyPy" in sys_version:
|
||||||
# PyPy
|
# PyPy
|
||||||
|
pypy_sys_version_parser = re.compile(
|
||||||
|
r'([\w.+]+)\s*'
|
||||||
|
r'\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*'
|
||||||
|
r'\[PyPy [^\]]+\]?')
|
||||||
|
|
||||||
name = "PyPy"
|
name = "PyPy"
|
||||||
match = _pypy_sys_version_parser.match(sys_version)
|
match = pypy_sys_version_parser.match(sys_version)
|
||||||
if match is None:
|
if match is None:
|
||||||
raise ValueError("failed to parse PyPy sys.version: %s" %
|
raise ValueError("failed to parse PyPy sys.version: %s" %
|
||||||
repr(sys_version))
|
repr(sys_version))
|
||||||
|
@ -1101,7 +1103,7 @@ def _sys_version(sys_version=None):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# CPython
|
# CPython
|
||||||
match = _sys_version_parser.match(sys_version)
|
match = sys_version_parser.match(sys_version)
|
||||||
if match is None:
|
if match is None:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'failed to parse CPython sys.version: %s' %
|
'failed to parse CPython sys.version: %s' %
|
||||||
|
@ -1290,13 +1292,6 @@ def platform(aliased=False, terse=False):
|
||||||
### freedesktop.org os-release standard
|
### freedesktop.org os-release standard
|
||||||
# https://www.freedesktop.org/software/systemd/man/os-release.html
|
# https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||||
|
|
||||||
# NAME=value with optional quotes (' or "). The regular expression is less
|
|
||||||
# strict than shell lexer, but that's ok.
|
|
||||||
_os_release_line = re.compile(
|
|
||||||
"^(?P<name>[a-zA-Z0-9_]+)=(?P<quote>[\"\']?)(?P<value>.*)(?P=quote)$"
|
|
||||||
)
|
|
||||||
# unescape five special characters mentioned in the standard
|
|
||||||
_os_release_unescape = re.compile(r"\\([\\\$\"\'`])")
|
|
||||||
# /etc takes precedence over /usr/lib
|
# /etc takes precedence over /usr/lib
|
||||||
_os_release_candidates = ("/etc/os-release", "/usr/lib/os-release")
|
_os_release_candidates = ("/etc/os-release", "/usr/lib/os-release")
|
||||||
_os_release_cache = None
|
_os_release_cache = None
|
||||||
|
@ -1311,10 +1306,18 @@ def _parse_os_release(lines):
|
||||||
"PRETTY_NAME": "Linux",
|
"PRETTY_NAME": "Linux",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# NAME=value with optional quotes (' or "). The regular expression is less
|
||||||
|
# strict than shell lexer, but that's ok.
|
||||||
|
os_release_line = re.compile(
|
||||||
|
"^(?P<name>[a-zA-Z0-9_]+)=(?P<quote>[\"\']?)(?P<value>.*)(?P=quote)$"
|
||||||
|
)
|
||||||
|
# unescape five special characters mentioned in the standard
|
||||||
|
os_release_unescape = re.compile(r"\\([\\\$\"\'`])")
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
mo = _os_release_line.match(line)
|
mo = os_release_line.match(line)
|
||||||
if mo is not None:
|
if mo is not None:
|
||||||
info[mo.group('name')] = _os_release_unescape.sub(
|
info[mo.group('name')] = os_release_unescape.sub(
|
||||||
r"\1", mo.group('value')
|
r"\1", mo.group('value')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Improve import time of :mod:`platform` module.
|
Loading…
Reference in New Issue