50
50
# define ASSERT_REFCNT (expr )
51
51
#endif
52
52
53
+
54
+ static PyObject *
55
+ create_string (const char * str )
56
+ {
57
+ PyObject * obj ;
58
+ #ifdef PYTHON3
59
+ obj = PyUnicode_FromString (str );
60
+ #else
61
+ obj = PyString_FromString (str );
62
+ #endif
63
+ assert (obj != NULL );
64
+ return obj ;
65
+ }
66
+
67
+
53
68
static PyObject *
54
69
test_object (PyObject * Py_UNUSED (module ), PyObject * Py_UNUSED (ignored ))
55
70
{
@@ -930,6 +945,51 @@ test_vectorcall(PyObject *module, PyObject *Py_UNUSED(args))
930
945
}
931
946
932
947
948
+ static PyObject *
949
+ test_getattr (PyObject * Py_UNUSED (module ), PyObject * Py_UNUSED (args ))
950
+ {
951
+ assert (!PyErr_Occurred ());
952
+
953
+ PyObject * obj = PyImport_ImportModule ("sys" );
954
+ if (obj == NULL ) {
955
+ return NULL ;
956
+ }
957
+ PyObject * attr_name ;
958
+ PyObject * value ;
959
+
960
+ // test PyObject_GetOptionalAttr(): attribute exists
961
+ attr_name = create_string ("version" );
962
+ value = Py_True ; // marker value
963
+ assert (PyObject_GetOptionalAttr (obj , attr_name , & value ) == 1 );
964
+ assert (value != NULL );
965
+ Py_DECREF (value );
966
+ Py_DECREF (attr_name );
967
+
968
+ // test PyObject_GetOptionalAttrString(): attribute exists
969
+ value = Py_True ; // marker value
970
+ assert (PyObject_GetOptionalAttrString (obj , "version" , & value ) == 1 );
971
+ assert (value != NULL );
972
+ Py_DECREF (value );
973
+
974
+ // test PyObject_GetOptionalAttr(): attribute doesn't exist
975
+ attr_name = create_string ("nonexistant_attr_name" );
976
+ value = Py_True ; // marker value
977
+ assert (PyObject_GetOptionalAttr (obj , attr_name , & value ) == 0 );
978
+ assert (value == NULL );
979
+ Py_DECREF (attr_name );
980
+ assert (!PyErr_Occurred ());
981
+
982
+ // test PyObject_GetOptionalAttrString(): attribute doesn't exist
983
+ value = Py_True ; // marker value
984
+ assert (PyObject_GetOptionalAttrString (obj , "nonexistant_attr_name" , & value ) == 0 );
985
+ assert (value == NULL );
986
+ assert (!PyErr_Occurred ());
987
+
988
+ Py_DECREF (obj );
989
+ Py_RETURN_NONE ;
990
+ }
991
+
992
+
933
993
static struct PyMethodDef methods [] = {
934
994
{"test_object" , test_object , METH_NOARGS , _Py_NULL },
935
995
{"test_py_is" , test_py_is , METH_NOARGS , _Py_NULL },
@@ -952,6 +1012,7 @@ static struct PyMethodDef methods[] = {
952
1012
{"test_weakref" , test_weakref , METH_NOARGS , _Py_NULL },
953
1013
{"func_varargs" , (PyCFunction )(void * )func_varargs , METH_VARARGS | METH_KEYWORDS , _Py_NULL },
954
1014
{"test_vectorcall" , test_vectorcall , METH_NOARGS , _Py_NULL },
1015
+ {"test_getattr" , test_getattr , METH_NOARGS , _Py_NULL },
955
1016
{_Py_NULL , _Py_NULL , 0 , _Py_NULL }
956
1017
};
957
1018
0 commit comments