diff --git a/src/main/c/jpy_jobj.c b/src/main/c/jpy_jobj.c index d67ff684..cdc571f1 100644 --- a/src/main/c/jpy_jobj.c +++ b/src/main/c/jpy_jobj.c @@ -727,7 +727,8 @@ int JType_InitSlots(JPy_JType* type) typeObj = JTYPE_AS_PYTYPE(type); // This is hacky to make the caller JType_GetType able to call JPy_INCREF regardless if the type was already created, - // but it will cause a ref counting error when this function fails, and we need to remove the type from the registry + // but it will cause a ref counting error when this function fails, and we need to remove the type from the registry. + // The proper ref counting needs to be done in JType_GetType(). // #if defined(JPY_COMPAT_39P) // Py_SET_REFCNT(typeObj, 1); // #else diff --git a/src/main/c/jpy_jtype.c b/src/main/c/jpy_jtype.c index fc0c089f..ab7997be 100644 --- a/src/main/c/jpy_jtype.c +++ b/src/main/c/jpy_jtype.c @@ -179,6 +179,7 @@ JPy_JType* JType_GetType(JNIEnv* jenv, jclass classRef, jboolean resolve) // registered-but-yet-finalized super classes, causing JType_InitSlots to fail for one of them because its super // class is not finalized. When this happens, the affected classes will not be properly resolved. if (JType_InitSuperType(jenv, type, JNI_FALSE) < 0) { + JPy_DIAG_PRINT(JPy_DIAG_F_TYPE, "JType_GetType: error: JType_InitSuperType() failed for javaName=\"%s\"\n", type->javaName); PyDict_DelItem(JPy_Types, typeKey); JPy_DECREF(typeKey); JPy_DECREF(type); @@ -208,6 +209,7 @@ JPy_JType* JType_GetType(JNIEnv* jenv, jclass classRef, jboolean resolve) } JType_AddClassAttribute(jenv, type); + // 'type' will be returned as a new reference. 'typeKey' needs to be released. JPy_DECREF(typeKey); //printf("T5: type->tp_init=%p\n", ((PyTypeObject*)type)->tp_init); @@ -230,24 +232,22 @@ JPy_JType* JType_GetType(JNIEnv* jenv, jclass classRef, jboolean resolve) return NULL; } - JPy_DECREF(typeKey); type = (JPy_JType*) typeValue; + // 'type' will be returned as a new reference. 'typeKey' needs to be released. + JPy_INCREF(type); + JPy_DECREF(typeKey); } JPy_DIAG_PRINT(JPy_DIAG_F_TYPE, "JType_GetType: javaName=\"%s\", found=%d, resolve=%d, resolved=%d, type=%p\n", type->javaName, found, resolve, type->isResolved, type); if (!type->isResolved && resolve) { if (JType_ResolveType(jenv, type) < 0) { + JPy_DECREF(type); return NULL; } } - // Only increment the refcount when the type is found in the registry to guarantee that we return a new reference - if (typeValue != NULL) { - JPy_INCREF(type); - } - - return type; + return type; } /** diff --git a/src/test/python/jpy_gettype_test.py b/src/test/python/jpy_gettype_test.py index a7233526..9370cd37 100644 --- a/src/test/python/jpy_gettype_test.py +++ b/src/test/python/jpy_gettype_test.py @@ -73,7 +73,7 @@ def test_issue_74(self): def test_cyclic_reference(self): """ - Test if delaying resolving super classes doesn't break existing class reference pattern. + Test if delaying resolving super classes breaks existing class reference pattern. """ j_child1_class = jpy.get_type("org.jpy.fixtures.CyclicReferenceChild1") j_child2_class = jpy.get_type("org.jpy.fixtures.CyclicReferenceChild2")