Skip to content

Commit 8c75068

Browse files
committed
reduce asymptotic complexity of platform._platform()
1 parent c419af9 commit 8c75068

3 files changed

Lines changed: 25 additions & 17 deletions

File tree

Lib/platform.py

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,11 @@ def system_alias(system, release, version):
612612

613613
### Various internal helpers
614614

615+
# Table for cleaning up characters in filenames.
616+
_SIMPLE_SUBSTITUTIONS = (
617+
dict.fromkeys(map(ord, '/\\:;"()'), '-') | {ord(' '): '_'}
618+
)
619+
615620
def _platform(*args):
616621

617622
""" Helper to format the platform string in a filename
@@ -621,28 +626,13 @@ def _platform(*args):
621626
platform = '-'.join(x.strip() for x in filter(len, args))
622627

623628
# Cleanup some possible filename obstacles...
624-
platform = platform.replace(' ', '_')
625-
platform = platform.replace('/', '-')
626-
platform = platform.replace('\\', '-')
627-
platform = platform.replace(':', '-')
628-
platform = platform.replace(';', '-')
629-
platform = platform.replace('"', '-')
630-
platform = platform.replace('(', '-')
631-
platform = platform.replace(')', '-')
629+
platform = platform.translate(_SIMPLE_SUBSTITUTIONS)
632630

633631
# No need to report 'unknown' information...
634632
platform = platform.replace('unknown', '')
635633

636634
# Fold '--'s and remove trailing '-'
637-
while True:
638-
cleaned = platform.replace('--', '-')
639-
if cleaned == platform:
640-
break
641-
platform = cleaned
642-
while platform and platform[-1] == '-':
643-
platform = platform[:-1]
644-
645-
return platform
635+
return re.sub(r'-+', '-', platform).rstrip('-')
646636

647637
def _node(default=''):
648638

Lib/test/test_platform.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,22 @@ def test_platform(self):
133133
for terse in (False, True):
134134
res = platform.platform(aliased, terse)
135135

136+
def test__platform(self):
137+
for src, res in [
138+
('foo bar', 'foo_bar'),
139+
(
140+
'1/2\\3:4;5"6(7)8(7)6"5;4:3\\2/1',
141+
'1-2-3-4-5-6-7-8-7-6-5-4-3-2-1'
142+
),
143+
('--', ''),
144+
('-f', '-f'),
145+
('-foo----', '-foo'),
146+
('--foo---', '-foo'),
147+
('---foo--', '-foo'),
148+
]:
149+
with self.subTest(src=src):
150+
self.assertEqual(platform._platform(src), res)
151+
136152
def test_system(self):
137153
res = platform.system()
138154

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`platform`: eliminate asymptotic quadratic-time complexity
2+
in the private helper :func:`!_platform`. Patch by Bénédikt Tran.

0 commit comments

Comments
 (0)