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