2
from importlib import _bootstrap
4
from . import util as source_util
13
class SimpleTest(unittest.TestCase):
15
"""Should have no issue importing a source module [basic]. And if there is
16
a syntax error, it should raise a SyntaxError [syntax error].
21
def test_module(self):
22
with source_util.create_modules('_temp') as mapping:
23
loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
25
module = loader.load_module('_temp')
26
self.assert_('_temp' in sys.modules)
27
check = {'__name__': '_temp', '__file__': mapping['_temp'],
29
for attr, value in check.items():
30
self.assertEqual(getattr(module, attr), value)
32
def test_package(self):
33
with source_util.create_modules('_pkg.__init__') as mapping:
34
loader = _bootstrap._PyPycFileLoader('_pkg',
35
mapping['_pkg.__init__'],
37
module = loader.load_module('_pkg')
38
self.assert_('_pkg' in sys.modules)
39
check = {'__name__': '_pkg', '__file__': mapping['_pkg.__init__'],
40
'__path__': [os.path.dirname(mapping['_pkg.__init__'])],
41
'__package__': '_pkg'}
42
for attr, value in check.items():
43
self.assertEqual(getattr(module, attr), value)
46
def test_lacking_parent(self):
47
with source_util.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
48
loader = _bootstrap._PyPycFileLoader('_pkg.mod',
49
mapping['_pkg.mod'], False)
50
module = loader.load_module('_pkg.mod')
51
self.assert_('_pkg.mod' in sys.modules)
52
check = {'__name__': '_pkg.mod', '__file__': mapping['_pkg.mod'],
53
'__package__': '_pkg'}
54
for attr, value in check.items():
55
self.assertEqual(getattr(module, attr), value)
57
def fake_mtime(self, fxn):
58
"""Fake mtime to always be higher than expected."""
59
return lambda name: fxn(name) + 1
61
def test_module_reuse(self):
62
with source_util.create_modules('_temp') as mapping:
63
loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
65
module = loader.load_module('_temp')
66
module_id = id(module)
67
module_dict_id = id(module.__dict__)
68
with open(mapping['_temp'], 'w') as file:
69
file.write("testing_var = 42\n")
70
# For filesystems where the mtime is only to a second granularity,
71
# everything that has happened above can be too fast;
72
# force an mtime on the source that is guaranteed to be different
73
# than the original mtime.
74
loader.source_mtime = self.fake_mtime(loader.source_mtime)
75
module = loader.load_module('_temp')
76
self.assert_('testing_var' in module.__dict__,
77
"'testing_var' not in "
78
"{0}".format(list(module.__dict__.keys())))
79
self.assertEqual(module, sys.modules['_temp'])
80
self.assertEqual(id(module), module_id)
81
self.assertEqual(id(module.__dict__), module_dict_id)
83
def test_state_after_failure(self):
84
# A failed reload should leave the original module intact.
85
attributes = ('__file__', '__path__', '__package__')
88
with source_util.create_modules(name) as mapping:
89
orig_module = imp.new_module(name)
90
for attr in attributes:
91
setattr(orig_module, attr, value)
92
with open(mapping[name], 'w') as file:
93
file.write('+++ bad syntax +++')
94
loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
96
self.assertRaises(SyntaxError, loader.load_module, name)
97
for attr in attributes:
98
self.assertEqual(getattr(orig_module, attr), value)
101
def test_bad_syntax(self):
102
with source_util.create_modules('_temp') as mapping:
103
with open(mapping['_temp'], 'w') as file:
105
loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
107
self.assertRaises(SyntaxError, loader.load_module, '_temp')
108
self.assert_('_temp' not in sys.modules)
111
class BadBytecodeTest(unittest.TestCase):
113
"""But there are several things about the bytecode which might lead to the
114
source being preferred. If the magic number differs from what the
115
interpreter uses, then the source is used with the bytecode regenerated.
116
If the timestamp is older than the modification time for the source then
117
the bytecode is not used [bad timestamp].
119
But if the marshal data is bad, even if the magic number and timestamp
120
work, a ValueError is raised and the source is not used [bad marshal].
124
def import_(self, file, module_name):
125
loader = _bootstrap._PyPycFileLoader(module_name, file, False)
126
module = loader.load_module(module_name)
127
self.assert_(module_name in sys.modules)
130
@source_util.writes_bytecode
131
def test_bad_magic(self):
132
with source_util.create_modules('_temp') as mapping:
133
py_compile.compile(mapping['_temp'])
134
bytecode_path = source_util.bytecode_path(mapping['_temp'])
135
with open(bytecode_path, 'r+b') as bytecode_file:
136
bytecode_file.seek(0)
137
bytecode_file.write(b'\x00\x00\x00\x00')
138
self.import_(mapping['_temp'], '_temp')
139
with open(bytecode_path, 'rb') as bytecode_file:
140
self.assertEqual(bytecode_file.read(4), imp.get_magic())
143
@source_util.writes_bytecode
144
def test_bad_bytecode(self):
145
zeros = b'\x00\x00\x00\x00'
146
with source_util.create_modules('_temp') as mapping:
147
py_compile.compile(mapping['_temp'])
148
bytecode_path = source_util.bytecode_path(mapping['_temp'])
149
with open(bytecode_path, 'r+b') as bytecode_file:
150
bytecode_file.seek(4)
151
bytecode_file.write(zeros)
152
self.import_(mapping['_temp'], '_temp')
153
source_mtime = os.path.getmtime(mapping['_temp'])
154
source_timestamp = importlib._w_long(source_mtime)
155
with open(bytecode_path, 'rb') as bytecode_file:
156
bytecode_file.seek(4)
157
self.assertEqual(bytecode_file.read(4), source_timestamp)
160
def test_bad_marshal(self):
161
with source_util.create_modules('_temp') as mapping:
162
bytecode_path = source_util.bytecode_path(mapping['_temp'])
163
source_mtime = os.path.getmtime(mapping['_temp'])
164
source_timestamp = importlib._w_long(source_mtime)
165
with open(bytecode_path, 'wb') as bytecode_file:
166
bytecode_file.write(imp.get_magic())
167
bytecode_file.write(source_timestamp)
168
bytecode_file.write(b'AAAA')
169
self.assertRaises(ValueError, self.import_, mapping['_temp'],
171
self.assert_('_temp' not in sys.modules)
175
from test.support import run_unittest
176
run_unittest(SimpleTest, DontWriteBytecodeTest, BadDataTest,
177
SourceBytecodeInteraction, BadBytecodeTest)
180
if __name__ == '__main__':