Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 1 | import importlib |
| 2 | from importlib import abc |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 3 | |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 4 | from .. import abc as testing_abc |
| 5 | from .. import util |
| 6 | from . import util as source_util |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 7 | |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 8 | import imp |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 9 | import inspect |
Brett Cannon | 418182e | 2010-07-03 22:32:41 +0000 | [diff] [blame] | 10 | import io |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 11 | import marshal |
| 12 | import os |
| 13 | import sys |
| 14 | import types |
| 15 | import unittest |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 16 | import warnings |
| 17 | |
| 18 | |
| 19 | class SourceOnlyLoaderMock(abc.SourceLoader): |
| 20 | |
| 21 | # Globals that should be defined for all modules. |
| 22 | source = (b"_ = '::'.join([__name__, __file__, __cached__, __package__, " |
| 23 | b"repr(__loader__)])") |
| 24 | |
| 25 | def __init__(self, path): |
| 26 | self.path = path |
| 27 | |
| 28 | def get_data(self, path): |
| 29 | assert self.path == path |
| 30 | return self.source |
| 31 | |
| 32 | def get_filename(self, fullname): |
| 33 | return self.path |
| 34 | |
| 35 | |
| 36 | class SourceLoaderMock(SourceOnlyLoaderMock): |
| 37 | |
| 38 | source_mtime = 1 |
| 39 | |
| 40 | def __init__(self, path, magic=imp.get_magic()): |
| 41 | super().__init__(path) |
| 42 | self.bytecode_path = imp.cache_from_source(self.path) |
| 43 | data = bytearray(magic) |
| 44 | data.extend(marshal._w_long(self.source_mtime)) |
| 45 | code_object = compile(self.source, self.path, 'exec', |
| 46 | dont_inherit=True) |
| 47 | data.extend(marshal.dumps(code_object)) |
| 48 | self.bytecode = bytes(data) |
| 49 | self.written = {} |
| 50 | |
| 51 | def get_data(self, path): |
| 52 | if path == self.path: |
| 53 | return super().get_data(path) |
| 54 | elif path == self.bytecode_path: |
| 55 | return self.bytecode |
| 56 | else: |
| 57 | raise IOError |
| 58 | |
| 59 | def path_mtime(self, path): |
| 60 | assert path == self.path |
| 61 | return self.source_mtime |
| 62 | |
| 63 | def set_data(self, path, data): |
| 64 | self.written[path] = bytes(data) |
| 65 | return path == self.bytecode_path |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 66 | |
| 67 | |
| 68 | class PyLoaderMock(abc.PyLoader): |
| 69 | |
| 70 | # Globals that should be defined for all modules. |
Brett Cannon | d43b30b | 2009-03-10 03:29:23 +0000 | [diff] [blame] | 71 | source = (b"_ = '::'.join([__name__, __file__, __package__, " |
| 72 | b"repr(__loader__)])") |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 73 | |
| 74 | def __init__(self, data): |
| 75 | """Take a dict of 'module_name: path' pairings. |
| 76 | |
| 77 | Paths should have no file extension, allowing packages to be denoted by |
| 78 | ending in '__init__'. |
| 79 | |
| 80 | """ |
| 81 | self.module_paths = data |
| 82 | self.path_to_module = {val:key for key,val in data.items()} |
| 83 | |
| 84 | def get_data(self, path): |
| 85 | if path not in self.path_to_module: |
| 86 | raise IOError |
Brett Cannon | d43b30b | 2009-03-10 03:29:23 +0000 | [diff] [blame] | 87 | return self.source |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 88 | |
| 89 | def is_package(self, name): |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 90 | filename = os.path.basename(self.get_filename(name)) |
| 91 | return os.path.splitext(filename)[0] == '__init__' |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 92 | |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 93 | def source_path(self, name): |
| 94 | try: |
| 95 | return self.module_paths[name] |
| 96 | except KeyError: |
| 97 | raise ImportError |
| 98 | |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 99 | def get_filename(self, name): |
| 100 | """Silence deprecation warning.""" |
| 101 | with warnings.catch_warnings(record=True) as w: |
| 102 | warnings.simplefilter("always") |
| 103 | path = super().get_filename(name) |
| 104 | assert len(w) == 1 |
| 105 | assert issubclass(w[0].category, PendingDeprecationWarning) |
| 106 | return path |
| 107 | |
| 108 | |
| 109 | class PyLoaderCompatMock(PyLoaderMock): |
| 110 | |
| 111 | """Mock that matches what is suggested to have a loader that is compatible |
| 112 | from Python 3.1 onwards.""" |
| 113 | |
| 114 | def get_filename(self, fullname): |
| 115 | try: |
| 116 | return self.module_paths[fullname] |
| 117 | except KeyError: |
| 118 | raise ImportError |
| 119 | |
| 120 | def source_path(self, fullname): |
| 121 | try: |
| 122 | return self.get_filename(fullname) |
| 123 | except ImportError: |
| 124 | return None |
| 125 | |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 126 | |
| 127 | class PyPycLoaderMock(abc.PyPycLoader, PyLoaderMock): |
| 128 | |
| 129 | default_mtime = 1 |
| 130 | |
| 131 | def __init__(self, source, bc={}): |
| 132 | """Initialize mock. |
| 133 | |
| 134 | 'bc' is a dict keyed on a module's name. The value is dict with |
| 135 | possible keys of 'path', 'mtime', 'magic', and 'bc'. Except for 'path', |
| 136 | each of those keys control if any part of created bytecode is to |
| 137 | deviate from default values. |
| 138 | |
| 139 | """ |
| 140 | super().__init__(source) |
| 141 | self.module_bytecode = {} |
| 142 | self.path_to_bytecode = {} |
| 143 | self.bytecode_to_path = {} |
| 144 | for name, data in bc.items(): |
| 145 | self.path_to_bytecode[data['path']] = name |
| 146 | self.bytecode_to_path[name] = data['path'] |
| 147 | magic = data.get('magic', imp.get_magic()) |
| 148 | mtime = importlib._w_long(data.get('mtime', self.default_mtime)) |
| 149 | if 'bc' in data: |
| 150 | bc = data['bc'] |
| 151 | else: |
| 152 | bc = self.compile_bc(name) |
| 153 | self.module_bytecode[name] = magic + mtime + bc |
| 154 | |
| 155 | def compile_bc(self, name): |
| 156 | source_path = self.module_paths.get(name, '<test>') or '<test>' |
| 157 | code = compile(self.source, source_path, 'exec') |
| 158 | return marshal.dumps(code) |
| 159 | |
| 160 | def source_mtime(self, name): |
| 161 | if name in self.module_paths: |
| 162 | return self.default_mtime |
| 163 | elif name in self.module_bytecode: |
| 164 | return None |
| 165 | else: |
| 166 | raise ImportError |
| 167 | |
| 168 | def bytecode_path(self, name): |
| 169 | try: |
| 170 | return self.bytecode_to_path[name] |
| 171 | except KeyError: |
| 172 | if name in self.module_paths: |
| 173 | return None |
| 174 | else: |
| 175 | raise ImportError |
| 176 | |
| 177 | def write_bytecode(self, name, bytecode): |
| 178 | self.module_bytecode[name] = bytecode |
| 179 | return True |
| 180 | |
| 181 | def get_data(self, path): |
| 182 | if path in self.path_to_module: |
| 183 | return super().get_data(path) |
| 184 | elif path in self.path_to_bytecode: |
| 185 | name = self.path_to_bytecode[path] |
| 186 | return self.module_bytecode[name] |
| 187 | else: |
| 188 | raise IOError |
| 189 | |
| 190 | def is_package(self, name): |
| 191 | try: |
| 192 | return super().is_package(name) |
| 193 | except TypeError: |
| 194 | return '__init__' in self.bytecode_to_path[name] |
| 195 | |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 196 | def get_code(self, name): |
| 197 | with warnings.catch_warnings(record=True) as w: |
| 198 | warnings.simplefilter("always") |
| 199 | code_object = super().get_code(name) |
| 200 | assert len(w) == 1 |
| 201 | assert issubclass(w[0].category, PendingDeprecationWarning) |
| 202 | return code_object |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 203 | |
| 204 | class PyLoaderTests(testing_abc.LoaderTests): |
| 205 | |
| 206 | """Tests for importlib.abc.PyLoader.""" |
| 207 | |
| 208 | mocker = PyLoaderMock |
| 209 | |
| 210 | def eq_attrs(self, ob, **kwargs): |
| 211 | for attr, val in kwargs.items(): |
Brett Cannon | 978259e | 2009-04-02 15:32:07 +0000 | [diff] [blame] | 212 | found = getattr(ob, attr) |
| 213 | self.assertEqual(found, val, |
| 214 | "{} attribute: {} != {}".format(attr, found, val)) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 215 | |
| 216 | def test_module(self): |
| 217 | name = '<module>' |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 218 | path = os.path.join('', 'path', 'to', 'module') |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 219 | mock = self.mocker({name: path}) |
| 220 | with util.uncache(name): |
| 221 | module = mock.load_module(name) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 222 | self.assertTrue(name in sys.modules) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 223 | self.eq_attrs(module, __name__=name, __file__=path, __package__='', |
| 224 | __loader__=mock) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 225 | self.assertTrue(not hasattr(module, '__path__')) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 226 | return mock, name |
| 227 | |
| 228 | def test_package(self): |
| 229 | name = '<pkg>' |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 230 | path = os.path.join('path', 'to', name, '__init__') |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 231 | mock = self.mocker({name: path}) |
| 232 | with util.uncache(name): |
| 233 | module = mock.load_module(name) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 234 | self.assertTrue(name in sys.modules) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 235 | self.eq_attrs(module, __name__=name, __file__=path, |
| 236 | __path__=[os.path.dirname(path)], __package__=name, |
| 237 | __loader__=mock) |
| 238 | return mock, name |
| 239 | |
| 240 | def test_lacking_parent(self): |
| 241 | name = 'pkg.mod' |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 242 | path = os.path.join('path', 'to', 'pkg', 'mod') |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 243 | mock = self.mocker({name: path}) |
| 244 | with util.uncache(name): |
| 245 | module = mock.load_module(name) |
Brett Cannon | 1262e7c | 2009-05-11 01:47:11 +0000 | [diff] [blame] | 246 | self.assertIn(name, sys.modules) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 247 | self.eq_attrs(module, __name__=name, __file__=path, __package__='pkg', |
| 248 | __loader__=mock) |
Brett Cannon | 1262e7c | 2009-05-11 01:47:11 +0000 | [diff] [blame] | 249 | self.assertFalse(hasattr(module, '__path__')) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 250 | return mock, name |
| 251 | |
| 252 | def test_module_reuse(self): |
| 253 | name = 'mod' |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 254 | path = os.path.join('path', 'to', 'mod') |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 255 | module = imp.new_module(name) |
| 256 | mock = self.mocker({name: path}) |
| 257 | with util.uncache(name): |
| 258 | sys.modules[name] = module |
| 259 | loaded_module = mock.load_module(name) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 260 | self.assertTrue(loaded_module is module) |
| 261 | self.assertTrue(sys.modules[name] is module) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 262 | return mock, name |
| 263 | |
| 264 | def test_state_after_failure(self): |
| 265 | name = "mod" |
| 266 | module = imp.new_module(name) |
| 267 | module.blah = None |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 268 | mock = self.mocker({name: os.path.join('path', 'to', 'mod')}) |
Brett Cannon | d43b30b | 2009-03-10 03:29:23 +0000 | [diff] [blame] | 269 | mock.source = b"1/0" |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 270 | with util.uncache(name): |
| 271 | sys.modules[name] = module |
Brett Cannon | 0a49c58 | 2009-07-19 23:43:45 +0000 | [diff] [blame] | 272 | with self.assertRaises(ZeroDivisionError): |
| 273 | mock.load_module(name) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 274 | self.assertTrue(sys.modules[name] is module) |
| 275 | self.assertTrue(hasattr(module, 'blah')) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 276 | return mock |
| 277 | |
| 278 | def test_unloadable(self): |
| 279 | name = "mod" |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 280 | mock = self.mocker({name: os.path.join('path', 'to', 'mod')}) |
Brett Cannon | d43b30b | 2009-03-10 03:29:23 +0000 | [diff] [blame] | 281 | mock.source = b"1/0" |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 282 | with util.uncache(name): |
Brett Cannon | 0a49c58 | 2009-07-19 23:43:45 +0000 | [diff] [blame] | 283 | with self.assertRaises(ZeroDivisionError): |
| 284 | mock.load_module(name) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 285 | self.assertTrue(name not in sys.modules) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 286 | return mock |
| 287 | |
| 288 | |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 289 | class PyLoaderCompatTests(PyLoaderTests): |
| 290 | |
| 291 | """Test that the suggested code to make a loader that is compatible from |
| 292 | Python 3.1 forward works.""" |
| 293 | |
| 294 | mocker = PyLoaderCompatMock |
| 295 | |
| 296 | |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 297 | class PyLoaderInterfaceTests(unittest.TestCase): |
| 298 | |
Brett Cannon | d43b30b | 2009-03-10 03:29:23 +0000 | [diff] [blame] | 299 | """Tests for importlib.abc.PyLoader to make sure that when source_path() |
| 300 | doesn't return a path everything works as expected.""" |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 301 | |
| 302 | def test_no_source_path(self): |
| 303 | # No source path should lead to ImportError. |
| 304 | name = 'mod' |
| 305 | mock = PyLoaderMock({}) |
Brett Cannon | 0a49c58 | 2009-07-19 23:43:45 +0000 | [diff] [blame] | 306 | with util.uncache(name), self.assertRaises(ImportError): |
| 307 | mock.load_module(name) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 308 | |
| 309 | def test_source_path_is_None(self): |
| 310 | name = 'mod' |
| 311 | mock = PyLoaderMock({name: None}) |
Brett Cannon | 0a49c58 | 2009-07-19 23:43:45 +0000 | [diff] [blame] | 312 | with util.uncache(name), self.assertRaises(ImportError): |
| 313 | mock.load_module(name) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 314 | |
Brett Cannon | 6919427 | 2009-07-20 04:23:48 +0000 | [diff] [blame] | 315 | def test_get_filename_with_source_path(self): |
| 316 | # get_filename() should return what source_path() returns. |
| 317 | name = 'mod' |
| 318 | path = os.path.join('path', 'to', 'source') |
| 319 | mock = PyLoaderMock({name: path}) |
| 320 | with util.uncache(name): |
| 321 | self.assertEqual(mock.get_filename(name), path) |
| 322 | |
| 323 | def test_get_filename_no_source_path(self): |
| 324 | # get_filename() should raise ImportError if source_path returns None. |
| 325 | name = 'mod' |
| 326 | mock = PyLoaderMock({name: None}) |
| 327 | with util.uncache(name), self.assertRaises(ImportError): |
| 328 | mock.get_filename(name) |
| 329 | |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 330 | |
| 331 | class PyPycLoaderTests(PyLoaderTests): |
| 332 | |
| 333 | """Tests for importlib.abc.PyPycLoader.""" |
| 334 | |
| 335 | mocker = PyPycLoaderMock |
| 336 | |
Brett Cannon | 1262e7c | 2009-05-11 01:47:11 +0000 | [diff] [blame] | 337 | @source_util.writes_bytecode_files |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 338 | def verify_bytecode(self, mock, name): |
| 339 | assert name in mock.module_paths |
Brett Cannon | 1262e7c | 2009-05-11 01:47:11 +0000 | [diff] [blame] | 340 | self.assertIn(name, mock.module_bytecode) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 341 | magic = mock.module_bytecode[name][:4] |
| 342 | self.assertEqual(magic, imp.get_magic()) |
| 343 | mtime = importlib._r_long(mock.module_bytecode[name][4:8]) |
| 344 | self.assertEqual(mtime, 1) |
| 345 | bc = mock.module_bytecode[name][8:] |
Brett Cannon | 1262e7c | 2009-05-11 01:47:11 +0000 | [diff] [blame] | 346 | self.assertEqual(bc, mock.compile_bc(name)) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 347 | |
| 348 | def test_module(self): |
| 349 | mock, name = super().test_module() |
| 350 | self.verify_bytecode(mock, name) |
| 351 | |
| 352 | def test_package(self): |
| 353 | mock, name = super().test_package() |
| 354 | self.verify_bytecode(mock, name) |
| 355 | |
| 356 | def test_lacking_parent(self): |
| 357 | mock, name = super().test_lacking_parent() |
| 358 | self.verify_bytecode(mock, name) |
| 359 | |
| 360 | def test_module_reuse(self): |
| 361 | mock, name = super().test_module_reuse() |
| 362 | self.verify_bytecode(mock, name) |
| 363 | |
| 364 | def test_state_after_failure(self): |
| 365 | super().test_state_after_failure() |
| 366 | |
| 367 | def test_unloadable(self): |
| 368 | super().test_unloadable() |
| 369 | |
| 370 | |
Brett Cannon | 6919427 | 2009-07-20 04:23:48 +0000 | [diff] [blame] | 371 | class PyPycLoaderInterfaceTests(unittest.TestCase): |
| 372 | |
| 373 | """Test for the interface of importlib.abc.PyPycLoader.""" |
| 374 | |
| 375 | def get_filename_check(self, src_path, bc_path, expect): |
| 376 | name = 'mod' |
| 377 | mock = PyPycLoaderMock({name: src_path}, {name: {'path': bc_path}}) |
| 378 | with util.uncache(name): |
| 379 | assert mock.source_path(name) == src_path |
| 380 | assert mock.bytecode_path(name) == bc_path |
| 381 | self.assertEqual(mock.get_filename(name), expect) |
| 382 | |
| 383 | def test_filename_with_source_bc(self): |
| 384 | # When source and bytecode paths present, return the source path. |
| 385 | self.get_filename_check('source_path', 'bc_path', 'source_path') |
| 386 | |
| 387 | def test_filename_with_source_no_bc(self): |
| 388 | # With source but no bc, return source path. |
| 389 | self.get_filename_check('source_path', None, 'source_path') |
| 390 | |
| 391 | def test_filename_with_no_source_bc(self): |
| 392 | # With not source but bc, return the bc path. |
| 393 | self.get_filename_check(None, 'bc_path', 'bc_path') |
| 394 | |
| 395 | def test_filename_with_no_source_or_bc(self): |
| 396 | # With no source or bc, raise ImportError. |
| 397 | name = 'mod' |
| 398 | mock = PyPycLoaderMock({name: None}, {name: {'path': None}}) |
| 399 | with util.uncache(name), self.assertRaises(ImportError): |
| 400 | mock.get_filename(name) |
| 401 | |
| 402 | |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 403 | class SkipWritingBytecodeTests(unittest.TestCase): |
| 404 | |
| 405 | """Test that bytecode is properly handled based on |
| 406 | sys.dont_write_bytecode.""" |
| 407 | |
Brett Cannon | 1262e7c | 2009-05-11 01:47:11 +0000 | [diff] [blame] | 408 | @source_util.writes_bytecode_files |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 409 | def run_test(self, dont_write_bytecode): |
| 410 | name = 'mod' |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 411 | mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 412 | sys.dont_write_bytecode = dont_write_bytecode |
| 413 | with util.uncache(name): |
| 414 | mock.load_module(name) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 415 | self.assertTrue((name in mock.module_bytecode) is not |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 416 | dont_write_bytecode) |
| 417 | |
| 418 | def test_no_bytecode_written(self): |
| 419 | self.run_test(True) |
| 420 | |
| 421 | def test_bytecode_written(self): |
| 422 | self.run_test(False) |
| 423 | |
| 424 | |
| 425 | class RegeneratedBytecodeTests(unittest.TestCase): |
| 426 | |
| 427 | """Test that bytecode is regenerated as expected.""" |
| 428 | |
Brett Cannon | 1262e7c | 2009-05-11 01:47:11 +0000 | [diff] [blame] | 429 | @source_util.writes_bytecode_files |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 430 | def test_different_magic(self): |
| 431 | # A different magic number should lead to new bytecode. |
| 432 | name = 'mod' |
| 433 | bad_magic = b'\x00\x00\x00\x00' |
| 434 | assert bad_magic != imp.get_magic() |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 435 | mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}, |
| 436 | {name: {'path': os.path.join('path', 'to', |
| 437 | 'mod.bytecode'), |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 438 | 'magic': bad_magic}}) |
| 439 | with util.uncache(name): |
| 440 | mock.load_module(name) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 441 | self.assertTrue(name in mock.module_bytecode) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 442 | magic = mock.module_bytecode[name][:4] |
| 443 | self.assertEqual(magic, imp.get_magic()) |
| 444 | |
Brett Cannon | 1262e7c | 2009-05-11 01:47:11 +0000 | [diff] [blame] | 445 | @source_util.writes_bytecode_files |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 446 | def test_old_mtime(self): |
| 447 | # Bytecode with an older mtime should be regenerated. |
| 448 | name = 'mod' |
| 449 | old_mtime = PyPycLoaderMock.default_mtime - 1 |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 450 | mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}, |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 451 | {name: {'path': 'path/to/mod.bytecode', 'mtime': old_mtime}}) |
| 452 | with util.uncache(name): |
| 453 | mock.load_module(name) |
Benjamin Peterson | c9c0f20 | 2009-06-30 23:06:06 +0000 | [diff] [blame] | 454 | self.assertTrue(name in mock.module_bytecode) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 455 | mtime = importlib._r_long(mock.module_bytecode[name][4:8]) |
| 456 | self.assertEqual(mtime, PyPycLoaderMock.default_mtime) |
| 457 | |
| 458 | |
| 459 | class BadBytecodeFailureTests(unittest.TestCase): |
| 460 | |
| 461 | """Test import failures when there is no source and parts of the bytecode |
| 462 | is bad.""" |
| 463 | |
| 464 | def test_bad_magic(self): |
| 465 | # A bad magic number should lead to an ImportError. |
| 466 | name = 'mod' |
| 467 | bad_magic = b'\x00\x00\x00\x00' |
Brett Cannon | 3c27384 | 2009-07-20 00:14:29 +0000 | [diff] [blame] | 468 | bc = {name: |
| 469 | {'path': os.path.join('path', 'to', 'mod'), |
| 470 | 'magic': bad_magic}} |
| 471 | mock = PyPycLoaderMock({name: None}, bc) |
Brett Cannon | 0a49c58 | 2009-07-19 23:43:45 +0000 | [diff] [blame] | 472 | with util.uncache(name), self.assertRaises(ImportError): |
| 473 | mock.load_module(name) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 474 | |
Brett Cannon | 3c27384 | 2009-07-20 00:14:29 +0000 | [diff] [blame] | 475 | def test_no_bytecode(self): |
| 476 | # Missing code object bytecode should lead to an EOFError. |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 477 | name = 'mod' |
Brett Cannon | 3c27384 | 2009-07-20 00:14:29 +0000 | [diff] [blame] | 478 | bc = {name: {'path': os.path.join('path', 'to', 'mod'), 'bc': b''}} |
| 479 | mock = PyPycLoaderMock({name: None}, bc) |
| 480 | with util.uncache(name), self.assertRaises(EOFError): |
| 481 | mock.load_module(name) |
| 482 | |
| 483 | def test_bad_bytecode(self): |
| 484 | # Malformed code object bytecode should lead to a ValueError. |
| 485 | name = 'mod' |
Benjamin Peterson | 2215c14 | 2010-06-28 00:24:13 +0000 | [diff] [blame] | 486 | bc = {name: {'path': os.path.join('path', 'to', 'mod'), 'bc': b'1234'}} |
Brett Cannon | 3c27384 | 2009-07-20 00:14:29 +0000 | [diff] [blame] | 487 | mock = PyPycLoaderMock({name: None}, bc) |
| 488 | with util.uncache(name), self.assertRaises(ValueError): |
Brett Cannon | 0a49c58 | 2009-07-19 23:43:45 +0000 | [diff] [blame] | 489 | mock.load_module(name) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 490 | |
| 491 | |
| 492 | def raise_ImportError(*args, **kwargs): |
| 493 | raise ImportError |
| 494 | |
| 495 | class MissingPathsTests(unittest.TestCase): |
| 496 | |
| 497 | """Test what happens when a source or bytecode path does not exist (either |
| 498 | from *_path returning None or raising ImportError).""" |
| 499 | |
| 500 | def test_source_path_None(self): |
| 501 | # Bytecode should be used when source_path returns None, along with |
| 502 | # __file__ being set to the bytecode path. |
| 503 | name = 'mod' |
| 504 | bytecode_path = 'path/to/mod' |
| 505 | mock = PyPycLoaderMock({name: None}, {name: {'path': bytecode_path}}) |
| 506 | with util.uncache(name): |
| 507 | module = mock.load_module(name) |
| 508 | self.assertEqual(module.__file__, bytecode_path) |
| 509 | |
| 510 | # Testing for bytecode_path returning None handled by all tests where no |
| 511 | # bytecode initially exists. |
| 512 | |
| 513 | def test_all_paths_None(self): |
| 514 | # If all *_path methods return None, raise ImportError. |
| 515 | name = 'mod' |
| 516 | mock = PyPycLoaderMock({name: None}) |
Brett Cannon | 0a49c58 | 2009-07-19 23:43:45 +0000 | [diff] [blame] | 517 | with util.uncache(name), self.assertRaises(ImportError): |
| 518 | mock.load_module(name) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 519 | |
| 520 | def test_source_path_ImportError(self): |
| 521 | # An ImportError from source_path should trigger an ImportError. |
| 522 | name = 'mod' |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 523 | mock = PyPycLoaderMock({}, {name: {'path': os.path.join('path', 'to', |
| 524 | 'mod')}}) |
Brett Cannon | 0a49c58 | 2009-07-19 23:43:45 +0000 | [diff] [blame] | 525 | with util.uncache(name), self.assertRaises(ImportError): |
| 526 | mock.load_module(name) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 527 | |
| 528 | def test_bytecode_path_ImportError(self): |
| 529 | # An ImportError from bytecode_path should trigger an ImportError. |
| 530 | name = 'mod' |
Brett Cannon | 5561982 | 2009-04-02 17:54:43 +0000 | [diff] [blame] | 531 | mock = PyPycLoaderMock({name: os.path.join('path', 'to', 'mod')}) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 532 | bad_meth = types.MethodType(raise_ImportError, mock) |
| 533 | mock.bytecode_path = bad_meth |
Brett Cannon | 0a49c58 | 2009-07-19 23:43:45 +0000 | [diff] [blame] | 534 | with util.uncache(name), self.assertRaises(ImportError): |
| 535 | mock.load_module(name) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 536 | |
| 537 | |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 538 | class SourceLoaderTestHarness(unittest.TestCase): |
| 539 | |
| 540 | def setUp(self, *, is_package=True, **kwargs): |
| 541 | self.package = 'pkg' |
| 542 | if is_package: |
| 543 | self.path = os.path.join(self.package, '__init__.py') |
| 544 | self.name = self.package |
| 545 | else: |
| 546 | module_name = 'mod' |
| 547 | self.path = os.path.join(self.package, '.'.join(['mod', 'py'])) |
| 548 | self.name = '.'.join([self.package, module_name]) |
| 549 | self.cached = imp.cache_from_source(self.path) |
| 550 | self.loader = self.loader_mock(self.path, **kwargs) |
| 551 | |
| 552 | def verify_module(self, module): |
| 553 | self.assertEqual(module.__name__, self.name) |
| 554 | self.assertEqual(module.__file__, self.path) |
| 555 | self.assertEqual(module.__cached__, self.cached) |
| 556 | self.assertEqual(module.__package__, self.package) |
| 557 | self.assertEqual(module.__loader__, self.loader) |
| 558 | values = module._.split('::') |
| 559 | self.assertEqual(values[0], self.name) |
| 560 | self.assertEqual(values[1], self.path) |
| 561 | self.assertEqual(values[2], self.cached) |
| 562 | self.assertEqual(values[3], self.package) |
| 563 | self.assertEqual(values[4], repr(self.loader)) |
| 564 | |
| 565 | def verify_code(self, code_object): |
| 566 | module = imp.new_module(self.name) |
| 567 | module.__file__ = self.path |
| 568 | module.__cached__ = self.cached |
| 569 | module.__package__ = self.package |
| 570 | module.__loader__ = self.loader |
| 571 | module.__path__ = [] |
| 572 | exec(code_object, module.__dict__) |
| 573 | self.verify_module(module) |
| 574 | |
| 575 | |
| 576 | class SourceOnlyLoaderTests(SourceLoaderTestHarness): |
| 577 | |
| 578 | """Test importlib.abc.SourceLoader for source-only loading. |
| 579 | |
| 580 | Reload testing is subsumed by the tests for |
| 581 | importlib.util.module_for_loader. |
| 582 | |
| 583 | """ |
| 584 | |
| 585 | loader_mock = SourceOnlyLoaderMock |
| 586 | |
| 587 | def test_get_source(self): |
| 588 | # Verify the source code is returned as a string. |
| 589 | # If an IOError is raised by get_data then raise ImportError. |
| 590 | expected_source = self.loader.source.decode('utf-8') |
| 591 | self.assertEqual(self.loader.get_source(self.name), expected_source) |
| 592 | def raise_IOError(path): |
| 593 | raise IOError |
| 594 | self.loader.get_data = raise_IOError |
| 595 | with self.assertRaises(ImportError): |
| 596 | self.loader.get_source(self.name) |
| 597 | |
| 598 | def test_is_package(self): |
| 599 | # Properly detect when loading a package. |
| 600 | self.setUp(is_package=True) |
| 601 | self.assertTrue(self.loader.is_package(self.name)) |
| 602 | self.setUp(is_package=False) |
| 603 | self.assertFalse(self.loader.is_package(self.name)) |
| 604 | |
| 605 | def test_get_code(self): |
| 606 | # Verify the code object is created. |
| 607 | code_object = self.loader.get_code(self.name) |
| 608 | self.verify_code(code_object) |
| 609 | |
| 610 | def test_load_module(self): |
| 611 | # Loading a module should set __name__, __loader__, __package__, |
| 612 | # __path__ (for packages), __file__, and __cached__. |
| 613 | # The module should also be put into sys.modules. |
| 614 | with util.uncache(self.name): |
| 615 | module = self.loader.load_module(self.name) |
| 616 | self.verify_module(module) |
| 617 | self.assertEqual(module.__path__, [os.path.dirname(self.path)]) |
| 618 | self.assertTrue(self.name in sys.modules) |
| 619 | |
| 620 | def test_package_settings(self): |
| 621 | # __package__ needs to be set, while __path__ is set on if the module |
| 622 | # is a package. |
| 623 | # Testing the values for a package are covered by test_load_module. |
| 624 | self.setUp(is_package=False) |
| 625 | with util.uncache(self.name): |
| 626 | module = self.loader.load_module(self.name) |
| 627 | self.verify_module(module) |
| 628 | self.assertTrue(not hasattr(module, '__path__')) |
| 629 | |
| 630 | def test_get_source_encoding(self): |
| 631 | # Source is considered encoded in UTF-8 by default unless otherwise |
| 632 | # specified by an encoding line. |
| 633 | source = "_ = 'ü'" |
| 634 | self.loader.source = source.encode('utf-8') |
| 635 | returned_source = self.loader.get_source(self.name) |
| 636 | self.assertEqual(returned_source, source) |
| 637 | source = "# coding: latin-1\n_ = ü" |
| 638 | self.loader.source = source.encode('latin-1') |
| 639 | returned_source = self.loader.get_source(self.name) |
| 640 | self.assertEqual(returned_source, source) |
| 641 | |
| 642 | |
| 643 | @unittest.skipIf(sys.dont_write_bytecode, "sys.dont_write_bytecode is true") |
| 644 | class SourceLoaderBytecodeTests(SourceLoaderTestHarness): |
| 645 | |
| 646 | """Test importlib.abc.SourceLoader's use of bytecode. |
| 647 | |
| 648 | Source-only testing handled by SourceOnlyLoaderTests. |
| 649 | |
| 650 | """ |
| 651 | |
| 652 | loader_mock = SourceLoaderMock |
| 653 | |
| 654 | def verify_code(self, code_object, *, bytecode_written=False): |
| 655 | super().verify_code(code_object) |
| 656 | if bytecode_written: |
| 657 | self.assertIn(self.cached, self.loader.written) |
| 658 | data = bytearray(imp.get_magic()) |
| 659 | data.extend(marshal._w_long(self.loader.source_mtime)) |
| 660 | data.extend(marshal.dumps(code_object)) |
| 661 | self.assertEqual(self.loader.written[self.cached], bytes(data)) |
| 662 | |
| 663 | def test_code_with_everything(self): |
| 664 | # When everything should work. |
| 665 | code_object = self.loader.get_code(self.name) |
| 666 | self.verify_code(code_object) |
| 667 | |
| 668 | def test_no_bytecode(self): |
| 669 | # If no bytecode exists then move on to the source. |
| 670 | self.loader.bytecode_path = "<does not exist>" |
| 671 | # Sanity check |
| 672 | with self.assertRaises(IOError): |
| 673 | bytecode_path = imp.cache_from_source(self.path) |
| 674 | self.loader.get_data(bytecode_path) |
| 675 | code_object = self.loader.get_code(self.name) |
| 676 | self.verify_code(code_object, bytecode_written=True) |
| 677 | |
| 678 | def test_code_bad_timestamp(self): |
| 679 | # Bytecode is only used when the timestamp matches the source EXACTLY. |
| 680 | for source_mtime in (0, 2): |
| 681 | assert source_mtime != self.loader.source_mtime |
| 682 | original = self.loader.source_mtime |
| 683 | self.loader.source_mtime = source_mtime |
| 684 | # If bytecode is used then EOFError would be raised by marshal. |
| 685 | self.loader.bytecode = self.loader.bytecode[8:] |
| 686 | code_object = self.loader.get_code(self.name) |
| 687 | self.verify_code(code_object, bytecode_written=True) |
| 688 | self.loader.source_mtime = original |
| 689 | |
| 690 | def test_code_bad_magic(self): |
| 691 | # Skip over bytecode with a bad magic number. |
| 692 | self.setUp(magic=b'0000') |
| 693 | # If bytecode is used then EOFError would be raised by marshal. |
| 694 | self.loader.bytecode = self.loader.bytecode[8:] |
| 695 | code_object = self.loader.get_code(self.name) |
| 696 | self.verify_code(code_object, bytecode_written=True) |
| 697 | |
| 698 | def test_dont_write_bytecode(self): |
| 699 | # Bytecode is not written if sys.dont_write_bytecode is true. |
| 700 | # Can assume it is false already thanks to the skipIf class decorator. |
| 701 | try: |
| 702 | sys.dont_write_bytecode = True |
| 703 | self.loader.bytecode_path = "<does not exist>" |
| 704 | code_object = self.loader.get_code(self.name) |
| 705 | self.assertNotIn(self.cached, self.loader.written) |
| 706 | finally: |
| 707 | sys.dont_write_bytecode = False |
| 708 | |
| 709 | def test_no_set_data(self): |
| 710 | # If set_data is not defined, one can still read bytecode. |
| 711 | self.setUp(magic=b'0000') |
| 712 | original_set_data = self.loader.__class__.set_data |
| 713 | try: |
| 714 | del self.loader.__class__.set_data |
| 715 | code_object = self.loader.get_code(self.name) |
| 716 | self.verify_code(code_object) |
| 717 | finally: |
| 718 | self.loader.__class__.set_data = original_set_data |
| 719 | |
| 720 | def test_set_data_raises_exceptions(self): |
| 721 | # Raising NotImplementedError or IOError is okay for set_data. |
| 722 | def raise_exception(exc): |
| 723 | def closure(*args, **kwargs): |
| 724 | raise exc |
| 725 | return closure |
| 726 | |
| 727 | self.setUp(magic=b'0000') |
Brett Cannon | 0cf9e6a | 2010-06-28 04:57:24 +0000 | [diff] [blame] | 728 | self.loader.set_data = raise_exception(NotImplementedError) |
| 729 | code_object = self.loader.get_code(self.name) |
| 730 | self.verify_code(code_object) |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 731 | |
Brett Cannon | 418182e | 2010-07-03 22:32:41 +0000 | [diff] [blame] | 732 | |
| 733 | class SourceLoaderGetSourceTests(unittest.TestCase): |
| 734 | |
| 735 | """Tests for importlib.abc.SourceLoader.get_source().""" |
| 736 | |
| 737 | def test_default_encoding(self): |
| 738 | # Should have no problems with UTF-8 text. |
| 739 | name = 'mod' |
| 740 | mock = SourceOnlyLoaderMock('mod.file') |
| 741 | source = 'x = "ü"' |
| 742 | mock.source = source.encode('utf-8') |
| 743 | returned_source = mock.get_source(name) |
| 744 | self.assertEqual(returned_source, source) |
| 745 | |
| 746 | def test_decoded_source(self): |
| 747 | # Decoding should work. |
| 748 | name = 'mod' |
| 749 | mock = SourceOnlyLoaderMock("mod.file") |
| 750 | source = "# coding: Latin-1\nx='ü'" |
| 751 | assert source.encode('latin-1') != source.encode('utf-8') |
| 752 | mock.source = source.encode('latin-1') |
| 753 | returned_source = mock.get_source(name) |
| 754 | self.assertEqual(returned_source, source) |
| 755 | |
| 756 | def test_universal_newlines(self): |
| 757 | # PEP 302 says universal newlines should be used. |
| 758 | name = 'mod' |
| 759 | mock = SourceOnlyLoaderMock('mod.file') |
| 760 | source = "x = 42\r\ny = -13\r\n" |
| 761 | mock.source = source.encode('utf-8') |
| 762 | expect = io.IncrementalNewlineDecoder(None, True).decode(source) |
| 763 | self.assertEqual(mock.get_source(name), expect) |
| 764 | |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 765 | class AbstractMethodImplTests(unittest.TestCase): |
| 766 | |
| 767 | """Test the concrete abstractmethod implementations.""" |
| 768 | |
| 769 | class Loader(abc.Loader): |
| 770 | def load_module(self, fullname): |
| 771 | super().load_module(fullname) |
| 772 | |
| 773 | class Finder(abc.Finder): |
| 774 | def find_module(self, _): |
| 775 | super().find_module(_) |
| 776 | |
| 777 | class ResourceLoader(Loader, abc.ResourceLoader): |
| 778 | def get_data(self, _): |
| 779 | super().get_data(_) |
| 780 | |
| 781 | class InspectLoader(Loader, abc.InspectLoader): |
| 782 | def is_package(self, _): |
| 783 | super().is_package(_) |
| 784 | |
| 785 | def get_code(self, _): |
| 786 | super().get_code(_) |
| 787 | |
| 788 | def get_source(self, _): |
| 789 | super().get_source(_) |
| 790 | |
| 791 | class ExecutionLoader(InspectLoader, abc.ExecutionLoader): |
| 792 | def get_filename(self, _): |
| 793 | super().get_filename(_) |
| 794 | |
| 795 | class SourceLoader(ResourceLoader, ExecutionLoader, abc.SourceLoader): |
| 796 | pass |
| 797 | |
| 798 | class PyLoader(ResourceLoader, InspectLoader, abc.PyLoader): |
| 799 | def source_path(self, _): |
| 800 | super().source_path(_) |
| 801 | |
| 802 | class PyPycLoader(PyLoader, abc.PyPycLoader): |
| 803 | def bytecode_path(self, _): |
| 804 | super().bytecode_path(_) |
| 805 | |
| 806 | def source_mtime(self, _): |
| 807 | super().source_mtime(_) |
| 808 | |
| 809 | def write_bytecode(self, _, _2): |
| 810 | super().write_bytecode(_, _2) |
| 811 | |
| 812 | def raises_NotImplementedError(self, ins, *args): |
| 813 | for method_name in args: |
| 814 | method = getattr(ins, method_name) |
| 815 | arg_count = len(inspect.getfullargspec(method)[0]) - 1 |
| 816 | args = [''] * arg_count |
| 817 | try: |
| 818 | method(*args) |
| 819 | except NotImplementedError: |
| 820 | pass |
| 821 | else: |
| 822 | msg = "{}.{} did not raise NotImplementedError" |
| 823 | self.fail(msg.format(ins.__class__.__name__, method_name)) |
| 824 | |
| 825 | def test_Loader(self): |
| 826 | self.raises_NotImplementedError(self.Loader(), 'load_module') |
| 827 | |
Brett Cannon | 61b1425 | 2010-07-03 21:48:25 +0000 | [diff] [blame] | 828 | # XXX misplaced; should be somewhere else |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 829 | def test_Finder(self): |
| 830 | self.raises_NotImplementedError(self.Finder(), 'find_module') |
| 831 | |
| 832 | def test_ResourceLoader(self): |
| 833 | self.raises_NotImplementedError(self.ResourceLoader(), 'load_module', |
| 834 | 'get_data') |
| 835 | |
| 836 | def test_InspectLoader(self): |
| 837 | self.raises_NotImplementedError(self.InspectLoader(), 'load_module', |
| 838 | 'is_package', 'get_code', 'get_source') |
| 839 | |
| 840 | def test_ExecutionLoader(self): |
| 841 | self.raises_NotImplementedError(self.ExecutionLoader(), 'load_module', |
| 842 | 'is_package', 'get_code', 'get_source', |
| 843 | 'get_filename') |
| 844 | |
| 845 | def test_SourceLoader(self): |
| 846 | ins = self.SourceLoader() |
| 847 | # Required abstractmethods. |
| 848 | self.raises_NotImplementedError(ins, 'get_filename', 'get_data') |
| 849 | # Optional abstractmethods. |
| 850 | self.raises_NotImplementedError(ins,'path_mtime', 'set_data') |
| 851 | |
| 852 | def test_PyLoader(self): |
| 853 | self.raises_NotImplementedError(self.PyLoader(), 'source_path', |
| 854 | 'get_data', 'is_package') |
| 855 | |
| 856 | def test_PyPycLoader(self): |
| 857 | self.raises_NotImplementedError(self.PyPycLoader(), 'source_path', |
| 858 | 'source_mtime', 'bytecode_path', |
| 859 | 'write_bytecode') |
| 860 | |
| 861 | |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 862 | def test_main(): |
| 863 | from test.support import run_unittest |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 864 | run_unittest(PyLoaderTests, PyLoaderCompatTests, |
Brett Cannon | 418182e | 2010-07-03 22:32:41 +0000 | [diff] [blame] | 865 | PyLoaderInterfaceTests, |
Brett Cannon | 6919427 | 2009-07-20 04:23:48 +0000 | [diff] [blame] | 866 | PyPycLoaderTests, PyPycLoaderInterfaceTests, |
| 867 | SkipWritingBytecodeTests, RegeneratedBytecodeTests, |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 868 | BadBytecodeFailureTests, MissingPathsTests, |
| 869 | SourceOnlyLoaderTests, |
| 870 | SourceLoaderBytecodeTests, |
Brett Cannon | 418182e | 2010-07-03 22:32:41 +0000 | [diff] [blame] | 871 | SourceLoaderGetSourceTests, |
Brett Cannon | f23e374 | 2010-06-27 23:57:46 +0000 | [diff] [blame] | 872 | AbstractMethodImplTests) |
Brett Cannon | 2a922ed | 2009-03-09 03:35:50 +0000 | [diff] [blame] | 873 | |
| 874 | |
| 875 | if __name__ == '__main__': |
| 876 | test_main() |