mirror of
https://github.com/python/cpython.git
synced 2025-07-24 03:35:53 +00:00
gh-93649: Move PyFrame C API tests to test_capi (#129512)
* Add Lib/test/test_capi/test_frame.py file. * Move C API tests from test_frame to test_capi.test_frame. * Add Modules/_testcapi/frame.c file. * Move C API tests from _testcapimodule.c to frame.c
This commit is contained in:
parent
22b2d37f42
commit
8b70ff5872
8 changed files with 199 additions and 157 deletions
56
Lib/test/test_capi/test_frame.py
Normal file
56
Lib/test/test_capi/test_frame.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
import sys
|
||||||
|
import unittest
|
||||||
|
from test.support import import_helper
|
||||||
|
|
||||||
|
|
||||||
|
_testcapi = import_helper.import_module('_testcapi')
|
||||||
|
|
||||||
|
|
||||||
|
class FrameTest(unittest.TestCase):
|
||||||
|
def getframe(self):
|
||||||
|
return sys._getframe()
|
||||||
|
|
||||||
|
def test_frame_getters(self):
|
||||||
|
frame = self.getframe()
|
||||||
|
self.assertEqual(frame.f_locals, _testcapi.frame_getlocals(frame))
|
||||||
|
self.assertIs(frame.f_globals, _testcapi.frame_getglobals(frame))
|
||||||
|
self.assertIs(frame.f_builtins, _testcapi.frame_getbuiltins(frame))
|
||||||
|
self.assertEqual(frame.f_lasti, _testcapi.frame_getlasti(frame))
|
||||||
|
|
||||||
|
def test_getvar(self):
|
||||||
|
current_frame = sys._getframe()
|
||||||
|
x = 1
|
||||||
|
self.assertEqual(_testcapi.frame_getvar(current_frame, "x"), 1)
|
||||||
|
self.assertEqual(_testcapi.frame_getvarstring(current_frame, b"x"), 1)
|
||||||
|
with self.assertRaises(NameError):
|
||||||
|
_testcapi.frame_getvar(current_frame, "y")
|
||||||
|
with self.assertRaises(NameError):
|
||||||
|
_testcapi.frame_getvarstring(current_frame, b"y")
|
||||||
|
|
||||||
|
# wrong name type
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
_testcapi.frame_getvar(current_frame, b'x')
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
_testcapi.frame_getvar(current_frame, 123)
|
||||||
|
|
||||||
|
def getgenframe(self):
|
||||||
|
yield sys._getframe()
|
||||||
|
|
||||||
|
def test_frame_get_generator(self):
|
||||||
|
gen = self.getgenframe()
|
||||||
|
frame = next(gen)
|
||||||
|
self.assertIs(gen, _testcapi.frame_getgenerator(frame))
|
||||||
|
|
||||||
|
def test_frame_fback_api(self):
|
||||||
|
"""Test that accessing `f_back` does not cause a segmentation fault on
|
||||||
|
a frame created with `PyFrame_New` (GH-99110)."""
|
||||||
|
def dummy():
|
||||||
|
pass
|
||||||
|
|
||||||
|
frame = _testcapi.frame_new(dummy.__code__, globals(), locals())
|
||||||
|
# The following line should not cause a segmentation fault.
|
||||||
|
self.assertIsNone(frame.f_back)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
|
@ -773,51 +773,6 @@ class TestIncompleteFrameAreInvisible(unittest.TestCase):
|
||||||
self.assertIs(catcher.unraisable.exc_type, TypeError)
|
self.assertIs(catcher.unraisable.exc_type, TypeError)
|
||||||
self.assertIsNone(weak())
|
self.assertIsNone(weak())
|
||||||
|
|
||||||
@unittest.skipIf(_testcapi is None, 'need _testcapi')
|
|
||||||
class TestCAPI(unittest.TestCase):
|
|
||||||
def getframe(self):
|
|
||||||
return sys._getframe()
|
|
||||||
|
|
||||||
def test_frame_getters(self):
|
|
||||||
frame = self.getframe()
|
|
||||||
self.assertEqual(frame.f_locals, _testcapi.frame_getlocals(frame))
|
|
||||||
self.assertIs(frame.f_globals, _testcapi.frame_getglobals(frame))
|
|
||||||
self.assertIs(frame.f_builtins, _testcapi.frame_getbuiltins(frame))
|
|
||||||
self.assertEqual(frame.f_lasti, _testcapi.frame_getlasti(frame))
|
|
||||||
|
|
||||||
def test_getvar(self):
|
|
||||||
current_frame = sys._getframe()
|
|
||||||
x = 1
|
|
||||||
self.assertEqual(_testcapi.frame_getvar(current_frame, "x"), 1)
|
|
||||||
self.assertEqual(_testcapi.frame_getvarstring(current_frame, b"x"), 1)
|
|
||||||
with self.assertRaises(NameError):
|
|
||||||
_testcapi.frame_getvar(current_frame, "y")
|
|
||||||
with self.assertRaises(NameError):
|
|
||||||
_testcapi.frame_getvarstring(current_frame, b"y")
|
|
||||||
|
|
||||||
# wrong name type
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
_testcapi.frame_getvar(current_frame, b'x')
|
|
||||||
with self.assertRaises(TypeError):
|
|
||||||
_testcapi.frame_getvar(current_frame, 123)
|
|
||||||
|
|
||||||
def getgenframe(self):
|
|
||||||
yield sys._getframe()
|
|
||||||
|
|
||||||
def test_frame_get_generator(self):
|
|
||||||
gen = self.getgenframe()
|
|
||||||
frame = next(gen)
|
|
||||||
self.assertIs(gen, _testcapi.frame_getgenerator(frame))
|
|
||||||
|
|
||||||
def test_frame_fback_api(self):
|
|
||||||
"""Test that accessing `f_back` does not cause a segmentation fault on
|
|
||||||
a frame created with `PyFrame_New` (GH-99110)."""
|
|
||||||
def dummy():
|
|
||||||
pass
|
|
||||||
|
|
||||||
frame = _testcapi.frame_new(dummy.__code__, globals(), locals())
|
|
||||||
# The following line should not cause a segmentation fault.
|
|
||||||
self.assertIsNone(frame.f_back)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -162,7 +162,7 @@
|
||||||
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
|
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
|
||||||
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
|
@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__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 _testcapi/config.c _testcapi/import.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 _testcapi/config.c _testcapi/import.c _testcapi/frame.c
|
||||||
@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/codec.c _testlimitedcapi/complex.c _testlimitedcapi/dict.c _testlimitedcapi/eval.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 _testlimitedcapi/version.c _testlimitedcapi/file.c
|
@MODULE__TESTLIMITEDCAPI_TRUE@_testlimitedcapi _testlimitedcapi.c _testlimitedcapi/abstract.c _testlimitedcapi/bytearray.c _testlimitedcapi/bytes.c _testlimitedcapi/codec.c _testlimitedcapi/complex.c _testlimitedcapi/dict.c _testlimitedcapi/eval.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 _testlimitedcapi/version.c _testlimitedcapi/file.c
|
||||||
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
|
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
|
||||||
@MODULE__TESTCLINIC_LIMITED_TRUE@_testclinic_limited _testclinic_limited.c
|
@MODULE__TESTCLINIC_LIMITED_TRUE@_testclinic_limited _testclinic_limited.c
|
||||||
|
|
134
Modules/_testcapi/frame.c
Normal file
134
Modules/_testcapi/frame.c
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
#include "parts.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#include "frameobject.h" // PyFrame_New()
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frame_getlocals(PyObject *self, PyObject *frame)
|
||||||
|
{
|
||||||
|
if (!PyFrame_Check(frame)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return PyFrame_GetLocals((PyFrameObject *)frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frame_getglobals(PyObject *self, PyObject *frame)
|
||||||
|
{
|
||||||
|
if (!PyFrame_Check(frame)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return PyFrame_GetGlobals((PyFrameObject *)frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frame_getgenerator(PyObject *self, PyObject *frame)
|
||||||
|
{
|
||||||
|
if (!PyFrame_Check(frame)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return PyFrame_GetGenerator((PyFrameObject *)frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frame_getbuiltins(PyObject *self, PyObject *frame)
|
||||||
|
{
|
||||||
|
if (!PyFrame_Check(frame)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return PyFrame_GetBuiltins((PyFrameObject *)frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frame_getlasti(PyObject *self, PyObject *frame)
|
||||||
|
{
|
||||||
|
if (!PyFrame_Check(frame)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
int lasti = PyFrame_GetLasti((PyFrameObject *)frame);
|
||||||
|
if (lasti < 0) {
|
||||||
|
assert(lasti == -1);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
return PyLong_FromLong(lasti);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frame_new(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *code, *globals, *locals;
|
||||||
|
if (!PyArg_ParseTuple(args, "OOO", &code, &globals, &locals)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!PyCode_Check(code)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "argument must be a code object");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyThreadState *tstate = PyThreadState_Get();
|
||||||
|
|
||||||
|
return (PyObject *)PyFrame_New(tstate, (PyCodeObject *)code, globals, locals);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frame_getvar(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *frame, *name;
|
||||||
|
if (!PyArg_ParseTuple(args, "OO", &frame, &name)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!PyFrame_Check(frame)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyFrame_GetVar((PyFrameObject *)frame, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
frame_getvarstring(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
PyObject *frame;
|
||||||
|
const char *name;
|
||||||
|
if (!PyArg_ParseTuple(args, "Oy", &frame, &name)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!PyFrame_Check(frame)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyFrame_GetVarString((PyFrameObject *)frame, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PyMethodDef test_methods[] = {
|
||||||
|
{"frame_getlocals", frame_getlocals, METH_O, NULL},
|
||||||
|
{"frame_getglobals", frame_getglobals, METH_O, NULL},
|
||||||
|
{"frame_getgenerator", frame_getgenerator, METH_O, NULL},
|
||||||
|
{"frame_getbuiltins", frame_getbuiltins, METH_O, NULL},
|
||||||
|
{"frame_getlasti", frame_getlasti, METH_O, NULL},
|
||||||
|
{"frame_new", frame_new, METH_VARARGS, NULL},
|
||||||
|
{"frame_getvar", frame_getvar, METH_VARARGS, NULL},
|
||||||
|
{"frame_getvarstring", frame_getvarstring, METH_VARARGS, NULL},
|
||||||
|
{NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
_PyTestCapi_Init_Frame(PyObject *m)
|
||||||
|
{
|
||||||
|
return PyModule_AddFunctions(m, test_methods);
|
||||||
|
}
|
||||||
|
|
|
@ -62,5 +62,6 @@ int _PyTestCapi_Init_Monitoring(PyObject *module);
|
||||||
int _PyTestCapi_Init_Object(PyObject *module);
|
int _PyTestCapi_Init_Object(PyObject *module);
|
||||||
int _PyTestCapi_Init_Config(PyObject *mod);
|
int _PyTestCapi_Init_Config(PyObject *mod);
|
||||||
int _PyTestCapi_Init_Import(PyObject *mod);
|
int _PyTestCapi_Init_Import(PyObject *mod);
|
||||||
|
int _PyTestCapi_Init_Frame(PyObject *mod);
|
||||||
|
|
||||||
#endif // Py_TESTCAPI_PARTS_H
|
#endif // Py_TESTCAPI_PARTS_H
|
||||||
|
|
|
@ -2533,109 +2533,6 @@ test_tstate_capi(PyObject *self, PyObject *Py_UNUSED(args))
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
frame_getlocals(PyObject *self, PyObject *frame)
|
|
||||||
{
|
|
||||||
if (!PyFrame_Check(frame)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return PyFrame_GetLocals((PyFrameObject *)frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
frame_getglobals(PyObject *self, PyObject *frame)
|
|
||||||
{
|
|
||||||
if (!PyFrame_Check(frame)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return PyFrame_GetGlobals((PyFrameObject *)frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
frame_getgenerator(PyObject *self, PyObject *frame)
|
|
||||||
{
|
|
||||||
if (!PyFrame_Check(frame)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return PyFrame_GetGenerator((PyFrameObject *)frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
frame_getbuiltins(PyObject *self, PyObject *frame)
|
|
||||||
{
|
|
||||||
if (!PyFrame_Check(frame)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return PyFrame_GetBuiltins((PyFrameObject *)frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
frame_getlasti(PyObject *self, PyObject *frame)
|
|
||||||
{
|
|
||||||
if (!PyFrame_Check(frame)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int lasti = PyFrame_GetLasti((PyFrameObject *)frame);
|
|
||||||
if (lasti < 0) {
|
|
||||||
assert(lasti == -1);
|
|
||||||
Py_RETURN_NONE;
|
|
||||||
}
|
|
||||||
return PyLong_FromLong(lasti);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
frame_new(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *code, *globals, *locals;
|
|
||||||
if (!PyArg_ParseTuple(args, "OOO", &code, &globals, &locals)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!PyCode_Check(code)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "argument must be a code object");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
PyThreadState *tstate = PyThreadState_Get();
|
|
||||||
|
|
||||||
return (PyObject *)PyFrame_New(tstate, (PyCodeObject *)code, globals, locals);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
test_frame_getvar(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *frame, *name;
|
|
||||||
if (!PyArg_ParseTuple(args, "OO", &frame, &name)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!PyFrame_Check(frame)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PyFrame_GetVar((PyFrameObject *)frame, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
test_frame_getvarstring(PyObject *self, PyObject *args)
|
|
||||||
{
|
|
||||||
PyObject *frame;
|
|
||||||
const char *name;
|
|
||||||
if (!PyArg_ParseTuple(args, "Oy", &frame, &name)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!PyFrame_Check(frame)) {
|
|
||||||
PyErr_SetString(PyExc_TypeError, "argument must be a frame");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PyFrame_GetVarString((PyFrameObject *)frame, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gen_get_code(PyObject *self, PyObject *gen)
|
gen_get_code(PyObject *self, PyObject *gen)
|
||||||
{
|
{
|
||||||
|
@ -3599,14 +3496,6 @@ static PyMethodDef TestMethods[] = {
|
||||||
{"type_get_tp_mro", type_get_tp_mro, METH_O},
|
{"type_get_tp_mro", type_get_tp_mro, METH_O},
|
||||||
{"get_basic_static_type", get_basic_static_type, METH_VARARGS, NULL},
|
{"get_basic_static_type", get_basic_static_type, METH_VARARGS, NULL},
|
||||||
{"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL},
|
{"test_tstate_capi", test_tstate_capi, METH_NOARGS, NULL},
|
||||||
{"frame_getlocals", frame_getlocals, METH_O, NULL},
|
|
||||||
{"frame_getglobals", frame_getglobals, METH_O, NULL},
|
|
||||||
{"frame_getgenerator", frame_getgenerator, METH_O, NULL},
|
|
||||||
{"frame_getbuiltins", frame_getbuiltins, METH_O, NULL},
|
|
||||||
{"frame_getlasti", frame_getlasti, METH_O, NULL},
|
|
||||||
{"frame_new", frame_new, METH_VARARGS, NULL},
|
|
||||||
{"frame_getvar", test_frame_getvar, METH_VARARGS, NULL},
|
|
||||||
{"frame_getvarstring", test_frame_getvarstring, METH_VARARGS, NULL},
|
|
||||||
{"gen_get_code", gen_get_code, METH_O, NULL},
|
{"gen_get_code", gen_get_code, METH_O, NULL},
|
||||||
{"get_feature_macros", get_feature_macros, METH_NOARGS, NULL},
|
{"get_feature_macros", get_feature_macros, METH_NOARGS, NULL},
|
||||||
{"test_code_api", test_code_api, METH_NOARGS, NULL},
|
{"test_code_api", test_code_api, METH_NOARGS, NULL},
|
||||||
|
@ -4404,6 +4293,9 @@ PyInit__testcapi(void)
|
||||||
if (_PyTestCapi_Init_Import(m) < 0) {
|
if (_PyTestCapi_Init_Import(m) < 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (_PyTestCapi_Init_Frame(m) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
PyState_AddModule(m, &_testcapimodule);
|
PyState_AddModule(m, &_testcapimodule);
|
||||||
return m;
|
return m;
|
||||||
|
|
|
@ -128,6 +128,7 @@
|
||||||
<ClCompile Include="..\Modules\_testcapi\monitoring.c" />
|
<ClCompile Include="..\Modules\_testcapi\monitoring.c" />
|
||||||
<ClCompile Include="..\Modules\_testcapi\config.c" />
|
<ClCompile Include="..\Modules\_testcapi\config.c" />
|
||||||
<ClCompile Include="..\Modules\_testcapi\import.c" />
|
<ClCompile Include="..\Modules\_testcapi\import.c" />
|
||||||
|
<ClCompile Include="..\Modules\_testcapi\frame.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\PC\python_nt.rc" />
|
<ResourceCompile Include="..\PC\python_nt.rc" />
|
||||||
|
|
|
@ -117,6 +117,9 @@
|
||||||
<ClCompile Include="..\Modules\_testcapi\import.c">
|
<ClCompile Include="..\Modules\_testcapi\import.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\Modules\_testcapi\frame.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\PC\python_nt.rc">
|
<ResourceCompile Include="..\PC\python_nt.rc">
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue