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 Bicking
Ian Lesperance Ian Lesperance
Ionuț Turturică Ionuț Turturică
Iwan Briquemont
Jaap Broekhuizen Jaap Broekhuizen
Jan Balster Jan Balster
Janne Vanhala 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): 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) co, pyc = self.modules.pop(name)
# I wish I could just call imp.load_compiled here, but __file__ has to if name in sys.modules:
# be set properly. In Python 3.2+, this all would be handled correctly # If there is an existing module object named 'fullname' in
# by load_compiled. # sys.modules, the loader must use that existing module. (Otherwise,
mod = sys.modules[name] = imp.new_module(name) # 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: try:
mod.__file__ = co.co_filename mod.__file__ = co.co_filename
# Normally, this attribute is 3.2+. # Normally, this attribute is 3.2+.

View File

@ -1050,6 +1050,48 @@ class TestAssertionRewriteHookDetails(object):
result = testdir.runpytest("-s") result = testdir.runpytest("-s")
result.stdout.fnmatch_lines(["* 1 passed*"]) 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): def test_get_data_support(self, testdir):
"""Implement optional PEP302 api (#808). """Implement optional PEP302 api (#808).
""" """