mirror of
https://github.com/python/cpython.git
synced 2025-12-31 12:33:28 +00:00
gh-128911: Add tests on the PyImport C API (#128915)
* Add Modules/_testlimitedcapi/import.c
* Add Lib/test/test_capi/test_import.py
* Remove _testcapi.check_pyimport_addmodule(): tests already covered
by newly added tests.
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
(cherry picked from commit d95ba9fa11)
This commit is contained in:
parent
dc77f1914d
commit
34ded1a1a1
9 changed files with 635 additions and 72 deletions
322
Lib/test/test_capi/test_import.py
Normal file
322
Lib/test/test_capi/test_import.py
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
import importlib.util
|
||||
import os.path
|
||||
import sys
|
||||
import types
|
||||
import unittest
|
||||
from test.support import os_helper
|
||||
from test.support import import_helper
|
||||
from test.support.warnings_helper import check_warnings
|
||||
|
||||
_testlimitedcapi = import_helper.import_module('_testlimitedcapi')
|
||||
NULL = None
|
||||
|
||||
|
||||
class ImportTests(unittest.TestCase):
|
||||
def test_getmagicnumber(self):
|
||||
# Test PyImport_GetMagicNumber()
|
||||
magic = _testlimitedcapi.PyImport_GetMagicNumber()
|
||||
self.assertEqual(magic,
|
||||
int.from_bytes(importlib.util.MAGIC_NUMBER, 'little'))
|
||||
|
||||
def test_getmagictag(self):
|
||||
# Test PyImport_GetMagicTag()
|
||||
tag = _testlimitedcapi.PyImport_GetMagicTag()
|
||||
self.assertEqual(tag, sys.implementation.cache_tag)
|
||||
|
||||
def test_getmoduledict(self):
|
||||
# Test PyImport_GetModuleDict()
|
||||
modules = _testlimitedcapi.PyImport_GetModuleDict()
|
||||
self.assertIs(modules, sys.modules)
|
||||
|
||||
def check_import_loaded_module(self, import_module):
|
||||
for name in ('os', 'sys', 'test', 'unittest'):
|
||||
with self.subTest(name=name):
|
||||
self.assertIn(name, sys.modules)
|
||||
old_module = sys.modules[name]
|
||||
module = import_module(name)
|
||||
self.assertIsInstance(module, types.ModuleType)
|
||||
self.assertIs(module, old_module)
|
||||
|
||||
def check_import_fresh_module(self, import_module):
|
||||
old_modules = dict(sys.modules)
|
||||
try:
|
||||
for name in ('colorsys', 'math'):
|
||||
with self.subTest(name=name):
|
||||
sys.modules.pop(name, None)
|
||||
module = import_module(name)
|
||||
self.assertIsInstance(module, types.ModuleType)
|
||||
self.assertIs(module, sys.modules[name])
|
||||
self.assertEqual(module.__name__, name)
|
||||
finally:
|
||||
sys.modules.clear()
|
||||
sys.modules.update(old_modules)
|
||||
|
||||
def test_getmodule(self):
|
||||
# Test PyImport_GetModule()
|
||||
getmodule = _testlimitedcapi.PyImport_GetModule
|
||||
self.check_import_loaded_module(getmodule)
|
||||
|
||||
nonexistent = 'nonexistent'
|
||||
self.assertNotIn(nonexistent, sys.modules)
|
||||
self.assertIs(getmodule(nonexistent), KeyError)
|
||||
self.assertIs(getmodule(''), KeyError)
|
||||
self.assertIs(getmodule(object()), KeyError)
|
||||
|
||||
self.assertRaises(TypeError, getmodule, []) # unhashable
|
||||
# CRASHES getmodule(NULL)
|
||||
|
||||
def check_addmodule(self, add_module, accept_nonstr=False):
|
||||
# create a new module
|
||||
names = ['nonexistent']
|
||||
if accept_nonstr:
|
||||
names.append(b'\xff') # non-UTF-8
|
||||
for name in names:
|
||||
with self.subTest(name=name):
|
||||
self.assertNotIn(name, sys.modules)
|
||||
try:
|
||||
module = add_module(name)
|
||||
self.assertIsInstance(module, types.ModuleType)
|
||||
self.assertEqual(module.__name__, name)
|
||||
self.assertIs(module, sys.modules[name])
|
||||
finally:
|
||||
sys.modules.pop(name, None)
|
||||
|
||||
# get an existing module
|
||||
self.check_import_loaded_module(add_module)
|
||||
|
||||
def test_addmoduleobject(self):
|
||||
# Test PyImport_AddModuleObject()
|
||||
addmoduleobject = _testlimitedcapi.PyImport_AddModuleObject
|
||||
self.check_addmodule(addmoduleobject, accept_nonstr=True)
|
||||
|
||||
self.assertRaises(TypeError, addmoduleobject, []) # unhashable
|
||||
# CRASHES addmoduleobject(NULL)
|
||||
|
||||
def test_addmodule(self):
|
||||
# Test PyImport_AddModule()
|
||||
addmodule = _testlimitedcapi.PyImport_AddModule
|
||||
self.check_addmodule(addmodule)
|
||||
|
||||
self.assertRaises(UnicodeDecodeError, addmodule, b'\xff')
|
||||
# CRASHES addmodule(NULL)
|
||||
|
||||
def test_addmoduleref(self):
|
||||
# Test PyImport_AddModuleRef()
|
||||
addmoduleref = _testlimitedcapi.PyImport_AddModuleRef
|
||||
self.check_addmodule(addmoduleref)
|
||||
|
||||
self.assertRaises(UnicodeDecodeError, addmoduleref, b'\xff')
|
||||
# CRASHES addmoduleref(NULL)
|
||||
|
||||
def check_import_func(self, import_module):
|
||||
self.check_import_loaded_module(import_module)
|
||||
self.check_import_fresh_module(import_module)
|
||||
self.assertRaises(ModuleNotFoundError, import_module, 'nonexistent')
|
||||
self.assertRaises(ValueError, import_module, '')
|
||||
|
||||
def test_import(self):
|
||||
# Test PyImport_Import()
|
||||
import_ = _testlimitedcapi.PyImport_Import
|
||||
self.check_import_func(import_)
|
||||
|
||||
self.assertRaises(TypeError, import_, b'os')
|
||||
self.assertRaises(SystemError, import_, NULL)
|
||||
|
||||
def test_importmodule(self):
|
||||
# Test PyImport_ImportModule()
|
||||
importmodule = _testlimitedcapi.PyImport_ImportModule
|
||||
self.check_import_func(importmodule)
|
||||
|
||||
self.assertRaises(UnicodeDecodeError, importmodule, b'\xff')
|
||||
# CRASHES importmodule(NULL)
|
||||
|
||||
def test_importmodulenoblock(self):
|
||||
# Test deprecated PyImport_ImportModuleNoBlock()
|
||||
importmodulenoblock = _testlimitedcapi.PyImport_ImportModuleNoBlock
|
||||
with check_warnings(('', DeprecationWarning)):
|
||||
self.check_import_func(importmodulenoblock)
|
||||
self.assertRaises(UnicodeDecodeError, importmodulenoblock, b'\xff')
|
||||
|
||||
# CRASHES importmodulenoblock(NULL)
|
||||
|
||||
def check_frozen_import(self, import_frozen_module):
|
||||
# Importing a frozen module executes its code, so start by unloading
|
||||
# the module to execute the code in a new (temporary) module.
|
||||
old_zipimport = sys.modules.pop('zipimport')
|
||||
try:
|
||||
self.assertEqual(import_frozen_module('zipimport'), 1)
|
||||
|
||||
# import zipimport again
|
||||
self.assertEqual(import_frozen_module('zipimport'), 1)
|
||||
finally:
|
||||
sys.modules['zipimport'] = old_zipimport
|
||||
|
||||
# not a frozen module
|
||||
self.assertEqual(import_frozen_module('sys'), 0)
|
||||
self.assertEqual(import_frozen_module('nonexistent'), 0)
|
||||
self.assertEqual(import_frozen_module(''), 0)
|
||||
|
||||
def test_importfrozenmodule(self):
|
||||
# Test PyImport_ImportFrozenModule()
|
||||
importfrozenmodule = _testlimitedcapi.PyImport_ImportFrozenModule
|
||||
self.check_frozen_import(importfrozenmodule)
|
||||
|
||||
self.assertRaises(UnicodeDecodeError, importfrozenmodule, b'\xff')
|
||||
# CRASHES importfrozenmodule(NULL)
|
||||
|
||||
def test_importfrozenmoduleobject(self):
|
||||
# Test PyImport_ImportFrozenModuleObject()
|
||||
importfrozenmoduleobject = _testlimitedcapi.PyImport_ImportFrozenModuleObject
|
||||
self.check_frozen_import(importfrozenmoduleobject)
|
||||
self.assertEqual(importfrozenmoduleobject(b'zipimport'), 0)
|
||||
self.assertEqual(importfrozenmoduleobject(NULL), 0)
|
||||
|
||||
def test_importmoduleex(self):
|
||||
# Test PyImport_ImportModuleEx()
|
||||
importmoduleex = _testlimitedcapi.PyImport_ImportModuleEx
|
||||
self.check_import_func(lambda name: importmoduleex(name, NULL, NULL, NULL))
|
||||
|
||||
self.assertRaises(ModuleNotFoundError, importmoduleex, 'nonexistent', NULL, NULL, NULL)
|
||||
self.assertRaises(ValueError, importmoduleex, '', NULL, NULL, NULL)
|
||||
self.assertRaises(UnicodeDecodeError, importmoduleex, b'\xff', NULL, NULL, NULL)
|
||||
# CRASHES importmoduleex(NULL, NULL, NULL, NULL)
|
||||
|
||||
def check_importmodulelevel(self, importmodulelevel):
|
||||
self.check_import_func(lambda name: importmodulelevel(name, NULL, NULL, NULL, 0))
|
||||
|
||||
self.assertRaises(ModuleNotFoundError, importmodulelevel, 'nonexistent', NULL, NULL, NULL, 0)
|
||||
self.assertRaises(ValueError, importmodulelevel, '', NULL, NULL, NULL, 0)
|
||||
|
||||
if __package__:
|
||||
self.assertIs(importmodulelevel('test_import', globals(), NULL, NULL, 1),
|
||||
sys.modules['test.test_capi.test_import'])
|
||||
self.assertIs(importmodulelevel('test_capi', globals(), NULL, NULL, 2),
|
||||
sys.modules['test.test_capi'])
|
||||
self.assertRaises(ValueError, importmodulelevel, 'os', NULL, NULL, NULL, -1)
|
||||
with self.assertWarns(ImportWarning):
|
||||
self.assertRaises(KeyError, importmodulelevel, 'test_import', {}, NULL, NULL, 1)
|
||||
self.assertRaises(TypeError, importmodulelevel, 'test_import', [], NULL, NULL, 1)
|
||||
|
||||
def test_importmodulelevel(self):
|
||||
# Test PyImport_ImportModuleLevel()
|
||||
importmodulelevel = _testlimitedcapi.PyImport_ImportModuleLevel
|
||||
self.check_importmodulelevel(importmodulelevel)
|
||||
|
||||
self.assertRaises(UnicodeDecodeError, importmodulelevel, b'\xff', NULL, NULL, NULL, 0)
|
||||
# CRASHES importmodulelevel(NULL, NULL, NULL, NULL, 0)
|
||||
|
||||
def test_importmodulelevelobject(self):
|
||||
# Test PyImport_ImportModuleLevelObject()
|
||||
importmodulelevel = _testlimitedcapi.PyImport_ImportModuleLevelObject
|
||||
self.check_importmodulelevel(importmodulelevel)
|
||||
|
||||
self.assertRaises(TypeError, importmodulelevel, b'os', NULL, NULL, NULL, 0)
|
||||
self.assertRaises(ValueError, importmodulelevel, NULL, NULL, NULL, NULL, 0)
|
||||
|
||||
def check_executecodemodule(self, execute_code, *args):
|
||||
name = 'test_import_executecode'
|
||||
try:
|
||||
# Create a temporary module where the code will be executed
|
||||
self.assertNotIn(name, sys.modules)
|
||||
module = _testlimitedcapi.PyImport_AddModuleRef(name)
|
||||
self.assertFalse(hasattr(module, 'attr'))
|
||||
|
||||
# Execute the code
|
||||
code = compile('attr = 1', '<test>', 'exec')
|
||||
module2 = execute_code(name, code, *args)
|
||||
self.assertIs(module2, module)
|
||||
|
||||
# Check the function side effects
|
||||
self.assertEqual(module.attr, 1)
|
||||
finally:
|
||||
sys.modules.pop(name, None)
|
||||
return module.__spec__.origin
|
||||
|
||||
def test_executecodemodule(self):
|
||||
# Test PyImport_ExecCodeModule()
|
||||
execcodemodule = _testlimitedcapi.PyImport_ExecCodeModule
|
||||
self.check_executecodemodule(execcodemodule)
|
||||
|
||||
code = compile('attr = 1', '<test>', 'exec')
|
||||
self.assertRaises(UnicodeDecodeError, execcodemodule, b'\xff', code)
|
||||
# CRASHES execcodemodule(NULL, code)
|
||||
# CRASHES execcodemodule(name, NULL)
|
||||
|
||||
def test_executecodemoduleex(self):
|
||||
# Test PyImport_ExecCodeModuleEx()
|
||||
execcodemoduleex = _testlimitedcapi.PyImport_ExecCodeModuleEx
|
||||
|
||||
# Test NULL path (it should not crash)
|
||||
self.check_executecodemodule(execcodemoduleex, NULL)
|
||||
|
||||
# Test non-NULL path
|
||||
pathname = b'pathname'
|
||||
origin = self.check_executecodemodule(execcodemoduleex, pathname)
|
||||
self.assertEqual(origin, os.path.abspath(os.fsdecode(pathname)))
|
||||
|
||||
pathname = os_helper.TESTFN_UNDECODABLE
|
||||
if pathname:
|
||||
origin = self.check_executecodemodule(execcodemoduleex, pathname)
|
||||
self.assertEqual(origin, os.path.abspath(os.fsdecode(pathname)))
|
||||
|
||||
code = compile('attr = 1', '<test>', 'exec')
|
||||
self.assertRaises(UnicodeDecodeError, execcodemoduleex, b'\xff', code, NULL)
|
||||
# CRASHES execcodemoduleex(NULL, code, NULL)
|
||||
# CRASHES execcodemoduleex(name, NULL, NULL)
|
||||
|
||||
def check_executecode_pathnames(self, execute_code_func, object=False):
|
||||
# Test non-NULL pathname and NULL cpathname
|
||||
|
||||
# Test NULL paths (it should not crash)
|
||||
self.check_executecodemodule(execute_code_func, NULL, NULL)
|
||||
|
||||
pathname = 'pathname'
|
||||
origin = self.check_executecodemodule(execute_code_func, pathname, NULL)
|
||||
self.assertEqual(origin, os.path.abspath(os.fsdecode(pathname)))
|
||||
origin = self.check_executecodemodule(execute_code_func, NULL, pathname)
|
||||
if not object:
|
||||
self.assertEqual(origin, os.path.abspath(os.fsdecode(pathname)))
|
||||
|
||||
pathname = os_helper.TESTFN_UNDECODABLE
|
||||
if pathname:
|
||||
if object:
|
||||
pathname = os.fsdecode(pathname)
|
||||
origin = self.check_executecodemodule(execute_code_func, pathname, NULL)
|
||||
self.assertEqual(origin, os.path.abspath(os.fsdecode(pathname)))
|
||||
self.check_executecodemodule(execute_code_func, NULL, pathname)
|
||||
|
||||
# Test NULL pathname and non-NULL cpathname
|
||||
pyc_filename = importlib.util.cache_from_source(__file__)
|
||||
py_filename = importlib.util.source_from_cache(pyc_filename)
|
||||
origin = self.check_executecodemodule(execute_code_func, NULL, pyc_filename)
|
||||
if not object:
|
||||
self.assertEqual(origin, py_filename)
|
||||
|
||||
def test_executecodemodulewithpathnames(self):
|
||||
# Test PyImport_ExecCodeModuleWithPathnames()
|
||||
execute_code_func = _testlimitedcapi.PyImport_ExecCodeModuleWithPathnames
|
||||
self.check_executecode_pathnames(execute_code_func)
|
||||
|
||||
code = compile('attr = 1', '<test>', 'exec')
|
||||
self.assertRaises(UnicodeDecodeError, execute_code_func, b'\xff', code, NULL, NULL)
|
||||
# CRASHES execute_code_func(NULL, code, NULL, NULL)
|
||||
# CRASHES execute_code_func(name, NULL, NULL, NULL)
|
||||
|
||||
def test_executecodemoduleobject(self):
|
||||
# Test PyImport_ExecCodeModuleObject()
|
||||
execute_code_func = _testlimitedcapi.PyImport_ExecCodeModuleObject
|
||||
self.check_executecode_pathnames(execute_code_func, object=True)
|
||||
|
||||
code = compile('attr = 1', '<test>', 'exec')
|
||||
self.assertRaises(TypeError, execute_code_func, [], code, NULL, NULL)
|
||||
# CRASHES execute_code_func(NULL, code, NULL, NULL)
|
||||
# CRASHES execute_code_func(name, NULL, NULL, NULL)
|
||||
|
||||
# TODO: test PyImport_GetImporter()
|
||||
# TODO: test PyImport_ReloadModule()
|
||||
# TODO: test PyImport_ExtendInittab()
|
||||
# PyImport_AppendInittab() is tested by test_embed
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
@ -3330,30 +3330,6 @@ def test_basic_multiple_interpreters_reset_each(self):
|
|||
# * module's global state was initialized, not reset
|
||||
|
||||
|
||||
@cpython_only
|
||||
class CAPITests(unittest.TestCase):
|
||||
def test_pyimport_addmodule(self):
|
||||
# gh-105922: Test PyImport_AddModuleRef(), PyImport_AddModule()
|
||||
# and PyImport_AddModuleObject()
|
||||
_testcapi = import_module("_testcapi")
|
||||
for name in (
|
||||
'sys', # frozen module
|
||||
'test', # package
|
||||
__name__, # package.module
|
||||
):
|
||||
_testcapi.check_pyimport_addmodule(name)
|
||||
|
||||
def test_pyimport_addmodule_create(self):
|
||||
# gh-105922: Test PyImport_AddModuleRef(), create a new module
|
||||
_testcapi = import_module("_testcapi")
|
||||
name = 'dontexist'
|
||||
self.assertNotIn(name, sys.modules)
|
||||
self.addCleanup(unload, name)
|
||||
|
||||
mod = _testcapi.check_pyimport_addmodule(name)
|
||||
self.assertIs(mod, sys.modules[name])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Test needs to be a package, so we can do relative imports.
|
||||
unittest.main()
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@
|
|||
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
|
||||
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c _testinternalcapi/test_lock.c _testinternalcapi/pytime.c _testinternalcapi/set.c _testinternalcapi/test_critical_sections.c
|
||||
@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/complex.c _testcapi/numbers.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyatomic.c _testcapi/run.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/gc.c _testcapi/hash.c _testcapi/time.c _testcapi/bytes.c _testcapi/object.c _testcapi/monitoring.c
|
||||
@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/complex.c _testlimitedcapi/dict.c _testlimitedcapi/float.c _testlimitedcapi/heaptype_relative.c _testlimitedcapi/list.c _testlimitedcapi/long.c _testlimitedcapi/object.c _testlimitedcapi/pyos.c _testlimitedcapi/set.c _testlimitedcapi/sys.c _testlimitedcapi/tuple.c _testlimitedcapi/unicode.c _testlimitedcapi/vectorcall_limited.c
|
||||
@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/complex.c _testlimitedcapi/dict.c _testlimitedcapi/float.c _testlimitedcapi/heaptype_relative.c _testlimitedcapi/import.c _testlimitedcapi/list.c _testlimitedcapi/long.c _testlimitedcapi/object.c _testlimitedcapi/pyos.c _testlimitedcapi/set.c _testlimitedcapi/sys.c _testlimitedcapi/tuple.c _testlimitedcapi/unicode.c _testlimitedcapi/vectorcall_limited.c
|
||||
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
|
||||
@MODULE__TESTCLINIC_LIMITED_TRUE@_testclinic_limited _testclinic_limited.c
|
||||
|
||||
|
|
|
|||
|
|
@ -3081,52 +3081,6 @@ function_set_closure(PyObject *self, PyObject *args)
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
check_pyimport_addmodule(PyObject *self, PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
if (!PyArg_ParseTuple(args, "s", &name)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// test PyImport_AddModuleRef()
|
||||
PyObject *module = PyImport_AddModuleRef(name);
|
||||
if (module == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
assert(PyModule_Check(module));
|
||||
// module is a strong reference
|
||||
|
||||
// test PyImport_AddModule()
|
||||
PyObject *module2 = PyImport_AddModule(name);
|
||||
if (module2 == NULL) {
|
||||
goto error;
|
||||
}
|
||||
assert(PyModule_Check(module2));
|
||||
assert(module2 == module);
|
||||
// module2 is a borrowed ref
|
||||
|
||||
// test PyImport_AddModuleObject()
|
||||
PyObject *name_obj = PyUnicode_FromString(name);
|
||||
if (name_obj == NULL) {
|
||||
goto error;
|
||||
}
|
||||
PyObject *module3 = PyImport_AddModuleObject(name_obj);
|
||||
Py_DECREF(name_obj);
|
||||
if (module3 == NULL) {
|
||||
goto error;
|
||||
}
|
||||
assert(PyModule_Check(module3));
|
||||
assert(module3 == module);
|
||||
// module3 is a borrowed ref
|
||||
|
||||
return module;
|
||||
|
||||
error:
|
||||
Py_DECREF(module);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static PyObject *
|
||||
test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
|
||||
|
|
@ -3526,7 +3480,6 @@ static PyMethodDef TestMethods[] = {
|
|||
{"function_set_kw_defaults", function_set_kw_defaults, METH_VARARGS, NULL},
|
||||
{"function_get_closure", function_get_closure, METH_O, NULL},
|
||||
{"function_set_closure", function_set_closure, METH_VARARGS, NULL},
|
||||
{"check_pyimport_addmodule", check_pyimport_addmodule, METH_VARARGS},
|
||||
{"test_weakref_capi", test_weakref_capi, METH_NOARGS},
|
||||
{"function_set_warning", function_set_warning, METH_NOARGS},
|
||||
{"test_critical_sections", test_critical_sections, METH_NOARGS},
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ PyInit__testlimitedcapi(void)
|
|||
if (_PyTestLimitedCAPI_Init_HeaptypeRelative(mod) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (_PyTestLimitedCAPI_Init_Import(mod) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (_PyTestLimitedCAPI_Init_List(mod) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
306
Modules/_testlimitedcapi/import.c
Normal file
306
Modules/_testlimitedcapi/import.c
Normal file
|
|
@ -0,0 +1,306 @@
|
|||
// Need limited C API version 3.13 for PyImport_AddModuleRef()
|
||||
#include "pyconfig.h" // Py_GIL_DISABLED
|
||||
#if !defined(Py_GIL_DISABLED) && !defined(Py_LIMITED_API)
|
||||
# define Py_LIMITED_API 0x030d0000
|
||||
#endif
|
||||
|
||||
#include "parts.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
/* Test PyImport_GetMagicNumber() */
|
||||
static PyObject *
|
||||
pyimport_getmagicnumber(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
|
||||
{
|
||||
long magic = PyImport_GetMagicNumber();
|
||||
return PyLong_FromLong(magic);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_GetMagicTag() */
|
||||
static PyObject *
|
||||
pyimport_getmagictag(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
|
||||
{
|
||||
const char *tag = PyImport_GetMagicTag();
|
||||
return PyUnicode_FromString(tag);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_GetModuleDict() */
|
||||
static PyObject *
|
||||
pyimport_getmoduledict(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
|
||||
{
|
||||
return Py_XNewRef(PyImport_GetModuleDict());
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_GetModule() */
|
||||
static PyObject *
|
||||
pyimport_getmodule(PyObject *Py_UNUSED(module), PyObject *name)
|
||||
{
|
||||
assert(!PyErr_Occurred());
|
||||
NULLABLE(name);
|
||||
PyObject *module = PyImport_GetModule(name);
|
||||
if (module == NULL && !PyErr_Occurred()) {
|
||||
return Py_NewRef(PyExc_KeyError);
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_AddModuleObject() */
|
||||
static PyObject *
|
||||
pyimport_addmoduleobject(PyObject *Py_UNUSED(module), PyObject *name)
|
||||
{
|
||||
NULLABLE(name);
|
||||
return Py_XNewRef(PyImport_AddModuleObject(name));
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_AddModule() */
|
||||
static PyObject *
|
||||
pyimport_addmodule(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
if (!PyArg_ParseTuple(args, "z#", &name, &size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return Py_XNewRef(PyImport_AddModule(name));
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_AddModuleRef() */
|
||||
static PyObject *
|
||||
pyimport_addmoduleref(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
if (!PyArg_ParseTuple(args, "z#", &name, &size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyImport_AddModuleRef(name);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_Import() */
|
||||
static PyObject *
|
||||
pyimport_import(PyObject *Py_UNUSED(module), PyObject *name)
|
||||
{
|
||||
NULLABLE(name);
|
||||
return PyImport_Import(name);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ImportModule() */
|
||||
static PyObject *
|
||||
pyimport_importmodule(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
if (!PyArg_ParseTuple(args, "z#", &name, &size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return PyImport_ImportModule(name);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ImportModuleNoBlock() */
|
||||
static PyObject *
|
||||
pyimport_importmodulenoblock(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
if (!PyArg_ParseTuple(args, "z#", &name, &size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_Py_COMP_DIAG_PUSH
|
||||
_Py_COMP_DIAG_IGNORE_DEPR_DECLS
|
||||
return PyImport_ImportModuleNoBlock(name);
|
||||
_Py_COMP_DIAG_POP
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ImportModuleEx() */
|
||||
static PyObject *
|
||||
pyimport_importmoduleex(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
PyObject *globals, *locals, *fromlist;
|
||||
if (!PyArg_ParseTuple(args, "z#OOO",
|
||||
&name, &size, &globals, &locals, &fromlist)) {
|
||||
return NULL;
|
||||
}
|
||||
NULLABLE(globals);
|
||||
NULLABLE(locals);
|
||||
NULLABLE(fromlist);
|
||||
|
||||
return PyImport_ImportModuleEx(name, globals, locals, fromlist);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ImportModuleLevel() */
|
||||
static PyObject *
|
||||
pyimport_importmodulelevel(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
PyObject *globals, *locals, *fromlist;
|
||||
int level;
|
||||
if (!PyArg_ParseTuple(args, "z#OOOi",
|
||||
&name, &size, &globals, &locals, &fromlist, &level)) {
|
||||
return NULL;
|
||||
}
|
||||
NULLABLE(globals);
|
||||
NULLABLE(locals);
|
||||
NULLABLE(fromlist);
|
||||
|
||||
return PyImport_ImportModuleLevel(name, globals, locals, fromlist, level);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ImportModuleLevelObject() */
|
||||
static PyObject *
|
||||
pyimport_importmodulelevelobject(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
PyObject *name, *globals, *locals, *fromlist;
|
||||
int level;
|
||||
if (!PyArg_ParseTuple(args, "OOOOi",
|
||||
&name, &globals, &locals, &fromlist, &level)) {
|
||||
return NULL;
|
||||
}
|
||||
NULLABLE(name);
|
||||
NULLABLE(globals);
|
||||
NULLABLE(locals);
|
||||
NULLABLE(fromlist);
|
||||
|
||||
return PyImport_ImportModuleLevelObject(name, globals, locals, fromlist, level);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ImportFrozenModule() */
|
||||
static PyObject *
|
||||
pyimport_importfrozenmodule(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
if (!PyArg_ParseTuple(args, "z#", &name, &size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RETURN_INT(PyImport_ImportFrozenModule(name));
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ImportFrozenModuleObject() */
|
||||
static PyObject *
|
||||
pyimport_importfrozenmoduleobject(PyObject *Py_UNUSED(module), PyObject *name)
|
||||
{
|
||||
NULLABLE(name);
|
||||
RETURN_INT(PyImport_ImportFrozenModuleObject(name));
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ExecCodeModule() */
|
||||
static PyObject *
|
||||
pyimport_executecodemodule(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
PyObject *code;
|
||||
if (!PyArg_ParseTuple(args, "z#O", &name, &size, &code)) {
|
||||
return NULL;
|
||||
}
|
||||
NULLABLE(code);
|
||||
|
||||
return PyImport_ExecCodeModule(name, code);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ExecCodeModuleEx() */
|
||||
static PyObject *
|
||||
pyimport_executecodemoduleex(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
PyObject *code;
|
||||
const char *pathname;
|
||||
if (!PyArg_ParseTuple(args, "z#Oz#", &name, &size, &code, &pathname, &size)) {
|
||||
return NULL;
|
||||
}
|
||||
NULLABLE(code);
|
||||
|
||||
return PyImport_ExecCodeModuleEx(name, code, pathname);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ExecCodeModuleWithPathnames() */
|
||||
static PyObject *
|
||||
pyimport_executecodemodulewithpathnames(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
const char *name;
|
||||
Py_ssize_t size;
|
||||
PyObject *code;
|
||||
const char *pathname;
|
||||
const char *cpathname;
|
||||
if (!PyArg_ParseTuple(args, "z#Oz#z#", &name, &size, &code, &pathname, &size, &cpathname, &size)) {
|
||||
return NULL;
|
||||
}
|
||||
NULLABLE(code);
|
||||
|
||||
return PyImport_ExecCodeModuleWithPathnames(name, code,
|
||||
pathname, cpathname);
|
||||
}
|
||||
|
||||
|
||||
/* Test PyImport_ExecCodeModuleObject() */
|
||||
static PyObject *
|
||||
pyimport_executecodemoduleobject(PyObject *Py_UNUSED(module), PyObject *args)
|
||||
{
|
||||
PyObject *name, *code, *pathname, *cpathname;
|
||||
if (!PyArg_ParseTuple(args, "OOOO", &name, &code, &pathname, &cpathname)) {
|
||||
return NULL;
|
||||
}
|
||||
NULLABLE(name);
|
||||
NULLABLE(code);
|
||||
NULLABLE(pathname);
|
||||
NULLABLE(cpathname);
|
||||
|
||||
return PyImport_ExecCodeModuleObject(name, code, pathname, cpathname);
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef test_methods[] = {
|
||||
{"PyImport_GetMagicNumber", pyimport_getmagicnumber, METH_NOARGS},
|
||||
{"PyImport_GetMagicTag", pyimport_getmagictag, METH_NOARGS},
|
||||
{"PyImport_GetModuleDict", pyimport_getmoduledict, METH_NOARGS},
|
||||
{"PyImport_GetModule", pyimport_getmodule, METH_O},
|
||||
{"PyImport_AddModuleObject", pyimport_addmoduleobject, METH_O},
|
||||
{"PyImport_AddModule", pyimport_addmodule, METH_VARARGS},
|
||||
{"PyImport_AddModuleRef", pyimport_addmoduleref, METH_VARARGS},
|
||||
{"PyImport_Import", pyimport_import, METH_O},
|
||||
{"PyImport_ImportModule", pyimport_importmodule, METH_VARARGS},
|
||||
{"PyImport_ImportModuleNoBlock", pyimport_importmodulenoblock, METH_VARARGS},
|
||||
{"PyImport_ImportModuleEx", pyimport_importmoduleex, METH_VARARGS},
|
||||
{"PyImport_ImportModuleLevel", pyimport_importmodulelevel, METH_VARARGS},
|
||||
{"PyImport_ImportModuleLevelObject", pyimport_importmodulelevelobject, METH_VARARGS},
|
||||
{"PyImport_ImportFrozenModule", pyimport_importfrozenmodule, METH_VARARGS},
|
||||
{"PyImport_ImportFrozenModuleObject", pyimport_importfrozenmoduleobject, METH_O},
|
||||
{"PyImport_ExecCodeModule", pyimport_executecodemodule, METH_VARARGS},
|
||||
{"PyImport_ExecCodeModuleEx", pyimport_executecodemoduleex, METH_VARARGS},
|
||||
{"PyImport_ExecCodeModuleWithPathnames", pyimport_executecodemodulewithpathnames, METH_VARARGS},
|
||||
{"PyImport_ExecCodeModuleObject", pyimport_executecodemoduleobject, METH_VARARGS},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
_PyTestLimitedCAPI_Init_Import(PyObject *module)
|
||||
{
|
||||
return PyModule_AddFunctions(module, test_methods);
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ int _PyTestLimitedCAPI_Init_Complex(PyObject *module);
|
|||
int _PyTestLimitedCAPI_Init_Dict(PyObject *module);
|
||||
int _PyTestLimitedCAPI_Init_Float(PyObject *module);
|
||||
int _PyTestLimitedCAPI_Init_HeaptypeRelative(PyObject *module);
|
||||
int _PyTestLimitedCAPI_Init_Import(PyObject *module);
|
||||
int _PyTestLimitedCAPI_Init_Object(PyObject *module);
|
||||
int _PyTestLimitedCAPI_Init_List(PyObject *module);
|
||||
int _PyTestLimitedCAPI_Init_Long(PyObject *module);
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@
|
|||
<ClCompile Include="..\Modules\_testlimitedcapi\dict.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\float.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\heaptype_relative.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\import.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\list.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\long.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\object.c" />
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
<ClCompile Include="..\Modules\_testlimitedcapi\dict.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\float.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\heaptype_relative.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\import.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\list.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\long.c" />
|
||||
<ClCompile Include="..\Modules\_testlimitedcapi\object.c" />
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue