Skip to content

Commit 0c11b8b

Browse files
authored
Merge pull request RustPython#1963 from palaviv/cpython-tests
Add CPython import tests
2 parents d71dc69 + 4ba6b47 commit 0c11b8b

File tree

96 files changed

+10217
-49
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+10217
-49
lines changed

Lib/imp.py

Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
"""This module provides the components needed to build your own __import__
2+
function. Undocumented functions are obsolete.
3+
4+
In most cases it is preferred you consider using the importlib module's
5+
functionality over this module.
6+
7+
"""
8+
# (Probably) need to stay in _imp
9+
from _imp import (lock_held, acquire_lock, release_lock,
10+
get_frozen_object, is_frozen_package,
11+
init_frozen, is_builtin, is_frozen,
12+
_fix_co_filename)
13+
try:
14+
from _imp import create_dynamic
15+
except ImportError:
16+
# Platform doesn't support dynamic loading.
17+
create_dynamic = None
18+
19+
from importlib._bootstrap import _ERR_MSG, _exec, _load, _builtin_from_name
20+
from importlib._bootstrap_external import SourcelessFileLoader
21+
22+
from importlib import machinery
23+
from importlib import util
24+
import importlib
25+
import os
26+
import sys
27+
import tokenize
28+
import types
29+
import warnings
30+
31+
warnings.warn("the imp module is deprecated in favour of importlib; "
32+
"see the module's documentation for alternative uses",
33+
DeprecationWarning, stacklevel=2)
34+
35+
# DEPRECATED
36+
SEARCH_ERROR = 0
37+
PY_SOURCE = 1
38+
PY_COMPILED = 2
39+
C_EXTENSION = 3
40+
PY_RESOURCE = 4
41+
PKG_DIRECTORY = 5
42+
C_BUILTIN = 6
43+
PY_FROZEN = 7
44+
PY_CODERESOURCE = 8
45+
IMP_HOOK = 9
46+
47+
48+
def new_module(name):
49+
"""**DEPRECATED**
50+
51+
Create a new module.
52+
53+
The module is not entered into sys.modules.
54+
55+
"""
56+
return types.ModuleType(name)
57+
58+
59+
def get_magic():
60+
"""**DEPRECATED**
61+
62+
Return the magic number for .pyc files.
63+
"""
64+
return util.MAGIC_NUMBER
65+
66+
67+
def get_tag():
68+
"""Return the magic tag for .pyc files."""
69+
return sys.implementation.cache_tag
70+
71+
72+
def cache_from_source(path, debug_override=None):
73+
"""**DEPRECATED**
74+
75+
Given the path to a .py file, return the path to its .pyc file.
76+
77+
The .py file does not need to exist; this simply returns the path to the
78+
.pyc file calculated as if the .py file were imported.
79+
80+
If debug_override is not None, then it must be a boolean and is used in
81+
place of sys.flags.optimize.
82+
83+
If sys.implementation.cache_tag is None then NotImplementedError is raised.
84+
85+
"""
86+
with warnings.catch_warnings():
87+
warnings.simplefilter('ignore')
88+
return util.cache_from_source(path, debug_override)
89+
90+
91+
def source_from_cache(path):
92+
"""**DEPRECATED**
93+
94+
Given the path to a .pyc. file, return the path to its .py file.
95+
96+
The .pyc file does not need to exist; this simply returns the path to
97+
the .py file calculated to correspond to the .pyc file. If path does
98+
not conform to PEP 3147 format, ValueError will be raised. If
99+
sys.implementation.cache_tag is None then NotImplementedError is raised.
100+
101+
"""
102+
return util.source_from_cache(path)
103+
104+
105+
def get_suffixes():
106+
"""**DEPRECATED**"""
107+
extensions = [(s, 'rb', C_EXTENSION) for s in machinery.EXTENSION_SUFFIXES]
108+
source = [(s, 'r', PY_SOURCE) for s in machinery.SOURCE_SUFFIXES]
109+
bytecode = [(s, 'rb', PY_COMPILED) for s in machinery.BYTECODE_SUFFIXES]
110+
111+
return extensions + source + bytecode
112+
113+
114+
class NullImporter:
115+
116+
"""**DEPRECATED**
117+
118+
Null import object.
119+
120+
"""
121+
122+
def __init__(self, path):
123+
if path == '':
124+
raise ImportError('empty pathname', path='')
125+
elif os.path.isdir(path):
126+
raise ImportError('existing directory', path=path)
127+
128+
def find_module(self, fullname):
129+
"""Always returns None."""
130+
return None
131+
132+
133+
class _HackedGetData:
134+
135+
"""Compatibility support for 'file' arguments of various load_*()
136+
functions."""
137+
138+
def __init__(self, fullname, path, file=None):
139+
super().__init__(fullname, path)
140+
self.file = file
141+
142+
def get_data(self, path):
143+
"""Gross hack to contort loader to deal w/ load_*()'s bad API."""
144+
if self.file and path == self.path:
145+
# The contract of get_data() requires us to return bytes. Reopen the
146+
# file in binary mode if needed.
147+
if not self.file.closed:
148+
file = self.file
149+
if 'b' not in file.mode:
150+
file.close()
151+
if self.file.closed:
152+
self.file = file = open(self.path, 'rb')
153+
154+
with file:
155+
return file.read()
156+
else:
157+
return super().get_data(path)
158+
159+
160+
class _LoadSourceCompatibility(_HackedGetData, machinery.SourceFileLoader):
161+
162+
"""Compatibility support for implementing load_source()."""
163+
164+
165+
def load_source(name, pathname, file=None):
166+
loader = _LoadSourceCompatibility(name, pathname, file)
167+
spec = util.spec_from_file_location(name, pathname, loader=loader)
168+
if name in sys.modules:
169+
module = _exec(spec, sys.modules[name])
170+
else:
171+
module = _load(spec)
172+
# To allow reloading to potentially work, use a non-hacked loader which
173+
# won't rely on a now-closed file object.
174+
module.__loader__ = machinery.SourceFileLoader(name, pathname)
175+
module.__spec__.loader = module.__loader__
176+
return module
177+
178+
179+
class _LoadCompiledCompatibility(_HackedGetData, SourcelessFileLoader):
180+
181+
"""Compatibility support for implementing load_compiled()."""
182+
183+
184+
def load_compiled(name, pathname, file=None):
185+
"""**DEPRECATED**"""
186+
loader = _LoadCompiledCompatibility(name, pathname, file)
187+
spec = util.spec_from_file_location(name, pathname, loader=loader)
188+
if name in sys.modules:
189+
module = _exec(spec, sys.modules[name])
190+
else:
191+
module = _load(spec)
192+
# To allow reloading to potentially work, use a non-hacked loader which
193+
# won't rely on a now-closed file object.
194+
module.__loader__ = SourcelessFileLoader(name, pathname)
195+
module.__spec__.loader = module.__loader__
196+
return module
197+
198+
199+
def load_package(name, path):
200+
"""**DEPRECATED**"""
201+
if os.path.isdir(path):
202+
extensions = (machinery.SOURCE_SUFFIXES[:] +
203+
machinery.BYTECODE_SUFFIXES[:])
204+
for extension in extensions:
205+
init_path = os.path.join(path, '__init__' + extension)
206+
if os.path.exists(init_path):
207+
path = init_path
208+
break
209+
else:
210+
raise ValueError('{!r} is not a package'.format(path))
211+
spec = util.spec_from_file_location(name, path,
212+
submodule_search_locations=[])
213+
if name in sys.modules:
214+
return _exec(spec, sys.modules[name])
215+
else:
216+
return _load(spec)
217+
218+
219+
def load_module(name, file, filename, details):
220+
"""**DEPRECATED**
221+
222+
Load a module, given information returned by find_module().
223+
224+
The module name must include the full package name, if any.
225+
226+
"""
227+
suffix, mode, type_ = details
228+
if mode and (not mode.startswith(('r', 'U')) or '+' in mode):
229+
raise ValueError('invalid file open mode {!r}'.format(mode))
230+
elif file is None and type_ in {PY_SOURCE, PY_COMPILED}:
231+
msg = 'file object required for import (type code {})'.format(type_)
232+
raise ValueError(msg)
233+
elif type_ == PY_SOURCE:
234+
return load_source(name, filename, file)
235+
elif type_ == PY_COMPILED:
236+
return load_compiled(name, filename, file)
237+
elif type_ == C_EXTENSION and load_dynamic is not None:
238+
if file is None:
239+
with open(filename, 'rb') as opened_file:
240+
return load_dynamic(name, filename, opened_file)
241+
else:
242+
return load_dynamic(name, filename, file)
243+
elif type_ == PKG_DIRECTORY:
244+
return load_package(name, filename)
245+
elif type_ == C_BUILTIN:
246+
return init_builtin(name)
247+
elif type_ == PY_FROZEN:
248+
return init_frozen(name)
249+
else:
250+
msg = "Don't know how to import {} (type code {})".format(name, type_)
251+
raise ImportError(msg, name=name)
252+
253+
254+
def find_module(name, path=None):
255+
"""**DEPRECATED**
256+
257+
Search for a module.
258+
259+
If path is omitted or None, search for a built-in, frozen or special
260+
module and continue search in sys.path. The module name cannot
261+
contain '.'; to search for a submodule of a package, pass the
262+
submodule name and the package's __path__.
263+
264+
"""
265+
if not isinstance(name, str):
266+
raise TypeError("'name' must be a str, not {}".format(type(name)))
267+
elif not isinstance(path, (type(None), list)):
268+
# Backwards-compatibility
269+
raise RuntimeError("'path' must be None or a list, "
270+
"not {}".format(type(path)))
271+
272+
if path is None:
273+
if is_builtin(name):
274+
return None, None, ('', '', C_BUILTIN)
275+
elif is_frozen(name):
276+
return None, None, ('', '', PY_FROZEN)
277+
else:
278+
path = sys.path
279+
280+
for entry in path:
281+
package_directory = os.path.join(entry, name)
282+
for suffix in ['.py', machinery.BYTECODE_SUFFIXES[0]]:
283+
package_file_name = '__init__' + suffix
284+
file_path = os.path.join(package_directory, package_file_name)
285+
if os.path.isfile(file_path):
286+
return None, package_directory, ('', '', PKG_DIRECTORY)
287+
for suffix, mode, type_ in get_suffixes():
288+
file_name = name + suffix
289+
file_path = os.path.join(entry, file_name)
290+
if os.path.isfile(file_path):
291+
break
292+
else:
293+
continue
294+
break # Break out of outer loop when breaking out of inner loop.
295+
else:
296+
raise ImportError(_ERR_MSG.format(name), name=name)
297+
298+
encoding = None
299+
if 'b' not in mode:
300+
with open(file_path, 'rb') as file:
301+
encoding = tokenize.detect_encoding(file.readline)[0]
302+
file = open(file_path, mode, encoding=encoding)
303+
return file, file_path, (suffix, mode, type_)
304+
305+
306+
def reload(module):
307+
"""**DEPRECATED**
308+
309+
Reload the module and return it.
310+
311+
The module must have been successfully imported before.
312+
313+
"""
314+
return importlib.reload(module)
315+
316+
317+
def init_builtin(name):
318+
"""**DEPRECATED**
319+
320+
Load and return a built-in module by name, or None is such module doesn't
321+
exist
322+
"""
323+
try:
324+
return _builtin_from_name(name)
325+
except ImportError:
326+
return None
327+
328+
329+
if create_dynamic:
330+
def load_dynamic(name, path, file=None):
331+
"""**DEPRECATED**
332+
333+
Load an extension module.
334+
"""
335+
import importlib.machinery
336+
loader = importlib.machinery.ExtensionFileLoader(name, path)
337+
338+
# Issue #24748: Skip the sys.modules check in _load_module_shim;
339+
# always load new extension
340+
spec = importlib.machinery.ModuleSpec(
341+
name=name, loader=loader, origin=path)
342+
return _load(spec)
343+
344+
else:
345+
load_dynamic = None

Lib/importlib/__init__.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
sys.modules['importlib._bootstrap_external'] = _bootstrap_external
4949

5050
# To simplify imports in test code
51-
_w_long = _bootstrap_external._w_long
52-
_r_long = _bootstrap_external._r_long
51+
_pack_uint32 = _bootstrap_external._pack_uint32
52+
_unpack_uint32 = _bootstrap_external._unpack_uint32
5353

5454
# Fully bootstrapped at this point, import whatever you like, circular
5555
# dependencies and startup overhead minimisation permitting :)
@@ -79,7 +79,8 @@ def find_loader(name, path=None):
7979
This function is deprecated in favor of importlib.util.find_spec().
8080
8181
"""
82-
warnings.warn('Use importlib.util.find_spec() instead.',
82+
warnings.warn('Deprecated since Python 3.4. '
83+
'Use importlib.util.find_spec() instead.',
8384
DeprecationWarning, stacklevel=2)
8485
try:
8586
loader = sys.modules[name].__loader__
@@ -136,7 +137,7 @@ def reload(module):
136137
137138
"""
138139
if not module or not isinstance(module, types.ModuleType):
139-
raise TypeError("reload() argument must be module")
140+
raise TypeError("reload() argument must be a module")
140141
try:
141142
name = module.__spec__.name
142143
except AttributeError:
@@ -163,6 +164,8 @@ def reload(module):
163164
pkgpath = None
164165
target = module
165166
spec = module.__spec__ = _bootstrap._find_spec(name, pkgpath, target)
167+
if spec is None:
168+
raise ModuleNotFoundError(f"spec not found for the module {name!r}", name=name)
166169
_bootstrap._exec(spec, module)
167170
# The module may have replaced itself in sys.modules!
168171
return sys.modules[name]

0 commit comments

Comments
 (0)