From c8f51fd8df42a4ad2b81fdc3144d5fa8c3f50bfa Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 21 Apr 2023 16:45:35 +0200 Subject: [PATCH 1/8] compile re expressions only if required --- Lib/platform.py | 65 ++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/Lib/platform.py b/Lib/platform.py index 790ef860bf106e..9a2ad95c999594 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -152,11 +152,6 @@ def _comparable_version(version): ### 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): @@ -190,6 +185,12 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384): # sys.executable is not set. 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 # We use os.path.realpath() # here to work around problems with Cygwin not being @@ -247,9 +248,6 @@ def _norm_version(version, build=''): version = '.'.join(strings[:3]) return version -_ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' - r'.*' - r'\[.* ([\d.]+)\])') # Examples of VER command output: # @@ -295,6 +293,10 @@ def _syscmd_ver(system='', release='', version='', else: return system, release, version + _ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' + r'.*' + r'\[.* ([\d.]+)\])') + # Parse the output info = info.strip() m = _ver_output.match(info) @@ -1033,18 +1035,6 @@ def processor(): ### Various APIs for extracting information from sys.version -_sys_version_parser = re.compile( - r'([\w.+]+)\s*' # "version" - r'\(#?([^,]+)' # "(#buildno" - r'(?:,\s*([\w ]*)' # ", builddate" - r'(?:,\s*([\w :]*))?)?\)\s*' # ", buildtime)" - r'\[([^\]]+)\]?', re.ASCII) # "[compiler]" - -_pypy_sys_version_parser = re.compile( - r'([\w.+]+)\s*' - r'\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' - r'\[PyPy [^\]]+\]?') - _sys_version_cache = {} def _sys_version(sys_version=None): @@ -1076,6 +1066,13 @@ def _sys_version(sys_version=None): if result is not None: return result + _sys_version_parser = re.compile( + r'([\w.+]+)\s*' # "version" + r'\(#?([^,]+)' # "(#buildno" + r'(?:,\s*([\w ]*)' # ", builddate" + r'(?:,\s*([\w :]*))?)?\)\s*' # ", buildtime)" + r'\[([^\]]+)\]?', re.ASCII) # "[compiler]" + if sys.platform.startswith('java'): # Jython name = 'Jython' @@ -1091,6 +1088,11 @@ def _sys_version(sys_version=None): elif "PyPy" in sys_version: # PyPy + _pypy_sys_version_parser = re.compile( + r'([\w.+]+)\s*' + r'\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' + r'\[PyPy [^\]]+\]?') + name = "PyPy" match = _pypy_sys_version_parser.match(sys_version) if match is None: @@ -1290,17 +1292,6 @@ def platform(aliased=False, terse=False): ### freedesktop.org os-release standard # 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[a-zA-Z0-9_]+)=(?P[\"\']?)(?P.*)(?P=quote)$" -) -# unescape five special characters mentioned in the standard -_os_release_unescape = re.compile(r"\\([\\\$\"\'`])") -# /etc takes precedence over /usr/lib -_os_release_candidates = ("/etc/os-release", "/usr/lib/os-release") -_os_release_cache = None - def _parse_os_release(lines): # These fields are mandatory fields with well-known defaults @@ -1311,6 +1302,14 @@ def _parse_os_release(lines): "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[a-zA-Z0-9_]+)=(?P[\"\']?)(?P.*)(?P=quote)$" + ) + # unescape five special characters mentioned in the standard + _os_release_unescape = re.compile(r"\\([\\\$\"\'`])") + for line in lines: mo = _os_release_line.match(line) if mo is not None: @@ -1326,6 +1325,10 @@ def freedesktop_os_release(): """ global _os_release_cache + # /etc takes precedence over /usr/lib + _os_release_candidates = ("/etc/os-release", "/usr/lib/os-release") + _os_release_cache = None + if _os_release_cache is None: errno = None for candidate in _os_release_candidates: From def8f54be638e8a1bf8e1eb5c1d2875e97f72f53 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 28 Apr 2023 19:08:54 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst diff --git a/Misc/NEWS.d/next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst b/Misc/NEWS.d/next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst new file mode 100644 index 00000000000000..8bd09c613cd08c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst @@ -0,0 +1 @@ +Improve import time of platform module. From 4061a6b32407c9bea44acbe445eec448e35f6592 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 28 Apr 2023 23:24:15 +0200 Subject: [PATCH 3/8] revert _os_release_cache --- Lib/platform.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Lib/platform.py b/Lib/platform.py index 9a2ad95c999594..dda74a0fc20b4b 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -1292,6 +1292,9 @@ def platform(aliased=False, terse=False): ### freedesktop.org os-release standard # https://www.freedesktop.org/software/systemd/man/os-release.html +# /etc takes precedence over /usr/lib +_os_release_candidates = ("/etc/os-release", "/usr/lib/os-release") +_os_release_cache = None def _parse_os_release(lines): # These fields are mandatory fields with well-known defaults @@ -1325,10 +1328,6 @@ def freedesktop_os_release(): """ global _os_release_cache - # /etc takes precedence over /usr/lib - _os_release_candidates = ("/etc/os-release", "/usr/lib/os-release") - _os_release_cache = None - if _os_release_cache is None: errno = None for candidate in _os_release_candidates: From d64373d4ed459b4b1cdd2dcd8d9c6b1597793c93 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Fri, 28 Apr 2023 23:52:22 +0200 Subject: [PATCH 4/8] whitespace --- Lib/platform.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/platform.py b/Lib/platform.py index dda74a0fc20b4b..16f57bc71a111d 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -1296,6 +1296,7 @@ def platform(aliased=False, terse=False): _os_release_candidates = ("/etc/os-release", "/usr/lib/os-release") _os_release_cache = None + def _parse_os_release(lines): # These fields are mandatory fields with well-known defaults # in practice all Linux distributions override NAME, ID, and PRETTY_NAME. From da59bfefc132fcfddb289f8ddabb7b382c6b3dc5 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 29 Apr 2023 12:00:23 +0200 Subject: [PATCH 5/8] patchcheck --- Lib/platform.py | 2 +- Lib/test/coding20731.py | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Lib/platform.py b/Lib/platform.py index 16f57bc71a111d..88c626165b0d31 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -1072,7 +1072,7 @@ def _sys_version(sys_version=None): r'(?:,\s*([\w ]*)' # ", builddate" r'(?:,\s*([\w :]*))?)?\)\s*' # ", buildtime)" r'\[([^\]]+)\]?', re.ASCII) # "[compiler]" - + if sys.platform.startswith('java'): # Jython name = 'Jython' diff --git a/Lib/test/coding20731.py b/Lib/test/coding20731.py index b0e227ad110e94..7b61917cacda4a 100644 --- a/Lib/test/coding20731.py +++ b/Lib/test/coding20731.py @@ -1,4 +1 @@ #coding:latin1 - - - From e0253a8852486903c29d6885966c5d08c47a26ff Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 29 Apr 2023 20:10:35 +0200 Subject: [PATCH 6/8] revert changes to coding20731.py --- Lib/test/coding20731.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/test/coding20731.py b/Lib/test/coding20731.py index 7b61917cacda4a..b0e227ad110e94 100644 --- a/Lib/test/coding20731.py +++ b/Lib/test/coding20731.py @@ -1 +1,4 @@ #coding:latin1 + + + From 470ddc4c69104f3ba762a9140cc7518d7dd6c187 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 29 Apr 2023 20:16:07 +0200 Subject: [PATCH 7/8] review comments --- Lib/platform.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/Lib/platform.py b/Lib/platform.py index 88c626165b0d31..7bb222088d5061 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -136,11 +136,11 @@ 'pl': 200, 'p': 200, } -_component_re = re.compile(r'([0-9]+|[._+-])') def _comparable_version(version): + component_re = re.compile(r'([0-9]+|[._+-])') result = [] - for v in _component_re.split(version): + for v in component_re.split(version): if v not in '._+-': try: v = int(v, 10) @@ -185,7 +185,7 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384): # sys.executable is not set. return lib, version - _libc_search = re.compile(b'(__libc_init)' + libc_search = re.compile(b'(__libc_init)' b'|' b'(GLIBC_([0-9.]+))' b'|' @@ -201,7 +201,7 @@ def libc_ver(executable=None, lib='', version='', chunksize=16384): pos = 0 while pos < len(binary): if b'libc' in binary or b'GLIBC' in binary: - m = _libc_search.search(binary, pos) + m = libc_search.search(binary, pos) else: m = None if not m or m.end() == len(binary): @@ -293,13 +293,13 @@ def _syscmd_ver(system='', release='', version='', else: return system, release, version - _ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' + ver_output = re.compile(r'(?:([\w ]+) ([\w.]+) ' r'.*' r'\[.* ([\d.]+)\])') # Parse the output info = info.strip() - m = _ver_output.match(info) + m = ver_output.match(info) if m is not None: system, release, version = m.groups() # Strip trailing dots from version and release @@ -1066,7 +1066,7 @@ def _sys_version(sys_version=None): if result is not None: return result - _sys_version_parser = re.compile( + sys_version_parser = re.compile( r'([\w.+]+)\s*' # "version" r'\(#?([^,]+)' # "(#buildno" r'(?:,\s*([\w ]*)' # ", builddate" @@ -1076,7 +1076,7 @@ def _sys_version(sys_version=None): if sys.platform.startswith('java'): # Jython name = 'Jython' - match = _sys_version_parser.match(sys_version) + match = sys_version_parser.match(sys_version) if match is None: raise ValueError( 'failed to parse Jython sys.version: %s' % @@ -1088,13 +1088,13 @@ def _sys_version(sys_version=None): elif "PyPy" in sys_version: # PyPy - _pypy_sys_version_parser = re.compile( + pypy_sys_version_parser = re.compile( r'([\w.+]+)\s*' r'\(#?([^,]+),\s*([\w ]+),\s*([\w :]+)\)\s*' r'\[PyPy [^\]]+\]?') name = "PyPy" - match = _pypy_sys_version_parser.match(sys_version) + match = pypy_sys_version_parser.match(sys_version) if match is None: raise ValueError("failed to parse PyPy sys.version: %s" % repr(sys_version)) @@ -1103,7 +1103,7 @@ def _sys_version(sys_version=None): else: # CPython - match = _sys_version_parser.match(sys_version) + match = sys_version_parser.match(sys_version) if match is None: raise ValueError( 'failed to parse CPython sys.version: %s' % @@ -1308,16 +1308,16 @@ def _parse_os_release(lines): # NAME=value with optional quotes (' or "). The regular expression is less # strict than shell lexer, but that's ok. - _os_release_line = re.compile( + os_release_line = re.compile( "^(?P[a-zA-Z0-9_]+)=(?P[\"\']?)(?P.*)(?P=quote)$" ) # unescape five special characters mentioned in the standard - _os_release_unescape = re.compile(r"\\([\\\$\"\'`])") + os_release_unescape = re.compile(r"\\([\\\$\"\'`])") for line in lines: - mo = _os_release_line.match(line) + mo = os_release_line.match(line) 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') ) From 6119af2c299ac0d8f096d537842cc41ac0ce76d4 Mon Sep 17 00:00:00 2001 From: Pieter Eendebak Date: Sat, 29 Apr 2023 20:43:39 +0200 Subject: [PATCH 8/8] Update Misc/NEWS.d/next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst Co-authored-by: Jelle Zijlstra --- .../next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst b/Misc/NEWS.d/next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst index 8bd09c613cd08c..ff4005774a95d2 100644 --- a/Misc/NEWS.d/next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst +++ b/Misc/NEWS.d/next/Library/2023-04-28-19-08-50.gh-issue-103977.msF70A.rst @@ -1 +1 @@ -Improve import time of platform module. +Improve import time of :mod:`platform` module.