From 1865de1c738a1a1ead520fbd38487815e13906e9 Mon Sep 17 00:00:00 2001
From: Campbell Barton <campbell@blender.org>
Date: Thu, 28 Nov 2024 12:04:45 +1100
Subject: [PATCH] Fix #129926: Crash with Python 3.12 & Manta flow

Python 3.12 no longer supports calls to PyImport_AppendInittab
once initialized.

The call was redundant as Blender's `bpy_internal_modules` already
includes the "manta" module.

Resolve by disabling the call when Python's lifecycle isn't being
managed by manta-flow.
---
 extern/mantaflow/helper/pwrapper/registry.cpp | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/extern/mantaflow/helper/pwrapper/registry.cpp b/extern/mantaflow/helper/pwrapper/registry.cpp
index b4206a41dea..3ad7475d0e3 100644
--- a/extern/mantaflow/helper/pwrapper/registry.cpp
+++ b/extern/mantaflow/helper/pwrapper/registry.cpp
@@ -112,7 +112,7 @@ class WrapperRegistry {
                            const std::string &name,
                            Manta::PbArgs &args,
                            Manta::PbClass *parent);
-  void construct(const std::string &scriptname, const vector<string> &args);
+  void construct(bool python_lifecycle, const std::string &scriptname, const vector<string> &args);
   void cleanup();
   void renameObjects();
   void runPreInit(PyObject *name_space);
@@ -566,7 +566,9 @@ PyObject *WrapperRegistry::createPyObject(const string &classname,
 }
 
 // prepare typeinfo and register python module
-void WrapperRegistry::construct(const string &scriptname, const vector<string> &args)
+void WrapperRegistry::construct(const bool python_lifecycle,
+                                const string &scriptname,
+                                const vector<string> &args)
 {
   mScriptName = scriptname;
   this->args = args;
@@ -575,8 +577,15 @@ void WrapperRegistry::construct(const string &scriptname, const vector<string> &
   registerMeta();
   registerDummyTypes();
 
-  // work around for certain gcc versions, cast to char*
-  PyImport_AppendInittab((char *)gDefaultModuleName.c_str(), PyInit_manta_main);
+  // Don't extend the init-tab when Python is already initialized.
+  // Since Python 3.12 this isn't supported and will crash.
+  //
+  // When `python_lifecycle` is false (when manta-flow is embedded), it's the responsibility
+  // of the application embedding this code to include #PyInit_manta_main in the init-tab.
+  if (python_lifecycle) {
+    // work around for certain gcc versions, cast to char*
+    PyImport_AppendInittab((char *)gDefaultModuleName.c_str(), PyInit_manta_main);
+  }
 }
 
 inline PyObject *castPy(PyTypeObject *p)
@@ -711,7 +720,7 @@ void setup(const bool python_lifecycle,
            const std::vector<std::string> &args,
            PyObject *name_space)
 {
-  WrapperRegistry::instance().construct(filename, args);
+  WrapperRegistry::instance().construct(python_lifecycle, filename, args);
   if (python_lifecycle) {
     Py_Initialize();
   }
