From: MonadChains Date: Mon, 3 Oct 2022 20:37:15 +0000 (+0200) Subject: gh-94808: Add test coverage for PyObject_HasAttrString (#96627) X-Git-Tag: v3.12.0a1~299 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9302e331c7e2edf1bb42f6b31085408a315195f5;p=thirdparty%2FPython%2Fcpython.git gh-94808: Add test coverage for PyObject_HasAttrString (#96627) * gh-94808: Add test for HasAttrString * Harmonize to Python C code style guidelines * Add check to verify no exception thrown --- diff --git a/Lib/test/test_class.py b/Lib/test/test_class.py index 91c53b7c894c..61df81b16977 100644 --- a/Lib/test/test_class.py +++ b/Lib/test/test_class.py @@ -445,6 +445,20 @@ class ClassTests(unittest.TestCase): del testme.cardinal self.assertCallStack([('__delattr__', (testme, "cardinal"))]) + def testHasAttrString(self): + import sys + from test.support import import_helper + _testcapi = import_helper.import_module('_testcapi') + + class A: + def __init__(self): + self.attr = 1 + + a = A() + self.assertEqual(_testcapi.hasattr_string(a, "attr"), True) + self.assertEqual(_testcapi.hasattr_string(a, "noattr"), False) + self.assertEqual(sys.exc_info(), (None, None, None)) + def testDel(self): x = [] diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index b8f71d47ed52..3d6535f50be9 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -4846,6 +4846,31 @@ sequence_setitem(PyObject *self, PyObject *args) } +static PyObject * +hasattr_string(PyObject *self, PyObject* args) +{ + PyObject* obj; + PyObject* attr_name; + + if (!PyArg_UnpackTuple(args, "hasattr_string", 2, 2, &obj, &attr_name)) { + return NULL; + } + + if (!PyUnicode_Check(attr_name)) { + PyErr_SetString(PyExc_TypeError, "attribute name must a be string"); + return PyErr_Occurred(); + } + + const char *name_str = PyUnicode_AsUTF8(attr_name); + if (PyObject_HasAttrString(obj, name_str)) { + Py_RETURN_TRUE; + } + else { + Py_RETURN_FALSE; + } +} + + /* Functions for testing C calling conventions (METH_*) are named meth_*, * e.g. "meth_varargs" for METH_VARARGS. * @@ -5707,6 +5732,7 @@ static PyMethodDef TestMethods[] = { {"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS}, {"sequence_getitem", sequence_getitem, METH_VARARGS}, {"sequence_setitem", sequence_setitem, METH_VARARGS}, + {"hasattr_string", hasattr_string, METH_VARARGS}, {"meth_varargs", meth_varargs, METH_VARARGS}, {"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS}, {"meth_o", meth_o, METH_O},