@@ -299,7 +299,10 @@ int pythonmod_init(struct module_env* env, int id)
299299 PyImport_AppendInittab (SWIG_name , (void * )SWIG_init );
300300#endif
301301 Py_Initialize ();
302+ #if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION <= 6 )
303+ /* initthreads only for python 3.6 and older */
302304 PyEval_InitThreads ();
305+ #endif
303306 SWIG_init ();
304307 mainthr = PyEval_SaveThread ();
305308 }
@@ -354,6 +357,8 @@ int pythonmod_init(struct module_env* env, int id)
354357 /* TODO: deallocation of pe->... if an error occurs */
355358
356359 if (PyRun_SimpleFile (script_py , pe -> fname ) < 0 ) {
360+ #if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9 )
361+ /* for python before 3.9 */
357362 log_err ("pythonmod: can't parse Python script %s" , pe -> fname );
358363 /* print the error to logs too, run it again */
359364 fseek (script_py , 0 , SEEK_SET );
@@ -369,9 +374,45 @@ int pythonmod_init(struct module_env* env, int id)
369374 /* ignore the NULL return of _node, it is NULL due to the parse failure
370375 * that we are expecting */
371376 (void )PyParser_SimpleParseFile (script_py , pe -> fname , Py_file_input );
377+ #else
378+ /* for python 3.9 and newer */
379+ char * fstr = NULL ;
380+ size_t flen = 0 ;
381+ log_err ("pythonmod: can't parse Python script %s" , pe -> fname );
382+ /* print the error to logs too, run it again */
383+ fseek (script_py , 0 , SEEK_END );
384+ flen = (size_t )ftell (script_py );
385+ fstr = malloc (flen + 1 );
386+ if (!fstr ) {
387+ log_err ("malloc failure to print parse error" );
388+ PyGILState_Release (gil );
389+ fclose (script_py );
390+ return 0 ;
391+ }
392+ fseek (script_py , 0 , SEEK_SET );
393+ if (fread (fstr , flen , 1 , script_py ) < 1 ) {
394+ log_err ("file read failed to print parse error: %s: %s" ,
395+ pe -> fname , strerror (errno ));
396+ PyGILState_Release (gil );
397+ fclose (script_py );
398+ free (fstr );
399+ return 0 ;
400+ }
401+ fstr [flen ] = 0 ;
402+ /* we compile the string, but do not run it, to stop side-effects */
403+ /* ignore the NULL return of _node, it is NULL due to the parse failure
404+ * that we are expecting */
405+ (void )Py_CompileString (fstr , pe -> fname , Py_file_input );
406+ #endif
372407 log_py_err ();
373408 PyGILState_Release (gil );
374409 fclose (script_py );
410+ #if PY_MAJOR_VERSION <= 2 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 9 )
411+ /* no cleanup needed for python before 3.9 */
412+ #else
413+ /* cleanup for python 3.9 and newer */
414+ free (fstr );
415+ #endif
375416 return 0 ;
376417 }
377418#if PY_MAJOR_VERSION < 3
0 commit comments