Add module reloading tests

This commit is contained in:
Brandon T. Willard 2018-08-20 10:27:31 -05:00
parent 87a5b117a1
commit e9e7171b56

View File

@ -3,10 +3,12 @@
# license. See the LICENSE.
import os
import sys
import ast
import imp
import tempfile
import importlib
import runpy
import importlib
from fractions import Fraction
@ -14,6 +16,7 @@ import pytest
import hy
from hy.errors import HyTypeError
from hy.lex import LexException
from hy.compiler import hy_compile
from hy.importer import hy_parse, HyLoader, cache_from_source
@ -98,3 +101,100 @@ def test_eval():
'(if True "this is if true" "this is if false")') == "this is if true"
assert eval_str('(lfor num (range 100) :if (= (% num 2) 1) (pow num 2))') == [
pow(num, 2) for num in range(100) if num % 2 == 1]
def test_reload():
"""Copied from CPython's `test_import.py`"""
def unlink(filename):
os.unlink(source)
bytecode = cache_from_source(source)
if os.path.isfile(bytecode):
os.unlink(bytecode)
TESTFN = 'testfn'
source = TESTFN + os.extsep + "hy"
with open(source, "w") as f:
f.write("(setv a 1)")
f.write("(setv b 2)")
sys.path.insert(0, os.curdir)
try:
mod = importlib.import_module(TESTFN)
assert TESTFN in sys.modules
assert mod.a == 1
assert mod.b == 2
# On WinXP, just replacing the .py file wasn't enough to
# convince reload() to reparse it. Maybe the timestamp didn't
# move enough. We force it to get reparsed by removing the
# compiled file too.
unlink(source)
# Now damage the module.
with open(source, "w") as f:
f.write("(setv a 10)")
f.write("(setv b (// 20 0))")
with pytest.raises(ZeroDivisionError):
imp.reload(mod)
# But we still expect the module to be in sys.modules.
mod = sys.modules.get(TESTFN)
assert mod is not None
# We should have replaced a w/ 10, but the old b value should
# stick.
assert mod.a == 10
assert mod.b == 2
# Now fix the issue and reload the module.
unlink(source)
with open(source, "w") as f:
f.write("(setv a 11)")
f.write("(setv b (// 20 1))")
imp.reload(mod)
mod = sys.modules.get(TESTFN)
assert mod is not None
assert mod.a == 11
assert mod.b == 20
# Now cause a LexException
unlink(source)
with open(source, "w") as f:
f.write("(setv a 11")
f.write("(setv b (// 20 1))")
with pytest.raises(LexException):
imp.reload(mod)
mod = sys.modules.get(TESTFN)
assert mod is not None
assert mod.a == 11
assert mod.b == 20
# Fix it and retry
unlink(source)
with open(source, "w") as f:
f.write("(setv a 12)")
f.write("(setv b (// 10 1))")
imp.reload(mod)
mod = sys.modules.get(TESTFN)
assert mod is not None
assert mod.a == 12
assert mod.b == 10
finally:
del sys.path[0]
unlink(source)
del sys.modules[TESTFN]