Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ed672d6

Browse files
committed
Make path manipulation more robust for platforms with alternative path
separators.
1 parent 24117a7 commit ed672d6

2 files changed

Lines changed: 3075 additions & 3031 deletions

File tree

Lib/importlib/_bootstrap.py

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,8 @@
77
88
"""
99

10-
# Injected modules are '_warnings', '_imp', 'sys', 'marshal', '_io',
11-
# and '_os' (a.k.a. 'posix', 'nt' or 'os2').
12-
# Injected attribute is path_sep.
13-
# Most injection is handled by _setup().
14-
#
10+
# See importlib._setup() for what is injected into the global namespace.
11+
1512
# When editing this code be aware that code executed at import time CANNOT
1613
# reference any injected objects! This includes not only global code but also
1714
# anything specified at the class level.
@@ -64,12 +61,23 @@ def _r_long(int_bytes):
6461
return x
6562

6663

67-
68-
# XXX Could also expose Modules/getpath.c:joinpath()
6964
def _path_join(*args):
70-
"""Replacement for os.path.join."""
71-
return path_sep.join(x[:-len(path_sep)] if x.endswith(path_sep) else x
72-
for x in args if x)
65+
"""Replacement for os.path.join()."""
66+
sep = path_sep if args[0][-1:] not in path_separators else args[0][-1]
67+
return sep.join(x[:-len(path_sep)] if x.endswith(path_sep) else x
68+
for x in args if x)
69+
70+
71+
def _path_split(path):
72+
"""Replacement for os.path.split()."""
73+
for x in reversed(path):
74+
if x in path_separators:
75+
sep = x
76+
break
77+
else:
78+
sep = path_sep
79+
front, _, tail = path.rpartition(sep)
80+
return front, tail
7381

7482

7583
def _path_exists(path):
@@ -388,7 +396,7 @@ class _LoaderBasics:
388396
def is_package(self, fullname):
389397
"""Concrete implementation of InspectLoader.is_package by checking if
390398
the path returned by get_filename has a filename of '__init__.py'."""
391-
filename = self.get_filename(fullname).rpartition(path_sep)[2]
399+
filename = _path_split(self.get_filename(fullname))[1]
392400
return filename.rsplit('.', 1)[0] == '__init__'
393401

394402
def _bytes_from_bytecode(self, fullname, data, bytecode_path, source_stats):
@@ -449,7 +457,7 @@ def _load_module(self, module, *, sourceless=False):
449457
module.__cached__ = module.__file__
450458
module.__package__ = name
451459
if self.is_package(name):
452-
module.__path__ = [module.__file__.rsplit(path_sep, 1)[0]]
460+
module.__path__ = [_path_split(module.__file__)[0]]
453461
else:
454462
module.__package__ = module.__package__.rpartition('.')[0]
455463
module.__loader__ = self
@@ -604,11 +612,11 @@ def path_stats(self, path):
604612

605613
def set_data(self, path, data):
606614
"""Write bytes data to a file."""
607-
parent, _, filename = path.rpartition(path_sep)
615+
parent, filename = _path_split(path)
608616
path_parts = []
609617
# Figure out what directories are missing.
610618
while parent and not _path_isdir(parent):
611-
parent, _, part = parent.rpartition(path_sep)
619+
parent, part = _path_split(parent)
612620
path_parts.append(part)
613621
# Create needed directories.
614622
for part in reversed(path_parts):
@@ -1142,7 +1150,9 @@ def _setup(sys_module, _imp_module):
11421150
builtin_module = sys.modules[builtin_name]
11431151
setattr(self_module, builtin_name, builtin_module)
11441152

1145-
for builtin_os, path_sep in [('posix', '/'), ('nt', '\\'), ('os2', '\\')]:
1153+
os_details = ('posix', ['/']), ('nt', ['\\', '/']), ('os2', ['\\', '/'])
1154+
for builtin_os, path_separators in os_details:
1155+
path_sep = path_separators[0]
11461156
if builtin_os in sys.modules:
11471157
os_module = sys.modules[builtin_os]
11481158
break
@@ -1151,14 +1161,15 @@ def _setup(sys_module, _imp_module):
11511161
os_module = BuiltinImporter.load_module(builtin_os)
11521162
# TODO: rip out os2 code after 3.3 is released as per PEP 11
11531163
if builtin_os == 'os2' and 'EMX GCC' in sys.version:
1154-
path_sep = '/'
1164+
path_sep = path_separators[1]
11551165
break
11561166
except ImportError:
11571167
continue
11581168
else:
11591169
raise ImportError('importlib requires posix or nt')
11601170
setattr(self_module, '_os', os_module)
11611171
setattr(self_module, 'path_sep', path_sep)
1172+
setattr(self_module, 'path_separators', set(path_separators))
11621173
# Constants
11631174
setattr(self_module, '_relax_case', _make_relax_case())
11641175
setattr(self_module, '_MAGIC_NUMBER', _imp_module.get_magic())

0 commit comments

Comments
 (0)