@@ -3231,6 +3231,86 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
32313231}
32323232
32333233
3234+ static PyObject *
3235+ sys_getattr (PyObject * Py_UNUSED (module ), PyObject * name )
3236+ {
3237+ NULLABLE (name );
3238+ PyObject * result = PySys_GetAttr (name );
3239+ if (result == NULL && PyErr_Occurred ()) {
3240+ return NULL ;
3241+ }
3242+ if (result == NULL ) {
3243+ result = PyExc_AttributeError ;
3244+ Py_INCREF (PyExc_AttributeError );
3245+ }
3246+ return result ;
3247+ }
3248+
3249+ static PyObject *
3250+ sys_getattrstring (PyObject * Py_UNUSED (module ), PyObject * arg )
3251+ {
3252+ const char * name ;
3253+ Py_ssize_t size ;
3254+ if (!PyArg_Parse (arg , "z#" , & name , & size )) {
3255+ return NULL ;
3256+ }
3257+ PyObject * result = PySys_GetAttrString (name );
3258+ if (result == NULL && PyErr_Occurred ()) {
3259+ return NULL ;
3260+ }
3261+ if (result == NULL ) {
3262+ result = PyExc_AttributeError ;
3263+ Py_INCREF (PyExc_AttributeError );
3264+ }
3265+ return result ;
3266+ }
3267+
3268+ static PyObject *
3269+ sys_getoptionalattr (PyObject * Py_UNUSED (module ), PyObject * name )
3270+ {
3271+ PyObject * value = UNINITIALIZED_PTR ;
3272+ NULLABLE (name );
3273+
3274+ switch (PySys_GetOptionalAttr (name , & value )) {
3275+ case -1 :
3276+ assert (value == NULL );
3277+ return NULL ;
3278+ case 0 :
3279+ assert (value == NULL );
3280+ return Py_NewRef (PyExc_AttributeError );
3281+ case 1 :
3282+ return value ;
3283+ default :
3284+ Py_FatalError ("PySys_GetOptionalAttr() returned invalid code" );
3285+ Py_UNREACHABLE ();
3286+ }
3287+ }
3288+
3289+ static PyObject *
3290+ sys_getoptionalattrstring (PyObject * Py_UNUSED (module ), PyObject * arg )
3291+ {
3292+ PyObject * value = UNINITIALIZED_PTR ;
3293+ const char * name ;
3294+ Py_ssize_t size ;
3295+ if (!PyArg_Parse (arg , "z#" , & name , & size )) {
3296+ return NULL ;
3297+ }
3298+
3299+ switch (PySys_GetOptionalAttrString (name , & value )) {
3300+ case -1 :
3301+ assert (value == NULL );
3302+ return NULL ;
3303+ case 0 :
3304+ assert (value == NULL );
3305+ return Py_NewRef (PyExc_AttributeError );
3306+ case 1 :
3307+ return value ;
3308+ default :
3309+ Py_FatalError ("PySys_GetOptionalAttrString() returned invalid code" );
3310+ Py_UNREACHABLE ();
3311+ }
3312+ }
3313+
32343314static PyObject *
32353315sys_getobject (PyObject * Py_UNUSED (module ), PyObject * arg )
32363316{
@@ -3392,6 +3472,10 @@ static PyMethodDef TestMethods[] = {
33923472 {"function_set_kw_defaults" , function_set_kw_defaults , METH_VARARGS , NULL },
33933473 {"check_pyimport_addmodule" , check_pyimport_addmodule , METH_VARARGS },
33943474 {"test_weakref_capi" , test_weakref_capi , METH_NOARGS },
3475+ {"sys_getattr" , sys_getattr , METH_O },
3476+ {"sys_getattrstring" , sys_getattrstring , METH_O },
3477+ {"sys_getoptionalattr" , sys_getoptionalattr , METH_O },
3478+ {"sys_getoptionalattrstring" , sys_getoptionalattrstring , METH_O },
33953479 {"sys_getobject" , sys_getobject , METH_O },
33963480 {"sys_setobject" , sys_setobject , METH_VARARGS },
33973481 {NULL , NULL } /* sentinel */
0 commit comments