Skip to content

Commit 9302e33

Browse files
authored
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
1 parent 3a49dbb commit 9302e33

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

Lib/test/test_class.py

+14
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,20 @@ def __delattr__(self, *args):
445445
del testme.cardinal
446446
self.assertCallStack([('__delattr__', (testme, "cardinal"))])
447447

448+
def testHasAttrString(self):
449+
import sys
450+
from test.support import import_helper
451+
_testcapi = import_helper.import_module('_testcapi')
452+
453+
class A:
454+
def __init__(self):
455+
self.attr = 1
456+
457+
a = A()
458+
self.assertEqual(_testcapi.hasattr_string(a, "attr"), True)
459+
self.assertEqual(_testcapi.hasattr_string(a, "noattr"), False)
460+
self.assertEqual(sys.exc_info(), (None, None, None))
461+
448462
def testDel(self):
449463
x = []
450464

Modules/_testcapimodule.c

+26
Original file line numberDiff line numberDiff line change
@@ -4846,6 +4846,31 @@ sequence_setitem(PyObject *self, PyObject *args)
48464846
}
48474847

48484848

4849+
static PyObject *
4850+
hasattr_string(PyObject *self, PyObject* args)
4851+
{
4852+
PyObject* obj;
4853+
PyObject* attr_name;
4854+
4855+
if (!PyArg_UnpackTuple(args, "hasattr_string", 2, 2, &obj, &attr_name)) {
4856+
return NULL;
4857+
}
4858+
4859+
if (!PyUnicode_Check(attr_name)) {
4860+
PyErr_SetString(PyExc_TypeError, "attribute name must a be string");
4861+
return PyErr_Occurred();
4862+
}
4863+
4864+
const char *name_str = PyUnicode_AsUTF8(attr_name);
4865+
if (PyObject_HasAttrString(obj, name_str)) {
4866+
Py_RETURN_TRUE;
4867+
}
4868+
else {
4869+
Py_RETURN_FALSE;
4870+
}
4871+
}
4872+
4873+
48494874
/* Functions for testing C calling conventions (METH_*) are named meth_*,
48504875
* e.g. "meth_varargs" for METH_VARARGS.
48514876
*
@@ -5707,6 +5732,7 @@ static PyMethodDef TestMethods[] = {
57075732
{"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS},
57085733
{"sequence_getitem", sequence_getitem, METH_VARARGS},
57095734
{"sequence_setitem", sequence_setitem, METH_VARARGS},
5735+
{"hasattr_string", hasattr_string, METH_VARARGS},
57105736
{"meth_varargs", meth_varargs, METH_VARARGS},
57115737
{"meth_varargs_keywords", _PyCFunction_CAST(meth_varargs_keywords), METH_VARARGS|METH_KEYWORDS},
57125738
{"meth_o", meth_o, METH_O},

0 commit comments

Comments
 (0)