@@ -3373,17 +3373,23 @@ check_pyimport_addmodule(PyObject *self, PyObject *args)
3373
3373
3374
3374
3375
3375
static PyObject *
3376
- check_weakref_capi (PyObject * self , PyObject * factory )
3376
+ test_weakref_capi (PyObject * Py_UNUSED ( module ) , PyObject * Py_UNUSED ( args ) )
3377
3377
{
3378
- // obj = factory()
3379
- PyObject * obj = PyObject_CallNoArgs (factory );
3378
+ // Create a new heap type, create an instance of this type, and delete the
3379
+ // type. This object supports weak references.
3380
+ PyObject * new_type = PyObject_CallFunction ((PyObject * )& PyType_Type ,
3381
+ "s(){}" , "TypeName" );
3382
+ if (new_type == NULL ) {
3383
+ return NULL ;
3384
+ }
3385
+ PyObject * obj = PyObject_CallNoArgs (new_type );
3386
+ Py_DECREF (new_type );
3380
3387
if (obj == NULL ) {
3381
3388
return NULL ;
3382
3389
}
3383
3390
Py_ssize_t refcnt = Py_REFCNT (obj );
3384
- assert (refcnt == 1 );
3385
3391
3386
- // test PyWeakref_NewRef()
3392
+ // test PyWeakref_NewRef(), reference is alive
3387
3393
PyObject * weakref = PyWeakref_NewRef (obj , NULL );
3388
3394
if (weakref == NULL ) {
3389
3395
Py_DECREF (obj );
@@ -3394,28 +3400,30 @@ check_weakref_capi(PyObject *self, PyObject *factory)
3394
3400
assert (PyWeakref_CheckRefExact (weakref ));
3395
3401
assert (Py_REFCNT (obj ) == refcnt );
3396
3402
3397
- // test PyWeakref_GetRef()
3403
+ // test PyWeakref_GetRef(), reference is alive
3398
3404
PyObject * ref1 ;
3399
3405
assert (PyWeakref_GetRef (weakref , & ref1 ) == 0 );
3400
3406
assert (ref1 == obj );
3401
3407
assert (Py_REFCNT (obj ) == (refcnt + 1 ));
3402
3408
Py_DECREF (ref1 );
3403
3409
3404
- // test PyWeakref_GetObject()
3410
+ // test PyWeakref_GetObject(), reference is alive
3405
3411
PyObject * ref2 = PyWeakref_GetObject (weakref );
3406
3412
assert (ref2 == obj );
3407
- assert (Py_REFCNT (obj ) == refcnt );
3408
3413
3409
- // test PyWeakref_GET_OBJECT()
3414
+ // test PyWeakref_GET_OBJECT(), reference is alive
3410
3415
PyObject * ref3 = PyWeakref_GET_OBJECT (weakref );
3411
3416
assert (ref3 == obj );
3412
- assert (Py_REFCNT (obj ) == refcnt );
3413
3417
3414
- // delete the object
3415
- assert (refcnt == 1 );
3418
+ // delete the referenced object
3419
+ assert (Py_REFCNT ( obj ) == 1 );
3416
3420
Py_DECREF (obj );
3421
+
3422
+ // test PyWeakref_GET_OBJECT(), reference is dead
3417
3423
assert (PyWeakref_GET_OBJECT (weakref ) == Py_None );
3418
- PyObject * ref4 ;
3424
+
3425
+ // test PyWeakref_GetRef(), reference is dead
3426
+ PyObject * ref4 = Py_True ; // marker to check that value was set
3419
3427
assert (PyWeakref_GetRef (weakref , & ref4 ) == 0 );
3420
3428
assert (ref4 == NULL );
3421
3429
@@ -3425,12 +3433,15 @@ check_weakref_capi(PyObject *self, PyObject *factory)
3425
3433
assert (!PyWeakref_CheckRefExact (invalid_weakref ));
3426
3434
assert (!PyWeakref_CheckRefExact (invalid_weakref ));
3427
3435
3436
+ // test PyWeakref_GetRef(), invalid type
3428
3437
assert (!PyErr_Occurred ());
3429
- PyObject * ref5 = factory ; // marker to check that value was set
3438
+ PyObject * ref5 = Py_True ; // marker to check that value was set
3430
3439
assert (PyWeakref_GetRef (invalid_weakref , & ref5 ) == -1 );
3431
3440
assert (PyErr_ExceptionMatches (PyExc_TypeError ));
3432
3441
PyErr_Clear ();
3442
+ assert (ref5 == NULL );
3433
3443
3444
+ // test PyWeakref_GetObject(), invalid type
3434
3445
assert (PyWeakref_GetObject (invalid_weakref ) == NULL );
3435
3446
assert (PyErr_ExceptionMatches (PyExc_SystemError ));
3436
3447
PyErr_Clear ();
@@ -3583,7 +3594,7 @@ static PyMethodDef TestMethods[] = {
3583
3594
{"function_set_kw_defaults" , function_set_kw_defaults , METH_VARARGS , NULL },
3584
3595
{"test_atexit" , test_atexit , METH_NOARGS },
3585
3596
{"check_pyimport_addmodule" , check_pyimport_addmodule , METH_VARARGS },
3586
- {"check_weakref_capi " , check_weakref_capi , METH_O },
3597
+ {"test_weakref_capi " , test_weakref_capi , METH_NOARGS },
3587
3598
{NULL , NULL } /* sentinel */
3588
3599
};
3589
3600
0 commit comments