Fix #3539: reload module with assertion rewrite import hook

This commit is contained in:
iwanb 2018-09-23 13:05:55 +02:00 committed by Iwan Briquemont
parent ec57cbf82d
commit c61ff31ffa
4 changed files with 54 additions and 10 deletions

View File

@ -93,6 +93,7 @@ Hui Wang (coldnight)
Ian Bicking
Ian Lesperance
Ionuț Turturică
Iwan Briquemont
Jaap Broekhuizen
Jan Balster
Janne Vanhala

View File

@ -0,0 +1 @@
Fix reload on assertion rewritten modules.

View File

@ -269,17 +269,17 @@ class AssertionRewritingHook(object):
)
def load_module(self, name):
# If there is an existing module object named 'fullname' in
# sys.modules, the loader must use that existing module. (Otherwise,
# the reload() builtin will not work correctly.)
if name in sys.modules:
return sys.modules[name]
co, pyc = self.modules.pop(name)
# I wish I could just call imp.load_compiled here, but __file__ has to
# be set properly. In Python 3.2+, this all would be handled correctly
# by load_compiled.
mod = sys.modules[name] = imp.new_module(name)
if name in sys.modules:
# If there is an existing module object named 'fullname' in
# sys.modules, the loader must use that existing module. (Otherwise,
# the reload() builtin will not work correctly.)
mod = sys.modules[name]
else:
# I wish I could just call imp.load_compiled here, but __file__ has to
# be set properly. In Python 3.2+, this all would be handled correctly
# by load_compiled.
mod = sys.modules[name] = imp.new_module(name)
try:
mod.__file__ = co.co_filename
# Normally, this attribute is 3.2+.

View File

@ -1050,6 +1050,48 @@ class TestAssertionRewriteHookDetails(object):
result = testdir.runpytest("-s")
result.stdout.fnmatch_lines(["* 1 passed*"])
def test_reload_reloads(self, testdir):
"""Reloading a module after change picks up the change."""
testdir.tmpdir.join("file.py").write(
textwrap.dedent(
"""
def reloaded():
return False
def rewrite_self():
with open(__file__, 'w') as self:
self.write('def reloaded(): return True')
"""
)
)
testdir.tmpdir.join("pytest.ini").write(
textwrap.dedent(
"""
[pytest]
python_files = *.py
"""
)
)
testdir.makepyfile(
test_fun="""
import sys
try:
from imp import reload
except ImportError:
pass
def test_loader():
import file
assert not file.reloaded()
file.rewrite_self()
reload(file)
assert file.reloaded()
"""
)
result = testdir.runpytest("-s")
result.stdout.fnmatch_lines(["* 1 passed*"])
def test_get_data_support(self, testdir):
"""Implement optional PEP302 api (#808).
"""