From 048ac14c81776e6b39eff09fbed9221044b0ab5f Mon Sep 17 00:00:00 2001 From: atc93 Date: Wed, 10 Dec 2025 10:31:45 -0500 Subject: [PATCH] Fix for Python 3.13: PyInt to PyLong # PR note: Python 3.13 import fix for `srwlpy` ## What changed - File: `cpp/src/clients/python/srwlpy.cpp` - Function: `ParseDeviceParam` - Replaced the `_PyLong_AsInt` / `PyLong_AsInt` block with a public API call: ```cpp long devIdx = PyLong_AsLong(oDev); if((devIdx == -1) && PyErr_Occurred()) { delete[] parGPUParam; parGPUParam = 0; return; } parGPUParam[1] = (double)devIdx; ``` ## Why - Python 3.13 removed the private symbol `_PyLong_AsInt`, causing `srwlpy.so` to fail at import with `undefined symbol: _PyLong_AsInt`. - `PyLong_AsInt` is not reliably exported in 3.13 builds either; the stable, public API is `PyLong_AsLong` (or `PyLong_AsLongAndOverflow`). - Switching to `PyLong_AsLong` restores compatibility with Python 3.13 and keeps behavior identical for device index parsing. ## Impact - Fixes import/runtime failure on Python 3.13. - No behavior change for earlier Python versions; still converts the device index to a double and assigns it to `parGPUParam[1]`. ## Notes - If a strict 32-bit range check is desired, `PyLong_AsLongAndOverflow` could be used instead; current behavior matches prior code semantics. - Python 3 unified ints as "long"; the Python/C API docs recommend using `PyLong_*` for all integer conversions in Python 3 (see https://docs.python.org/3/c-api/long.html). --- cpp/src/clients/python/srwlpy.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cpp/src/clients/python/srwlpy.cpp b/cpp/src/clients/python/srwlpy.cpp index 03a8e9c9..d9cb018a 100644 --- a/cpp/src/clients/python/srwlpy.cpp +++ b/cpp/src/clients/python/srwlpy.cpp @@ -3515,11 +3515,13 @@ void ParseDeviceParam(PyObject* oDev, double* &parGPUParam) //HG10202021 Convert if(PyLong_Check(oDev)) { parGPUParam = new double[2]; //HG08022024 parGPUParam[0] = 1; //OC: The number of parameters? -#if PY_MAJOR_VERSION >=3 && PY_MINOR_VERSION >= 13 //HG16062025 - parGPUParam[1] = (double)PyLong_AsInt(oDev); -#else - parGPUParam[1] = (double)_PyLong_AsInt(oDev); -#endif + long devIdx = PyLong_AsLong(oDev); // avoid deprecated/private APIs removed in Python 3.13 + if((devIdx == -1) && PyErr_Occurred()) { + delete[] parGPUParam; // propagate failure if conversion failed + parGPUParam = 0; + return; + } + parGPUParam[1] = (double)devIdx; return; } }