annotate Lib/importlib/_bootstrap.py @ 87690:66c1c9f32567 default tip

Add use_weakref option to functools.lru_cache The use_weakref option makes lru_cache create weak references to the function arguments when creating the cache key, which prevents them from staying in the memory forever even after all other references to them are gone. This is a proof of concept for http://bugs.python.org/issue19859
author Radomir Dopieralski <devel@sheep.art.pl>
date Tue, 03 Dec 2013 16:02:48 +0100
parents b5bbd47a9bc4
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1 """Core implementation of import.
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
3 This module is NOT meant to be directly imported! It has been designed such
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
4 that it can be bootstrapped into Python as the implementation of import. As
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
5 such it requires the injection of specific modules and attributes in order to
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
6 work. One should use importlib as the public-facing version of this module.
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
7
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
8 """
76549
acfdf46b8de1 Issue #14605 and #14642:
Marc-Andre Lemburg <mal@egenix.com>
parents: 76548
diff changeset
9 #
acfdf46b8de1 Issue #14605 and #14642:
Marc-Andre Lemburg <mal@egenix.com>
parents: 76548
diff changeset
10 # IMPORTANT: Whenever making changes to this module, be sure to run
acfdf46b8de1 Issue #14605 and #14642:
Marc-Andre Lemburg <mal@egenix.com>
parents: 76548
diff changeset
11 # a top-level make in order to get the frozen version of the module
83960
3a1976680717 Introduce importlib.util.ModuleManager which is a context manager to
Brett Cannon <brett@python.org>
parents: 83791
diff changeset
12 # update. Not doing so will result in the Makefile to fail for
76549
acfdf46b8de1 Issue #14605 and #14642:
Marc-Andre Lemburg <mal@egenix.com>
parents: 76548
diff changeset
13 # all others who don't have a ./python around to freeze the module
acfdf46b8de1 Issue #14605 and #14642:
Marc-Andre Lemburg <mal@egenix.com>
parents: 76548
diff changeset
14 # in the early stages of compilation.
acfdf46b8de1 Issue #14605 and #14642:
Marc-Andre Lemburg <mal@egenix.com>
parents: 76548
diff changeset
15 #
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
16
76449
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
17 # See importlib._setup() for what is injected into the global namespace.
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
18
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
19 # When editing this code be aware that code executed at import time CANNOT
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
20 # reference any injected objects! This includes not only global code but also
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
21 # anything specified at the class level.
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
22
52140
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
23 # Bootstrap-related code ######################################################
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
24
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
25 _CASE_INSENSITIVE_PLATFORMS = 'win', 'cygwin', 'darwin'
74643
ecf4a7bb8807 Relocate importlib._case_ok to importlib._bootstrap.
Brett Cannon <brett@python.org>
parents: 74630
diff changeset
26
ecf4a7bb8807 Relocate importlib._case_ok to importlib._bootstrap.
Brett Cannon <brett@python.org>
parents: 74630
diff changeset
27
75055
b8576719fe71 _relax_case -> _make_relax_case
Antoine Pitrou <solipsis@pitrou.net>
parents: 75048
diff changeset
28 def _make_relax_case():
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
29 if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS):
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
30 def _relax_case():
75070
defd944af91b put docstrings on functions
Benjamin Peterson <benjamin@python.org>
parents: 75055
diff changeset
31 """True if filenames must be checked case-insensitively."""
85518
7801ef4a4ce3 Issue #16826: Revert fix while Windows issues are being worked out.
Meador Inge <meadori@gmail.com>
parents: 85515
diff changeset
32 return b'PYTHONCASEOK' in _os.environ
74643
ecf4a7bb8807 Relocate importlib._case_ok to importlib._bootstrap.
Brett Cannon <brett@python.org>
parents: 74630
diff changeset
33 else:
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
34 def _relax_case():
75070
defd944af91b put docstrings on functions
Benjamin Peterson <benjamin@python.org>
parents: 75055
diff changeset
35 """True if filenames must be checked case-insensitively."""
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
36 return False
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
37 return _relax_case
74643
ecf4a7bb8807 Relocate importlib._case_ok to importlib._bootstrap.
Brett Cannon <brett@python.org>
parents: 74630
diff changeset
38
ecf4a7bb8807 Relocate importlib._case_ok to importlib._bootstrap.
Brett Cannon <brett@python.org>
parents: 74630
diff changeset
39
74630
7d8f016784cd Move some code from importlib.__init__ to importlib._bootstrap that
Brett Cannon <brett@python.org>
parents: 74449
diff changeset
40 def _w_long(x):
83963
185a0e649fb8 Issue #18070: importlib.util.module_for_loader() now sets __loader__
Brett Cannon <brett@python.org>
parents: 83960
diff changeset
41 """Convert a 32-bit integer to little-endian."""
82385
d98a82f4c9bd Issue #17220: two fixes for changeset 2528e4aea338.
Brett Cannon <brett@python.org>
parents: 82382
diff changeset
42 return (int(x) & 0xFFFFFFFF).to_bytes(4, 'little')
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
43
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
44
74630
7d8f016784cd Move some code from importlib.__init__ to importlib._bootstrap that
Brett Cannon <brett@python.org>
parents: 74449
diff changeset
45 def _r_long(int_bytes):
83963
185a0e649fb8 Issue #18070: importlib.util.module_for_loader() now sets __loader__
Brett Cannon <brett@python.org>
parents: 83960
diff changeset
46 """Convert 4 bytes in little-endian to an integer."""
82382
2528e4aea338 Issue #17220: Little cleanup of _bootstrap.py.
Serhiy Storchaka <storchaka@gmail.com>
parents: 82237
diff changeset
47 return int.from_bytes(int_bytes, 'little')
74630
7d8f016784cd Move some code from importlib.__init__ to importlib._bootstrap that
Brett Cannon <brett@python.org>
parents: 74449
diff changeset
48
7d8f016784cd Move some code from importlib.__init__ to importlib._bootstrap that
Brett Cannon <brett@python.org>
parents: 74449
diff changeset
49
76472
4e853913054c Issue #13959: Continue to try to accomodate altsep in importlib by not
Brett Cannon <brett@python.org>
parents: 76466
diff changeset
50 def _path_join(*path_parts):
76449
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
51 """Replacement for os.path.join()."""
82382
2528e4aea338 Issue #17220: Little cleanup of _bootstrap.py.
Serhiy Storchaka <storchaka@gmail.com>
parents: 82237
diff changeset
52 return path_sep.join([part.rstrip(path_separators)
2528e4aea338 Issue #17220: Little cleanup of _bootstrap.py.
Serhiy Storchaka <storchaka@gmail.com>
parents: 82237
diff changeset
53 for part in path_parts if part])
74630
7d8f016784cd Move some code from importlib.__init__ to importlib._bootstrap that
Brett Cannon <brett@python.org>
parents: 74449
diff changeset
54
76449
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
55
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
56 def _path_split(path):
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
57 """Replacement for os.path.split()."""
82382
2528e4aea338 Issue #17220: Little cleanup of _bootstrap.py.
Serhiy Storchaka <storchaka@gmail.com>
parents: 82237
diff changeset
58 if len(path_separators) == 1:
2528e4aea338 Issue #17220: Little cleanup of _bootstrap.py.
Serhiy Storchaka <storchaka@gmail.com>
parents: 82237
diff changeset
59 front, _, tail = path.rpartition(path_sep)
2528e4aea338 Issue #17220: Little cleanup of _bootstrap.py.
Serhiy Storchaka <storchaka@gmail.com>
parents: 82237
diff changeset
60 return front, tail
76449
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
61 for x in reversed(path):
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
62 if x in path_separators:
82385
d98a82f4c9bd Issue #17220: two fixes for changeset 2528e4aea338.
Brett Cannon <brett@python.org>
parents: 82382
diff changeset
63 front, tail = path.rsplit(x, maxsplit=1)
82382
2528e4aea338 Issue #17220: Little cleanup of _bootstrap.py.
Serhiy Storchaka <storchaka@gmail.com>
parents: 82237
diff changeset
64 return front, tail
2528e4aea338 Issue #17220: Little cleanup of _bootstrap.py.
Serhiy Storchaka <storchaka@gmail.com>
parents: 82237
diff changeset
65 return '', path
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
66
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
67
86824
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
68 def _path_stat(path):
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
69 """Stat the path.
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
70
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
71 Made a separate function to make it easier to override in experiments
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
72 (e.g. cache stat results).
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
73
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
74 """
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
75 return _os.stat(path)
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
76
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
77
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
78 def _path_is_mode_type(path, mode):
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
79 """Test whether the path is the specified mode type."""
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
80 try:
86824
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
81 stat_info = _path_stat(path)
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
82 except OSError:
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
83 return False
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
84 return (stat_info.st_mode & 0o170000) == mode
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
85
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
86
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
87 def _path_isfile(path):
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
88 """Replacement for os.path.isfile."""
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
89 return _path_is_mode_type(path, 0o100000)
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
90
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
91
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
92 def _path_isdir(path):
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
93 """Replacement for os.path.isdir."""
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
94 if not path:
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
95 path = _os.getcwd()
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
96 return _path_is_mode_type(path, 0o040000)
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
97
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
98
78722
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
99 def _write_atomic(path, data, mode=0o666):
75185
27d31f0c4ad5 Issue #14077: importlib: Fix regression introduced by de6703671386.
Charles-François Natali <neologix@free.fr>
parents: 75082
diff changeset
100 """Best-effort function to write data to a path atomically.
27d31f0c4ad5 Issue #14077: importlib: Fix regression introduced by de6703671386.
Charles-François Natali <neologix@free.fr>
parents: 75082
diff changeset
101 Be prepared to handle a FileExistsError if concurrent writing of the
27d31f0c4ad5 Issue #14077: importlib: Fix regression introduced by de6703671386.
Charles-François Natali <neologix@free.fr>
parents: 75082
diff changeset
102 temporary file is attempted."""
73573
b75b41237380 Issue #13392: Writing a pyc file should now be atomic under Windows as well.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73477
diff changeset
103 # id() is used to generate a pseudo-random filename.
b75b41237380 Issue #13392: Writing a pyc file should now be atomic under Windows as well.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73477
diff changeset
104 path_tmp = '{}.{}'.format(path, id(path))
78722
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
105 fd = _os.open(path_tmp,
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
106 _os.O_EXCL | _os.O_CREAT | _os.O_WRONLY, mode & 0o666)
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
107 try:
74998
de6703671386 Have importlib use os.replace() for atomic renaming.
Brett Cannon <brett@python.org>
parents: 74994
diff changeset
108 # We first write data to a temporary file, and then use os.replace() to
de6703671386 Have importlib use os.replace() for atomic renaming.
Brett Cannon <brett@python.org>
parents: 74994
diff changeset
109 # perform an atomic rename.
73573
b75b41237380 Issue #13392: Writing a pyc file should now be atomic under Windows as well.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73477
diff changeset
110 with _io.FileIO(fd, 'wb') as file:
b75b41237380 Issue #13392: Writing a pyc file should now be atomic under Windows as well.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73477
diff changeset
111 file.write(data)
74998
de6703671386 Have importlib use os.replace() for atomic renaming.
Brett Cannon <brett@python.org>
parents: 74994
diff changeset
112 _os.replace(path_tmp, path)
73573
b75b41237380 Issue #13392: Writing a pyc file should now be atomic under Windows as well.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73477
diff changeset
113 except OSError:
b75b41237380 Issue #13392: Writing a pyc file should now be atomic under Windows as well.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73477
diff changeset
114 try:
b75b41237380 Issue #13392: Writing a pyc file should now be atomic under Windows as well.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73477
diff changeset
115 _os.unlink(path_tmp)
72960
c16063765d3a Issue #13146: Writing a pyc file is now atomic under POSIX.
Antoine Pitrou <solipsis@pitrou.net>
parents: 68887
diff changeset
116 except OSError:
73573
b75b41237380 Issue #13392: Writing a pyc file should now be atomic under Windows as well.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73477
diff changeset
117 pass
b75b41237380 Issue #13392: Writing a pyc file should now be atomic under Windows as well.
Antoine Pitrou <solipsis@pitrou.net>
parents: 73477
diff changeset
118 raise
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
119
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
120
52139
2e8e897a1244 Make utility code in importlib._bootstrap private.
Brett Cannon <bcannon@gmail.com>
parents: 52115
diff changeset
121 def _wrap(new, old):
77964
37850f083af5 Minor refactoring in importlib._bootstrap, and fix the '_wrap' docstring.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 77917
diff changeset
122 """Simple substitute for functools.update_wrapper."""
73977
54a77c556d9a Issue #13593: updating the importlib utility decorators for __qualname__.
Meador Inge <meadori@gmail.com>
parents: 73974
diff changeset
123 for replace in ['__module__', '__name__', '__qualname__', '__doc__']:
74838
7a6fd7cd16e9 Don't fail in the face of a lacking attribute when wrapping a
Brett Cannon <brett@python.org>
parents: 74643
diff changeset
124 if hasattr(old, replace):
7a6fd7cd16e9 Don't fail in the face of a lacking attribute when wrapping a
Brett Cannon <brett@python.org>
parents: 74643
diff changeset
125 setattr(new, replace, getattr(old, replace))
51433
43d3a95ed662 Create a simple substitute for functools.wraps to use in importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 51430
diff changeset
126 new.__dict__.update(old.__dict__)
43d3a95ed662 Create a simple substitute for functools.wraps to use in importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 51430
diff changeset
127
43d3a95ed662 Create a simple substitute for functools.wraps to use in importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 51430
diff changeset
128
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
129 def _new_module(name):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
130 return type(sys)(name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
131
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
132
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
133 _code_type = type(_wrap.__code__)
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
134
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
135
87636
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
136
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
137 class _ManageReload:
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
138
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
139 """Manages the possible clean-up of sys.modules for load_module()."""
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
140
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
141 def __init__(self, name):
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
142 self._name = name
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
143
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
144 def __enter__(self):
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
145 self._is_reload = self._name in sys.modules
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
146
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
147 def __exit__(self, *args):
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
148 if any(arg is not None for arg in args) and not self._is_reload:
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
149 try:
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
150 del sys.modules[self._name]
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
151 except KeyError:
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
152 pass
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
153
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
154 # Module-level locking ########################################################
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
155
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
156 # A dict mapping module names to weakrefs of _ModuleLock instances
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
157 _module_locks = {}
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
158 # A dict mapping thread ids to _ModuleLock instances
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
159 _blocking_on = {}
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
160
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
161
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
162 class _DeadlockError(RuntimeError):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
163 pass
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
164
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
165
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
166 class _ModuleLock:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
167 """A recursive lock implementation which is able to detect deadlocks
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
168 (e.g. thread 1 trying to take locks A then B, and thread 2 trying to
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
169 take locks B then A).
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
170 """
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
171
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
172 def __init__(self, name):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
173 self.lock = _thread.allocate_lock()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
174 self.wakeup = _thread.allocate_lock()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
175 self.name = name
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
176 self.owner = None
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
177 self.count = 0
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
178 self.waiters = 0
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
179
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
180 def has_deadlock(self):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
181 # Deadlock avoidance for concurrent circular imports.
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
182 me = _thread.get_ident()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
183 tid = self.owner
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
184 while True:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
185 lock = _blocking_on.get(tid)
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
186 if lock is None:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
187 return False
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
188 tid = lock.owner
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
189 if tid == me:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
190 return True
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
191
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
192 def acquire(self):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
193 """
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
194 Acquire the module lock. If a potential deadlock is detected,
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
195 a _DeadlockError is raised.
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
196 Otherwise, the lock is always acquired and True is returned.
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
197 """
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
198 tid = _thread.get_ident()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
199 _blocking_on[tid] = self
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
200 try:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
201 while True:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
202 with self.lock:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
203 if self.count == 0 or self.owner == tid:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
204 self.owner = tid
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
205 self.count += 1
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
206 return True
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
207 if self.has_deadlock():
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
208 raise _DeadlockError('deadlock detected by %r' % self)
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
209 if self.wakeup.acquire(False):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
210 self.waiters += 1
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
211 # Wait for a release() call
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
212 self.wakeup.acquire()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
213 self.wakeup.release()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
214 finally:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
215 del _blocking_on[tid]
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
216
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
217 def release(self):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
218 tid = _thread.get_ident()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
219 with self.lock:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
220 if self.owner != tid:
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
221 raise RuntimeError('cannot release un-acquired lock')
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
222 assert self.count > 0
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
223 self.count -= 1
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
224 if self.count == 0:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
225 self.owner = None
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
226 if self.waiters:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
227 self.waiters -= 1
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
228 self.wakeup.release()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
229
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
230 def __repr__(self):
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
231 return '_ModuleLock({!r}) at {}'.format(self.name, id(self))
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
232
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
233
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
234 class _DummyModuleLock:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
235 """A simple _ModuleLock equivalent for Python builds without
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
236 multi-threading support."""
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
237
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
238 def __init__(self, name):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
239 self.name = name
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
240 self.count = 0
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
241
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
242 def acquire(self):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
243 self.count += 1
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
244 return True
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
245
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
246 def release(self):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
247 if self.count == 0:
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
248 raise RuntimeError('cannot release un-acquired lock')
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
249 self.count -= 1
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
250
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
251 def __repr__(self):
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
252 return '_DummyModuleLock({!r}) at {}'.format(self.name, id(self))
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
253
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
254
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
255 class _ModuleLockManager:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
256
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
257 def __init__(self, name):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
258 self._name = name
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
259 self._lock = None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
260
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
261 def __enter__(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
262 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
263 self._lock = _get_module_lock(self._name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
264 finally:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
265 _imp.release_lock()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
266 self._lock.acquire()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
267
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
268 def __exit__(self, *args, **kwargs):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
269 self._lock.release()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
270
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
271
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
272 # The following two functions are for consumption by Python/import.c.
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
273
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
274 def _get_module_lock(name):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
275 """Get or create the module lock for a given module name.
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
276
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
277 Should only be called with the import lock taken."""
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
278 lock = None
78779
7fa6336e9864 Issue #15781: Fix two small race conditions in import's module locking.
Antoine Pitrou <solipsis@pitrou.net>
parents: 78758
diff changeset
279 try:
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
280 lock = _module_locks[name]()
78779
7fa6336e9864 Issue #15781: Fix two small race conditions in import's module locking.
Antoine Pitrou <solipsis@pitrou.net>
parents: 78758
diff changeset
281 except KeyError:
7fa6336e9864 Issue #15781: Fix two small race conditions in import's module locking.
Antoine Pitrou <solipsis@pitrou.net>
parents: 78758
diff changeset
282 pass
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
283 if lock is None:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
284 if _thread is None:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
285 lock = _DummyModuleLock(name)
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
286 else:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
287 lock = _ModuleLock(name)
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
288 def cb(_):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
289 del _module_locks[name]
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
290 _module_locks[name] = _weakref.ref(lock, cb)
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
291 return lock
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
292
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
293 def _lock_unlock_module(name):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
294 """Release the global import lock, and acquires then release the
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
295 module lock for a given module name.
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
296 This is used to ensure a module is completely initialized, in the
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
297 event it is being imported by another thread.
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
298
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
299 Should only be called with the import lock taken."""
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
300 lock = _get_module_lock(name)
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
301 _imp.release_lock()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
302 try:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
303 lock.acquire()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
304 except _DeadlockError:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
305 # Concurrent circular import, we'll accept a partially initialized
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
306 # module object.
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
307 pass
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
308 else:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
309 lock.release()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
310
78344
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
311 # Frame stripping magic ###############################################
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
312
78344
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
313 def _call_with_frames_removed(f, *args, **kwds):
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
314 """remove_importlib_frames in import.c will always remove sequences
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
315 of importlib frames that end with a call to this function
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
316
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
317 Use it instead of a normal call in places where including the importlib
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
318 frames introduces unwanted noise into the traceback (e.g. when executing
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
319 module code)
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
320 """
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
321 return f(*args, **kwds)
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
322
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
323
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
324 # Finder/loader utility code ###############################################
52140
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
325
82957
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
326 # Magic word to reject .pyc files generated by other Python versions.
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
327 # It should change for each incompatible change to the bytecode.
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
328 #
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
329 # The value of CR and LF is incorporated so if you ever read or write
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
330 # a .pyc file in text mode the magic number will be wrong; also, the
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
331 # Apple MPW compiler swaps their values, botching string constants.
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
332 #
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
333 # The magic numbers must be spaced apart at least 2 values, as the
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
334 # -U interpeter flag will cause MAGIC+1 being used. They have been
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
335 # odd numbers for some time now.
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
336 #
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
337 # There were a variety of old schemes for setting the magic number.
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
338 # The current working scheme is to increment the previous value by
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
339 # 10.
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
340 #
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
341 # Starting with the adoption of PEP 3147 in Python 3.2, every bump in magic
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
342 # number also includes a new "magic tag", i.e. a human readable string used
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
343 # to represent the magic number in __pycache__ directories. When you change
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
344 # the magic number, you must also set a new unique magic tag. Generally this
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
345 # can be named after the Python major version of the magic number bump, but
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
346 # it can really be anything, as long as it's different than anything else
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
347 # that's come before. The tags are included in the following table, starting
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
348 # with Python 3.2a0.
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
349 #
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
350 # Known values:
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
351 # Python 1.5: 20121
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
352 # Python 1.5.1: 20121
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
353 # Python 1.5.2: 20121
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
354 # Python 1.6: 50428
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
355 # Python 2.0: 50823
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
356 # Python 2.0.1: 50823
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
357 # Python 2.1: 60202
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
358 # Python 2.1.1: 60202
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
359 # Python 2.1.2: 60202
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
360 # Python 2.2: 60717
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
361 # Python 2.3a0: 62011
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
362 # Python 2.3a0: 62021
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
363 # Python 2.3a0: 62011 (!)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
364 # Python 2.4a0: 62041
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
365 # Python 2.4a3: 62051
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
366 # Python 2.4b1: 62061
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
367 # Python 2.5a0: 62071
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
368 # Python 2.5a0: 62081 (ast-branch)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
369 # Python 2.5a0: 62091 (with)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
370 # Python 2.5a0: 62092 (changed WITH_CLEANUP opcode)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
371 # Python 2.5b3: 62101 (fix wrong code: for x, in ...)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
372 # Python 2.5b3: 62111 (fix wrong code: x += yield)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
373 # Python 2.5c1: 62121 (fix wrong lnotab with for loops and
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
374 # storing constants that should have been removed)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
375 # Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
376 # Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
377 # Python 2.6a1: 62161 (WITH_CLEANUP optimization)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
378 # Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
379 # Python 2.7a0: 62181 (optimize conditional branches:
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
380 # introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
381 # Python 2.7a0 62191 (introduce SETUP_WITH)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
382 # Python 2.7a0 62201 (introduce BUILD_SET)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
383 # Python 2.7a0 62211 (introduce MAP_ADD and SET_ADD)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
384 # Python 3000: 3000
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
385 # 3010 (removed UNARY_CONVERT)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
386 # 3020 (added BUILD_SET)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
387 # 3030 (added keyword-only parameters)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
388 # 3040 (added signature annotations)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
389 # 3050 (print becomes a function)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
390 # 3060 (PEP 3115 metaclass syntax)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
391 # 3061 (string literals become unicode)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
392 # 3071 (PEP 3109 raise changes)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
393 # 3081 (PEP 3137 make __file__ and __name__ unicode)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
394 # 3091 (kill str8 interning)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
395 # 3101 (merge from 2.6a0, see 62151)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
396 # 3103 (__file__ points to source file)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
397 # Python 3.0a4: 3111 (WITH_CLEANUP optimization).
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
398 # Python 3.0a5: 3131 (lexical exception stacking, including POP_EXCEPT)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
399 # Python 3.1a0: 3141 (optimize list, set and dict comprehensions:
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
400 # change LIST_APPEND and SET_ADD, add MAP_ADD)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
401 # Python 3.1a0: 3151 (optimize conditional branches:
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
402 # introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
403 # Python 3.2a0: 3160 (add SETUP_WITH)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
404 # tag: cpython-32
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
405 # Python 3.2a1: 3170 (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
406 # tag: cpython-32
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
407 # Python 3.2a2 3180 (add DELETE_DEREF)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
408 # Python 3.3a0 3190 __class__ super closure changed
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
409 # Python 3.3a0 3200 (__qualname__ added)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
410 # 3210 (added size modulo 2**32 to the pyc header)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
411 # Python 3.3a1 3220 (changed PEP 380 implementation)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
412 # Python 3.3a4 3230 (revert changes to implicit __class__ closure)
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
413 # Python 3.4a1 3250 (evaluate positional default arguments before
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
414 # keyword-only defaults)
83572
cf65c7a75f55 check local class namespace before reaching for cells (closes #17853)
Benjamin Peterson <benjamin@python.org>
parents: 83376
diff changeset
415 # Python 3.4a1 3260 (add LOAD_CLASSDEREF; allow locals of class to override
cf65c7a75f55 check local class namespace before reaching for cells (closes #17853)
Benjamin Peterson <benjamin@python.org>
parents: 83376
diff changeset
416 # free vars)
84090
32527aa9ad16 typo fix
Brett Cannon <brett@python.org>
parents: 84046
diff changeset
417 # Python 3.4a1 3270 (various tweaks to the __class__ closure)
83791
6db3741e59be rather than passing locals to the class body, just execute the class body in the proper environment
Benjamin Peterson <benjamin@python.org>
parents: 83783
diff changeset
418 # Python 3.4a1 3280 (remove implicit class argument)
86491
35b384ed594b give explicitly global functions and classes a global __qualname__ (closes #19301)
Benjamin Peterson <benjamin@python.org>
parents: 86444
diff changeset
419 # Python 3.4a4 3290 (changes to __qualname__ computation)
86521
bb2affc1e317 cleanup the construction of __qualname__ (closes #19301 again)
Benjamin Peterson <benjamin@python.org>
parents: 86491
diff changeset
420 # Python 3.4a4 3300 (more changes to __qualname__ computation)
82957
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
421 #
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
422 # MAGIC must change whenever the bytecode emitted by the compiler may no
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
423 # longer be understood by older implementations of the eval loop (usually
313bcff51900 Issue #17516: use comment syntax for comments, instead of multiline string
Victor Stinner <victor.stinner@gmail.com>
parents: 82876
diff changeset
424 # due to the addition of new opcodes).
78042
efb5e6ab10f4 Issue #15167 (as part of #13959): imp.get_magic() is no implemented in
Brett Cannon <brett@python.org>
parents: 78026
diff changeset
425
86521
bb2affc1e317 cleanup the construction of __qualname__ (closes #19301 again)
Benjamin Peterson <benjamin@python.org>
parents: 86491
diff changeset
426 MAGIC_NUMBER = (3300).to_bytes(2, 'little') + b'\r\n'
84128
5619bc2d8207 Issue #18192: Introduce importlib.util.MAGIC_NUMBER and document the
Brett Cannon <brett@python.org>
parents: 84109
diff changeset
427 _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
78042
efb5e6ab10f4 Issue #15167 (as part of #13959): imp.get_magic() is no implemented in
Brett Cannon <brett@python.org>
parents: 78026
diff changeset
428
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
429 _PYCACHE = '__pycache__'
76450
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
430
76874
b81ddaf0db47 Issue #13959: Deprecate imp.get_suffixes() for new attributes on
Brett Cannon <brett@python.org>
parents: 76826
diff changeset
431 SOURCE_SUFFIXES = ['.py'] # _setup() adds .pyw as needed.
76451
ea46ebba8a0f Issue #13959: Re-implement imp.source_from_cache() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76450
diff changeset
432
76874
b81ddaf0db47 Issue #13959: Deprecate imp.get_suffixes() for new attributes on
Brett Cannon <brett@python.org>
parents: 76826
diff changeset
433 DEBUG_BYTECODE_SUFFIXES = ['.pyc']
b81ddaf0db47 Issue #13959: Deprecate imp.get_suffixes() for new attributes on
Brett Cannon <brett@python.org>
parents: 76826
diff changeset
434 OPTIMIZED_BYTECODE_SUFFIXES = ['.pyo']
76450
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
435
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
436 def cache_from_source(path, debug_override=None):
76450
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
437 """Given the path to a .py file, return the path to its .pyc/.pyo file.
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
438
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
439 The .py file does not need to exist; this simply returns the path to the
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
440 .pyc/.pyo file calculated as if the .py file were imported. The extension
79173
4de5e4ec3cff don't depend on __debug__ because it's baked in at freeze time (issue #16046)
Benjamin Peterson <benjamin@python.org>
parents: 78779
diff changeset
441 will be .pyc unless sys.flags.optimize is non-zero, then it will be .pyo.
76450
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
442
79191
9b0582477aad rephrase
Benjamin Peterson <benjamin@python.org>
parents: 79173
diff changeset
443 If debug_override is not None, then it must be a boolean and is used in
9b0582477aad rephrase
Benjamin Peterson <benjamin@python.org>
parents: 79173
diff changeset
444 place of sys.flags.optimize.
76450
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
445
78026
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
446 If sys.implementation.cache_tag is None then NotImplementedError is raised.
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
447
76450
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
448 """
79173
4de5e4ec3cff don't depend on __debug__ because it's baked in at freeze time (issue #16046)
Benjamin Peterson <benjamin@python.org>
parents: 78779
diff changeset
449 debug = not sys.flags.optimize if debug_override is None else debug_override
76874
b81ddaf0db47 Issue #13959: Deprecate imp.get_suffixes() for new attributes on
Brett Cannon <brett@python.org>
parents: 76826
diff changeset
450 if debug:
b81ddaf0db47 Issue #13959: Deprecate imp.get_suffixes() for new attributes on
Brett Cannon <brett@python.org>
parents: 76826
diff changeset
451 suffixes = DEBUG_BYTECODE_SUFFIXES
b81ddaf0db47 Issue #13959: Deprecate imp.get_suffixes() for new attributes on
Brett Cannon <brett@python.org>
parents: 76826
diff changeset
452 else:
b81ddaf0db47 Issue #13959: Deprecate imp.get_suffixes() for new attributes on
Brett Cannon <brett@python.org>
parents: 76826
diff changeset
453 suffixes = OPTIMIZED_BYTECODE_SUFFIXES
76450
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
454 head, tail = _path_split(path)
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
455 base_filename, sep, _ = tail.partition('.')
78026
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
456 tag = sys.implementation.cache_tag
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
457 if tag is None:
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
458 raise NotImplementedError('sys.implementation.cache_tag is None')
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
459 filename = ''.join([base_filename, sep, tag, suffixes[0]])
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
460 return _path_join(head, _PYCACHE, filename)
76450
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
461
b773a751c2e7 Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76449
diff changeset
462
78078
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
463 def source_from_cache(path):
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
464 """Given the path to a .pyc./.pyo file, return the path to its .py file.
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
465
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
466 The .pyc/.pyo file does not need to exist; this simply returns the path to
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
467 the .py file calculated to correspond to the .pyc/.pyo file. If path does
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
468 not conform to PEP 3147 format, ValueError will be raised. If
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
469 sys.implementation.cache_tag is None then NotImplementedError is raised.
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
470
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
471 """
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
472 if sys.implementation.cache_tag is None:
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
473 raise NotImplementedError('sys.implementation.cache_tag is None')
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
474 head, pycache_filename = _path_split(path)
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
475 head, pycache = _path_split(head)
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
476 if pycache != _PYCACHE:
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
477 raise ValueError('{} not bottom-level directory in '
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
478 '{!r}'.format(_PYCACHE, path))
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
479 if pycache_filename.count('.') != 2:
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
480 raise ValueError('expected only 2 dots in '
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
481 '{!r}'.format(pycache_filename))
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
482 base_filename = pycache_filename.partition('.')[0]
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
483 return _path_join(head, base_filename + SOURCE_SUFFIXES[0])
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
484
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
485
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
486 def _get_sourcefile(bytecode_path):
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
487 """Convert a bytecode file path to a source path (if possible).
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
488
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
489 This function exists purely for backwards-compatibility for
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
490 PyImport_ExecCodeModuleWithFilenames() in the C API.
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
491
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
492 """
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
493 if len(bytecode_path) == 0:
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
494 return None
84467
b8028f74bac4 Issue #18351: Fix various issues with
Brett Cannon <brett@python.org>
parents: 84174
diff changeset
495 rest, _, extension = bytecode_path.rpartition('.')
b8028f74bac4 Issue #18351: Fix various issues with
Brett Cannon <brett@python.org>
parents: 84174
diff changeset
496 if not rest or extension.lower()[-3:-1] != 'py':
78078
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
497 return bytecode_path
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
498 try:
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
499 source_path = source_from_cache(bytecode_path)
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
500 except (NotImplementedError, ValueError):
84467
b8028f74bac4 Issue #18351: Fix various issues with
Brett Cannon <brett@python.org>
parents: 84174
diff changeset
501 source_path = bytecode_path[:-1]
b8028f74bac4 Issue #18351: Fix various issues with
Brett Cannon <brett@python.org>
parents: 84174
diff changeset
502 return source_path if _path_isfile(source_path) else bytecode_path
78078
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
503
9e164b404983 Issues #15169, #14599: Make PyImport_ExecCodeModuleWithPathnames() use
Brett Cannon <brett@python.org>
parents: 78051
diff changeset
504
83376
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
505 def _calc_mode(path):
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
506 """Calculate the mode permissions for a bytecode file."""
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
507 try:
86824
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
508 mode = _path_stat(path).st_mode
83376
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
509 except OSError:
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
510 mode = 0o666
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
511 # We always ensure write access so we can update cached files
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
512 # later even when the source files are read-only on Windows (#6074)
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
513 mode |= 0o200
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
514 return mode
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
515
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
516
83055
ac89e7bc0e2f Issue #17357: Add missing verbosity messages when running under
Brett Cannon <brett@python.org>
parents: 82236
diff changeset
517 def _verbose_message(message, *args, verbosity=1):
76303
2dd046be2c88 Issue #2377: Make importlib the implementation of __import__().
Brett Cannon <brett@python.org>
parents: 76280
diff changeset
518 """Print the message to stderr if -v/PYTHONVERBOSE is turned on."""
83055
ac89e7bc0e2f Issue #17357: Add missing verbosity messages when running under
Brett Cannon <brett@python.org>
parents: 82236
diff changeset
519 if sys.flags.verbose >= verbosity:
76327
1ca10eb58483 utilize startswith(tuple)
Philip Jenvey <pjenvey@underboss.org>
parents: 76312
diff changeset
520 if not message.startswith(('#', 'import ')):
76303
2dd046be2c88 Issue #2377: Make importlib the implementation of __import__().
Brett Cannon <brett@python.org>
parents: 76280
diff changeset
521 message = '# ' + message
2dd046be2c88 Issue #2377: Make importlib the implementation of __import__().
Brett Cannon <brett@python.org>
parents: 76280
diff changeset
522 print(message.format(*args), file=sys.stderr)
2dd046be2c88 Issue #2377: Make importlib the implementation of __import__().
Brett Cannon <brett@python.org>
parents: 76280
diff changeset
523
52140
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
524
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
525 def _check_name(method):
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
526 """Decorator to verify that the module being requested matches the one the
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
527 loader can handle.
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
528
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
529 The first argument (self) must define _name which the second argument is
68488
0991b40e895d #11515: fix several typos. Patch by Piotr Kasprzyk.
Ezio Melotti <ezio.melotti@gmail.com>
parents: 58960
diff changeset
530 compared against. If the comparison fails then ImportError is raised.
52140
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
531
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
532 """
76877
626d5c6fbd95 Issue #13959: Have
Brett Cannon <brett@python.org>
parents: 76874
diff changeset
533 def _check_name_wrapper(self, name=None, *args, **kwargs):
626d5c6fbd95 Issue #13959: Have
Brett Cannon <brett@python.org>
parents: 76874
diff changeset
534 if name is None:
626d5c6fbd95 Issue #13959: Have
Brett Cannon <brett@python.org>
parents: 76874
diff changeset
535 name = self.name
626d5c6fbd95 Issue #13959: Have
Brett Cannon <brett@python.org>
parents: 76874
diff changeset
536 elif self.name != name:
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
537 raise ImportError('loader cannot handle %s' % name, name=name)
52140
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
538 return method(self, name, *args, **kwargs)
74449
9935f7837c4b Issue #13588: Rename decorators in importlib.
Brett Cannon <brett@python.org>
parents: 74358
diff changeset
539 _wrap(_check_name_wrapper, method)
9935f7837c4b Issue #13588: Rename decorators in importlib.
Brett Cannon <brett@python.org>
parents: 74358
diff changeset
540 return _check_name_wrapper
52140
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
541
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
542
52166
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
543 def _requires_builtin(fxn):
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
544 """Decorator to verify the named module is built-in."""
74449
9935f7837c4b Issue #13588: Rename decorators in importlib.
Brett Cannon <brett@python.org>
parents: 74358
diff changeset
545 def _requires_builtin_wrapper(self, fullname):
52166
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
546 if fullname not in sys.builtin_module_names:
87360
2e4169aac667 User the repr for a module name in more places
Brett Cannon <brett@python.org>
parents: 87353
diff changeset
547 raise ImportError('{!r} is not a built-in module'.format(fullname),
76280
c071af95772a Have importlib take advantage of ImportError's new 'name' and 'path'
Brett Cannon <brett@python.org>
parents: 76081
diff changeset
548 name=fullname)
52166
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
549 return fxn(self, fullname)
74449
9935f7837c4b Issue #13588: Rename decorators in importlib.
Brett Cannon <brett@python.org>
parents: 74358
diff changeset
550 _wrap(_requires_builtin_wrapper, fxn)
9935f7837c4b Issue #13588: Rename decorators in importlib.
Brett Cannon <brett@python.org>
parents: 74358
diff changeset
551 return _requires_builtin_wrapper
52166
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
552
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
553
52168
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
554 def _requires_frozen(fxn):
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
555 """Decorator to verify the named module is frozen."""
74449
9935f7837c4b Issue #13588: Rename decorators in importlib.
Brett Cannon <brett@python.org>
parents: 74358
diff changeset
556 def _requires_frozen_wrapper(self, fullname):
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
557 if not _imp.is_frozen(fullname):
87360
2e4169aac667 User the repr for a module name in more places
Brett Cannon <brett@python.org>
parents: 87353
diff changeset
558 raise ImportError('{!r} is not a frozen module'.format(fullname),
76280
c071af95772a Have importlib take advantage of ImportError's new 'name' and 'path'
Brett Cannon <brett@python.org>
parents: 76081
diff changeset
559 name=fullname)
52168
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
560 return fxn(self, fullname)
74449
9935f7837c4b Issue #13588: Rename decorators in importlib.
Brett Cannon <brett@python.org>
parents: 74358
diff changeset
561 _wrap(_requires_frozen_wrapper, fxn)
9935f7837c4b Issue #13588: Rename decorators in importlib.
Brett Cannon <brett@python.org>
parents: 74358
diff changeset
562 return _requires_frozen_wrapper
52168
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
563
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
564
78489
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
565 def _find_module_shim(self, fullname):
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
566 """Try to find a loader for the specified module by delegating to
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
567 self.find_loader()."""
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
568 # Call find_loader(). If it returns a string (indicating this
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
569 # is a namespace package portion), generate a warning and
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
570 # return None.
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
571 loader, portions = self.find_loader(fullname)
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
572 if loader is None and len(portions):
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
573 msg = 'Not importing directory {}: missing __init__'
78489
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
574 _warnings.warn(msg.format(portions[0]), ImportWarning)
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
575 return loader
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
576
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
577
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
578 def _load_module_shim(self, fullname):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
579 """Load the specified module into sys.modules and return it."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
580 # XXX Deprecation Warning here...
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
581 spec = spec_from_loader(fullname, self)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
582 methods = _SpecMethods(spec)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
583 if fullname in sys.modules:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
584 module = sys.modules[fullname]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
585 methods.exec(module)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
586 return sys.modules[fullname]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
587 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
588 return methods.load()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
589
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
590
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
591 def _validate_bytecode_header(data, source_stats=None, name=None, path=None):
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
592 """Validate the header of the passed-in bytecode against source_stats (if
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
593 given) and returning the bytecode that can be compiled by compile().
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
594
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
595 All other arguments are used to enhance error reporting.
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
596
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
597 ImportError is raised when the magic number is incorrect or the bytecode is
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
598 found to be stale. EOFError is raised when the data is found to be
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
599 truncated.
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
600
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
601 """
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
602 exc_details = {}
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
603 if name is not None:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
604 exc_details['name'] = name
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
605 else:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
606 # To prevent having to make all messages have a conditional name.
81735
792810303239 Touch up exception messaging
Brett Cannon <brett@python.org>
parents: 81432
diff changeset
607 name = '<bytecode>'
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
608 if path is not None:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
609 exc_details['path'] = path
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
610 magic = data[:4]
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
611 raw_timestamp = data[4:8]
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
612 raw_size = data[8:12]
84128
5619bc2d8207 Issue #18192: Introduce importlib.util.MAGIC_NUMBER and document the
Brett Cannon <brett@python.org>
parents: 84109
diff changeset
613 if magic != MAGIC_NUMBER:
83056
Brett Cannon <brett@python.org>
parents: 82957 83055
diff changeset
614 message = 'bad magic number in {!r}: {!r}'.format(name, magic)
Brett Cannon <brett@python.org>
parents: 82957 83055
diff changeset
615 _verbose_message(message)
Brett Cannon <brett@python.org>
parents: 82957 83055
diff changeset
616 raise ImportError(message, **exc_details)
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
617 elif len(raw_timestamp) != 4:
84046
6b189f29b1e6 tweak exception message (again)
Brett Cannon <brett@python.org>
parents: 84023
diff changeset
618 message = 'reached EOF while reading timestamp in {!r}'.format(name)
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
619 _verbose_message(message)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
620 raise EOFError(message)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
621 elif len(raw_size) != 4:
84046
6b189f29b1e6 tweak exception message (again)
Brett Cannon <brett@python.org>
parents: 84023
diff changeset
622 message = 'reached EOF while reading size of source in {!r}'.format(name)
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
623 _verbose_message(message)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
624 raise EOFError(message)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
625 if source_stats is not None:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
626 try:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
627 source_mtime = int(source_stats['mtime'])
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
628 except KeyError:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
629 pass
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
630 else:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
631 if _r_long(raw_timestamp) != source_mtime:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
632 message = 'bytecode is stale for {!r}'.format(name)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
633 _verbose_message(message)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
634 raise ImportError(message, **exc_details)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
635 try:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
636 source_size = source_stats['size'] & 0xFFFFFFFF
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
637 except KeyError:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
638 pass
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
639 else:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
640 if _r_long(raw_size) != source_size:
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
641 raise ImportError('bytecode is stale for {!r}'.format(name),
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
642 **exc_details)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
643 return data[12:]
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
644
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
645
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
646 def _compile_bytecode(data, name=None, bytecode_path=None, source_path=None):
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
647 """Compile bytecode as returned by _validate_bytecode_header()."""
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
648 code = marshal.loads(data)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
649 if isinstance(code, _code_type):
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
650 _verbose_message('code object from {!r}', bytecode_path)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
651 if source_path is not None:
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
652 _imp._fix_co_filename(code, source_path)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
653 return code
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
654 else:
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
655 raise ImportError('Non-code object in {!r}'.format(bytecode_path),
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
656 name=name, path=bytecode_path)
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
657
81761
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
658 def _code_to_bytecode(code, mtime=0, source_size=0):
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
659 """Compile a code object into bytecode for writing out to a byte-compiled
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
660 file."""
84128
5619bc2d8207 Issue #18192: Introduce importlib.util.MAGIC_NUMBER and document the
Brett Cannon <brett@python.org>
parents: 84109
diff changeset
661 data = bytearray(MAGIC_NUMBER)
81761
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
662 data.extend(_w_long(mtime))
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
663 data.extend(_w_long(source_size))
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
664 data.extend(marshal.dumps(code))
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
665 return data
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
666
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
667
84173
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
668 def decode_source(source_bytes):
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
669 """Decode bytes representing source code and return the string.
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
670
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
671 Universal newline support is used in the decoding.
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
672 """
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
673 import tokenize # To avoid bootstrap issues.
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
674 source_bytes_readline = _io.BytesIO(source_bytes).readline
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
675 encoding = tokenize.detect_encoding(source_bytes_readline)
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
676 newline_decoder = _io.IncrementalNewlineDecoder(None, True)
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
677 return newline_decoder.decode(source_bytes.decode(encoding[0]))
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
678
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
679
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
680 # Module specifications #######################################################
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
681
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
682 def _module_repr(module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
683 # The implementation of ModuleType__repr__().
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
684 loader = getattr(module, '__loader__', None)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
685 if hasattr(loader, 'module_repr'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
686 # XXX Deprecation Warning here...
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
687 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
688 return loader.module_repr(module)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
689 except Exception:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
690 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
691 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
692 spec = module.__spec__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
693 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
694 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
695 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
696 if spec is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
697 return _SpecMethods(spec).module_repr()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
698
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
699 # We could use module.__class__.__name__ instead of 'module' in the
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
700 # various repr permutations.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
701 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
702 name = module.__name__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
703 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
704 name = '?'
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
705 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
706 filename = module.__file__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
707 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
708 if loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
709 return '<module {!r}>'.format(name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
710 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
711 return '<module {!r} ({!r})>'.format(name, loader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
712 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
713 return '<module {!r} from {!r}>'.format(name, filename)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
714
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
715
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
716 class _installed_safely:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
717
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
718 def __init__(self, module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
719 self._module = module
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
720 self._spec = module.__spec__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
721
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
722 def __enter__(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
723 # This must be done before putting the module in sys.modules
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
724 # (otherwise an optimization shortcut in import.c becomes
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
725 # wrong)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
726 self._spec._initializing = True
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
727 sys.modules[self._spec.name] = self._module
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
728
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
729 def __exit__(self, *args):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
730 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
731 spec = self._spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
732 if any(arg is not None for arg in args):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
733 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
734 del sys.modules[spec.name]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
735 except KeyError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
736 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
737 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
738 _verbose_message('import {!r} # {!r}', spec.name, spec.loader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
739 finally:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
740 self._spec._initializing = False
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
741
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
742
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
743 class ModuleSpec:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
744 """The specification for a module, used for loading.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
745
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
746 A module's spec is the source for information about the module. For
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
747 data associated with the module, including source, use the spec's
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
748 loader.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
749
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
750 `name` is the absolute name of the module. `loader` is the loader
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
751 to use when loading the module. `parent` is the name of the
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
752 package the module is in. The parent is derived from the name.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
753
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
754 `is_package` determines if the module is considered a package or
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
755 not. On modules this is reflected by the `__path__` attribute.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
756
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
757 `origin` is the specific location used by the loader from which to
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
758 load the module, if that information is available. When filename is
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
759 set, origin will match.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
760
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
761 `has_location` indicates that a spec's "origin" reflects a location.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
762 When this is True, `__file__` attribute of the module is set.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
763
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
764 `cached` is the location of the cached bytecode file, if any. It
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
765 corresponds to the `__cached__` attribute.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
766
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
767 `submodule_search_locations` is the sequence of path entries to
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
768 search when importing submodules. If set, is_package should be
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
769 True--and False otherwise.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
770
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
771 Packages are simply modules that (may) have submodules. If a spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
772 has a non-None value in `submodule_search_locations`, the import
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
773 system will consider modules loaded from the spec as packages.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
774
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
775 Only finders (see importlib.abc.MetaPathFinder and
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
776 importlib.abc.PathEntryFinder) should modify ModuleSpec instances.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
777
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
778 """
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
779
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
780 def __init__(self, name, loader, *, origin=None, loader_state=None,
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
781 is_package=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
782 self.name = name
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
783 self.loader = loader
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
784 self.origin = origin
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
785 self.loader_state = loader_state
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
786 self.submodule_search_locations = [] if is_package else None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
787
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
788 # file-location attributes
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
789 self._set_fileattr = False
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
790 self._cached = None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
791
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
792 def __repr__(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
793 args = ['name={!r}'.format(self.name),
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
794 'loader={!r}'.format(self.loader)]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
795 if self.origin is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
796 args.append('origin={!r}'.format(self.origin))
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
797 if self.submodule_search_locations is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
798 args.append('submodule_search_locations={}'
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
799 .format(self.submodule_search_locations))
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
800 return '{}({})'.format(self.__class__.__name__, ', '.join(args))
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
801
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
802 def __eq__(self, other):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
803 smsl = self.submodule_search_locations
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
804 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
805 return (self.name == other.name and
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
806 self.loader == other.loader and
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
807 self.origin == other.origin and
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
808 smsl == other.submodule_search_locations and
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
809 self.cached == other.cached and
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
810 self.has_location == other.has_location)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
811 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
812 return False
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
813
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
814 @property
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
815 def cached(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
816 if self._cached is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
817 if self.origin is not None and self._set_fileattr:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
818 filename = self.origin
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
819 if filename.endswith(tuple(SOURCE_SUFFIXES)):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
820 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
821 self._cached = cache_from_source(filename)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
822 except NotImplementedError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
823 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
824 elif filename.endswith(tuple(BYTECODE_SUFFIXES)):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
825 self._cached = filename
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
826 return self._cached
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
827
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
828 @cached.setter
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
829 def cached(self, cached):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
830 self._cached = cached
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
831
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
832 @property
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
833 def parent(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
834 """The name of the module's parent."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
835 if self.submodule_search_locations is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
836 return self.name.rpartition('.')[0]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
837 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
838 return self.name
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
839
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
840 @property
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
841 def has_location(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
842 return self._set_fileattr
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
843
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
844
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
845 def spec_from_loader(name, loader, *, origin=None, is_package=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
846 """Return a module spec based on various loader methods."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
847 if hasattr(loader, 'get_filename'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
848 if is_package is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
849 return spec_from_file_location(name, loader=loader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
850 search = [] if is_package else None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
851 return spec_from_file_location(name, loader=loader,
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
852 submodule_search_locations=search)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
853
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
854 if is_package is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
855 if hasattr(loader, 'is_package'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
856 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
857 is_package = loader.is_package(name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
858 except ImportError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
859 is_package = None # aka, undefined
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
860 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
861 # the default
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
862 is_package = False
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
863
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
864 return ModuleSpec(name, loader, origin=origin, is_package=is_package)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
865
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
866
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
867 _POPULATE = object()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
868
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
869
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
870 def spec_from_file_location(name, location=None, *, loader=None,
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
871 submodule_search_locations=_POPULATE):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
872 """Return a module spec based on a file location.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
873
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
874 To indicate that the module is a package, set
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
875 submodule_search_locations to a list of directory paths. An
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
876 empty list is sufficient, though its not otherwise useful to the
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
877 import system.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
878
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
879 The loader must take a spec as its only __init__() arg.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
880
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
881 """
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
882 if location is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
883 # The caller may simply want a partially populated location-
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
884 # oriented spec. So we set the location to a bogus value and
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
885 # fill in as much as we can.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
886 location = '<unknown>'
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
887 if hasattr(loader, 'get_filename'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
888 # ExecutionLoader
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
889 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
890 location = loader.get_filename(name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
891 except ImportError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
892 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
893
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
894 # If the location is on the filesystem, but doesn't actually exist,
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
895 # we could return None here, indicating that the location is not
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
896 # valid. However, we don't have a good way of testing since an
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
897 # indirect location (e.g. a zip file or URL) will look like a
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
898 # non-existent file relative to the filesystem.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
899
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
900 spec = ModuleSpec(name, loader, origin=location)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
901 spec._set_fileattr = True
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
902
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
903 # Pick a loader if one wasn't provided.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
904 if loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
905 for loader_class, suffixes in _get_supported_file_loaders():
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
906 if location.endswith(tuple(suffixes)):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
907 loader = loader_class(name, location)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
908 spec.loader = loader
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
909 break
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
910 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
911 return None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
912
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
913 # Set submodule_search_paths appropriately.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
914 if submodule_search_locations is _POPULATE:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
915 # Check the loader.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
916 if hasattr(loader, 'is_package'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
917 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
918 is_package = loader.is_package(name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
919 except ImportError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
920 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
921 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
922 if is_package:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
923 spec.submodule_search_locations = []
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
924 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
925 spec.submodule_search_locations = submodule_search_locations
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
926 if spec.submodule_search_locations == []:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
927 if location:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
928 dirname = _path_split(location)[0]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
929 spec.submodule_search_locations.append(dirname)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
930
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
931 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
932
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
933
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
934 def _spec_from_module(module, loader=None, origin=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
935 # This function is meant for use in _setup().
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
936 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
937 spec = module.__spec__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
938 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
939 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
940 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
941 if spec is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
942 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
943
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
944 name = module.__name__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
945 if loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
946 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
947 loader = module.__loader__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
948 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
949 # loader will stay None.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
950 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
951 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
952 location = module.__file__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
953 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
954 location = None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
955 if origin is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
956 if location is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
957 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
958 origin = loader._ORIGIN
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
959 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
960 origin = None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
961 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
962 origin = location
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
963 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
964 cached = module.__cached__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
965 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
966 cached = None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
967 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
968 submodule_search_locations = list(module.__path__)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
969 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
970 submodule_search_locations = None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
971
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
972 spec = ModuleSpec(name, loader, origin=origin)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
973 spec._set_fileattr = False if location is None else True
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
974 spec.cached = cached
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
975 spec.submodule_search_locations = submodule_search_locations
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
976 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
977
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
978
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
979 class _SpecMethods:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
980
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
981 """Convenience wrapper around spec objects to provide spec-specific
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
982 methods."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
983
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
984 def __init__(self, spec):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
985 self.spec = spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
986
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
987 @classmethod
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
988 def from_module(cls, module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
989 """Create a spec from a module's attributes."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
990 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
991 spec = module.__spec__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
992 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
993 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
994 loader = spec.__loader__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
995 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
996 spec = _find_spec(module.__name__)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
997 if spec is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
998 spec = spec_from_loader(module.__name__, loader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
999 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1000 spec = spec_from_loader(module.__name__, loader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1001 return cls(spec)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1002
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1003 def module_repr(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1004 """Return the repr to use for the module."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1005 # We mostly replicate _module_repr() using the spec attributes.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1006 spec = self.spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1007 name = '?' if spec.name is None else spec.name
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1008 if spec.origin is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1009 if spec.loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1010 return '<module {!r}>'.format(name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1011 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1012 return '<module {!r} ({!r})>'.format(name, spec.loader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1013 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1014 if spec.has_location:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1015 return '<module {!r} from {!r}>'.format(name, spec.origin)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1016 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1017 return '<module {!r} ({})>'.format(spec.name, spec.origin)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1018
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1019 def init_module_attrs(self, module, *, _override=False, _force_name=True):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1020 """Set the module's attributes.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1021
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1022 All missing import-related module attributes will be set. Here
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1023 is how the spec attributes map onto the module:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1024
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1025 spec.name -> module.__name__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1026 spec.loader -> module.__loader__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1027 spec.parent -> module.__package__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1028 spec -> module.__spec__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1029
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1030 Optional:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1031 spec.origin -> module.__file__ (if spec.set_fileattr is true)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1032 spec.cached -> module.__cached__ (if __file__ also set)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1033 spec.submodule_search_locations -> module.__path__ (if set)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1034
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1035 """
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1036 spec = self.spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1037
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1038 # The passed in module may be not support attribute assignment,
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1039 # in which case we simply don't set the attributes.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1040
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1041 # __name__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1042 if (_override or _force_name or
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1043 getattr(module, '__name__', None) is None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1044 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1045 module.__name__ = spec.name
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1046 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1047 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1048
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1049 # __loader__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1050 if _override or getattr(module, '__loader__', None) is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1051 loader = spec.loader
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1052 if loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1053 # A backward compatibility hack.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1054 if spec.submodule_search_locations is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1055 loader = _NamespaceLoader.__new__(_NamespaceLoader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1056 loader._path = spec.submodule_search_locations
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1057 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1058 module.__loader__ = loader
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1059 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1060 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1061
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1062 # __package__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1063 if _override or getattr(module, '__package__', None) is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1064 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1065 module.__package__ = spec.parent
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1066 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1067 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1068
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1069 # __spec__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1070 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1071 module.__spec__ = spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1072 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1073 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1074
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1075 # __path__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1076 if _override or getattr(module, '__path__', None) is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1077 if spec.submodule_search_locations is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1078 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1079 module.__path__ = spec.submodule_search_locations
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1080 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1081 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1082
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1083 if spec.has_location:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1084 # __file__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1085 if _override or getattr(module, '__file__', None) is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1086 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1087 module.__file__ = spec.origin
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1088 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1089 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1090
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1091 # __cached__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1092 if _override or getattr(module, '__cached__', None) is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1093 if spec.cached is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1094 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1095 module.__cached__ = spec.cached
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1096 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1097 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1098
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1099 def create(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1100 """Return a new module to be loaded.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1101
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1102 The import-related module attributes are also set with the
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1103 appropriate values from the spec.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1104
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1105 """
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1106 spec = self.spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1107 # Typically loaders will not implement create_module().
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1108 if hasattr(spec.loader, 'create_module'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1109 # If create_module() returns `None` it means the default
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1110 # module creation should be used.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1111 module = spec.loader.create_module(spec)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1112 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1113 module = None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1114 if module is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1115 # This must be done before open() is ever called as the 'io'
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1116 # module implicitly imports 'locale' and would otherwise
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1117 # trigger an infinite loop.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1118 module = _new_module(spec.name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1119 self.init_module_attrs(module)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1120 return module
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1121
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1122 def _exec(self, module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1123 """Do everything necessary to execute the module.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1124
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1125 The namespace of `module` is used as the target of execution.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1126 This method uses the loader's `exec_module()` method.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1127
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1128 """
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1129 self.spec.loader.exec_module(module)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1130
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1131 # Used by importlib.reload() and _load_module_shim().
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1132 def exec(self, module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1133 """Execute the spec in an existing module's namespace."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1134 name = self.spec.name
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1135 _imp.acquire_lock()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1136 with _ModuleLockManager(name):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1137 if sys.modules.get(name) is not module:
87360
2e4169aac667 User the repr for a module name in more places
Brett Cannon <brett@python.org>
parents: 87353
diff changeset
1138 msg = 'module {!r} not in sys.modules'.format(name)
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1139 raise ImportError(msg, name=name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1140 if self.spec.loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1141 if self.spec.submodule_search_locations is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1142 raise ImportError('missing loader', name=self.spec.name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1143 # namespace package
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1144 self.init_module_attrs(module, _override=True)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1145 return module
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1146 self.init_module_attrs(module, _override=True)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1147 if not hasattr(self.spec.loader, 'exec_module'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1148 # XXX DeprecationWarning goes here...
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1149 self.spec.loader.load_module(name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1150 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1151 self._exec(module)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1152 return sys.modules[name]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1153
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1154 def _load_backward_compatible(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1155 # XXX DeprecationWarning goes here...
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1156 spec = self.spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1157 # The module must be in sys.modules!
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1158 spec.loader.load_module(spec.name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1159 module = sys.modules[spec.name]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1160 if getattr(module, '__loader__', None) is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1161 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1162 module.__loader__ = spec.loader
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1163 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1164 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1165 if getattr(module, '__package__', None) is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1166 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1167 # Since module.__path__ may not line up with
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1168 # spec.submodule_search_paths, we can't necessarily rely
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1169 # on spec.parent here.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1170 module.__package__ = module.__name__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1171 if not hasattr(module, '__path__'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1172 module.__package__ = spec.name.rpartition('.')[0]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1173 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1174 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1175 if getattr(module, '__spec__', None) is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1176 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1177 module.__spec__ = spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1178 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1179 pass
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1180 return module
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1181
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1182 # XXX If we don't end up using this for pythonrun.c/runpy, we should
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1183 # get rid of it.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1184 def _load_existing(self, module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1185 """Exec the spec'ed module into an existing module's namespace."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1186 # For use by runpy.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1187 with _installed_safely(module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1188 loaded = self.exec(module)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1189 return loaded
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1190
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1191 def _load_unlocked(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1192 # A helper for direct use by the import system.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1193 if self.spec.loader is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1194 # not a namespace package
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1195 if not hasattr(self.spec.loader, 'exec_module'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1196 return self._load_backward_compatible()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1197
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1198 module = self.create()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1199 with _installed_safely(module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1200 if self.spec.loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1201 if self.spec.submodule_search_locations is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1202 raise ImportError('missing loader', name=self.spec.name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1203 # A namespace package so do nothing.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1204 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1205 self._exec(module)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1206
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1207 # We don't ensure that the import-related module attributes get
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1208 # set in the sys.modules replacement case. Such modules are on
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1209 # their own.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1210 return sys.modules[self.spec.name]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1211
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1212 # A method used during testing of _load_unlocked() and by
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1213 # _load_module_shim().
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1214 def load(self):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1215 """Return a new module object, loaded by the spec's loader.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1216
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1217 The module is not added to its parent.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1218
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1219 If a module is already in sys.modules, that existing module gets
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1220 clobbered.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1221
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1222 """
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1223 _imp.acquire_lock()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1224 with _ModuleLockManager(self.spec.name):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1225 return self._load_unlocked()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1226
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1227
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1228 # Loaders #####################################################################
52140
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
1229
50983
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1230 class BuiltinImporter:
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1231
52165
62f9dad628de A few more docstring/API cleanups for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 52164
diff changeset
1232 """Meta path import for built-in modules.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1233
52165
62f9dad628de A few more docstring/API cleanups for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 52164
diff changeset
1234 All methods are either class or static methods to avoid the need to
62f9dad628de A few more docstring/API cleanups for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 52164
diff changeset
1235 instantiate the class.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1236
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1237 """
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1238
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1239 @staticmethod
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1240 def module_repr(module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1241 # XXX deprecate
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1242 return '<module {!r} (built-in)>'.format(module.__name__)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1243
50983
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1244 @classmethod
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1245 def find_spec(cls, fullname, path=None, target=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1246 if path is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1247 return None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1248 if _imp.is_builtin(fullname):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1249 return spec_from_loader(fullname, cls, origin='built-in')
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1250 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1251 return None
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1252
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1253 @classmethod
50983
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1254 def find_module(cls, fullname, path=None):
52165
62f9dad628de A few more docstring/API cleanups for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 52164
diff changeset
1255 """Find the built-in module.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1256
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1257 If 'path' is ever specified then the search is considered a failure.
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1258
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1259 """
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1260 spec = cls.find_spec(fullname, path)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1261 return spec.loader if spec is not None else None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1262
51026
c26f1af26bfc Document both importlib.machinery.BuiltinImporter and FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 50983
diff changeset
1263 @classmethod
87636
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1264 @_requires_builtin
51026
c26f1af26bfc Document both importlib.machinery.BuiltinImporter and FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 50983
diff changeset
1265 def load_module(cls, fullname):
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1266 """Load a built-in module."""
87636
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1267 with _ManageReload(fullname):
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1268 module = _call_with_frames_removed(_imp.init_builtin, fullname)
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1269 module.__loader__ = cls
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1270 module.__package__ = ''
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1271 return module
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1272
52166
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1273 @classmethod
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1274 @_requires_builtin
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1275 def get_code(cls, fullname):
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1276 """Return None as built-in modules do not have code objects."""
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1277 return None
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1278
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1279 @classmethod
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1280 @_requires_builtin
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1281 def get_source(cls, fullname):
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1282 """Return None as built-in modules do not have source code."""
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1283 return None
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1284
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1285 @classmethod
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1286 @_requires_builtin
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1287 def is_package(cls, fullname):
77964
37850f083af5 Minor refactoring in importlib._bootstrap, and fix the '_wrap' docstring.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 77917
diff changeset
1288 """Return False as built-in modules are never packages."""
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1289 # XXX DeprecationWarning here...
52166
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1290 return False
69cd615b76fb Implement InspectLoader for BuiltinImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52165
diff changeset
1291
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1292
50983
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1293 class FrozenImporter:
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1294
52165
62f9dad628de A few more docstring/API cleanups for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 52164
diff changeset
1295 """Meta path import for frozen modules.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1296
52165
62f9dad628de A few more docstring/API cleanups for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 52164
diff changeset
1297 All methods are either class or static methods to avoid the need to
62f9dad628de A few more docstring/API cleanups for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 52164
diff changeset
1298 instantiate the class.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1299
50983
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1300 """
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1301
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1302 @staticmethod
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1303 def module_repr(m):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1304 # XXX deprecate
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1305 return '<module {!r} (frozen)>'.format(m.__name__)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1306
50983
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1307 @classmethod
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1308 def find_spec(cls, fullname, path=None, target=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1309 if _imp.is_frozen(fullname):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1310 return spec_from_loader(fullname, cls, origin='frozen')
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1311 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1312 return None
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1313
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1314 @classmethod
50983
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1315 def find_module(cls, fullname, path=None):
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1316 """Find a frozen module."""
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
1317 return cls if _imp.is_frozen(fullname) else None
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1318
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1319 @staticmethod
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1320 def exec_module(module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1321 name = module.__spec__.name
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1322 if not _imp.is_frozen(name):
87360
2e4169aac667 User the repr for a module name in more places
Brett Cannon <brett@python.org>
parents: 87353
diff changeset
1323 raise ImportError('{!r} is not a frozen module'.format(name),
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1324 name=name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1325 code = _call_with_frames_removed(_imp.get_frozen_object, name)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1326 exec(code, module.__dict__)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1327
50983
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1328 @classmethod
0940a4f2506e Add importlib.machinery with its first tenants, BuitinImporter and
Brett Cannon <bcannon@gmail.com>
parents: 50893
diff changeset
1329 def load_module(cls, fullname):
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1330 """Load a frozen module."""
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1331 return _load_module_shim(cls, fullname)
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1332
52168
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1333 @classmethod
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1334 @_requires_frozen
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1335 def get_code(cls, fullname):
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1336 """Return the code object for the frozen module."""
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
1337 return _imp.get_frozen_object(fullname)
52168
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1338
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1339 @classmethod
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1340 @_requires_frozen
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1341 def get_source(cls, fullname):
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1342 """Return None as frozen modules do not have source code."""
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1343 return None
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1344
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1345 @classmethod
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1346 @_requires_frozen
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1347 def is_package(cls, fullname):
78491
f7b59e890e30 fix docstring wording
Philip Jenvey <pjenvey@underboss.org>
parents: 78489
diff changeset
1348 """Return True if the frozen module is a package."""
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
1349 return _imp.is_frozen_package(fullname)
52168
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1350
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1351
78380
a1ac1e13c5a0 Close #15519: Properly expose WindowsRegistryFinder in importlib and bring the name into line with normal import terminology. Original patch by Eric Snow
Nick Coghlan <ncoghlan@gmail.com>
parents: 78344
diff changeset
1352 class WindowsRegistryFinder:
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1353
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1354 """Meta path finder for modules declared in the Windows registry."""
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1355
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1356 REGISTRY_KEY = (
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
1357 'Software\\Python\\PythonCore\\{sys_version}'
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
1358 '\\Modules\\{fullname}')
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1359 REGISTRY_KEY_DEBUG = (
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
1360 'Software\\Python\\PythonCore\\{sys_version}'
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
1361 '\\Modules\\{fullname}\\Debug')
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1362 DEBUG_BUILD = False # Changed in _setup()
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1363
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1364 @classmethod
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1365 def _open_registry(cls, key):
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1366 try:
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1367 return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key)
80944
bb94f6222fef Issue #16719: Get rid of WindowsError. Use OSError instead
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80930
diff changeset
1368 except OSError:
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1369 return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1370
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1371 @classmethod
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1372 def _search_registry(cls, fullname):
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1373 if cls.DEBUG_BUILD:
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1374 registry_key = cls.REGISTRY_KEY_DEBUG
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1375 else:
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1376 registry_key = cls.REGISTRY_KEY
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1377 key = registry_key.format(fullname=fullname,
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1378 sys_version=sys.version[:3])
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1379 try:
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1380 with cls._open_registry(key) as hkey:
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
1381 filepath = _winreg.QueryValue(hkey, '')
80944
bb94f6222fef Issue #16719: Get rid of WindowsError. Use OSError instead
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80930
diff changeset
1382 except OSError:
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1383 return None
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1384 return filepath
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1385
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1386 @classmethod
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1387 def find_spec(cls, fullname, path=None, target=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1388 # XXX untested! Need a Windows person to write tests (otherwise mock out appropriately)
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1389 filepath = cls._search_registry(fullname)
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1390 if filepath is None:
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1391 return None
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1392 try:
86824
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
1393 _path_stat(filepath)
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1394 except OSError:
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1395 return None
85945
32b18998a560 [issue19151] Fix docstring and use of _get_suppported_file_loaders() to reflect 2-tuples.
Eric Snow <ericsnowcurrently@gmail.com>
parents: 85518
diff changeset
1396 for loader, suffixes in _get_supported_file_loaders():
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
1397 if filepath.endswith(tuple(suffixes)):
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1398 spec = spec_from_loader(fullname, loader(fullname, filepath),
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1399 origin=filepath)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1400 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1401
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1402 @classmethod
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1403 def find_module(cls, fullname, path=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1404 """Find module named in the registry."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1405 spec = self.find_spec(fullname, path)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1406 if spec is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1407 return spec.loader
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1408 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1409 return None
52168
70f5f9113ae1 Implement InspectLoader for FrozenImporter.
Brett Cannon <bcannon@gmail.com>
parents: 52166
diff changeset
1410
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1411
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1412 class _LoaderBasics:
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1413
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1414 """Base class of common code needed by both SourceLoader and
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1415 SourcelessFileLoader."""
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1416
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1417 # XXX deprecate?
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1418 def is_package(self, fullname):
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1419 """Concrete implementation of InspectLoader.is_package by checking if
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1420 the path returned by get_filename has a filename of '__init__.py'."""
76449
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
1421 filename = _path_split(self.get_filename(fullname))[1]
77457
240b7467e65c Issue #14938: importlib.abc.SourceLoader.is_package() now takes the
Brett Cannon <brett@python.org>
parents: 77180
diff changeset
1422 filename_base = filename.rsplit('.', 1)[0]
240b7467e65c Issue #14938: importlib.abc.SourceLoader.is_package() now takes the
Brett Cannon <brett@python.org>
parents: 77180
diff changeset
1423 tail_name = fullname.rpartition('.')[2]
240b7467e65c Issue #14938: importlib.abc.SourceLoader.is_package() now takes the
Brett Cannon <brett@python.org>
parents: 77180
diff changeset
1424 return filename_base == '__init__' and tail_name != '__init__'
52165
62f9dad628de A few more docstring/API cleanups for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 52164
diff changeset
1425
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1426 def exec_module(self, module):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1427 """Execute the module."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1428 code = self.get_code(module.__name__)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1429 if code is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1430 raise ImportError('cannot load module {!r} when get_code() '
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1431 'returns None'.format(module.__name__))
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1432 _call_with_frames_removed(exec, code, module.__dict__)
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1433
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1434 load_module = _load_module_shim
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1435
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1436
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1437 class SourceLoader(_LoaderBasics):
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1438
67573
e125d92f7438 Issue 10899: Remove function type annotations from the stdlib
Raymond Hettinger <python@rcn.com>
parents: 66226
diff changeset
1439 def path_mtime(self, path):
67581
7d658b49b3e1 Issue 10899: Remove function type annotations from the stdlib
Raymond Hettinger <python@rcn.com>
parents: 67573
diff changeset
1440 """Optional method that returns the modification time (an int) for the
7d658b49b3e1 Issue 10899: Remove function type annotations from the stdlib
Raymond Hettinger <python@rcn.com>
parents: 67573
diff changeset
1441 specified path, where path is a str.
83225
8e733e30edf6 Issue #17093,17566,17567: Methods from classes in importlib.abc now raise/return
Brett Cannon <brett@python.org>
parents: 83056
diff changeset
1442
8e733e30edf6 Issue #17093,17566,17567: Methods from classes in importlib.abc now raise/return
Brett Cannon <brett@python.org>
parents: 83056
diff changeset
1443 Raises IOError when the path cannot be handled.
74358
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1444 """
83225
8e733e30edf6 Issue #17093,17566,17567: Methods from classes in importlib.abc now raise/return
Brett Cannon <brett@python.org>
parents: 83056
diff changeset
1445 raise IOError
74358
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1446
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1447 def path_stats(self, path):
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1448 """Optional method returning a metadata dict for the specified path
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1449 to by the path (str).
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1450 Possible keys:
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1451 - 'mtime' (mandatory) is the numeric timestamp of last source
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1452 code modification;
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1453 - 'size' (optional) is the size in bytes of the source code.
52112
03080fa08dfe Implement get_source for importlib.abc.PyLoader using source_path and get_data.
Brett Cannon <bcannon@gmail.com>
parents: 52083
diff changeset
1454
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1455 Implementing this method allows the loader to read bytecode files.
83225
8e733e30edf6 Issue #17093,17566,17567: Methods from classes in importlib.abc now raise/return
Brett Cannon <brett@python.org>
parents: 83056
diff changeset
1456 Raises IOError when the path cannot be handled.
52112
03080fa08dfe Implement get_source for importlib.abc.PyLoader using source_path and get_data.
Brett Cannon <bcannon@gmail.com>
parents: 52083
diff changeset
1457 """
74358
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1458 return {'mtime': self.path_mtime(path)}
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1459
78722
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1460 def _cache_bytecode(self, source_path, cache_path, data):
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1461 """Optional method which writes data (bytes) to a file path (a str).
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1462
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1463 Implementing this method allows for the writing of bytecode files.
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1464
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1465 The source path is needed in order to correctly transfer permissions
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1466 """
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1467 # For backwards compatibility, we delegate to set_data()
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1468 return self.set_data(cache_path, data)
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1469
67573
e125d92f7438 Issue 10899: Remove function type annotations from the stdlib
Raymond Hettinger <python@rcn.com>
parents: 66226
diff changeset
1470 def set_data(self, path, data):
67581
7d658b49b3e1 Issue 10899: Remove function type annotations from the stdlib
Raymond Hettinger <python@rcn.com>
parents: 67573
diff changeset
1471 """Optional method which writes data (bytes) to a file path (a str).
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1472
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1473 Implementing this method allows for the writing of bytecode files.
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1474 """
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1475
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1476
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1477 def get_source(self, fullname):
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1478 """Concrete implementation of InspectLoader.get_source."""
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1479 path = self.get_filename(fullname)
52112
03080fa08dfe Implement get_source for importlib.abc.PyLoader using source_path and get_data.
Brett Cannon <bcannon@gmail.com>
parents: 52083
diff changeset
1480 try:
03080fa08dfe Implement get_source for importlib.abc.PyLoader using source_path and get_data.
Brett Cannon <bcannon@gmail.com>
parents: 52083
diff changeset
1481 source_bytes = self.get_data(path)
81039
7d69d04522e3 Replace IOError with OSError (#16715)
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80944
diff changeset
1482 except OSError as exc:
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
1483 raise ImportError('source not available through get_data()',
78112
7d202353a728 Issue #15343: A lot more than just unicode decoding can go wrong when retrieving a source file
Nick Coghlan <ncoghlan@gmail.com>
parents: 78078
diff changeset
1484 name=fullname) from exc
84173
bdd60bedf933 Issue #18076: Introduce imoportlib.util.decode_source().
Brett Cannon <brett@python.org>
parents: 84172
diff changeset
1485 return decode_source(source_bytes)
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1486
81761
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
1487 def source_to_code(self, data, path, *, _optimize=-1):
80507
e30bcce5c634 Issue #15627: Add the compile_source() method to
Brett Cannon <brett@python.org>
parents: 80410
diff changeset
1488 """Return the code object compiled from source.
e30bcce5c634 Issue #15627: Add the compile_source() method to
Brett Cannon <brett@python.org>
parents: 80410
diff changeset
1489
e30bcce5c634 Issue #15627: Add the compile_source() method to
Brett Cannon <brett@python.org>
parents: 80410
diff changeset
1490 The 'data' argument can be any object type that compile() supports.
e30bcce5c634 Issue #15627: Add the compile_source() method to
Brett Cannon <brett@python.org>
parents: 80410
diff changeset
1491 """
e30bcce5c634 Issue #15627: Add the compile_source() method to
Brett Cannon <brett@python.org>
parents: 80410
diff changeset
1492 return _call_with_frames_removed(compile, data, path, 'exec',
81761
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
1493 dont_inherit=True, optimize=_optimize)
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1494
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1495 def get_code(self, fullname):
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1496 """Concrete implementation of InspectLoader.get_code.
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1497
74358
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1498 Reading of bytecode requires path_stats to be implemented. To write
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1499 bytecode, set_data must also be implemented.
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1500
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1501 """
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1502 source_path = self.get_filename(fullname)
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1503 source_mtime = None
78026
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
1504 try:
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
1505 bytecode_path = cache_from_source(source_path)
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
1506 except NotImplementedError:
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
1507 bytecode_path = None
e86330669bb5 Issue #15056: imp.cache_from_source() and source_from_cache() raise
Brett Cannon <brett@python.org>
parents: 78010
diff changeset
1508 else:
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1509 try:
74358
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1510 st = self.path_stats(source_path)
83225
8e733e30edf6 Issue #17093,17566,17567: Methods from classes in importlib.abc now raise/return
Brett Cannon <brett@python.org>
parents: 83056
diff changeset
1511 except IOError:
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1512 pass
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1513 else:
74358
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1514 source_mtime = int(st['mtime'])
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1515 try:
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1516 data = self.get_data(bytecode_path)
81039
7d69d04522e3 Replace IOError with OSError (#16715)
Andrew Svetlov <andrew.svetlov@gmail.com>
parents: 80944
diff changeset
1517 except OSError:
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1518 pass
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1519 else:
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1520 try:
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
1521 bytes_data = _validate_bytecode_header(data,
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
1522 source_stats=st, name=fullname,
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
1523 path=bytecode_path)
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1524 except (ImportError, EOFError):
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1525 pass
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1526 else:
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
1527 _verbose_message('{} matches {}', bytecode_path,
76303
2dd046be2c88 Issue #2377: Make importlib the implementation of __import__().
Brett Cannon <brett@python.org>
parents: 76280
diff changeset
1528 source_path)
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
1529 return _compile_bytecode(bytes_data, name=fullname,
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
1530 bytecode_path=bytecode_path,
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
1531 source_path=source_path)
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1532 source_bytes = self.get_data(source_path)
80725
7caab48f171e Issue #15627: This is simply an update to the name of a new method recently added
Eric Snow <ericsnowcurrently@gmail.com>
parents: 80530
diff changeset
1533 code_object = self.source_to_code(source_bytes, source_path)
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
1534 _verbose_message('code object from {}', source_path)
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1535 if (not sys.dont_write_bytecode and bytecode_path is not None and
81761
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
1536 source_mtime is not None):
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
1537 data = _code_to_bytecode(code_object, source_mtime,
d4eb02b6aac9 Port py_compile over to importlib
Brett Cannon <brett@python.org>
parents: 81735
diff changeset
1538 len(source_bytes))
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1539 try:
78722
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1540 self._cache_bytecode(source_path, bytecode_path, data)
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
1541 _verbose_message('wrote {!r}', bytecode_path)
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1542 except NotImplementedError:
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1543 pass
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1544 return code_object
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1545
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1546
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1547 class FileLoader:
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1548
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1549 """Base file loader class which implements the loader protocol methods that
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1550 require file system usage."""
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1551
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1552 def __init__(self, fullname, path):
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1553 """Cache the module name and the path to the file found by the
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1554 finder."""
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1555 self.name = fullname
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1556 self.path = path
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1557
52139
2e8e897a1244 Make utility code in importlib._bootstrap private.
Brett Cannon <bcannon@gmail.com>
parents: 52115
diff changeset
1558 @_check_name
76877
626d5c6fbd95 Issue #13959: Have
Brett Cannon <brett@python.org>
parents: 76874
diff changeset
1559 def load_module(self, fullname):
626d5c6fbd95 Issue #13959: Have
Brett Cannon <brett@python.org>
parents: 76874
diff changeset
1560 """Load a module from a file."""
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1561 # The only reason for this method is for the name check.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1562
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1563 # Issue #14857: Avoid the zero-argument form of super so the implementation
77180
bcb3b81853cc Tweak importlib._bootstrap to avoid zero-argument super so I can work on issue #14857 without breaking imports
Nick Coghlan <ncoghlan@gmail.com>
parents: 77164
diff changeset
1564 # of that form can be updated without breaking the frozen module
bcb3b81853cc Tweak importlib._bootstrap to avoid zero-argument super so I can work on issue #14857 without breaking imports
Nick Coghlan <ncoghlan@gmail.com>
parents: 77164
diff changeset
1565 return super(FileLoader, self).load_module(fullname)
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1566
52139
2e8e897a1244 Make utility code in importlib._bootstrap private.
Brett Cannon <bcannon@gmail.com>
parents: 52115
diff changeset
1567 @_check_name
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1568 def get_filename(self, fullname):
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1569 """Return the path to the source file as found by the finder."""
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1570 return self.path
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1571
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1572 def get_data(self, path):
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1573 """Return the data from path as raw bytes."""
64407
f8ba9558adbf Remove redundant context manager.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 64291
diff changeset
1574 with _io.FileIO(path, 'r') as file:
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1575 return file.read()
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1576
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1577
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1578 class SourceFileLoader(FileLoader, SourceLoader):
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1579
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1580 """Concrete implementation of SourceLoader using the file system."""
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1581
74358
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1582 def path_stats(self, path):
78491
f7b59e890e30 fix docstring wording
Philip Jenvey <pjenvey@underboss.org>
parents: 78489
diff changeset
1583 """Return the metadata for the path."""
86824
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
1584 st = _path_stat(path)
74358
87331661042b Issue #13645: pyc files now contain the size of the corresponding source
Antoine Pitrou <solipsis@pitrou.net>
parents: 73977
diff changeset
1585 return {'mtime': st.st_mtime, 'size': st.st_size}
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1586
78722
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1587 def _cache_bytecode(self, source_path, bytecode_path, data):
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1588 # Adapt between the two APIs
83376
04aaeae6ee7b Issue #17244: Don't mask exceptions raised during the creation of
Brett Cannon <brett@python.org>
parents: 83225
diff changeset
1589 mode = _calc_mode(source_path)
78738
0c661c5632e0 Issue #2051: Tweak last commit for this issue to pass in mode instead
Brett Cannon <brett@python.org>
parents: 78722
diff changeset
1590 return self.set_data(bytecode_path, data, _mode=mode)
78722
3a831a0a29c4 Close #2501: Permission bits are once again correctly copied from the source file to the cached bytecode file. Test by Eric Snow.
Nick Coghlan <ncoghlan@gmail.com>
parents: 78663
diff changeset
1591
78738
0c661c5632e0 Issue #2051: Tweak last commit for this issue to pass in mode instead
Brett Cannon <brett@python.org>
parents: 78722
diff changeset
1592 def set_data(self, path, data, *, _mode=0o666):
62587
b07b2c954a80 Move importlib.abc.SourceLoader to _bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 61692
diff changeset
1593 """Write bytes data to a file."""
76449
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
1594 parent, filename = _path_split(path)
64240
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1595 path_parts = []
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1596 # Figure out what directories are missing.
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1597 while parent and not _path_isdir(parent):
76449
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
1598 parent, part = _path_split(parent)
64240
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1599 path_parts.append(part)
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1600 # Create needed directories.
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1601 for part in reversed(path_parts):
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1602 parent = _path_join(parent, part)
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1603 try:
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1604 _os.mkdir(parent)
73169
e4d44c2e8e81 Simplify and remove few dependencies on 'errno', thanks to PEP 3151.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 73016
diff changeset
1605 except FileExistsError:
64240
cf399de12b54 One of the joys of having test_multiprocessing occasionally execute after
Brett Cannon <bcannon@gmail.com>
parents: 62761
diff changeset
1606 # Probably another Python process already created the dir.
73169
e4d44c2e8e81 Simplify and remove few dependencies on 'errno', thanks to PEP 3151.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 73016
diff changeset
1607 continue
79741
53ce30b62de2 Issue #15833: don't raise an exception if importlib can't write byte-compiled
Trent Nelson <trent@trent.me>
parents: 79652
diff changeset
1608 except OSError as exc:
53ce30b62de2 Issue #15833: don't raise an exception if importlib can't write byte-compiled
Trent Nelson <trent@trent.me>
parents: 79652
diff changeset
1609 # Could be a permission error, read-only filesystem: just forget
53ce30b62de2 Issue #15833: don't raise an exception if importlib can't write byte-compiled
Trent Nelson <trent@trent.me>
parents: 79652
diff changeset
1610 # about writing the data.
53ce30b62de2 Issue #15833: don't raise an exception if importlib can't write byte-compiled
Trent Nelson <trent@trent.me>
parents: 79652
diff changeset
1611 _verbose_message('could not create {!r}: {!r}', parent, exc)
73169
e4d44c2e8e81 Simplify and remove few dependencies on 'errno', thanks to PEP 3151.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 73016
diff changeset
1612 return
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1613 try:
78738
0c661c5632e0 Issue #2051: Tweak last commit for this issue to pass in mode instead
Brett Cannon <brett@python.org>
parents: 78722
diff changeset
1614 _write_atomic(path, data, _mode)
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
1615 _verbose_message('created {!r}', path)
79741
53ce30b62de2 Issue #15833: don't raise an exception if importlib can't write byte-compiled
Trent Nelson <trent@trent.me>
parents: 79652
diff changeset
1616 except OSError as exc:
53ce30b62de2 Issue #15833: don't raise an exception if importlib can't write byte-compiled
Trent Nelson <trent@trent.me>
parents: 79652
diff changeset
1617 # Same as above: just don't write the bytecode.
53ce30b62de2 Issue #15833: don't raise an exception if importlib can't write byte-compiled
Trent Nelson <trent@trent.me>
parents: 79652
diff changeset
1618 _verbose_message('could not create {!r}: {!r}', path, exc)
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1619
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1620
76548
a2cf07135e4f Issue #14605: Rename _SourcelessFileLoader to SourcelessFileLoader.
Marc-Andre Lemburg <mal@egenix.com>
parents: 76547
diff changeset
1621 class SourcelessFileLoader(FileLoader, _LoaderBasics):
55355
dfaf6de2c8ce Implement the PEP 302 protocol for get_filename() as
Brett Cannon <bcannon@gmail.com>
parents: 52633
diff changeset
1622
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1623 """Loader which handles sourceless file imports."""
52112
03080fa08dfe Implement get_source for importlib.abc.PyLoader using source_path and get_data.
Brett Cannon <bcannon@gmail.com>
parents: 52083
diff changeset
1624
51771
ee7029710c05 Refactor source and bytecode file loaders in importlib so that there
Brett Cannon <bcannon@gmail.com>
parents: 51770
diff changeset
1625 def get_code(self, fullname):
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1626 path = self.get_filename(fullname)
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1627 data = self.get_data(path)
81432
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
1628 bytes_data = _validate_bytecode_header(data, name=fullname, path=path)
a4292889e942 Issue #15031: Refactor some code in importlib pertaining to validating
Brett Cannon <brett@python.org>
parents: 81428
diff changeset
1629 return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path)
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1630
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1631 def get_source(self, fullname):
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1632 """Return None as there is no source code."""
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1633 return None
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1634
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1635
78486
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
1636 # Filled in by _setup().
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
1637 EXTENSION_SUFFIXES = []
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
1638
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
1639
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1640 class ExtensionFileLoader:
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1641
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1642 """Loader for extension modules.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1643
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1644 The constructor is designed to work with FileFinder.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1645
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1646 """
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1647
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1648 def __init__(self, name, path):
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1649 self.name = name
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1650 self.path = path
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1651
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1652 @_check_name
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1653 def load_module(self, fullname):
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1654 """Load an extension module."""
87636
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1655 with _ManageReload(fullname):
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1656 module = _call_with_frames_removed(_imp.load_dynamic,
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1657 fullname, self.path)
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1658 _verbose_message('extension module loaded from {!r}', self.path)
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1659 is_package = self.is_package(fullname)
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1660 if is_package and not hasattr(module, '__path__'):
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1661 module.__path__ = [_path_split(self.path)[0]]
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1662 module.__loader__ = self
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1663 module.__package__ = module.__name__
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1664 if not is_package:
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1665 module.__package__ = module.__package__.rpartition('.')[0]
b5bbd47a9bc4 Issue #19698: Remove exec_module() from the built-in and extension
Brett Cannon <brett@python.org>
parents: 87360
diff changeset
1666 return module
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1667
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1668 def is_package(self, fullname):
78491
f7b59e890e30 fix docstring wording
Philip Jenvey <pjenvey@underboss.org>
parents: 78489
diff changeset
1669 """Return True if the extension module is a package."""
78486
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
1670 file_name = _path_split(self.path)[1]
78487
e024f6ba5ed8 update docstring per the extension package fix, refactor
Philip Jenvey <pjenvey@underboss.org>
parents: 78486
diff changeset
1671 return any(file_name == '__init__' + suffix
e024f6ba5ed8 update docstring per the extension package fix, refactor
Philip Jenvey <pjenvey@underboss.org>
parents: 78486
diff changeset
1672 for suffix in EXTENSION_SUFFIXES)
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1673
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1674 def get_code(self, fullname):
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1675 """Return None as an extension module cannot create a code object."""
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1676 return None
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1677
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1678 def get_source(self, fullname):
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1679 """Return None as extension modules have no source code."""
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1680 return None
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1681
85946
832579dbafd6 [issue19152] Add ExtensionFileLoader.get_filename().
Eric Snow <ericsnowcurrently@gmail.com>
parents: 85945
diff changeset
1682 @_check_name
832579dbafd6 [issue19152] Add ExtensionFileLoader.get_filename().
Eric Snow <ericsnowcurrently@gmail.com>
parents: 85945
diff changeset
1683 def get_filename(self, fullname):
832579dbafd6 [issue19152] Add ExtensionFileLoader.get_filename().
Eric Snow <ericsnowcurrently@gmail.com>
parents: 85945
diff changeset
1684 """Return the path to the source file as found by the finder."""
832579dbafd6 [issue19152] Add ExtensionFileLoader.get_filename().
Eric Snow <ericsnowcurrently@gmail.com>
parents: 85945
diff changeset
1685 return self.path
832579dbafd6 [issue19152] Add ExtensionFileLoader.get_filename().
Eric Snow <ericsnowcurrently@gmail.com>
parents: 85945
diff changeset
1686
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1687
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1688 class _NamespacePath:
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1689 """Represents a namespace package's path. It uses the module name
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1690 to find its parent module, and from there it looks up the parent's
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1691 __path__. When this changes, the module's own path is recomputed,
80409
58d6fea0c0c7 missing letter
Benjamin Peterson <benjamin@python.org>
parents: 79832
diff changeset
1692 using path_finder. For top-level modules, the parent module's path
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1693 is sys.path."""
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1694
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1695 def __init__(self, name, path, path_finder):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1696 self._name = name
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1697 self._path = path
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1698 self._last_parent_path = tuple(self._get_parent_path())
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1699 self._path_finder = path_finder
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1700
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1701 def _find_parent_path_names(self):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1702 """Returns a tuple of (parent-module-name, parent-path-attr-name)"""
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1703 parent, dot, me = self._name.rpartition('.')
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1704 if dot == '':
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1705 # This is a top-level module. sys.path contains the parent path.
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1706 return 'sys', 'path'
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1707 # Not a top-level module. parent-module.__path__ contains the
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1708 # parent path.
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1709 return parent, '__path__'
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1710
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1711 def _get_parent_path(self):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1712 parent_module_name, path_attr_name = self._find_parent_path_names()
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1713 return getattr(sys.modules[parent_module_name], path_attr_name)
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1714
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1715 def _recalculate(self):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1716 # If the parent's path has changed, recalculate _path
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1717 parent_path = tuple(self._get_parent_path()) # Make a copy
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1718 if parent_path != self._last_parent_path:
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1719 spec = self._path_finder(self._name, parent_path)
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1720 # Note that no changes are made if a loader is returned, but we
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1721 # do remember the new parent path
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1722 if spec is not None and spec.loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1723 if spec.submodule_search_locations:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1724 self._path = spec.submodule_search_locations
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1725 self._last_parent_path = parent_path # Save the copy
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1726 return self._path
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1727
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1728 def __iter__(self):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1729 return iter(self._recalculate())
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1730
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1731 def __len__(self):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1732 return len(self._recalculate())
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1733
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1734 def __repr__(self):
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
1735 return '_NamespacePath({!r})'.format(self._path)
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1736
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1737 def __contains__(self, item):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1738 return item in self._recalculate()
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1739
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1740 def append(self, item):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1741 self._path.append(item)
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1742
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1743
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1744 # We use this exclusively in init_module_attrs() for backward-compatibility.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1745 class _NamespaceLoader:
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1746 def __init__(self, name, path, path_finder):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1747 self._path = _NamespacePath(name, path, path_finder)
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1748
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1749 # XXX Deprecate
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1750 @classmethod
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1751 def module_repr(cls, module):
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
1752 return '<module {!r} (namespace)>'.format(module.__name__)
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1753
84169
ebec625b13f9 Issues #18058, 18057: Make importlib._bootstrap.NamespaceLoader
Brett Cannon <brett@python.org>
parents: 84134
diff changeset
1754 def is_package(self, fullname):
ebec625b13f9 Issues #18058, 18057: Make importlib._bootstrap.NamespaceLoader
Brett Cannon <brett@python.org>
parents: 84134
diff changeset
1755 return True
ebec625b13f9 Issues #18058, 18057: Make importlib._bootstrap.NamespaceLoader
Brett Cannon <brett@python.org>
parents: 84134
diff changeset
1756
ebec625b13f9 Issues #18058, 18057: Make importlib._bootstrap.NamespaceLoader
Brett Cannon <brett@python.org>
parents: 84134
diff changeset
1757 def get_source(self, fullname):
ebec625b13f9 Issues #18058, 18057: Make importlib._bootstrap.NamespaceLoader
Brett Cannon <brett@python.org>
parents: 84134
diff changeset
1758 return ''
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1759
84169
ebec625b13f9 Issues #18058, 18057: Make importlib._bootstrap.NamespaceLoader
Brett Cannon <brett@python.org>
parents: 84134
diff changeset
1760 def get_code(self, fullname):
ebec625b13f9 Issues #18058, 18057: Make importlib._bootstrap.NamespaceLoader
Brett Cannon <brett@python.org>
parents: 84134
diff changeset
1761 return compile('', '<string>', 'exec', dont_inherit=True)
ebec625b13f9 Issues #18058, 18057: Make importlib._bootstrap.NamespaceLoader
Brett Cannon <brett@python.org>
parents: 84134
diff changeset
1762
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1763 # XXX Deprecate
84001
e873f2e67353 Issues #18088, 18089: Introduce
Brett Cannon <brett@python.org>
parents: 83999
diff changeset
1764 def load_module(self, fullname):
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1765 """Load a namespace module."""
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1766 _verbose_message('namespace module loaded with path {!r}', self._path)
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1767 return _load_module_shim(self, fullname)
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1768
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1769
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1770 # Finders #####################################################################
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
1771
51322
53d6445c6c5a Rename importlib._bootstrap.SysPathFinder to PathFinder and expose off of
Brett Cannon <bcannon@gmail.com>
parents: 51266
diff changeset
1772 class PathFinder:
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1773
78382
1f8351cf00f3 Issue #15502: Bring the importlib.PathFinder docs and docstring more in line with the new import system documentation, and fix various parts of the new docs that weren't quite right given PEP 420 or were otherwise a bit misleading. Also note the key terminology problem still being discussed in the issue
Nick Coghlan <ncoghlan@gmail.com>
parents: 78380
diff changeset
1774 """Meta path finder for sys.path and package __path__ attributes."""
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1775
51639
ef2cba80c975 Change importlib.machinery.PathFinder to not have implicit semantics (that's
Brett Cannon <bcannon@gmail.com>
parents: 51433
diff changeset
1776 @classmethod
78485
0a75ce232f56 Issue #15502: Finish bringing importlib.abc in line with the current
Brett Cannon <brett@python.org>
parents: 78456
diff changeset
1777 def invalidate_caches(cls):
0a75ce232f56 Issue #15502: Finish bringing importlib.abc in line with the current
Brett Cannon <brett@python.org>
parents: 78456
diff changeset
1778 """Call the invalidate_caches() method on all path entry finders
0a75ce232f56 Issue #15502: Finish bringing importlib.abc in line with the current
Brett Cannon <brett@python.org>
parents: 78456
diff changeset
1779 stored in sys.path_importer_caches (where implemented)."""
0a75ce232f56 Issue #15502: Finish bringing importlib.abc in line with the current
Brett Cannon <brett@python.org>
parents: 78456
diff changeset
1780 for finder in sys.path_importer_cache.values():
0a75ce232f56 Issue #15502: Finish bringing importlib.abc in line with the current
Brett Cannon <brett@python.org>
parents: 78456
diff changeset
1781 if hasattr(finder, 'invalidate_caches'):
0a75ce232f56 Issue #15502: Finish bringing importlib.abc in line with the current
Brett Cannon <brett@python.org>
parents: 78456
diff changeset
1782 finder.invalidate_caches()
0a75ce232f56 Issue #15502: Finish bringing importlib.abc in line with the current
Brett Cannon <brett@python.org>
parents: 78456
diff changeset
1783
0a75ce232f56 Issue #15502: Finish bringing importlib.abc in line with the current
Brett Cannon <brett@python.org>
parents: 78456
diff changeset
1784 @classmethod
76566
57d558f1904d Issue #14605: Make explicit the entries on sys.path_hooks that used to
Brett Cannon <brett@python.org>
parents: 76549
diff changeset
1785 def _path_hooks(cls, path):
51639
ef2cba80c975 Change importlib.machinery.PathFinder to not have implicit semantics (that's
Brett Cannon <bcannon@gmail.com>
parents: 51433
diff changeset
1786 """Search sequence of hooks for a finder for 'path'.
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1787
51639
ef2cba80c975 Change importlib.machinery.PathFinder to not have implicit semantics (that's
Brett Cannon <bcannon@gmail.com>
parents: 51433
diff changeset
1788 If 'hooks' is false then use sys.path_hooks.
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1789
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1790 """
76566
57d558f1904d Issue #14605: Make explicit the entries on sys.path_hooks that used to
Brett Cannon <brett@python.org>
parents: 76549
diff changeset
1791 if not sys.path_hooks:
57d558f1904d Issue #14605: Make explicit the entries on sys.path_hooks that used to
Brett Cannon <brett@python.org>
parents: 76549
diff changeset
1792 _warnings.warn('sys.path_hooks is empty', ImportWarning)
57d558f1904d Issue #14605: Make explicit the entries on sys.path_hooks that used to
Brett Cannon <brett@python.org>
parents: 76549
diff changeset
1793 for hook in sys.path_hooks:
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1794 try:
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1795 return hook(path)
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1796 except ImportError:
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1797 continue
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1798 else:
76582
7025ee00dbf6 Issue #14605: Use None in sys.path_importer_cache to represent no
Brett Cannon <brett@python.org>
parents: 76579
diff changeset
1799 return None
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1800
51322
53d6445c6c5a Rename importlib._bootstrap.SysPathFinder to PathFinder and expose off of
Brett Cannon <bcannon@gmail.com>
parents: 51266
diff changeset
1801 @classmethod
76566
57d558f1904d Issue #14605: Make explicit the entries on sys.path_hooks that used to
Brett Cannon <brett@python.org>
parents: 76549
diff changeset
1802 def _path_importer_cache(cls, path):
78382
1f8351cf00f3 Issue #15502: Bring the importlib.PathFinder docs and docstring more in line with the new import system documentation, and fix various parts of the new docs that weren't quite right given PEP 420 or were otherwise a bit misleading. Also note the key terminology problem still being discussed in the issue
Nick Coghlan <ncoghlan@gmail.com>
parents: 78380
diff changeset
1803 """Get the finder for the path entry from sys.path_importer_cache.
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1804
78382
1f8351cf00f3 Issue #15502: Bring the importlib.PathFinder docs and docstring more in line with the new import system documentation, and fix various parts of the new docs that weren't quite right given PEP 420 or were otherwise a bit misleading. Also note the key terminology problem still being discussed in the issue
Nick Coghlan <ncoghlan@gmail.com>
parents: 78380
diff changeset
1805 If the path entry is not in the cache, find the appropriate finder
1f8351cf00f3 Issue #15502: Bring the importlib.PathFinder docs and docstring more in line with the new import system documentation, and fix various parts of the new docs that weren't quite right given PEP 420 or were otherwise a bit misleading. Also note the key terminology problem still being discussed in the issue
Nick Coghlan <ncoghlan@gmail.com>
parents: 78380
diff changeset
1806 and cache it. If no finder is available, store None.
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1807
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1808 """
74994
b8593ec7e8c5 Tweak the handling of the empty string in sys.path for importlib.
Brett Cannon <brett@python.org>
parents: 74992
diff changeset
1809 if path == '':
86436
76184b5339f2 Issue #18416: Have importlib.machinery.PathFinder treat '' as the cwd
Brett Cannon <brett@python.org>
parents: 85952
diff changeset
1810 path = _os.getcwd()
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1811 try:
51322
53d6445c6c5a Rename importlib._bootstrap.SysPathFinder to PathFinder and expose off of
Brett Cannon <bcannon@gmail.com>
parents: 51266
diff changeset
1812 finder = sys.path_importer_cache[path]
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1813 except KeyError:
51322
53d6445c6c5a Rename importlib._bootstrap.SysPathFinder to PathFinder and expose off of
Brett Cannon <bcannon@gmail.com>
parents: 51266
diff changeset
1814 finder = cls._path_hooks(path)
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1815 sys.path_importer_cache[path] = finder
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1816 return finder
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1817
51322
53d6445c6c5a Rename importlib._bootstrap.SysPathFinder to PathFinder and expose off of
Brett Cannon <bcannon@gmail.com>
parents: 51266
diff changeset
1818 @classmethod
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1819 def _legacy_get_spec(cls, fullname, finder):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1820 if hasattr(finder, 'find_loader'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1821 loader, portions = finder.find_loader(fullname)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1822 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1823 loader = finder.find_module(fullname)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1824 portions = None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1825 if loader is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1826 return spec_from_loader(fullname, loader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1827 spec = ModuleSpec(fullname, None)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1828 spec.submodule_search_locations = portions
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1829 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1830
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1831 @classmethod
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1832 def _get_spec(cls, fullname, path, target=None):
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1833 """Find the loader or namespace_path for this module/package name."""
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1834 # If this ends up being a namespace package, namespace_path is
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1835 # the list of paths that will become its __path__
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1836 namespace_path = []
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1837 for entry in path:
80529
291406748217 - Issue #16514: Fix regression causing a traceback when sys.path[0] is None
Barry Warsaw <barry@python.org>
parents: 80409
diff changeset
1838 if not isinstance(entry, (str, bytes)):
291406748217 - Issue #16514: Fix regression causing a traceback when sys.path[0] is None
Barry Warsaw <barry@python.org>
parents: 80409
diff changeset
1839 continue
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1840 finder = cls._path_importer_cache(entry)
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1841 if finder is not None:
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1842 if hasattr(finder, 'find_spec'):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1843 spec = finder.find_spec(fullname, target)
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1844 else:
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1845 spec = cls._legacy_get_spec(fullname, finder)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1846 if spec is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1847 continue
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1848 if spec.loader is not None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1849 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1850 portions = spec.submodule_search_locations
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1851 if portions is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1852 raise ImportError('spec missing loader')
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1853 # This is possibly part of a namespace package.
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1854 # Remember these path entries (if any) for when we
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1855 # create a namespace package, and continue iterating
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1856 # on path.
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1857 namespace_path.extend(portions)
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1858 else:
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1859 spec = ModuleSpec(fullname, None)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1860 spec.submodule_search_locations = namespace_path
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1861 return spec
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1862
51322
53d6445c6c5a Rename importlib._bootstrap.SysPathFinder to PathFinder and expose off of
Brett Cannon <bcannon@gmail.com>
parents: 51266
diff changeset
1863 @classmethod
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1864 def find_spec(cls, fullname, path=None, target=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1865 """find the module on sys.path or 'path' based on sys.path_hooks and
52165
62f9dad628de A few more docstring/API cleanups for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 52164
diff changeset
1866 sys.path_importer_cache."""
76384
c1399cf7bd6a Issue #12599: Be more strict in accepting None vs. a false-like object
Brett Cannon <brett@python.org>
parents: 76331
diff changeset
1867 if path is None:
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1868 path = sys.path
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1869 spec = cls._get_spec(fullname, path, target)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1870 if spec is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1871 return None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1872 elif spec.loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1873 namespace_path = spec.submodule_search_locations
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1874 if namespace_path:
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1875 # We found at least one namespace path. Return a
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1876 # spec which can create the namespace package.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1877 spec.origin = 'namespace'
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1878 spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1879 return spec
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1880 else:
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1881 return None
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1882 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1883 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1884
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1885 @classmethod
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1886 def find_module(cls, fullname, path=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1887 """find the module on sys.path or 'path' based on sys.path_hooks and
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1888 sys.path_importer_cache."""
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1889 # XXX Deprecation warning here.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1890 spec = cls.find_spec(fullname, path)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1891 if spec is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1892 return None
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1893 return spec.loader
51266
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1894
63386ae77f79 To prevent another screw-up on my part where my prototype gets lost thanks to
Brett Cannon <bcannon@gmail.com>
parents: 51242
diff changeset
1895
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1896 class FileFinder:
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1897
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1898 """File-based finder.
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1899
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1900 Interactions with the file system are cached for performance, being
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1901 refreshed when the directory the finder is handling has been modified.
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1902
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1903 """
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1904
84174
e13371d5b4e4 Fix a misnaming of a method and an argument
Brett Cannon <brett@python.org>
parents: 83055
diff changeset
1905 def __init__(self, path, *loader_details):
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
1906 """Initialize with the path to search on and a variable number of
82236
0f65bf6063ca Fixes a FileFinder docstring to reflect an old change.
Eric Snow <ericsnowcurrently@gmail.com>
parents: 81884
diff changeset
1907 2-tuples containing the loader and the file suffixes the loader
0f65bf6063ca Fixes a FileFinder docstring to reflect an old change.
Eric Snow <ericsnowcurrently@gmail.com>
parents: 81884
diff changeset
1908 recognizes."""
78486
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
1909 loaders = []
84174
e13371d5b4e4 Fix a misnaming of a method and an argument
Brett Cannon <brett@python.org>
parents: 83055
diff changeset
1910 for loader, suffixes in loader_details:
78486
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
1911 loaders.extend((suffix, loader) for suffix in suffixes)
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
1912 self._loaders = loaders
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1913 # Base (directory) path
86823
17d730d37b2f Issue #19410: Put back in special-casing of '' for
Brett Cannon <brett@python.org>
parents: 86819
diff changeset
1914 self.path = path or '.'
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1915 self._path_mtime = -1
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1916 self._path_cache = set()
75082
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1917 self._relaxed_path_cache = set()
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1918
75324
de125ee32897 Update importlib.invalidate_caches() to be more general.
Brett Cannon <brett@python.org>
parents: 75250
diff changeset
1919 def invalidate_caches(self):
de125ee32897 Update importlib.invalidate_caches() to be more general.
Brett Cannon <brett@python.org>
parents: 75250
diff changeset
1920 """Invalidate the directory mtime."""
de125ee32897 Update importlib.invalidate_caches() to be more general.
Brett Cannon <brett@python.org>
parents: 75250
diff changeset
1921 self._path_mtime = -1
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1922
78489
e7a67f1bf604 Issue #15502: Refactor some code.
Brett Cannon <brett@python.org>
parents: 78487
diff changeset
1923 find_module = _find_module_shim
77126
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1924
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1925 def find_loader(self, fullname):
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1926 """Try to find a loader for the specified module, or the namespace
702009f3c0b1 issue 14660: Implement PEP 420, namespace packages.
Eric V. Smith <eric@trueblade.com>
parents: 77013
diff changeset
1927 package portions. Returns (loader, list-of-portions)."""
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1928 spec = self.find_spec(fullname)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1929 if spec is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1930 return None, []
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1931 return spec.loader, spec.submodule_search_locations or []
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1932
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1933 def _get_spec(self, loader_class, fullname, path, submodule_search_locations, target):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1934 loader = loader_class(fullname, path)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1935 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1936 get_spec = loader._get_spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1937 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1938 return spec_from_file_location(fullname, path, loader=loader,
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1939 submodule_search_locations=submodule_search_locations)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1940 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1941 return get_spec(fullname, path, submodule_search_locations, target)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1942
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1943 def find_spec(self, fullname, target=None):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1944 """Try to find a loader for the specified module, or the namespace
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1945 package portions. Returns (loader, list-of-portions)."""
77757
2051fead1933 Fixes issue 15039: namespace packages are no longer imported in preference to modules of the same name.
Eric V. Smith <eric@trueblade.com>
parents: 77600
diff changeset
1946 is_namespace = False
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
1947 tail_module = fullname.rpartition('.')[2]
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1948 try:
86824
e071977772bf Abstract out stat calls in importlib for easier experimentation.
Brett Cannon <brett@python.org>
parents: 86823
diff changeset
1949 mtime = _path_stat(self.path or _os.getcwd()).st_mtime
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1950 except OSError:
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1951 mtime = -1
75324
de125ee32897 Update importlib.invalidate_caches() to be more general.
Brett Cannon <brett@python.org>
parents: 75250
diff changeset
1952 if mtime != self._path_mtime:
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1953 self._fill_cache()
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1954 self._path_mtime = mtime
75082
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1955 # tail_module keeps the original casing, for __file__ and friends
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1956 if _relax_case():
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1957 cache = self._relaxed_path_cache
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1958 cache_module = tail_module.lower()
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1959 else:
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1960 cache = self._path_cache
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1961 cache_module = tail_module
76309
e2f48b076012 Add some comments.
Brett Cannon <brett@python.org>
parents: 76303
diff changeset
1962 # Check if the module is the name of a directory (and thus a package).
75082
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1963 if cache_module in cache:
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1964 base_path = _path_join(self.path, tail_module)
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1965 for suffix, loader_class in self._loaders:
86444
11f2f4af1979 Issue #18810: Be optimistic with stat calls when seeing if a directory
Brett Cannon <brett@python.org>
parents: 86438
diff changeset
1966 init_filename = '__init__' + suffix
11f2f4af1979 Issue #18810: Be optimistic with stat calls when seeing if a directory
Brett Cannon <brett@python.org>
parents: 86438
diff changeset
1967 full_path = _path_join(base_path, init_filename)
11f2f4af1979 Issue #18810: Be optimistic with stat calls when seeing if a directory
Brett Cannon <brett@python.org>
parents: 86438
diff changeset
1968 if _path_isfile(full_path):
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1969 return self._get_spec(loader_class, fullname, full_path, [base_path], target)
86444
11f2f4af1979 Issue #18810: Be optimistic with stat calls when seeing if a directory
Brett Cannon <brett@python.org>
parents: 86438
diff changeset
1970 else:
11f2f4af1979 Issue #18810: Be optimistic with stat calls when seeing if a directory
Brett Cannon <brett@python.org>
parents: 86438
diff changeset
1971 # If a namespace package, return the path if we don't
11f2f4af1979 Issue #18810: Be optimistic with stat calls when seeing if a directory
Brett Cannon <brett@python.org>
parents: 86438
diff changeset
1972 # find a module in the next section.
11f2f4af1979 Issue #18810: Be optimistic with stat calls when seeing if a directory
Brett Cannon <brett@python.org>
parents: 86438
diff changeset
1973 is_namespace = _path_isdir(base_path)
76309
e2f48b076012 Add some comments.
Brett Cannon <brett@python.org>
parents: 76303
diff changeset
1974 # Check for a file w/ a proper suffix exists.
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1975 for suffix, loader_class in self._loaders:
83055
ac89e7bc0e2f Issue #17357: Add missing verbosity messages when running under
Brett Cannon <brett@python.org>
parents: 82236
diff changeset
1976 full_path = _path_join(self.path, tail_module + suffix)
ac89e7bc0e2f Issue #17357: Add missing verbosity messages when running under
Brett Cannon <brett@python.org>
parents: 82236
diff changeset
1977 _verbose_message('trying {}'.format(full_path), verbosity=2)
75082
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1978 if cache_module + suffix in cache:
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1979 if _path_isfile(full_path):
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1980 return self._get_spec(loader_class, fullname, full_path, None, target)
77757
2051fead1933 Fixes issue 15039: namespace packages are no longer imported in preference to modules of the same name.
Eric V. Smith <eric@trueblade.com>
parents: 77600
diff changeset
1981 if is_namespace:
83055
ac89e7bc0e2f Issue #17357: Add missing verbosity messages when running under
Brett Cannon <brett@python.org>
parents: 82236
diff changeset
1982 _verbose_message('possible namespace for {}'.format(base_path))
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1983 spec = ModuleSpec(fullname, None)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1984 spec.submodule_search_locations = [base_path]
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1985 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
1986 return None
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
1987
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1988 def _fill_cache(self):
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1989 """Fill the cache of potential modules and packages for this directory."""
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
1990 path = self.path
78663
bfd04bfb55c5 Close #14846: Handle a sys.path entry going away
Nick Coghlan <ncoghlan@gmail.com>
parents: 78619
diff changeset
1991 try:
86438
33844153cd02 Issue #18416: Fix various os calls in importlib.machinery.FileFinder
Brett Cannon <brett@python.org>
parents: 86436
diff changeset
1992 contents = _os.listdir(path or _os.getcwd())
81427
159967aa24a5 Issue #16730: Don't raise an exception in
Brett Cannon <brett@python.org>
parents: 80929
diff changeset
1993 except (FileNotFoundError, PermissionError, NotADirectoryError):
159967aa24a5 Issue #16730: Don't raise an exception in
Brett Cannon <brett@python.org>
parents: 80929
diff changeset
1994 # Directory has either been removed, turned into a file, or made
159967aa24a5 Issue #16730: Don't raise an exception in
Brett Cannon <brett@python.org>
parents: 80929
diff changeset
1995 # unreadable.
78663
bfd04bfb55c5 Close #14846: Handle a sys.path entry going away
Nick Coghlan <ncoghlan@gmail.com>
parents: 78619
diff changeset
1996 contents = []
75082
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1997 # We store two cached versions, to handle runtime changes of the
3297dcdad196 Issue #14063: fix test_importlib failure under OS X case-insensitive filesystems
Antoine Pitrou <solipsis@pitrou.net>
parents: 75070
diff changeset
1998 # PYTHONCASEOK environment variable.
76428
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
1999 if not sys.platform.startswith('win'):
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2000 self._path_cache = set(contents)
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2001 else:
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2002 # Windows users can import modules with case-insensitive file
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2003 # suffixes (for legacy reasons). Make the suffix lowercase here
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2004 # so it's done once instead of for every import. This is safe as
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2005 # the specified suffixes to check against are always specified in a
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2006 # case-sensitive manner.
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2007 lower_suffix_contents = set()
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2008 for item in contents:
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2009 name, dot, suffix = item.partition('.')
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2010 if dot:
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2011 new_name = '{}.{}'.format(name, suffix.lower())
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2012 else:
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2013 new_name = name
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2014 lower_suffix_contents.add(new_name)
a32be109bd86 Issue #14581: Windows users are allowed to import modules w/o taking
Brett Cannon <brett@python.org>
parents: 76406
diff changeset
2015 self._path_cache = lower_suffix_contents
76753
59b8a7fcb047 Properly mark names in importlib._bootstrap as private.
Brett Cannon <brett@python.org>
parents: 76586
diff changeset
2016 if sys.platform.startswith(_CASE_INSENSITIVE_PLATFORMS):
82382
2528e4aea338 Issue #17220: Little cleanup of _bootstrap.py.
Serhiy Storchaka <storchaka@gmail.com>
parents: 82237
diff changeset
2017 self._relaxed_path_cache = {fn.lower() for fn in contents}
62756
34d827249ce0 Make importlib.abc.SourceLoader the primary mechanism for importlib.
Brett Cannon <bcannon@gmail.com>
parents: 62587
diff changeset
2018
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2019 @classmethod
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2020 def path_hook(cls, *loader_details):
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2021 """A class method which returns a closure to use on sys.path_hook
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2022 which will return an instance using the specified loaders and the path
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2023 called on the closure.
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2024
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2025 If the path called on the closure is not a directory, ImportError is
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2026 raised.
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2027
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2028 """
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2029 def path_hook_for_FileFinder(path):
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2030 """Path hook for importlib.machinery.FileFinder."""
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2031 if not _path_isdir(path):
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
2032 raise ImportError('only directories are supported', path=path)
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2033 return cls(path, *loader_details)
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2034
76478
1da623513b26 Issue #14605: Expose importlib.abc.FileLoader and
Brett Cannon <brett@python.org>
parents: 76472
diff changeset
2035 return path_hook_for_FileFinder
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2036
77600
df856963fc6c A better repr() for FileFinder
Antoine Pitrou <solipsis@pitrou.net>
parents: 77457
diff changeset
2037 def __repr__(self):
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
2038 return 'FileFinder({!r})'.format(self.path)
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2039
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2040
52140
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
2041 # Import itself ###############################################################
1a8bbc5fb3ef Do a little bit of reorganization on importlib._bootstrap.
Brett Cannon <bcannon@gmail.com>
parents: 52139
diff changeset
2042
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2043 class _ImportLockContext:
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2044
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2045 """Context manager for the import lock."""
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2046
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2047 def __enter__(self):
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2048 """Acquire the import lock."""
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
2049 _imp.acquire_lock()
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2050
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2051 def __exit__(self, exc_type, exc_value, exc_traceback):
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2052 """Release the import lock regardless of any raised exceptions."""
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
2053 _imp.release_lock()
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2054
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2055
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2056 def _resolve_name(name, package, level):
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2057 """Resolve a relative module name to an absolute one."""
75250
8840037a9c53 unused imports, pep8
Philip Jenvey <pjenvey@underboss.org>
parents: 75239
diff changeset
2058 bits = package.rsplit('.', level - 1)
75239
5cfc9c97af23 Simplify importib._resolve_name().
Brett Cannon <brett@python.org>
parents: 75235
diff changeset
2059 if len(bits) < level:
5cfc9c97af23 Simplify importib._resolve_name().
Brett Cannon <brett@python.org>
parents: 75235
diff changeset
2060 raise ValueError('attempted relative import beyond top-level package')
5cfc9c97af23 Simplify importib._resolve_name().
Brett Cannon <brett@python.org>
parents: 75235
diff changeset
2061 base = bits[0]
77964
37850f083af5 Minor refactoring in importlib._bootstrap, and fix the '_wrap' docstring.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 77917
diff changeset
2062 return '{}.{}'.format(base, name) if name else base
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2063
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2064
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2065 def _find_spec(name, path, target=None):
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2066 """Find a module's loader."""
76579
3bd60cc27664 Issue #14605: Stop having implicit entries for sys.meta_path.
Brett Cannon <brett@python.org>
parents: 76566
diff changeset
2067 if not sys.meta_path:
3bd60cc27664 Issue #14605: Stop having implicit entries for sys.meta_path.
Brett Cannon <brett@python.org>
parents: 76566
diff changeset
2068 _warnings.warn('sys.meta_path is empty', ImportWarning)
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2069 # We check sys.modules here for the reload case. While a passed-in
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2070 # target will usually indicate a reload there is no guarantee, whereas
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2071 # sys.modules provides one.
86819
88c3a1a3c2ff Issue #19413: Restore pre-3.3 reload() semantics of re-finding modules.
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86521
diff changeset
2072 is_reload = name in sys.modules
76579
3bd60cc27664 Issue #14605: Stop having implicit entries for sys.meta_path.
Brett Cannon <brett@python.org>
parents: 76566
diff changeset
2073 for finder in sys.meta_path:
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2074 with _ImportLockContext():
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2075 try:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2076 find_spec = finder.find_spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2077 except AttributeError:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2078 loader = finder.find_module(name, path)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2079 if loader is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2080 continue
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2081 spec = spec_from_loader(name, loader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2082 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2083 spec = find_spec(name, path, target)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2084 if spec is not None:
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2085 # The parent import may have already imported this module.
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2086 if not is_reload and name in sys.modules:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2087 module = sys.modules[name]
86819
88c3a1a3c2ff Issue #19413: Restore pre-3.3 reload() semantics of re-finding modules.
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86521
diff changeset
2088 try:
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2089 __spec__ = module.__spec__
86819
88c3a1a3c2ff Issue #19413: Restore pre-3.3 reload() semantics of re-finding modules.
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86521
diff changeset
2090 except AttributeError:
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2091 # We use the found spec since that is the one that
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2092 # we would have used if the parent module hadn't
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2093 # beaten us to the punch.
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2094 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2095 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2096 if __spec__ is None:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2097 return spec
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2098 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2099 return __spec__
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2100 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2101 return spec
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2102 else:
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2103 return None
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2104
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2105
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2106 def _sanity_check(name, package, level):
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2107 """Verify arguments are "sane"."""
75228
909935a236e3 Do a type check instead of an interface check.
Brett Cannon <brett@python.org>
parents: 75193
diff changeset
2108 if not isinstance(name, str):
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
2109 raise TypeError('module name must be str, not {}'.format(type(name)))
75193
f95faebf5dea Refactor importlib to make it easier to re-implement in C.
Brett Cannon <brett@python.org>
parents: 75185
diff changeset
2110 if level < 0:
f95faebf5dea Refactor importlib to make it easier to re-implement in C.
Brett Cannon <brett@python.org>
parents: 75185
diff changeset
2111 raise ValueError('level must be >= 0')
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2112 if package:
75228
909935a236e3 Do a type check instead of an interface check.
Brett Cannon <brett@python.org>
parents: 75193
diff changeset
2113 if not isinstance(package, str):
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
2114 raise TypeError('__package__ not set to a string')
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2115 elif package not in sys.modules:
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
2116 msg = ('Parent module {!r} not loaded, cannot perform relative '
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
2117 'import')
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2118 raise SystemError(msg.format(package))
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2119 if not name and level == 0:
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
2120 raise ValueError('Empty module name')
52141
f188dd68620e Last big re-organization of importlib._bootstrap. Should actually be able to find something in the file now.
Brett Cannon <bcannon@gmail.com>
parents: 52140
diff changeset
2121
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2122
84464
0d590683c8d1 Issue #18364: Stop using the ImportError._not_found hack.
Brett Cannon <brett@python.org>
parents: 84445
diff changeset
2123 _ERR_MSG_PREFIX = 'No module named '
0d590683c8d1 Issue #18364: Stop using the ImportError._not_found hack.
Brett Cannon <brett@python.org>
parents: 84445
diff changeset
2124 _ERR_MSG = _ERR_MSG_PREFIX + '{!r}'
51639
ef2cba80c975 Change importlib.machinery.PathFinder to not have implicit semantics (that's
Brett Cannon <bcannon@gmail.com>
parents: 51433
diff changeset
2125
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2126 def _find_and_load_unlocked(name, import_):
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2127 path = None
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2128 parent = name.rpartition('.')[0]
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2129 if parent:
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2130 if parent not in sys.modules:
78344
62033490ca0f Close #15486: Simplify the mechanism used to remove importlib frames from tracebacks when they just introduce irrelevant noise
Nick Coghlan <ncoghlan@gmail.com>
parents: 78314
diff changeset
2131 _call_with_frames_removed(import_, parent)
76081
a40cd5976215 If a module injects something into sys.modules as a side-effect of
Brett Cannon <brett@python.org>
parents: 75463
diff changeset
2132 # Crazy side-effects!
a40cd5976215 If a module injects something into sys.modules as a side-effect of
Brett Cannon <brett@python.org>
parents: 75463
diff changeset
2133 if name in sys.modules:
a40cd5976215 If a module injects something into sys.modules as a side-effect of
Brett Cannon <brett@python.org>
parents: 75463
diff changeset
2134 return sys.modules[name]
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2135 parent_module = sys.modules[parent]
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2136 try:
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2137 path = parent_module.__path__
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2138 except AttributeError:
87360
2e4169aac667 User the repr for a module name in more places
Brett Cannon <brett@python.org>
parents: 87353
diff changeset
2139 msg = (_ERR_MSG + '; {!r} is not a package').format(name, parent)
76280
c071af95772a Have importlib take advantage of ImportError's new 'name' and 'path'
Brett Cannon <brett@python.org>
parents: 76081
diff changeset
2140 raise ImportError(msg, name=name)
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2141 spec = _find_spec(name, path)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2142 if spec is None:
84464
0d590683c8d1 Issue #18364: Stop using the ImportError._not_found hack.
Brett Cannon <brett@python.org>
parents: 84445
diff changeset
2143 raise ImportError(_ERR_MSG.format(name), name=name)
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2144 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2145 module = _SpecMethods(spec)._load_unlocked()
75193
f95faebf5dea Refactor importlib to make it easier to re-implement in C.
Brett Cannon <brett@python.org>
parents: 75185
diff changeset
2146 if parent:
f95faebf5dea Refactor importlib to make it easier to re-implement in C.
Brett Cannon <brett@python.org>
parents: 75185
diff changeset
2147 # Set the module as an attribute on its parent.
f95faebf5dea Refactor importlib to make it easier to re-implement in C.
Brett Cannon <brett@python.org>
parents: 75185
diff changeset
2148 parent_module = sys.modules[parent]
f95faebf5dea Refactor importlib to make it easier to re-implement in C.
Brett Cannon <brett@python.org>
parents: 75185
diff changeset
2149 setattr(parent_module, name.rpartition('.')[2], module)
f95faebf5dea Refactor importlib to make it easier to re-implement in C.
Brett Cannon <brett@python.org>
parents: 75185
diff changeset
2150 return module
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2151
66226
af13fb6fb3df Fix a minor inconsistency in capitalization for the 'No module named' exception
Brett Cannon <bcannon@gmail.com>
parents: 64407
diff changeset
2152
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2153 def _find_and_load(name, import_):
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2154 """Find and load the module, and release the import lock."""
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2155 with _ModuleLockManager(name):
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2156 return _find_and_load_unlocked(name, import_)
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2157
66226
af13fb6fb3df Fix a minor inconsistency in capitalization for the 'No module named' exception
Brett Cannon <bcannon@gmail.com>
parents: 64407
diff changeset
2158
51383
a00e5dcea16c Initial, untested stab at writing a common denominator function for __import__
Brett Cannon <bcannon@gmail.com>
parents: 51356
diff changeset
2159 def _gcd_import(name, package=None, level=0):
a00e5dcea16c Initial, untested stab at writing a common denominator function for __import__
Brett Cannon <bcannon@gmail.com>
parents: 51356
diff changeset
2160 """Import and return the module based on its name, the package the call is
a00e5dcea16c Initial, untested stab at writing a common denominator function for __import__
Brett Cannon <bcannon@gmail.com>
parents: 51356
diff changeset
2161 being made from, and the level adjustment.
a00e5dcea16c Initial, untested stab at writing a common denominator function for __import__
Brett Cannon <bcannon@gmail.com>
parents: 51356
diff changeset
2162
a00e5dcea16c Initial, untested stab at writing a common denominator function for __import__
Brett Cannon <bcannon@gmail.com>
parents: 51356
diff changeset
2163 This function represents the greatest common denominator of functionality
68447
Eric V. Smith <eric@trueblade.com>
parents: 68257
diff changeset
2164 between import_module and __import__. This includes setting __package__ if
51426
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2165 the loader did not.
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2166
51383
a00e5dcea16c Initial, untested stab at writing a common denominator function for __import__
Brett Cannon <bcannon@gmail.com>
parents: 51356
diff changeset
2167 """
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2168 _sanity_check(name, package, level)
51383
a00e5dcea16c Initial, untested stab at writing a common denominator function for __import__
Brett Cannon <bcannon@gmail.com>
parents: 51356
diff changeset
2169 if level > 0:
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2170 name = _resolve_name(name, package, level)
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2171 _imp.acquire_lock()
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2172 if name not in sys.modules:
75193
f95faebf5dea Refactor importlib to make it easier to re-implement in C.
Brett Cannon <brett@python.org>
parents: 75185
diff changeset
2173 return _find_and_load(name, _gcd_import)
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2174 module = sys.modules[name]
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2175 if module is None:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2176 _imp.release_lock()
84582
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
2177 message = ('import of {} halted; '
33d379c2bb79 Issue #18415: Normalize what type of quotes are used with string
Brett Cannon <brett@python.org>
parents: 84468
diff changeset
2178 'None in sys.modules'.format(name))
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2179 raise ImportError(message, name=name)
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2180 _lock_unlock_module(name)
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2181 return module
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2182
75235
3670df23081d Turn _return_module() into _handle_fromlist().
Brett Cannon <brett@python.org>
parents: 75229
diff changeset
2183 def _handle_fromlist(module, fromlist, import_):
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2184 """Figure out what __import__ should return.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2185
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2186 The import_ parameter is a callable which takes the name of module to
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2187 import. It is required to decouple the function from assuming importlib's
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2188 import implementation is desired.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2189
51426
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2190 """
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2191 # The hell that is fromlist ...
75235
3670df23081d Turn _return_module() into _handle_fromlist().
Brett Cannon <brett@python.org>
parents: 75229
diff changeset
2192 # If a package was imported, try to import stuff from fromlist.
3670df23081d Turn _return_module() into _handle_fromlist().
Brett Cannon <brett@python.org>
parents: 75229
diff changeset
2193 if hasattr(module, '__path__'):
78051
dc18a2a66d16 Issue #15111: When a module was imported using a 'from import'
Brett Cannon <brett@python.org>
parents: 78042
diff changeset
2194 if '*' in fromlist:
75235
3670df23081d Turn _return_module() into _handle_fromlist().
Brett Cannon <brett@python.org>
parents: 75229
diff changeset
2195 fromlist = list(fromlist)
3670df23081d Turn _return_module() into _handle_fromlist().
Brett Cannon <brett@python.org>
parents: 75229
diff changeset
2196 fromlist.remove('*')
78051
dc18a2a66d16 Issue #15111: When a module was imported using a 'from import'
Brett Cannon <brett@python.org>
parents: 78042
diff changeset
2197 if hasattr(module, '__all__'):
dc18a2a66d16 Issue #15111: When a module was imported using a 'from import'
Brett Cannon <brett@python.org>
parents: 78042
diff changeset
2198 fromlist.extend(module.__all__)
77964
37850f083af5 Minor refactoring in importlib._bootstrap, and fix the '_wrap' docstring.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 77917
diff changeset
2199 for x in fromlist:
37850f083af5 Minor refactoring in importlib._bootstrap, and fix the '_wrap' docstring.
Florent Xicluna <florent.xicluna@gmail.com>
parents: 77917
diff changeset
2200 if not hasattr(module, x):
79652
09b5158d5284 Closes issue #15111: Calling __import__ with a module specified in
Brett Cannon <brett@python.org>
parents: 79228
diff changeset
2201 from_name = '{}.{}'.format(module.__name__, x)
78619
0d52f125dd32 Issue #15715: Ignore failed imports triggered by the use of fromlist.
Brett Cannon <brett@python.org>
parents: 78511
diff changeset
2202 try:
79652
09b5158d5284 Closes issue #15111: Calling __import__ with a module specified in
Brett Cannon <brett@python.org>
parents: 79228
diff changeset
2203 _call_with_frames_removed(import_, from_name)
78758
ca4bf8e10bc0 Issue #15316: Let exceptions raised during imports triggered by the
Brett Cannon <brett@python.org>
parents: 78738
diff changeset
2204 except ImportError as exc:
78619
0d52f125dd32 Issue #15715: Ignore failed imports triggered by the use of fromlist.
Brett Cannon <brett@python.org>
parents: 78511
diff changeset
2205 # Backwards-compatibility dictates we ignore failed
78758
ca4bf8e10bc0 Issue #15316: Let exceptions raised during imports triggered by the
Brett Cannon <brett@python.org>
parents: 78738
diff changeset
2206 # imports triggered by fromlist for modules that don't
ca4bf8e10bc0 Issue #15316: Let exceptions raised during imports triggered by the
Brett Cannon <brett@python.org>
parents: 78738
diff changeset
2207 # exist.
84464
0d590683c8d1 Issue #18364: Stop using the ImportError._not_found hack.
Brett Cannon <brett@python.org>
parents: 84445
diff changeset
2208 if str(exc).startswith(_ERR_MSG_PREFIX):
79652
09b5158d5284 Closes issue #15111: Calling __import__ with a module specified in
Brett Cannon <brett@python.org>
parents: 79228
diff changeset
2209 if exc.name == from_name:
09b5158d5284 Closes issue #15111: Calling __import__ with a module specified in
Brett Cannon <brett@python.org>
parents: 79228
diff changeset
2210 continue
09b5158d5284 Closes issue #15111: Calling __import__ with a module specified in
Brett Cannon <brett@python.org>
parents: 79228
diff changeset
2211 raise
75235
3670df23081d Turn _return_module() into _handle_fromlist().
Brett Cannon <brett@python.org>
parents: 75229
diff changeset
2212 return module
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2213
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2214
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2215 def _calc___package__(globals):
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2216 """Calculate what __package__ should be.
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2217
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2218 __package__ is not guaranteed to be defined or could be set to None
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2219 to represent that its proper value is unknown.
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2220
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2221 """
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2222 package = globals.get('__package__')
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2223 if package is None:
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2224 package = globals['__name__']
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2225 if '__path__' not in globals:
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2226 package = package.rpartition('.')[0]
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2227 return package
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2228
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2229
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2230 def _get_supported_file_loaders():
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2231 """Returns a list of file-based module loaders.
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2232
85945
32b18998a560 [issue19151] Fix docstring and use of _get_suppported_file_loaders() to reflect 2-tuples.
Eric Snow <ericsnowcurrently@gmail.com>
parents: 85518
diff changeset
2233 Each item is a tuple (loader, suffixes).
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2234 """
78486
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
2235 extensions = ExtensionFileLoader, _imp.extension_suffixes()
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
2236 source = SourceFileLoader, SOURCE_SUFFIXES
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
2237 bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2238 return [extensions, source, bytecode]
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2239
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2240
78456
4240282a9f4a Issue #15471: Don't use mutable object as default values for the
Brett Cannon <brett@python.org>
parents: 78382
diff changeset
2241 def __import__(name, globals=None, locals=None, fromlist=(), level=0):
51426
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2242 """Import a module.
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2243
51426
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2244 The 'globals' argument is used to infer where the import is occuring from
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2245 to handle relative imports. The 'locals' argument is ignored. The
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2246 'fromlist' argument specifies what should exist as attributes on the module
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2247 being imported (e.g. ``from module import <fromlist>``). The 'level'
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2248 argument represents the package location to import from in a relative
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2249 import (e.g. ``from ..pkg import mod`` would have a 'level' of 2).
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2250
51426
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2251 """
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2252 if level == 0:
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2253 module = _gcd_import(name)
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2254 else:
78456
4240282a9f4a Issue #15471: Don't use mutable object as default values for the
Brett Cannon <brett@python.org>
parents: 78382
diff changeset
2255 globals_ = globals if globals is not None else {}
4240282a9f4a Issue #15471: Don't use mutable object as default values for the
Brett Cannon <brett@python.org>
parents: 78382
diff changeset
2256 package = _calc___package__(globals_)
51426
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2257 module = _gcd_import(name, package, level)
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2258 if not fromlist:
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2259 # Return up to the first dot in 'name'. This is complicated by the fact
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2260 # that 'name' may be relative.
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2261 if level == 0:
76826
d6324941b739 Issue #14583: Fix importlib bug when a package's __init__.py would first import one of its modules then raise an error.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76765
diff changeset
2262 return _gcd_import(name.partition('.')[0])
51426
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2263 elif not name:
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2264 return module
50845
aac51b70c74c Add initial implementation of importlib. See the NOTES files for what is
Brett Cannon <bcannon@gmail.com>
parents:
diff changeset
2265 else:
79228
4a979326e6d6 Add some comments.
Brett Cannon <brett@python.org>
parents: 79191
diff changeset
2266 # Figure out where to slice the module's name up to the first dot
4a979326e6d6 Add some comments.
Brett Cannon <brett@python.org>
parents: 79191
diff changeset
2267 # in 'name'.
51426
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2268 cut_off = len(name) - len(name.partition('.')[0])
79228
4a979326e6d6 Add some comments.
Brett Cannon <brett@python.org>
parents: 79191
diff changeset
2269 # Slice end needs to be positive to alleviate need to special-case
4a979326e6d6 Add some comments.
Brett Cannon <brett@python.org>
parents: 79191
diff changeset
2270 # when ``'.' not in name``.
76312
9e8cbf07068a Handle importing pkg.mod by executing
Brett Cannon <brett@python.org>
parents: 76309
diff changeset
2271 return sys.modules[module.__name__[:len(module.__name__)-cut_off]]
75235
3670df23081d Turn _return_module() into _handle_fromlist().
Brett Cannon <brett@python.org>
parents: 75229
diff changeset
2272 else:
3670df23081d Turn _return_module() into _handle_fromlist().
Brett Cannon <brett@python.org>
parents: 75229
diff changeset
2273 return _handle_fromlist(module, fromlist, _gcd_import)
74983
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2274
03140936913c Refactor importlib.__import__() and _gcd_import() to facilitate using
Brett Cannon <brett@python.org>
parents: 74935
diff changeset
2275
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2276 def _builtin_from_name(name):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2277 spec = BuiltinImporter.find_spec(name)
87351
2bea86df60b9 Don't assume trying to find a builtin will succeed (e.g. posix isn't on Windows)
Brett Cannon <brett@python.org>
parents: 87347
diff changeset
2278 if spec is None:
2bea86df60b9 Don't assume trying to find a builtin will succeed (e.g. posix isn't on Windows)
Brett Cannon <brett@python.org>
parents: 87347
diff changeset
2279 raise ImportError('no built-in module named ' + name)
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2280 methods = _SpecMethods(spec)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2281 return methods._load_unlocked()
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2282
76445
c820aa9c0c00 Issue #13959: Keep imp.get_magic() in C code, but cache in importlib
Brett Cannon <brett@python.org>
parents: 76428
diff changeset
2283
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
2284 def _setup(sys_module, _imp_module):
74839
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2285 """Setup importlib by importing needed built-in modules and injecting them
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2286 into the global namespace.
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2287
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
2288 As sys is needed for sys.modules access and _imp is needed to load built-in
74935
81f3bb5efa40 Bring importlib in line w/ changes made in my personal bootstrap branch in the sandbox.
Brett Cannon <brett@python.org>
parents: 74867
diff changeset
2289 modules, those two modules must be explicitly passed in.
74839
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2290
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2291 """
79173
4de5e4ec3cff don't depend on __debug__ because it's baked in at freeze time (issue #16046)
Benjamin Peterson <benjamin@python.org>
parents: 78779
diff changeset
2292 global _imp, sys, BYTECODE_SUFFIXES
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
2293 _imp = _imp_module
74839
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2294 sys = sys_module
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2295
79173
4de5e4ec3cff don't depend on __debug__ because it's baked in at freeze time (issue #16046)
Benjamin Peterson <benjamin@python.org>
parents: 78779
diff changeset
2296 if sys.flags.optimize:
4de5e4ec3cff don't depend on __debug__ because it's baked in at freeze time (issue #16046)
Benjamin Peterson <benjamin@python.org>
parents: 78779
diff changeset
2297 BYTECODE_SUFFIXES = OPTIMIZED_BYTECODE_SUFFIXES
51426
7a1356d2aeef Rewrite the code implementing __import__ for importlib. Now it is much simpler
Brett Cannon <bcannon@gmail.com>
parents: 51383
diff changeset
2298 else:
79173
4de5e4ec3cff don't depend on __debug__ because it's baked in at freeze time (issue #16046)
Benjamin Peterson <benjamin@python.org>
parents: 78779
diff changeset
2299 BYTECODE_SUFFIXES = DEBUG_BYTECODE_SUFFIXES
4de5e4ec3cff don't depend on __debug__ because it's baked in at freeze time (issue #16046)
Benjamin Peterson <benjamin@python.org>
parents: 78779
diff changeset
2300
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2301 # Set up the spec for existing builtin/frozen modules.
81869
05747d3bcd9c Issue #17098: Make sure every module has __loader__ defined.
Brett Cannon <brett@python.org>
parents: 81427
diff changeset
2302 module_type = type(sys)
81884
19ea454ccdf7 Issue #17098: Be more stringent of setting __loader__ on early imported
Brett Cannon <brett@python.org>
parents: 81869
diff changeset
2303 for name, module in sys.modules.items():
81869
05747d3bcd9c Issue #17098: Make sure every module has __loader__ defined.
Brett Cannon <brett@python.org>
parents: 81427
diff changeset
2304 if isinstance(module, module_type):
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2305 if name in sys.builtin_module_names:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2306 loader = BuiltinImporter
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2307 elif _imp.is_frozen(name):
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2308 loader = FrozenImporter
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2309 else:
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2310 continue
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2311 spec = _spec_from_module(module, loader)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2312 methods = _SpecMethods(spec)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2313 methods.init_module_attrs(module)
74839
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2314
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2315 # Directly load built-in modules needed during bootstrap.
74839
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2316 self_module = sys.modules[__name__]
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2317 for builtin_name in ('_io', '_warnings', 'builtins', 'marshal'):
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2318 if builtin_name not in sys.modules:
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2319 builtin_module = _builtin_from_name(builtin_name)
74839
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2320 else:
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2321 builtin_module = sys.modules[builtin_name]
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2322 setattr(self_module, builtin_name, builtin_module)
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2323
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2324 # Directly load the os module (needed during bootstrap).
79480
15949f34e08f #16135: Removal of OS/2 support (Python code partial cleanup)
Jesus Cea <jcea@jcea.es>
parents: 79228
diff changeset
2325 os_details = ('posix', ['/']), ('nt', ['\\', '/'])
76449
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
2326 for builtin_os, path_separators in os_details:
76472
4e853913054c Issue #13959: Continue to try to accomodate altsep in importlib by not
Brett Cannon <brett@python.org>
parents: 76466
diff changeset
2327 # Assumption made in _path_join()
4e853913054c Issue #13959: Continue to try to accomodate altsep in importlib by not
Brett Cannon <brett@python.org>
parents: 76466
diff changeset
2328 assert all(len(sep) == 1 for sep in path_separators)
76449
163360370ad2 Make path manipulation more robust for platforms with alternative path
Brett Cannon <brett@python.org>
parents: 76445
diff changeset
2329 path_sep = path_separators[0]
74839
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2330 if builtin_os in sys.modules:
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2331 os_module = sys.modules[builtin_os]
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2332 break
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2333 else:
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2334 try:
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2335 os_module = _builtin_from_name(builtin_os)
74839
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2336 break
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2337 except ImportError:
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2338 continue
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2339 else:
322e6f818cd2 Move setup code from importlib.__init__ to
Brett Cannon <brett@python.org>
parents: 74838
diff changeset
2340 raise ImportError('importlib requires posix or nt')
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2341 setattr(self_module, '_os', os_module)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2342 setattr(self_module, 'path_sep', path_sep)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2343 setattr(self_module, 'path_separators', ''.join(path_separators))
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2344
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2345 # Directly load the _thread module (needed during bootstrap).
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2346 try:
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2347 thread_module = _builtin_from_name('_thread')
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2348 except ImportError:
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2349 # Python was built without threads
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2350 thread_module = None
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2351 setattr(self_module, '_thread', thread_module)
77013
edb9ce3a6c2e Issue #9260: A finer-grained import lock.
Antoine Pitrou <solipsis@pitrou.net>
parents: 76877
diff changeset
2352
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2353 # Directly load the _weakref module (needed during bootstrap).
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2354 weakref_module = _builtin_from_name('_weakref')
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2355 setattr(self_module, '_weakref', weakref_module)
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2356
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2357 # Directly load the winreg module (needed during bootstrap).
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2358 if builtin_os == 'nt':
87347
07229c6104b1 Implement PEP 451 (ModuleSpec).
Eric Snow <ericsnowcurrently@gmail.com>
parents: 86824
diff changeset
2359 winreg_module = _builtin_from_name('winreg')
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2360 setattr(self_module, '_winreg', winreg_module)
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2361
75048
bbaab666e6c7 Issue #14043: Speed up importlib's _FileFinder by at least 8x, and add a new importlib.invalidate_caches() function.
Antoine Pitrou <solipsis@pitrou.net>
parents: 75045
diff changeset
2362 # Constants
75055
b8576719fe71 _relax_case -> _make_relax_case
Antoine Pitrou <solipsis@pitrou.net>
parents: 75048
diff changeset
2363 setattr(self_module, '_relax_case', _make_relax_case())
78486
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
2364 EXTENSION_SUFFIXES.extend(_imp.extension_suffixes())
76451
ea46ebba8a0f Issue #13959: Re-implement imp.source_from_cache() in Lib/imp.py.
Brett Cannon <brett@python.org>
parents: 76450
diff changeset
2365 if builtin_os == 'nt':
76874
b81ddaf0db47 Issue #13959: Deprecate imp.get_suffixes() for new attributes on
Brett Cannon <brett@python.org>
parents: 76826
diff changeset
2366 SOURCE_SUFFIXES.append('.pyw')
78486
1db6553f3f8c Issue #15576: Allow extension modules to be a package's __init__
Brett Cannon <brett@python.org>
parents: 78485
diff changeset
2367 if '_d.pyd' in EXTENSION_SUFFIXES:
78380
a1ac1e13c5a0 Close #15519: Properly expose WindowsRegistryFinder in importlib and bring the name into line with normal import terminology. Original patch by Eric Snow
Nick Coghlan <ncoghlan@gmail.com>
parents: 78344
diff changeset
2368 WindowsRegistryFinder.DEBUG_BUILD = True
75000
e477832212b9 Optimize importlib's case-sensitivity check by wasting as little time as possible under case-sensitive OSs.
Brett Cannon <brett@python.org>
parents: 74998
diff changeset
2369
74935
81f3bb5efa40 Bring importlib in line w/ changes made in my personal bootstrap branch in the sandbox.
Brett Cannon <brett@python.org>
parents: 74867
diff changeset
2370
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
2371 def _install(sys_module, _imp_module):
76765
146001e3364d Clean up a docstring.
Brett Cannon <brett@python.org>
parents: 76755
diff changeset
2372 """Install importlib as the implementation of import."""
76331
d777f854a66e Issue #13959: Rename imp to _imp and add Lib/imp.py and begin
Brett Cannon <brett@python.org>
parents: 76330
diff changeset
2373 _setup(sys_module, _imp_module)
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2374 supported_loaders = _get_supported_file_loaders()
76582
7025ee00dbf6 Issue #14605: Use None in sys.path_importer_cache to represent no
Brett Cannon <brett@python.org>
parents: 76579
diff changeset
2375 sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2376 sys.meta_path.append(BuiltinImporter)
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2377 sys.meta_path.append(FrozenImporter)
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2378 if _os.__name__ == 'nt':
78380
a1ac1e13c5a0 Close #15519: Properly expose WindowsRegistryFinder in importlib and bring the name into line with normal import terminology. Original patch by Eric Snow
Nick Coghlan <ncoghlan@gmail.com>
parents: 78344
diff changeset
2379 sys.meta_path.append(WindowsRegistryFinder)
78308
bd58c421057c Issue #14578: Support modules registered in the Windows registry again.
Martin v. Löwis <martin@v.loewis.de>
parents: 78112
diff changeset
2380 sys.meta_path.append(PathFinder)