@@ -668,6 +668,78 @@ test_import(PyObject *Py_UNUSED(module), PyObject *Py_UNUSED(args))
668
668
}
669
669
670
670
671
+ static void
672
+ gc_collect (void )
673
+ {
674
+ #if defined(PYPY_VERSION )
675
+ PyObject * mod = PyImport_ImportModule ("gc" );
676
+ assert (mod != NULL );
677
+
678
+ PyObject * res = PyObject_CallMethod (mod , "collect" , NULL );
679
+ Py_DECREF (mod );
680
+ assert (res != NULL );
681
+ Py_DECREF (res );
682
+ #else
683
+ PyGC_Collect ();
684
+ #endif
685
+ }
686
+
687
+
688
+ static PyObject *
689
+ test_weakref (PyObject * Py_UNUSED (module ), PyObject * Py_UNUSED (args ))
690
+ {
691
+ // Create a new heap type, create an instance of this type, and delete the
692
+ // type. This object supports weak references.
693
+ PyObject * new_type = PyObject_CallFunction ((PyObject * )& PyType_Type ,
694
+ "s(){}" , "TypeName" );
695
+ if (new_type == NULL ) {
696
+ return NULL ;
697
+ }
698
+ PyObject * obj = PyObject_CallNoArgs (new_type );
699
+ Py_DECREF (new_type );
700
+ if (obj == NULL ) {
701
+ return NULL ;
702
+ }
703
+ Py_ssize_t refcnt = Py_REFCNT (obj );
704
+
705
+ // create a weak reference
706
+ PyObject * weakref = PyWeakref_NewRef (obj , NULL );
707
+ if (weakref == NULL ) {
708
+ return NULL ;
709
+ }
710
+
711
+ // test PyWeakref_GetRef(), reference is alive
712
+ PyObject * ref1 ;
713
+ assert (PyWeakref_GetRef (weakref , & ref1 ) == 0 );
714
+ assert (ref1 == obj );
715
+ assert (Py_REFCNT (obj ) == (refcnt + 1 ));
716
+ Py_DECREF (ref1 );
717
+
718
+ // delete the referenced object
719
+ assert (Py_REFCNT (obj ) == 1 );
720
+ Py_DECREF (obj );
721
+ gc_collect ();
722
+
723
+ // test PyWeakref_GetRef(), reference is dead
724
+ PyObject * ref2 = Py_True ; // marker to check that value was set
725
+ assert (PyWeakref_GetRef (weakref , & ref2 ) == 0 );
726
+ assert (ref2 == NULL );
727
+
728
+ // test PyWeakref_GetRef(), invalid type
729
+ PyObject * invalid_weakref = Py_None ;
730
+ assert (!PyErr_Occurred ());
731
+ PyObject * ref3 = Py_True ; // marker to check that value was set
732
+ assert (PyWeakref_GetRef (invalid_weakref , & ref3 ) == -1 );
733
+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
734
+ assert (ref3 == NULL );
735
+ PyErr_Clear ();
736
+
737
+ Py_DECREF (weakref );
738
+
739
+ Py_RETURN_NONE ;
740
+ }
741
+
742
+
671
743
static struct PyMethodDef methods [] = {
672
744
{"test_object" , test_object , METH_NOARGS , _Py_NULL },
673
745
{"test_py_is" , test_py_is , METH_NOARGS , _Py_NULL },
@@ -687,6 +759,7 @@ static struct PyMethodDef methods[] = {
687
759
#endif
688
760
{"test_api_casts" , test_api_casts , METH_NOARGS , _Py_NULL },
689
761
{"test_import" , test_import , METH_NOARGS , _Py_NULL },
762
+ {"test_weakref" , test_weakref , METH_NOARGS , _Py_NULL },
690
763
{_Py_NULL , _Py_NULL , 0 , _Py_NULL }
691
764
};
692
765
0 commit comments