From 16a24406b2c48d5962bce39507528c68b154482e Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 13 May 2026 13:56:37 +0100 Subject: [PATCH] In python extensions, set `pyrenderdoc` global before calling register() --- docs/how/how_python_extension.rst | 2 +- qrenderdoc/Code/pyrenderdoc/PythonContext.cpp | 34 +++++++++---------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/how/how_python_extension.rst b/docs/how/how_python_extension.rst index b32a99863..e6ebbf9e8 100644 --- a/docs/how/how_python_extension.rst +++ b/docs/how/how_python_extension.rst @@ -58,7 +58,7 @@ A python extension when loaded will have a ``register`` function called in its m def register(version, pyrenderdoc): # version is the RenderDoc Major.Minor version as a string, such as "1.2" - # pyrenderdoc is the CaptureContext handle, the same as the global available in the python shell + # pyrenderdoc is the CaptureContext handle, the same as the global available Optionally you can define an ``unregister`` function to be called if the extension is reloaded. This takes no parameters and is simply an opportunity to clean-up or remove anything persistent that shouldn't hang around, before ``register`` is called again. diff --git a/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp b/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp index 954200c11..ac1d44c6f 100644 --- a/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp +++ b/qrenderdoc/Code/pyrenderdoc/PythonContext.cpp @@ -1296,6 +1296,8 @@ QString PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extensi ext = PyImport_ReloadModule(extensions[extension]); } + PyObject *pyctx = PassObjectToPython((rdcstr(TypeName()) + " *").c_str(), &ctx); + // if import succeeded, store this extension module in our map. If import failed, we might have // failed a reimport in which case the original module is still there and valid, so don't // overwrite the value. @@ -1316,6 +1318,19 @@ QString PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extensi redir->extension = extension; PyModule_AddObject(ext, "_renderdoc_internal", ext_context); + + Py_XINCREF(pyctx); + + int pyret = PyModule_AddObject(ext, "pyrenderdoc", pyctx); + + if(pyret != 0) + { + Py_XDECREF(pyctx); + + qCritical() << "Couldn't set pyrenderdoc global in loaded module"; + ret += tr("Couldn't set pyrenderdoc global in loaded module\n"); + ext = NULL; + } } if(ext) @@ -1327,9 +1342,6 @@ QString PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extensi if(register_func) { - PyObject *pyctx = - PassObjectToPython((rdcstr(TypeName()) + " *").c_str(), &ctx); - PyObject *retval = NULL; if(pyctx) { @@ -1351,20 +1363,6 @@ QString PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extensi } Py_XDECREF(retval); - - if(ext) - { - int pyret = PyModule_AddObject(ext, "pyrenderdoc", pyctx); - - if(pyret != 0) - { - qCritical() << "Couldn't set pyrenderdoc global in loaded module"; - ret += tr("Couldn't set pyrenderdoc global in loaded module\n"); - ext = NULL; - } - } - - Py_XDECREF(pyctx); } else { @@ -1378,6 +1376,8 @@ QString PythonContext::LoadExtension(ICaptureContext &ctx, const rdcstr &extensi ext = NULL; } + Py_XDECREF(pyctx); + if(ext) { emit m_ExtensionContext->extensionLoaded(extension);