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