@@ -3464,6 +3464,196 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
34643464}
34653465
34663466
3467+ static PyObject *
3468+ test_dict_capi (PyObject * Py_UNUSED (module ), PyObject * Py_UNUSED (args ))
3469+ {
3470+ assert (!PyErr_Occurred ());
3471+
3472+ PyObject * dict = NULL , * key = NULL , * missing_key = NULL , * value = NULL ;
3473+ PyObject * invalid_key = NULL ;
3474+ int res ;
3475+
3476+ // test PyDict_New()
3477+ dict = PyDict_New ();
3478+ if (dict == NULL ) {
3479+ goto error ;
3480+ }
3481+
3482+ key = PyUnicode_FromString ("key" );
3483+ if (key == NULL ) {
3484+ goto error ;
3485+ }
3486+
3487+ missing_key = PyUnicode_FromString ("missing_key" );
3488+ if (missing_key == NULL ) {
3489+ goto error ;
3490+ }
3491+
3492+ value = PyUnicode_FromString ("value" );
3493+ if (value == NULL ) {
3494+ goto error ;
3495+ }
3496+
3497+ // test PyDict_SetItem()
3498+ Py_ssize_t key_refcnt = Py_REFCNT (key );
3499+ Py_ssize_t value_refcnt = Py_REFCNT (value );
3500+ res = PyDict_SetItem (dict , key , value );
3501+ if (res < 0 ) {
3502+ goto error ;
3503+ }
3504+ assert (res == 0 );
3505+ assert (Py_REFCNT (key ) == (key_refcnt + 1 ));
3506+ assert (Py_REFCNT (value ) == (value_refcnt + 1 ));
3507+
3508+ // test PyDict_SetItemString()
3509+ res = PyDict_SetItemString (dict , "key" , value );
3510+ if (res < 0 ) {
3511+ goto error ;
3512+ }
3513+ assert (res == 0 );
3514+ assert (Py_REFCNT (key ) == (key_refcnt + 1 ));
3515+ assert (Py_REFCNT (value ) == (value_refcnt + 1 ));
3516+
3517+ // test PyDict_Size()
3518+ assert (PyDict_Size (dict ) == 1 );
3519+
3520+ // test PyDict_Contains(), key is present
3521+ assert (PyDict_Contains (dict , key ) == 1 );
3522+
3523+ // test PyDict_GetItem(), key is present
3524+ assert (PyDict_GetItem (dict , key ) == value );
3525+
3526+ // test PyDict_GetItemString(), key is present
3527+ assert (PyDict_GetItemString (dict , "key" ) == value );
3528+
3529+ // test PyDict_GetItemWithError(), key is present
3530+ assert (PyDict_GetItemWithError (dict , key ) == value );
3531+ assert (!PyErr_Occurred ());
3532+
3533+ // test PyDict_GetItemRef(), key is present
3534+ PyObject * get_value = Py_Ellipsis ; // marker value
3535+ assert (PyDict_GetItemRef (dict , key , & get_value ) == 1 );
3536+ assert (get_value == value );
3537+ Py_DECREF (get_value );
3538+
3539+ // test PyDict_GetItemStringRef(), key is present
3540+ get_value = Py_Ellipsis ; // marker value
3541+ assert (PyDict_GetItemStringRef (dict , "key" , & get_value ) == 1 );
3542+ assert (get_value == value );
3543+ Py_DECREF (get_value );
3544+
3545+ // test PyDict_Contains(), missing key
3546+ assert (PyDict_Contains (dict , missing_key ) == 0 );
3547+
3548+ // test PyDict_GetItem(), missing key
3549+ assert (PyDict_GetItem (dict , missing_key ) == NULL );
3550+ assert (!PyErr_Occurred ());
3551+
3552+ // test PyDict_GetItemString(), missing key
3553+ assert (PyDict_GetItemString (dict , "missing_key" ) == NULL );
3554+ assert (!PyErr_Occurred ());
3555+
3556+ // test PyDict_GetItemWithError(), missing key
3557+ assert (PyDict_GetItem (dict , missing_key ) == NULL );
3558+ assert (!PyErr_Occurred ());
3559+
3560+ // test PyDict_GetItemRef(), missing key
3561+ get_value = Py_Ellipsis ; // marker value
3562+ assert (PyDict_GetItemRef (dict , missing_key , & get_value ) == 0 );
3563+ assert (!PyErr_Occurred ());
3564+ assert (get_value == NULL );
3565+
3566+ // test PyDict_GetItemStringRef(), missing key
3567+ get_value = Py_Ellipsis ; // marker value
3568+ assert (PyDict_GetItemStringRef (dict , "missing_key" , & get_value ) == 0 );
3569+ assert (!PyErr_Occurred ());
3570+ assert (get_value == NULL );
3571+
3572+ // test PyDict_GetItem(), invalid dict
3573+ PyObject * invalid_dict = key ; // borrowed reference
3574+ assert (PyDict_GetItem (invalid_dict , key ) == NULL );
3575+ assert (!PyErr_Occurred ());
3576+
3577+ // test PyDict_GetItemWithError(), invalid dict
3578+ assert (PyDict_GetItemWithError (invalid_dict , key ) == NULL );
3579+ assert (PyErr_ExceptionMatches (PyExc_SystemError ));
3580+ PyErr_Clear ();
3581+
3582+ // test PyDict_GetItemRef(), invalid dict
3583+ get_value = Py_Ellipsis ; // marker value
3584+ assert (PyDict_GetItemRef (invalid_dict , key , & get_value ) == -1 );
3585+ assert (PyErr_ExceptionMatches (PyExc_SystemError ));
3586+ PyErr_Clear ();
3587+ assert (get_value == NULL );
3588+
3589+ // test PyDict_GetItemStringRef(), invalid dict
3590+ get_value = Py_Ellipsis ; // marker value
3591+ assert (PyDict_GetItemStringRef (invalid_dict , "key" , & get_value ) == -1 );
3592+ assert (PyErr_ExceptionMatches (PyExc_SystemError ));
3593+ PyErr_Clear ();
3594+ assert (get_value == NULL );
3595+
3596+ invalid_key = PyList_New (0 );
3597+ if (invalid_key == NULL ) {
3598+ goto error ;
3599+ }
3600+
3601+ // test PyDict_Contains(), invalid key
3602+ assert (PyDict_Contains (dict , invalid_key ) == -1 );
3603+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
3604+ PyErr_Clear ();
3605+
3606+ // test PyDict_GetItem(), invalid key
3607+ assert (PyDict_GetItem (dict , invalid_key ) == NULL );
3608+ assert (!PyErr_Occurred ());
3609+
3610+ // test PyDict_GetItemWithError(), invalid key
3611+ assert (PyDict_GetItemWithError (dict , invalid_key ) == NULL );
3612+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
3613+ PyErr_Clear ();
3614+
3615+ // test PyDict_GetItemRef(), invalid key
3616+ get_value = Py_Ellipsis ; // marker value
3617+ assert (PyDict_GetItemRef (dict , invalid_key , & get_value ) == -1 );
3618+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
3619+ PyErr_Clear ();
3620+ assert (get_value == NULL );
3621+
3622+ // test PyDict_DelItem(), key is present
3623+ assert (PyDict_DelItem (dict , key ) == 0 );
3624+ assert (PyDict_Size (dict ) == 0 );
3625+
3626+ // test PyDict_DelItem(), missing key
3627+ assert (PyDict_DelItem (dict , missing_key ) == -1 );
3628+ assert (PyErr_ExceptionMatches (PyExc_KeyError ));
3629+ PyErr_Clear ();
3630+
3631+ // test PyDict_DelItem(), invalid key
3632+ assert (PyDict_DelItem (dict , invalid_key ) == -1 );
3633+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
3634+ PyErr_Clear ();
3635+
3636+ // test PyDict_Clear()
3637+ PyDict_Clear (dict );
3638+
3639+ Py_DECREF (dict );
3640+ Py_DECREF (key );
3641+ Py_DECREF (missing_key );
3642+ Py_DECREF (value );
3643+ Py_DECREF (invalid_key );
3644+
3645+ Py_RETURN_NONE ;
3646+
3647+ error :
3648+ Py_XDECREF (dict );
3649+ Py_XDECREF (key );
3650+ Py_XDECREF (missing_key );
3651+ Py_XDECREF (value );
3652+ Py_XDECREF (invalid_key );
3653+ return NULL ;
3654+ }
3655+
3656+
34673657static PyMethodDef TestMethods [] = {
34683658 {"set_errno" , set_errno , METH_VARARGS },
34693659 {"test_config" , test_config , METH_NOARGS },
@@ -3609,6 +3799,7 @@ static PyMethodDef TestMethods[] = {
36093799 {"function_set_kw_defaults" , function_set_kw_defaults , METH_VARARGS , NULL },
36103800 {"check_pyimport_addmodule" , check_pyimport_addmodule , METH_VARARGS },
36113801 {"test_weakref_capi" , test_weakref_capi , METH_NOARGS },
3802+ {"test_dict_capi" , test_dict_capi , METH_NOARGS },
36123803 {NULL , NULL } /* sentinel */
36133804};
36143805
0 commit comments