From 8c75068c788a7cfdc1ecd6082c2aee71c9ffd8df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 28 Jun 2025 11:11:02 +0200 Subject: [PATCH 1/2] reduce asymptotic complexity of `platform._platform()` --- Lib/platform.py | 24 ++++++------------- Lib/test/test_platform.py | 16 +++++++++++++ ...-06-28-11-12-12.gh-issue-136066.WqsKka.rst | 2 ++ 3 files changed, 25 insertions(+), 17 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2025-06-28-11-12-12.gh-issue-136066.WqsKka.rst diff --git a/Lib/platform.py b/Lib/platform.py index e7f180fc5ac3a3..24190bb3a21e60 100644 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -612,6 +612,11 @@ def system_alias(system, release, version): ### Various internal helpers +# Table for cleaning up characters in filenames. +_SIMPLE_SUBSTITUTIONS = ( + dict.fromkeys(map(ord, '/\\:;"()'), '-') | {ord(' '): '_'} +) + def _platform(*args): """ Helper to format the platform string in a filename @@ -621,28 +626,13 @@ def _platform(*args): platform = '-'.join(x.strip() for x in filter(len, args)) # Cleanup some possible filename obstacles... - platform = platform.replace(' ', '_') - platform = platform.replace('/', '-') - platform = platform.replace('\\', '-') - platform = platform.replace(':', '-') - platform = platform.replace(';', '-') - platform = platform.replace('"', '-') - platform = platform.replace('(', '-') - platform = platform.replace(')', '-') + platform = platform.translate(_SIMPLE_SUBSTITUTIONS) # No need to report 'unknown' information... platform = platform.replace('unknown', '') # Fold '--'s and remove trailing '-' - while True: - cleaned = platform.replace('--', '-') - if cleaned == platform: - break - platform = cleaned - while platform and platform[-1] == '-': - platform = platform[:-1] - - return platform + return re.sub(r'-+', '-', platform).rstrip('-') def _node(default=''): diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index 3688cc4267b6b2..479649053abc01 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -133,6 +133,22 @@ def test_platform(self): for terse in (False, True): res = platform.platform(aliased, terse) + def test__platform(self): + for src, res in [ + ('foo bar', 'foo_bar'), + ( + '1/2\\3:4;5"6(7)8(7)6"5;4:3\\2/1', + '1-2-3-4-5-6-7-8-7-6-5-4-3-2-1' + ), + ('--', ''), + ('-f', '-f'), + ('-foo----', '-foo'), + ('--foo---', '-foo'), + ('---foo--', '-foo'), + ]: + with self.subTest(src=src): + self.assertEqual(platform._platform(src), res) + def test_system(self): res = platform.system() diff --git a/Misc/NEWS.d/next/Library/2025-06-28-11-12-12.gh-issue-136066.WqsKka.rst b/Misc/NEWS.d/next/Library/2025-06-28-11-12-12.gh-issue-136066.WqsKka.rst new file mode 100644 index 00000000000000..4bcca5852486fd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-06-28-11-12-12.gh-issue-136066.WqsKka.rst @@ -0,0 +1,2 @@ +:mod:`platform`: eliminate asymptotic quadratic-time complexity +in the private helper :func:`!_platform`. Patch by Bénédikt Tran. From d7f9dce02058552ecc33798392ff8e904b6902d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 28 Jun 2025 14:21:55 +0200 Subject: [PATCH 2/2] address review --- Lib/platform.py | 6 ++---- .../Library/2025-06-28-11-12-12.gh-issue-136066.WqsKka.rst | 2 -- 2 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 Misc/NEWS.d/next/Library/2025-06-28-11-12-12.gh-issue-136066.WqsKka.rst diff --git a/Lib/platform.py b/Lib/platform.py index 24190bb3a21e60..da15bb4717bb96 100644 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -613,9 +613,7 @@ def system_alias(system, release, version): ### Various internal helpers # Table for cleaning up characters in filenames. -_SIMPLE_SUBSTITUTIONS = ( - dict.fromkeys(map(ord, '/\\:;"()'), '-') | {ord(' '): '_'} -) +_SIMPLE_SUBSTITUTIONS = str.maketrans(r' /\:;"()', r'_-------') def _platform(*args): @@ -632,7 +630,7 @@ def _platform(*args): platform = platform.replace('unknown', '') # Fold '--'s and remove trailing '-' - return re.sub(r'-+', '-', platform).rstrip('-') + return re.sub(r'-{2,}', '-', platform).rstrip('-') def _node(default=''): diff --git a/Misc/NEWS.d/next/Library/2025-06-28-11-12-12.gh-issue-136066.WqsKka.rst b/Misc/NEWS.d/next/Library/2025-06-28-11-12-12.gh-issue-136066.WqsKka.rst deleted file mode 100644 index 4bcca5852486fd..00000000000000 --- a/Misc/NEWS.d/next/Library/2025-06-28-11-12-12.gh-issue-136066.WqsKka.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`platform`: eliminate asymptotic quadratic-time complexity -in the private helper :func:`!_platform`. Patch by Bénédikt Tran.