@@ -3372,6 +3372,73 @@ check_pyimport_addmodule(PyObject *self, PyObject *args)
3372
3372
}
3373
3373
3374
3374
3375
+ static PyObject *
3376
+ check_weakref_capi (PyObject * self , PyObject * factory )
3377
+ {
3378
+ // obj = factory()
3379
+ PyObject * obj = PyObject_CallNoArgs (factory );
3380
+ if (obj == NULL ) {
3381
+ return NULL ;
3382
+ }
3383
+ Py_ssize_t refcnt = Py_REFCNT (obj );
3384
+ assert (refcnt == 1 );
3385
+
3386
+ // test PyWeakref_GetRef()
3387
+ PyObject * weakref = PyWeakref_NewRef (obj , NULL );
3388
+ if (weakref == NULL ) {
3389
+ Py_DECREF (obj );
3390
+ return NULL ;
3391
+ }
3392
+ assert (PyWeakref_Check (weakref ));
3393
+ assert (PyWeakref_CheckRefExact (weakref ));
3394
+ assert (PyWeakref_CheckRefExact (weakref ));
3395
+ assert (Py_REFCNT (obj ) == refcnt );
3396
+
3397
+ // test PyWeakref_GetRef()
3398
+ PyObject * ref1 ;
3399
+ assert (PyWeakref_GetRef (weakref , & ref1 ) == 0 );
3400
+ assert (ref1 == obj );
3401
+ assert (Py_REFCNT (obj ) == (refcnt + 1 ));
3402
+ Py_DECREF (ref1 );
3403
+
3404
+ // test PyWeakref_GetObject()
3405
+ PyObject * ref2 = PyWeakref_GetObject (weakref );
3406
+ assert (ref2 == obj );
3407
+ assert (Py_REFCNT (obj ) == refcnt );
3408
+
3409
+ // test PyWeakref_GET_OBJECT()
3410
+ PyObject * ref3 = PyWeakref_GET_OBJECT (weakref );
3411
+ assert (ref3 == obj );
3412
+ assert (Py_REFCNT (obj ) == refcnt );
3413
+
3414
+ // delete the object
3415
+ assert (refcnt == 1 );
3416
+ Py_DECREF (obj );
3417
+ assert (PyWeakref_GET_OBJECT (weakref ) == Py_None );
3418
+ PyObject * ref4 ;
3419
+ assert (PyWeakref_GetRef (weakref , & ref4 ) == 0 );
3420
+ assert (ref4 == NULL );
3421
+
3422
+ // None is not a weak reference object
3423
+ PyObject * invalid_weakref = Py_None ;
3424
+ assert (!PyWeakref_Check (invalid_weakref ));
3425
+ assert (!PyWeakref_CheckRefExact (invalid_weakref ));
3426
+ assert (!PyWeakref_CheckRefExact (invalid_weakref ));
3427
+
3428
+ assert (!PyErr_Occurred ());
3429
+ PyObject * ref5 = factory ; // marker to check that value was set
3430
+ assert (PyWeakref_GetRef (invalid_weakref , & ref5 ) == -1 );
3431
+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
3432
+ PyErr_Clear ();
3433
+
3434
+ assert (PyWeakref_GetObject (invalid_weakref ) == NULL );
3435
+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
3436
+ PyErr_Clear ();
3437
+
3438
+ Py_RETURN_NONE ;
3439
+ }
3440
+
3441
+
3375
3442
static PyMethodDef TestMethods [] = {
3376
3443
{"set_errno" , set_errno , METH_VARARGS },
3377
3444
{"test_config" , test_config , METH_NOARGS },
@@ -3516,6 +3583,7 @@ static PyMethodDef TestMethods[] = {
3516
3583
{"function_set_kw_defaults" , function_set_kw_defaults , METH_VARARGS , NULL },
3517
3584
{"test_atexit" , test_atexit , METH_NOARGS },
3518
3585
{"check_pyimport_addmodule" , check_pyimport_addmodule , METH_VARARGS },
3586
+ {"check_weakref_capi" , check_weakref_capi , METH_O },
3519
3587
{NULL , NULL } /* sentinel */
3520
3588
};
3521
3589
0 commit comments