-
-
Notifications
You must be signed in to change notification settings - Fork 31.9k
bpo-45020: Freeze the modules imported during startup. #28107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a8bd3fc
6555ae4
3a63f92
0587328
9881456
3df3e23
bfd733c
ca952fc
b4ca34c
ef5f3f7
4b630b8
dd1a498
af07489
4e4baeb
344a5ec
8710d80
77cf801
2702554
becae8f
7f0c8eb
d07f63c
4787a70
a75b808
2050793
e16771d
e5b4da7
8b54908
a82b06a
ead34a1
58ccaff
6d068b1
1021f53
c01b532
0c1061d
fa23009
03b9571
b3a7aaf
6a896f1
211febe
fbaf15c
6243c54
da978a2
46d488f
93fc5c0
dd36ba5
45e7509
a7d607f
75556af
37b79f1
d93c1e7
25b60de
358ab69
1fc1198
37eb1f8
2e05771
82b4f85
097fc40
a333fa3
8abf4a0
1005321
7d62747
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -109,7 +109,20 @@ def _save_and_block_module(name, orig_modules): | |
return saved | ||
|
||
|
||
def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): | ||
@contextlib.contextmanager | ||
def frozen_modules(enabled=True): | ||
# FYI: the env var will never show up in os.environ. | ||
os.putenv('_PYTHONTESTFROZENMODULES', '1' if enabled else '0') | ||
try: | ||
yield | ||
finally: | ||
os.unsetenv('_PYTHONTESTFROZENMODULES') | ||
|
||
|
||
def import_fresh_module(name, fresh=(), blocked=(), *, | ||
deprecated=False, | ||
usefrozen=False, | ||
): | ||
"""Import and return a module, deliberately bypassing sys.modules. | ||
|
||
This function imports and returns a fresh copy of the named Python module | ||
|
@@ -148,7 +161,8 @@ def import_fresh_module(name, fresh=(), blocked=(), deprecated=False): | |
for blocked_name in blocked: | ||
if not _save_and_block_module(blocked_name, orig_modules): | ||
names_to_remove.append(blocked_name) | ||
fresh_module = importlib.import_module(name) | ||
with frozen_modules(usefrozen): | ||
fresh_module = importlib.import_module(name) | ||
except ImportError: | ||
fresh_module = None | ||
finally: | ||
|
@@ -171,7 +185,7 @@ class CleanImport(object): | |
importlib.import_module("foo") # new reference | ||
""" | ||
|
||
def __init__(self, *module_names): | ||
def __init__(self, *module_names, usefrozen=False): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you update the class docstring to mention that it also disabled frozen modules unless usefrozen=True is passed? |
||
self.original_modules = sys.modules.copy() | ||
for module_name in module_names: | ||
if module_name in sys.modules: | ||
|
@@ -183,12 +197,15 @@ def __init__(self, *module_names): | |
if module.__name__ != module_name: | ||
del sys.modules[module.__name__] | ||
del sys.modules[module_name] | ||
self._frozen_modules = frozen_modules(usefrozen) | ||
|
||
def __enter__(self): | ||
self._frozen_modules.__enter__() | ||
return self | ||
|
||
def __exit__(self, *ignore_exc): | ||
sys.modules.update(self.original_modules) | ||
self._frozen_modules.__exit__(*ignore_exc) | ||
|
||
|
||
class DirsOnSysPath(object): | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -474,7 +474,6 @@ def test_dash_m_errors(self): | |
br'ModuleNotFoundError'), | ||
('builtins.x.y', br'Error while finding module specification.*' | ||
br'ModuleNotFoundError.*No module named.*not a package'), | ||
('os.path', br'loader.*cannot handle'), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's another failure (two actually) in this test: test_module_in_[sub]package_in_zipfile are both failing. The crucial error seems to be this (from a subprocess):
Note that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I fixed this by adding "zipimport" back as one of the essential frozen modules. |
||
('importlib', br'No module named.*' | ||
br'is a package and cannot be directly executed'), | ||
('importlib.nonexistent', br'No module named'), | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What stdout content is being captured?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The frozen test module (hello.py) prints out
Hello world!
.