Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9302e33

Browse filesBrowse 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
Copy full SHA for 9302e33

File tree

Expand file treeCollapse file tree

2 files changed

+40
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+40
-0
lines changed

‎Lib/test/test_class.py

Copy file name to clipboardExpand all lines: Lib/test/test_class.py
+14Lines changed: 14 additions & 0 deletions
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

Copy file name to clipboardExpand all lines: Modules/_testcapimodule.c
+26Lines changed: 26 additions & 0 deletions
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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.