[Python-checkins] gh-94808: Add test coverage for PyObject_HasAttrString (#96627)

orsenthil webhook-mailer at python.org
Mon Oct 3 16:37:23 EDT 2022


https://github.com/python/cpython/commit/9302e331c7e2edf1bb42f6b31085408a315195f5
commit: 9302e331c7e2edf1bb42f6b31085408a315195f5
branch: main
author: MonadChains <monadchains at gmail.com>
committer: orsenthil <senthilx at amazon.com>
date: 2022-10-03T13:37:15-07:00
summary:

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

files:
M Lib/test/test_class.py
M Modules/_testcapimodule.c

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 @@ def __delattr__(self, *args):
         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},



More information about the Python-checkins mailing list