gh-128911: Add PyImport_ImportModuleAttr() function (#128912) · python/cpython@3bebe46

GitHub

@@ -7,6 +7,7 @@

77fromtest.supportimportimport_helper

88fromtest.support.warnings_helperimportcheck_warnings

9910+_testcapi=import_helper.import_module('_testcapi')

1011_testlimitedcapi=import_helper.import_module('_testlimitedcapi')

1112NULL=None

1213@@ -148,7 +149,7 @@ def check_frozen_import(self, import_frozen_module):

148149try:

149150self.assertEqual(import_frozen_module('zipimport'), 1)

150151151-#import zipimport again

152+#import zipimport again

152153self.assertEqual(import_frozen_module('zipimport'), 1)

153154finally:

154155sys.modules['zipimport'] =old_zipimport

@@ -317,6 +318,59 @@ def test_executecodemoduleobject(self):

317318# CRASHES execute_code_func(NULL, code, NULL, NULL)

318319# CRASHES execute_code_func(name, NULL, NULL, NULL)

319320321+defcheck_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+fromemail.messageimportMessage

328+self.assertIs(attr, Message)

329+330+withself.assertRaises(ImportError):

331+# nonexistent module

332+importmoduleattr('nonexistentmodule', 'attr')

333+withself.assertRaises(AttributeError):

334+# nonexistent attribute

335+importmoduleattr('sys', 'nonexistentattr')

336+withself.assertRaises(AttributeError):

337+# attribute name containing a dot

338+importmoduleattr('sys', 'implementation.name')

339+340+deftest_importmoduleattr(self):

341+# Test PyImport_ImportModuleAttr()

342+importmoduleattr=_testcapi.PyImport_ImportModuleAttr

343+self.check_importmoduleattr(importmoduleattr)

344+345+# Invalid module name type

346+formod_namein (object(), 123, b'bytes'):

347+withself.subTest(mod_name=mod_name):

348+withself.assertRaises(TypeError):

349+importmoduleattr(mod_name, "attr")

350+351+# Invalid attribute name type

352+forattr_namein (object(), 123, b'bytes'):

353+withself.subTest(attr_name=attr_name):

354+withself.assertRaises(TypeError):

355+importmoduleattr("sys", attr_name)

356+357+withself.assertRaises(SystemError):

358+importmoduleattr(NULL, "argv")

359+# CRASHES importmoduleattr("sys", NULL)

360+361+deftest_importmoduleattrstring(self):

362+# Test PyImport_ImportModuleAttrString()

363+importmoduleattr=_testcapi.PyImport_ImportModuleAttrString

364+self.check_importmoduleattr(importmoduleattr)

365+366+withself.assertRaises(UnicodeDecodeError):

367+importmoduleattr(b"sys\xff", "argv")

368+withself.assertRaises(UnicodeDecodeError):

369+importmoduleattr("sys", b"argv\xff")

370+371+# CRASHES importmoduleattr(NULL, "argv")

372+# CRASHES importmoduleattr("sys", NULL)

373+320374# TODO: test PyImport_GetImporter()

321375# TODO: test PyImport_ReloadModule()

322376# TODO: test PyImport_ExtendInittab()