blob: d01a2a70072daa19b3160ce550bea29592fa6047 [file] [log] [blame]
Brett Cannon23cbd8a2009-01-18 00:24:28 +00001import importlib
Brett Cannonf87e04d2009-03-12 22:47:53 +00002from importlib import _bootstrap
Brett Cannon30b047d2009-02-01 02:05:11 +00003from .. import abc
Brett Cannon4ee2cda2009-02-01 03:08:31 +00004from . import util as source_util
Brett Cannon23cbd8a2009-01-18 00:24:28 +00005
6import imp
7import os
8import py_compile
9import sys
10import unittest
11
12
13class SimpleTest(unittest.TestCase):
14
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].
17
18 """
19
20 # [basic]
Brett Cannon30b047d2009-02-01 02:05:11 +000021 def test_module(self):
Brett Cannon4ee2cda2009-02-01 03:08:31 +000022 with source_util.create_modules('_temp') as mapping:
Brett Cannonf87e04d2009-03-12 22:47:53 +000023 loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
24 False)
Brett Cannon30b047d2009-02-01 02:05:11 +000025 module = loader.load_module('_temp')
Brett Cannon23cbd8a2009-01-18 00:24:28 +000026 self.assert_('_temp' in sys.modules)
Brett Cannon30b047d2009-02-01 02:05:11 +000027 check = {'__name__': '_temp', '__file__': mapping['_temp'],
Brett Cannon06c9d962009-02-07 01:52:25 +000028 '__package__': ''}
Brett Cannon30b047d2009-02-01 02:05:11 +000029 for attr, value in check.items():
30 self.assertEqual(getattr(module, attr), value)
31
32 def test_package(self):
Brett Cannon4ee2cda2009-02-01 03:08:31 +000033 with source_util.create_modules('_pkg.__init__') as mapping:
Brett Cannonf87e04d2009-03-12 22:47:53 +000034 loader = _bootstrap._PyPycFileLoader('_pkg',
35 mapping['_pkg.__init__'],
36 True)
Brett Cannon30b047d2009-02-01 02:05:11 +000037 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)
44
45
46 def test_lacking_parent(self):
Brett Cannon4ee2cda2009-02-01 03:08:31 +000047 with source_util.create_modules('_pkg.__init__', '_pkg.mod')as mapping:
Brett Cannonf87e04d2009-03-12 22:47:53 +000048 loader = _bootstrap._PyPycFileLoader('_pkg.mod',
49 mapping['_pkg.mod'], False)
Brett Cannon30b047d2009-02-01 02:05:11 +000050 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)
56
57 def fake_mtime(self, fxn):
58 """Fake mtime to always be higher than expected."""
59 return lambda name: fxn(name) + 1
60
61 def test_module_reuse(self):
Brett Cannon4ee2cda2009-02-01 03:08:31 +000062 with source_util.create_modules('_temp') as mapping:
Brett Cannonf87e04d2009-03-12 22:47:53 +000063 loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
64 False)
Brett Cannon30b047d2009-02-01 02:05:11 +000065 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)
82
83 def test_state_after_failure(self):
84 # A failed reload should leave the original module intact.
85 attributes = ('__file__', '__path__', '__package__')
86 value = '<test>'
87 name = '_temp'
Brett Cannon4ee2cda2009-02-01 03:08:31 +000088 with source_util.create_modules(name) as mapping:
Brett Cannon30b047d2009-02-01 02:05:11 +000089 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 +++')
Brett Cannonf87e04d2009-03-12 22:47:53 +000094 loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
95 False)
Brett Cannon30b047d2009-02-01 02:05:11 +000096 self.assertRaises(SyntaxError, loader.load_module, name)
97 for attr in attributes:
98 self.assertEqual(getattr(orig_module, attr), value)
Brett Cannon23cbd8a2009-01-18 00:24:28 +000099
100 # [syntax error]
101 def test_bad_syntax(self):
Brett Cannon4ee2cda2009-02-01 03:08:31 +0000102 with source_util.create_modules('_temp') as mapping:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000103 with open(mapping['_temp'], 'w') as file:
104 file.write('=')
Brett Cannonf87e04d2009-03-12 22:47:53 +0000105 loader = _bootstrap._PyPycFileLoader('_temp', mapping['_temp'],
106 False)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000107 self.assertRaises(SyntaxError, loader.load_module, '_temp')
108 self.assert_('_temp' not in sys.modules)
109
110
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000111class BadBytecodeTest(unittest.TestCase):
112
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].
118
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].
121
122 """
123
124 def import_(self, file, module_name):
Brett Cannonf87e04d2009-03-12 22:47:53 +0000125 loader = _bootstrap._PyPycFileLoader(module_name, file, False)
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000126 module = loader.load_module(module_name)
127 self.assert_(module_name in sys.modules)
128
129 # [bad magic]
Brett Cannon1262e7c2009-05-11 01:47:11 +0000130 @source_util.writes_bytecode_files
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000131 def test_bad_magic(self):
Brett Cannon4ee2cda2009-02-01 03:08:31 +0000132 with source_util.create_modules('_temp') as mapping:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000133 py_compile.compile(mapping['_temp'])
Brett Cannon4ee2cda2009-02-01 03:08:31 +0000134 bytecode_path = source_util.bytecode_path(mapping['_temp'])
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000135 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())
141
142 # [bad timestamp]
Brett Cannon1262e7c2009-05-11 01:47:11 +0000143 @source_util.writes_bytecode_files
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000144 def test_bad_bytecode(self):
145 zeros = b'\x00\x00\x00\x00'
Brett Cannon4ee2cda2009-02-01 03:08:31 +0000146 with source_util.create_modules('_temp') as mapping:
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000147 py_compile.compile(mapping['_temp'])
Brett Cannon4ee2cda2009-02-01 03:08:31 +0000148 bytecode_path = source_util.bytecode_path(mapping['_temp'])
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000149 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)
158
159 # [bad marshal]
160 def test_bad_marshal(self):
Brett Cannon4ee2cda2009-02-01 03:08:31 +0000161 with source_util.create_modules('_temp') as mapping:
162 bytecode_path = source_util.bytecode_path(mapping['_temp'])
Brett Cannon23cbd8a2009-01-18 00:24:28 +0000163 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'],
170 '_temp')
171 self.assert_('_temp' not in sys.modules)
172
173
174def test_main():
175 from test.support import run_unittest
176 run_unittest(SimpleTest, DontWriteBytecodeTest, BadDataTest,
177 SourceBytecodeInteraction, BadBytecodeTest)
178
179
180if __name__ == '__main__':
181 test_main()