33
33
#define MODULE_NAME_STR STR(MODULE_NAME)
34
34
35
35
// Ignore reference count checks on PyPy
36
- #if !defined( PYPY_VERSION )
36
+ #ifndef PYPY_VERSION
37
37
# define CHECK_REFCNT
38
38
#endif
39
39
@@ -148,7 +148,7 @@ test_py_is(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
148
148
}
149
149
150
150
151
- #if !defined( PYPY_VERSION )
151
+ #ifndef PYPY_VERSION
152
152
static void
153
153
test_frame_getvar (PyFrameObject * frame )
154
154
{
@@ -279,7 +279,7 @@ test_thread_state(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
279
279
PyInterpreterState * interp = PyThreadState_GetInterpreter (tstate );
280
280
assert (interp != _Py_NULL );
281
281
282
- #if !defined( PYPY_VERSION )
282
+ #ifndef PYPY_VERSION
283
283
// test PyThreadState_GetFrame()
284
284
PyFrameObject * frame = PyThreadState_GetFrame (tstate );
285
285
if (frame != _Py_NULL ) {
@@ -293,7 +293,7 @@ test_thread_state(PyObject *Py_UNUSED(module), PyObject* Py_UNUSED(ignored))
293
293
assert (id > 0 );
294
294
#endif
295
295
296
- #if !defined( PYPY_VERSION )
296
+ #ifndef PYPY_VERSION
297
297
// PyThreadState_EnterTracing(), PyThreadState_LeaveTracing()
298
298
PyThreadState_EnterTracing (tstate );
299
299
PyThreadState_LeaveTracing (tstate );
@@ -668,10 +668,90 @@ 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 * ref = Py_True ; // marker to check that value was set
713
+ assert (PyWeakref_GetRef (weakref , & ref ) == 0 );
714
+ assert (ref == obj );
715
+ assert (Py_REFCNT (obj ) == (refcnt + 1 ));
716
+ Py_DECREF (ref );
717
+
718
+ // delete the referenced object: clear the weakref
719
+ Py_DECREF (obj );
720
+ gc_collect ();
721
+
722
+ // test PyWeakref_GetRef(), reference is dead
723
+ ref = Py_True ;
724
+ assert (PyWeakref_GetRef (weakref , & ref ) == 0 );
725
+ assert (ref == NULL );
726
+
727
+ // test PyWeakref_GetRef(), invalid type
728
+ PyObject * invalid_weakref = Py_None ;
729
+ assert (!PyErr_Occurred ());
730
+ ref = Py_True ;
731
+ assert (PyWeakref_GetRef (invalid_weakref , & ref ) == -1 );
732
+ assert (PyErr_ExceptionMatches (PyExc_TypeError ));
733
+ assert (ref == NULL );
734
+ PyErr_Clear ();
735
+
736
+ #ifndef PYPY_VERSION
737
+ // test PyWeakref_GetRef(NULL)
738
+ ref = Py_True ;
739
+ assert (PyWeakref_GetRef (NULL , & ref ) == -1 );
740
+ assert (PyErr_ExceptionMatches (PyExc_SystemError ));
741
+ assert (ref == NULL );
742
+ PyErr_Clear ();
743
+ #endif
744
+
745
+ Py_DECREF (weakref );
746
+
747
+ Py_RETURN_NONE ;
748
+ }
749
+
750
+
671
751
static struct PyMethodDef methods [] = {
672
752
{"test_object" , test_object , METH_NOARGS , _Py_NULL },
673
753
{"test_py_is" , test_py_is , METH_NOARGS , _Py_NULL },
674
- #if ! defined ( PYPY_VERSION )
754
+ #ifndef PYPY_VERSION
675
755
{"test_frame" , test_frame , METH_NOARGS , _Py_NULL },
676
756
#endif
677
757
{"test_thread_state" , test_thread_state , METH_NOARGS , _Py_NULL },
@@ -682,11 +762,12 @@ static struct PyMethodDef methods[] = {
682
762
#if (PY_VERSION_HEX <= 0x030B00A1 || 0x030B00A7 <= PY_VERSION_HEX ) && !defined (PYPY_VERSION )
683
763
{"test_float_pack" , test_float_pack , METH_NOARGS , _Py_NULL },
684
764
#endif
685
- #if ! defined ( PYPY_VERSION )
765
+ #ifndef PYPY_VERSION
686
766
{"test_code" , test_code , METH_NOARGS , _Py_NULL },
687
767
#endif
688
768
{"test_api_casts" , test_api_casts , METH_NOARGS , _Py_NULL },
689
769
{"test_import" , test_import , METH_NOARGS , _Py_NULL },
770
+ {"test_weakref" , test_weakref , METH_NOARGS , _Py_NULL },
690
771
{_Py_NULL , _Py_NULL , 0 , _Py_NULL }
691
772
};
692
773
0 commit comments