1616#include < frameobject.h>
1717
1818#if !IS_PRE_PYTHON_3_11
19+ #if !IS_PRE_PYTHON_3_13
20+ # define Py_BUILD_CORE 1
21+ #endif
1922#include < internal/pycore_code.h>
2023#include < internal/pycore_frame.h>
24+ #if !IS_PRE_PYTHON_3_13
25+ # undef Py_BUILD_CORE
26+ #endif
2127#endif
2228
2329namespace csp ::python
@@ -48,7 +54,7 @@ PyNode::~PyNode()
4854void PyNode::init ( PyObjectPtr inputs, PyObjectPtr outputs )
4955{
5056 PyGenObject * pygen = ( PyGenObject * ) m_gen.ptr ();
51-
57+
5258 // call gen first yield to setup locals
5359 call_gen ();
5460
@@ -85,7 +91,11 @@ void PyNode::init( PyObjectPtr inputs, PyObjectPtr outputs )
8591// PY311+ changes
8692#else
8793 _PyInterpreterFrame * frame = ( _PyInterpreterFrame * ) pygen -> gi_iframe;
94+ #if IS_PRE_PYTHON_3_12
8895 PyCodeObject * code = frame -> f_code;
96+ #else
97+ PyPtr<PyCodeObject> code = PyPtr<PyCodeObject>::own ( PyGen_GetCode ( ( PyGenObject * ) pygen ) );
98+ #endif
8999 int localPlusIndex = 0 ;
90100 for ( int stackloc = code -> co_argcount; stackloc < code -> co_nlocalsplus; ++stackloc, ++localPlusIndex )
91101 {
@@ -102,7 +112,7 @@ void PyNode::init( PyObjectPtr inputs, PyObjectPtr outputs )
102112 var = &( ( ( PyCellObject * ) *var ) -> ob_ref );
103113 else if ( kind == CO_FAST_CELL )
104114 continue ;
105- #endif
115+ #endif
106116 // null var indicates a stack slot for a local state variable ( state hasnt initialized yet )
107117 // we can skip those
108118 if ( !*var )
@@ -119,7 +129,7 @@ void PyNode::init( PyObjectPtr inputs, PyObjectPtr outputs )
119129 CSP_ASSERT ( !isInputBasket ( index ) );
120130
121131 m_localVars[ index ] = var;
122- // These vars will be "deleted" from the python stack after start
132+ // These vars will be "deleted" from the python stack after start
123133 continue ;
124134 }
125135
@@ -215,7 +225,7 @@ void PyNode::stop()
215225 if ( this -> rootEngine () -> interrupted () && PyErr_CheckSignals () == -1 )
216226 {
217227 // When an interrupt occurs a KeyboardInterrupt exception is raised in Python, which we need to clear
218- // before calling "close" on the generator. Else, the close method will fail due to the unhandled
228+ // before calling "close" on the generator. Else, the close method will fail due to the unhandled
219229 // exception, and we lose the state of the generator before the "finally" block that calls stop() is executed.
220230 PyErr_Clear ();
221231 }
@@ -230,15 +240,15 @@ PyNode * PyNode::create( PyEngine * pyengine, PyObject * inputs, PyObject * outp
230240 // parse inputs/outputs, create outputs time series, etc
231241 Py_ssize_t numInputs = PyTuple_GET_SIZE ( inputs );
232242 Py_ssize_t numOutputs = PyTuple_GET_SIZE ( outputs );
233-
243+
234244 if ( size_t ( numInputs ) >= InputId::maxId () )
235245 CSP_THROW ( ValueError, " number of inputs exceeds limit of " << InputId::maxBasketElements () );
236246
237247 if ( size_t ( numOutputs ) > OutputId::maxId () )
238248 CSP_THROW ( ValueError, " number of outputs exceeds limit of " << OutputId::maxBasketElements () );
239249
240- return pyengine -> engine () -> createOwnedObject<PyNode>( PyObjectPtr::incref ( gen ),
241- PyObjectPtr::incref ( inputs ),
250+ return pyengine -> engine () -> createOwnedObject<PyNode>( PyObjectPtr::incref ( gen ),
251+ PyObjectPtr::incref ( inputs ),
242252 PyObjectPtr::incref ( outputs ),
243253 NodeDef ( numInputs, numOutputs ) );
244254}
@@ -317,10 +327,10 @@ static PyObject * PyNode_create( PyObject * module, PyObject * args )
317327 PyObject * outputs;
318328 PyObject * gen;
319329
320- if ( !PyArg_ParseTuple ( args, " O!O!O!O!" ,
321- &PyEngine::PyType, &engine,
322- &PyTuple_Type, &inputs,
323- &PyTuple_Type, &outputs,
330+ if ( !PyArg_ParseTuple ( args, " O!O!O!O!" ,
331+ &PyEngine::PyType, &engine,
332+ &PyTuple_Type, &inputs,
333+ &PyTuple_Type, &outputs,
324334 &PyGen_Type, &gen ) )
325335 CSP_THROW ( PythonPassthrough, " " );
326336
0 commit comments