@@ -3466,6 +3466,196 @@ test_weakref_capi(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
3466
3466
}
3467
3467
3468
3468
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
+
3469
3659
static PyMethodDef TestMethods [] = {
3470
3660
{"set_errno" , set_errno , METH_VARARGS },
3471
3661
{"test_config" , test_config , METH_NOARGS },
@@ -3611,6 +3801,7 @@ static PyMethodDef TestMethods[] = {
3611
3801
{"test_atexit" , test_atexit , METH_NOARGS },
3612
3802
{"check_pyimport_addmodule" , check_pyimport_addmodule , METH_VARARGS },
3613
3803
{"test_weakref_capi" , test_weakref_capi , METH_NOARGS },
3804
+ {"test_dict_capi" , test_dict_capi , METH_NOARGS },
3614
3805
{NULL , NULL } /* sentinel */
3615
3806
};
3616
3807
0 commit comments