Skip to content

[3.12] gh-111495: Add more tests on PyEval C APIs (#122789) (#128987) #129023

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions Lib/test/test_capi/test_eval.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import sys
import unittest
from test.support import import_helper

_testcapi = import_helper.import_module('_testcapi')


class Tests(unittest.TestCase):
def test_eval_get_func_name(self):
eval_get_func_name = _testcapi.eval_get_func_name

def function_example(): ...

class A:
def method_example(self): ...

self.assertEqual(eval_get_func_name(function_example),
"function_example")
self.assertEqual(eval_get_func_name(A.method_example),
"method_example")
self.assertEqual(eval_get_func_name(A().method_example),
"method_example")
self.assertEqual(eval_get_func_name(sum), "sum") # c function
self.assertEqual(eval_get_func_name(A), "type")

def test_eval_get_func_desc(self):
eval_get_func_desc = _testcapi.eval_get_func_desc

def function_example(): ...

class A:
def method_example(self): ...

self.assertEqual(eval_get_func_desc(function_example),
"()")
self.assertEqual(eval_get_func_desc(A.method_example),
"()")
self.assertEqual(eval_get_func_desc(A().method_example),
"()")
self.assertEqual(eval_get_func_desc(sum), "()") # c function
self.assertEqual(eval_get_func_desc(A), " object")

def test_eval_getlocals(self):
# Test PyEval_GetLocals()
x = 1
self.assertEqual(_testcapi.eval_getlocals(),
{'self': self,
'x': 1})

y = 2
self.assertEqual(_testcapi.eval_getlocals(),
{'self': self,
'x': 1,
'y': 2})

def test_eval_getglobals(self):
# Test PyEval_GetGlobals()
self.assertEqual(_testcapi.eval_getglobals(),
globals())

def test_eval_getbuiltins(self):
# Test PyEval_GetBuiltins()
self.assertEqual(_testcapi.eval_getbuiltins(),
globals()['__builtins__'])

def test_eval_getframe(self):
# Test PyEval_GetFrame()
self.assertEqual(_testcapi.eval_getframe(),
sys._getframe())

def test_eval_get_recursion_limit(self):
# Test Py_GetRecursionLimit()
self.assertEqual(_testcapi.eval_get_recursion_limit(),
sys.getrecursionlimit())

def test_eval_set_recursion_limit(self):
# Test Py_SetRecursionLimit()
old_limit = sys.getrecursionlimit()
try:
limit = old_limit + 123
_testcapi.eval_set_recursion_limit(limit)
self.assertEqual(sys.getrecursionlimit(), limit)
finally:
sys.setrecursionlimit(old_limit)


if __name__ == "__main__":
unittest.main()
30 changes: 0 additions & 30 deletions Lib/test/test_capi/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,36 +879,6 @@ def __init__(self):
_testcapi.clear_managed_dict(c)
self.assertEqual(c.__dict__, {})

def test_eval_get_func_name(self):
def function_example(): ...

class A:
def method_example(self): ...

self.assertEqual(_testcapi.eval_get_func_name(function_example),
"function_example")
self.assertEqual(_testcapi.eval_get_func_name(A.method_example),
"method_example")
self.assertEqual(_testcapi.eval_get_func_name(A().method_example),
"method_example")
self.assertEqual(_testcapi.eval_get_func_name(sum), "sum") # c function
self.assertEqual(_testcapi.eval_get_func_name(A), "type")

def test_eval_get_func_desc(self):
def function_example(): ...

class A:
def method_example(self): ...

self.assertEqual(_testcapi.eval_get_func_desc(function_example),
"()")
self.assertEqual(_testcapi.eval_get_func_desc(A.method_example),
"()")
self.assertEqual(_testcapi.eval_get_func_desc(A().method_example),
"()")
self.assertEqual(_testcapi.eval_get_func_desc(sum), "()") # c function
self.assertEqual(_testcapi.eval_get_func_desc(A), " object")

def test_function_get_code(self):
import types

Expand Down
2 changes: 1 addition & 1 deletion Modules/Setup.stdlib.in
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c
@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/bytearray.c _testcapi/bytes.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/pytime.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/pyos.c _testcapi/run.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/heaptype_relative.c _testcapi/gc.c _testcapi/sys.c _testcapi/import.c
@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/abstract.c _testcapi/bytearray.c _testcapi/bytes.c _testcapi/unicode.c _testcapi/dict.c _testcapi/set.c _testcapi/list.c _testcapi/tuple.c _testcapi/getargs.c _testcapi/pytime.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/pyos.c _testcapi/run.c _testcapi/file.c _testcapi/codec.c _testcapi/immortal.c _testcapi/heaptype_relative.c _testcapi/gc.c _testcapi/sys.c _testcapi/import.c _testcapi/eval.c
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c

# Some testing modules MUST be built as shared libraries.
Expand Down
74 changes: 74 additions & 0 deletions Modules/_testcapi/eval.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "parts.h"
#include "util.h"

static PyObject *
eval_get_func_name(PyObject *self, PyObject *func)
{
return PyUnicode_FromString(PyEval_GetFuncName(func));
}

static PyObject *
eval_get_func_desc(PyObject *self, PyObject *func)
{
return PyUnicode_FromString(PyEval_GetFuncDesc(func));
}

static PyObject *
eval_getlocals(PyObject *module, PyObject *Py_UNUSED(args))
{
return Py_XNewRef(PyEval_GetLocals());
}

static PyObject *
eval_getglobals(PyObject *module, PyObject *Py_UNUSED(args))
{
return Py_XNewRef(PyEval_GetGlobals());
}

static PyObject *
eval_getbuiltins(PyObject *module, PyObject *Py_UNUSED(args))
{
return Py_XNewRef(PyEval_GetBuiltins());
}

static PyObject *
eval_getframe(PyObject *module, PyObject *Py_UNUSED(args))
{
return Py_XNewRef(PyEval_GetFrame());
}

static PyObject *
eval_get_recursion_limit(PyObject *module, PyObject *Py_UNUSED(args))
{
int limit = Py_GetRecursionLimit();
return PyLong_FromLong(limit);
}

static PyObject *
eval_set_recursion_limit(PyObject *module, PyObject *args)
{
int limit;
if (!PyArg_ParseTuple(args, "i", &limit)) {
return NULL;
}
Py_SetRecursionLimit(limit);
Py_RETURN_NONE;
}

static PyMethodDef test_methods[] = {
{"eval_get_func_name", eval_get_func_name, METH_O, NULL},
{"eval_get_func_desc", eval_get_func_desc, METH_O, NULL},
{"eval_getlocals", eval_getlocals, METH_NOARGS},
{"eval_getglobals", eval_getglobals, METH_NOARGS},
{"eval_getbuiltins", eval_getbuiltins, METH_NOARGS},
{"eval_getframe", eval_getframe, METH_NOARGS},
{"eval_get_recursion_limit", eval_get_recursion_limit, METH_NOARGS},
{"eval_set_recursion_limit", eval_set_recursion_limit, METH_VARARGS},
{NULL},
};

int
_PyTestCapi_Init_Eval(PyObject *m)
{
return PyModule_AddFunctions(m, test_methods);
}
1 change: 1 addition & 0 deletions Modules/_testcapi/parts.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ int _PyTestCapi_Init_Immortal(PyObject *module);
int _PyTestCapi_Init_GC(PyObject *module);
int _PyTestCapi_Init_Sys(PyObject *module);
int _PyTestCapi_Init_Import(PyObject *module);
int _PyTestCapi_Init_Eval(PyObject *module);

#ifdef LIMITED_API_AVAILABLE
int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
Expand Down
17 changes: 3 additions & 14 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2797,18 +2797,6 @@ test_frame_getvarstring(PyObject *self, PyObject *args)
}


static PyObject *
eval_get_func_name(PyObject *self, PyObject *func)
{
return PyUnicode_FromString(PyEval_GetFuncName(func));
}

static PyObject *
eval_get_func_desc(PyObject *self, PyObject *func)
{
return PyUnicode_FromString(PyEval_GetFuncDesc(func));
}

static PyObject *
gen_get_code(PyObject *self, PyObject *gen)
{
Expand Down Expand Up @@ -3361,8 +3349,6 @@ static PyMethodDef TestMethods[] = {
{"frame_new", frame_new, METH_VARARGS, NULL},
{"frame_getvar", test_frame_getvar, METH_VARARGS, NULL},
{"frame_getvarstring", test_frame_getvarstring, METH_VARARGS, NULL},
{"eval_get_func_name", eval_get_func_name, METH_O, NULL},
{"eval_get_func_desc", eval_get_func_desc, METH_O, NULL},
{"gen_get_code", gen_get_code, METH_O, NULL},
{"get_feature_macros", get_feature_macros, METH_NOARGS, NULL},
{"test_code_api", test_code_api, METH_NOARGS, NULL},
Expand Down Expand Up @@ -4074,6 +4060,9 @@ PyInit__testcapi(void)
if (_PyTestCapi_Init_Import(m) < 0) {
return NULL;
}
if (_PyTestCapi_Init_Eval(m) < 0) {
return NULL;
}

#ifndef LIMITED_API_AVAILABLE
PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False);
Expand Down
1 change: 1 addition & 0 deletions PCbuild/_testcapi.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@
<ClCompile Include="..\Modules\_testcapi\immortal.c" />
<ClCompile Include="..\Modules\_testcapi\gc.c" />
<ClCompile Include="..\Modules\_testcapi\run.c" />
<ClCompile Include="..\Modules\_testcapi\eval.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc" />
Expand Down
3 changes: 3 additions & 0 deletions PCbuild/_testcapi.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@
<ClCompile Include="..\Modules\_testcapi\import.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\Modules\_testcapi\eval.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc">
Expand Down
Loading