|
7 | 7 | from test.support import import_helper
|
8 | 8 | from test.support.warnings_helper import check_warnings
|
9 | 9 |
|
| 10 | +_testcapi = import_helper.import_module('_testcapi') |
10 | 11 | _testlimitedcapi = import_helper.import_module('_testlimitedcapi')
|
11 | 12 | NULL = None
|
12 | 13 |
|
@@ -148,7 +149,7 @@ def check_frozen_import(self, import_frozen_module):
|
148 | 149 | try:
|
149 | 150 | self.assertEqual(import_frozen_module('zipimport'), 1)
|
150 | 151 |
|
151 |
| - # import zipimport again |
| 152 | + # import zipimport again |
152 | 153 | self.assertEqual(import_frozen_module('zipimport'), 1)
|
153 | 154 | finally:
|
154 | 155 | sys.modules['zipimport'] = old_zipimport
|
@@ -317,6 +318,59 @@ def test_executecodemoduleobject(self):
|
317 | 318 | # CRASHES execute_code_func(NULL, code, NULL, NULL)
|
318 | 319 | # CRASHES execute_code_func(name, NULL, NULL, NULL)
|
319 | 320 |
|
| 321 | + def check_importmoduleattr(self, importmoduleattr): |
| 322 | + self.assertIs(importmoduleattr('sys', 'argv'), sys.argv) |
| 323 | + self.assertIs(importmoduleattr('types', 'ModuleType'), types.ModuleType) |
| 324 | + |
| 325 | + # module name containing a dot |
| 326 | + attr = importmoduleattr('email.message', 'Message') |
| 327 | + from email.message import Message |
| 328 | + self.assertIs(attr, Message) |
| 329 | + |
| 330 | + with self.assertRaises(ImportError): |
| 331 | + # nonexistent module |
| 332 | + importmoduleattr('nonexistentmodule', 'attr') |
| 333 | + with self.assertRaises(AttributeError): |
| 334 | + # nonexistent attribute |
| 335 | + importmoduleattr('sys', 'nonexistentattr') |
| 336 | + with self.assertRaises(AttributeError): |
| 337 | + # attribute name containing a dot |
| 338 | + importmoduleattr('sys', 'implementation.name') |
| 339 | + |
| 340 | + def test_importmoduleattr(self): |
| 341 | + # Test PyImport_ImportModuleAttr() |
| 342 | + importmoduleattr = _testcapi.PyImport_ImportModuleAttr |
| 343 | + self.check_importmoduleattr(importmoduleattr) |
| 344 | + |
| 345 | + # Invalid module name type |
| 346 | + for mod_name in (object(), 123, b'bytes'): |
| 347 | + with self.subTest(mod_name=mod_name): |
| 348 | + with self.assertRaises(TypeError): |
| 349 | + importmoduleattr(mod_name, "attr") |
| 350 | + |
| 351 | + # Invalid attribute name type |
| 352 | + for attr_name in (object(), 123, b'bytes'): |
| 353 | + with self.subTest(attr_name=attr_name): |
| 354 | + with self.assertRaises(TypeError): |
| 355 | + importmoduleattr("sys", attr_name) |
| 356 | + |
| 357 | + with self.assertRaises(SystemError): |
| 358 | + importmoduleattr(NULL, "argv") |
| 359 | + # CRASHES importmoduleattr("sys", NULL) |
| 360 | + |
| 361 | + def test_importmoduleattrstring(self): |
| 362 | + # Test PyImport_ImportModuleAttrString() |
| 363 | + importmoduleattr = _testcapi.PyImport_ImportModuleAttrString |
| 364 | + self.check_importmoduleattr(importmoduleattr) |
| 365 | + |
| 366 | + with self.assertRaises(UnicodeDecodeError): |
| 367 | + importmoduleattr(b"sys\xff", "argv") |
| 368 | + with self.assertRaises(UnicodeDecodeError): |
| 369 | + importmoduleattr("sys", b"argv\xff") |
| 370 | + |
| 371 | + # CRASHES importmoduleattr(NULL, "argv") |
| 372 | + # CRASHES importmoduleattr("sys", NULL) |
| 373 | + |
320 | 374 | # TODO: test PyImport_GetImporter()
|
321 | 375 | # TODO: test PyImport_ReloadModule()
|
322 | 376 | # TODO: test PyImport_ExtendInittab()
|
|
0 commit comments