From 222d048adcb037fcc8a589ab5337a619d8559106 Mon Sep 17 00:00:00 2001 From: Jianfeng Mao <4297243+jmao-denver@users.noreply.github.com> Date: Mon, 23 Sep 2024 10:20:05 -0600 Subject: [PATCH] fix: Make org.jpy.PyLib.getCurrentLocals/Globals work for Python 3.13 (#164) * Made getCurrentLocals/Globals work in py3.13 * Make getting globals/locals thread safe * Add JPy_XINCREF and use it --- src/main/c/jni/org_jpy_PyLib.c | 22 ++++++++++++++++++++-- src/main/c/jpy_module.h | 1 + 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/main/c/jni/org_jpy_PyLib.c b/src/main/c/jni/org_jpy_PyLib.c index 7200c12b..75d6d39b 100644 --- a/src/main/c/jni/org_jpy_PyLib.c +++ b/src/main/c/jni/org_jpy_PyLib.c @@ -521,6 +521,7 @@ PyObject *getMainGlobals() { } pyGlobals = PyModule_GetDict(pyMainModule); // borrowed ref + JPy_INCREF(pyGlobals); return pyGlobals; } @@ -532,7 +533,7 @@ JNIEXPORT jobject JNICALL Java_org_jpy_PyLib_getMainGlobals JPy_BEGIN_GIL_STATE - globals = getMainGlobals(); // borrowed ref + globals = getMainGlobals(); // new ref if (globals == NULL) { goto error; } @@ -543,6 +544,7 @@ JNIEXPORT jobject JNICALL Java_org_jpy_PyLib_getMainGlobals } error: + JPy_XDECREF(globals); JPy_END_GIL_STATE return objectRef; @@ -555,7 +557,13 @@ JNIEXPORT jobject JNICALL Java_org_jpy_PyLib_getCurrentGlobals JPy_BEGIN_GIL_STATE +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION <= 12 globals = PyEval_GetGlobals(); // borrowed ref + JPy_XINCREF(globals); +#else + // See https://peps.python.org/pep-0667 for the change in Python 3.13 + globals = PyEval_GetFrameGlobals(); // new ref +#endif if (globals == NULL) { goto error; @@ -567,6 +575,7 @@ JNIEXPORT jobject JNICALL Java_org_jpy_PyLib_getCurrentGlobals } error: + JPy_XDECREF(globals); JPy_END_GIL_STATE return objectRef; @@ -579,7 +588,14 @@ JNIEXPORT jobject JNICALL Java_org_jpy_PyLib_getCurrentLocals JPy_BEGIN_GIL_STATE +#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION <= 12 locals = PyEval_GetLocals(); // borrowed ref + JPy_XINCREF(locals); +#else + // See https://peps.python.org/pep-0667 for the change in Python 3.13 + locals = PyEval_GetFrameLocals(); // new ref +#endif + if (locals == NULL) { goto error; } @@ -590,6 +606,7 @@ JNIEXPORT jobject JNICALL Java_org_jpy_PyLib_getCurrentLocals } error: + JPy_XDECREF(locals); JPy_END_GIL_STATE return objectRef; @@ -904,7 +921,8 @@ jlong executeInternal(JNIEnv* jenv, jclass jLibClass, jint jStart, jobject jGlob if (jGlobals == NULL) { JPy_DIAG_PRINT(JPy_DIAG_F_EXEC, "Java_org_jpy_PyLib_executeInternal: using main globals\n"); - pyGlobals = getMainGlobals(); + pyGlobals = getMainGlobals(); // new ref + decGlobals = JNI_TRUE; if (pyGlobals == NULL) { PyLib_HandlePythonException(jenv); goto error; diff --git a/src/main/c/jpy_module.h b/src/main/c/jpy_module.h index 1607681f..52c71e77 100644 --- a/src/main/c/jpy_module.h +++ b/src/main/c/jpy_module.h @@ -33,6 +33,7 @@ extern "C" { #if 1 #define JPy_DECREF(x) Py_DECREF(x) #define JPy_INCREF(x) Py_INCREF(x) +#define JPy_XINCREF(x) Py_XINCREF(x) #define JPy_XDECREF(x) Py_XDECREF(x) #else #include "jpy_diag.h"