Skip to content

Commit 2657df4

Browse files
committed
Issue python#13959: Re-implement imp.get_suffixes() in Lib/imp.py.
This introduces a new function, imp.extension_suffixes(), which is currently undocumented. That is forthcoming once issue python#14657 is resolved and how to expose file suffixes is decided.
1 parent 17098a5 commit 2657df4

19 files changed

+2923
-3123
lines changed

Lib/imp.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@
99
from _imp import (lock_held, acquire_lock, release_lock,
1010
load_dynamic, get_frozen_object, is_frozen_package,
1111
init_builtin, init_frozen, is_builtin, is_frozen,
12-
_fix_co_filename)
12+
_fix_co_filename, extension_suffixes)
1313
# Could move out of _imp, but not worth the code
1414
from _imp import get_magic, get_tag
15-
# Can (probably) move to importlib
16-
from _imp import get_suffixes
1715

1816
from importlib._bootstrap import new_module
1917
from importlib._bootstrap import cache_from_source
@@ -38,6 +36,14 @@
3836
IMP_HOOK = 9
3937

4038

39+
def get_suffixes():
40+
extensions = [(s, 'rb', C_EXTENSION) for s in extension_suffixes()]
41+
source = [(s, 'U', PY_SOURCE) for s in _bootstrap._SOURCE_SUFFIXES]
42+
bytecode = [(_bootstrap._BYTECODE_SUFFIX, 'rb', PY_COMPILED)]
43+
44+
return extensions + source + bytecode
45+
46+
4147
def source_from_cache(path):
4248
"""Given the path to a .pyc./.pyo file, return the path to its .py file.
4349
@@ -120,8 +126,8 @@ def load_compiled(name, pathname, file=None):
120126
# XXX deprecate
121127
def load_package(name, path):
122128
if os.path.isdir(path):
123-
extensions = _bootstrap._suffix_list(PY_SOURCE)
124-
extensions += _bootstrap._suffix_list(PY_COMPILED)
129+
extensions = _bootstrap._SOURCE_SUFFIXES
130+
extensions += [_bootstrap._BYTECODE_SUFFIX]
125131
for extension in extensions:
126132
path = os.path.join(path, '__init__'+extension)
127133
if os.path.exists(path):

Lib/importlib/_bootstrap.py

Lines changed: 4 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,6 @@ def _path_split(path):
9595
return front, tail
9696

9797

98-
def _path_exists(path):
99-
"""Replacement for os.path.exists."""
100-
try:
101-
_os.stat(path)
102-
except OSError:
103-
return False
104-
else:
105-
return True
106-
107-
10898
def _path_is_mode_type(path, mode):
10999
"""Test whether the path is the specified mode type."""
110100
try:
@@ -128,28 +118,6 @@ def _path_isdir(path):
128118
return _path_is_mode_type(path, 0o040000)
129119

130120

131-
def _path_without_ext(path, ext_type):
132-
"""Replacement for os.path.splitext()[0]."""
133-
for suffix in _suffix_list(ext_type):
134-
if path.endswith(suffix):
135-
return path[:-len(suffix)]
136-
else:
137-
raise ValueError("path is not of the specified type")
138-
139-
140-
def _path_absolute(path):
141-
"""Replacement for os.path.abspath."""
142-
if not path:
143-
path = _os.getcwd()
144-
try:
145-
return _os._getfullpathname(path)
146-
except AttributeError:
147-
if path.startswith('/'):
148-
return path
149-
else:
150-
return _path_join(_os.getcwd(), path)
151-
152-
153121
def _write_atomic(path, data):
154122
"""Best-effort function to write data to a path atomically.
155123
Be prepared to handle a FileExistsError if concurrent writing of the
@@ -338,12 +306,6 @@ def _requires_frozen_wrapper(self, fullname):
338306
return _requires_frozen_wrapper
339307

340308

341-
def _suffix_list(suffix_type):
342-
"""Return a list of file suffixes based on the imp file type."""
343-
return [suffix[0] for suffix in _imp.get_suffixes()
344-
if suffix[2] == suffix_type]
345-
346-
347309
# Loaders #####################################################################
348310

349311
class BuiltinImporter:
@@ -1196,8 +1158,9 @@ def _install(sys_module, _imp_module):
11961158
11971159
"""
11981160
_setup(sys_module, _imp_module)
1199-
supported_loaders = [(ExtensionFileLoader, _suffix_list(3), False),
1200-
(SourceFileLoader, _suffix_list(1), True),
1201-
(SourcelessFileLoader, _suffix_list(2), True)]
1161+
extensions = ExtensionFileLoader, _imp_module.extension_suffixes(), False
1162+
source = SourceFileLoader, _SOURCE_SUFFIXES, True
1163+
bytecode = SourcelessFileLoader, [_BYTECODE_SUFFIX], True
1164+
supported_loaders = [extensions, source, bytecode]
12021165
sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
12031166
sys.meta_path.extend([BuiltinImporter, FrozenImporter, PathFinder])

Lib/importlib/test/extension/test_case_sensitivity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ def find_module(self):
1616
assert good_name != bad_name
1717
finder = _bootstrap.FileFinder(ext_util.PATH,
1818
(_bootstrap.ExtensionFileLoader,
19-
_bootstrap._suffix_list(imp.C_EXTENSION),
19+
imp.extension_suffixes(),
2020
False))
2121
return finder.find_module(bad_name)
2222

Lib/importlib/test/extension/test_finder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class FinderTests(abc.FinderTests):
1212
def find_module(self, fullname):
1313
importer = _bootstrap.FileFinder(util.PATH,
1414
(_bootstrap.ExtensionFileLoader,
15-
_bootstrap._suffix_list(imp.C_EXTENSION),
15+
imp.extension_suffixes(),
1616
False))
1717
return importer.find_module(fullname)
1818

Lib/importlib/test/extension/test_path_hook.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class PathHookTests(unittest.TestCase):
1515

1616
def hook(self, entry):
1717
return _bootstrap.FileFinder.path_hook((_bootstrap.ExtensionFileLoader,
18-
_bootstrap._suffix_list(imp.C_EXTENSION), False))(entry)
18+
imp.extension_suffixes(), False))(entry)
1919

2020
def test_success(self):
2121
# Path hook should handle a directory where a known extension module

Lib/importlib/test/source/test_case_sensitivity.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ class CaseSensitivityTest(unittest.TestCase):
2222
def find(self, path):
2323
finder = _bootstrap.FileFinder(path,
2424
(_bootstrap.SourceFileLoader,
25-
_bootstrap._suffix_list(imp.PY_SOURCE),
25+
_bootstrap._SOURCE_SUFFIXES,
2626
True),
2727
(_bootstrap.SourcelessFileLoader,
28-
_bootstrap._suffix_list(imp.PY_COMPILED),
28+
[_bootstrap._BYTECODE_SUFFIX],
2929
True))
3030
return finder.find_module(self.name)
3131

Lib/importlib/test/source/test_finder.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ class FinderTests(abc.FinderTests):
3737

3838
def import_(self, root, module):
3939
loader_details = [(_bootstrap.SourceFileLoader,
40-
_bootstrap._suffix_list(imp.PY_SOURCE), True),
40+
_bootstrap._SOURCE_SUFFIXES, True),
4141
(_bootstrap.SourcelessFileLoader,
42-
_bootstrap._suffix_list(imp.PY_COMPILED), True)]
42+
[_bootstrap._BYTECODE_SUFFIX], True)]
4343
finder = _bootstrap.FileFinder(root, *loader_details)
4444
return finder.find_module(module)
4545

@@ -139,7 +139,7 @@ def test_empty_dir(self):
139139
def test_empty_string_for_dir(self):
140140
# The empty string from sys.path means to search in the cwd.
141141
finder = _bootstrap.FileFinder('', (_bootstrap.SourceFileLoader,
142-
_bootstrap._suffix_list(imp.PY_SOURCE), True))
142+
_bootstrap._SOURCE_SUFFIXES, True))
143143
with open('mod.py', 'w') as file:
144144
file.write("# test file for importlib")
145145
try:
@@ -151,7 +151,7 @@ def test_empty_string_for_dir(self):
151151
def test_invalidate_caches(self):
152152
# invalidate_caches() should reset the mtime.
153153
finder = _bootstrap.FileFinder('', (_bootstrap.SourceFileLoader,
154-
_bootstrap._suffix_list(imp.PY_SOURCE), True))
154+
_bootstrap._SOURCE_SUFFIXES, True))
155155
finder._path_mtime = 42
156156
finder.invalidate_caches()
157157
self.assertEqual(finder._path_mtime, -1)

Lib/importlib/test/source/test_path_hook.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class PathHookTest(unittest.TestCase):
1111

1212
def path_hook(self):
1313
return _bootstrap.FileFinder.path_hook((_bootstrap.SourceFileLoader,
14-
_bootstrap._suffix_list(imp.PY_SOURCE), True))
14+
_bootstrap._SOURCE_SUFFIXES, True))
1515

1616
def test_success(self):
1717
with source_util.create_modules('dummy') as mapping:

Python/dynload_aix.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ typedef struct Module {
2626
void *entry;
2727
} Module, *ModulePtr;
2828

29-
const struct filedescr _PyImport_DynLoadFiletab[] = {
30-
{".so", "rb", C_EXTENSION},
31-
{0, 0}
32-
};
29+
const char *_PyImport_DynLoadFiletab[] = {".so", NULL};
3330

3431
static int
3532
aix_getoldmodules(void **modlistptr)

Python/dynload_dl.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@
99

1010
extern char *Py_GetProgramName(void);
1111

12-
const struct filedescr _PyImport_DynLoadFiletab[] = {
13-
{".o", "rb", C_EXTENSION},
14-
{0, 0}
15-
};
12+
const char *_PyImport_DynLoadFiletab[] = {".o", NULL};
1613

1714

1815
dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,

0 commit comments

Comments
 (0)