@@ -2181,6 +2181,77 @@ test_config(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
21812181#endif
21822182
21832183
2184+ static PyObject *
2185+ test_sys (PyObject * Py_UNUSED (module ), PyObject * Py_UNUSED (args ))
2186+ {
2187+ const char * stdout_str = "stdout" ;
2188+ PyObject * stdout_obj = create_string (stdout_str );
2189+ #if PYTHON3
2190+ PyObject * sys_stdout = PySys_GetObject (stdout_str ); // borrowed ref
2191+ #else
2192+ PyObject * sys_stdout = PySys_GetObject ((char * )stdout_str ); // borrowed ref
2193+ #endif
2194+ const char * nonexistent_str = "nonexistent" ;
2195+ PyObject * nonexistent_obj = create_string (nonexistent_str );
2196+ PyObject * error_obj = PyLong_FromLong (1 );
2197+ PyObject * value ;
2198+
2199+ // get sys.stdout
2200+ value = PySys_GetAttr (stdout_obj );
2201+ assert (value == sys_stdout );
2202+ Py_DECREF (value );
2203+
2204+ value = PySys_GetAttrString (stdout_str );
2205+ assert (value == sys_stdout );
2206+ Py_DECREF (value );
2207+
2208+ value = UNINITIALIZED_OBJ ;
2209+ assert (PySys_GetOptionalAttr (stdout_obj , & value ) == 1 );
2210+ assert (value == sys_stdout );
2211+ Py_DECREF (value );
2212+
2213+ value = UNINITIALIZED_OBJ ;
2214+ assert (PySys_GetOptionalAttrString (stdout_str , & value ) == 1 );
2215+ assert (value == sys_stdout );
2216+ Py_DECREF (value );
2217+
2218+ // non existent attribute
2219+ value = PySys_GetAttr (nonexistent_obj );
2220+ assert (value == NULL );
2221+ assert (PyErr_ExceptionMatches (PyExc_RuntimeError ));
2222+ PyErr_Clear ();
2223+
2224+ value = PySys_GetAttrString (nonexistent_str );
2225+ assert (value == NULL );
2226+ assert (PyErr_ExceptionMatches (PyExc_RuntimeError ));
2227+ PyErr_Clear ();
2228+
2229+ value = UNINITIALIZED_OBJ ;
2230+ assert (PySys_GetOptionalAttr (nonexistent_obj , & value ) == 0 );
2231+ assert (value == NULL );
2232+
2233+ value = UNINITIALIZED_OBJ ;
2234+ assert (PySys_GetOptionalAttrString (nonexistent_str , & value ) == 0 );
2235+ assert (value == NULL );
2236+
2237+ // invalid attribute type
2238+ value = PySys_GetAttr (error_obj );
2239+ assert (value == NULL );
2240+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
2241+ PyErr_Clear ();
2242+
2243+ value = UNINITIALIZED_OBJ ;
2244+ assert (PySys_GetOptionalAttr (error_obj , & value ) == -1 );
2245+ assert (value == NULL );
2246+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
2247+ PyErr_Clear ();
2248+
2249+ Py_DECREF (stdout_obj );
2250+ Py_DECREF (nonexistent_obj );
2251+ Py_RETURN_NONE ;
2252+ }
2253+
2254+
21842255static struct PyMethodDef methods [] = {
21852256 {"test_object" , test_object , METH_NOARGS , _Py_NULL },
21862257 {"test_py_is" , test_py_is , METH_NOARGS , _Py_NULL },
@@ -2232,6 +2303,7 @@ static struct PyMethodDef methods[] = {
22322303#if 0x03090000 <= PY_VERSION_HEX && !defined (PYPY_VERSION )
22332304 {"test_config" , test_config , METH_NOARGS , _Py_NULL },
22342305#endif
2306+ {"test_sys" , test_sys , METH_NOARGS , _Py_NULL },
22352307 {_Py_NULL , _Py_NULL , 0 , _Py_NULL }
22362308};
22372309
0 commit comments