This is an automated email from the ASF dual-hosted git repository.

jimjag pushed a commit to branch AOO50X
in repository https://gitbox.apache.org/repos/asf/openoffice.git

commit b072f66e5cda8678bfd5e7db81d53d8affe43e8c
Author: Jim Jagielski <[email protected]>
AuthorDate: Tue Nov 10 06:21:40 2026 -0500

    pyuno: release the GIL around hasMethod, hasProperty and getMemberNames
    
    When the wrapped object is itself a Python XInvocation, these calls
    re-enter Python on the same thread while the GIL is held: Python 3.14
    aborts and the bundled 3.11 deadlocks. setattr and callable calls
    already release it. Plain attribute lookups now also reset LC_NUMERIC.
    
    (cherry picked from commit 1a90caaf711eb0c8fba10d331504670475957a66)
---
 main/pyuno/source/module/pyuno.cxx | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/main/pyuno/source/module/pyuno.cxx 
b/main/pyuno/source/module/pyuno.cxx
index fb6ff2bd63..a3ae24bfce 100644
--- a/main/pyuno/source/module/pyuno.cxx
+++ b/main/pyuno/source/module/pyuno.cxx
@@ -399,7 +399,12 @@ PyObject *PyUNO_invoke( PyObject *object, const char *name 
, PyObject *args )
             PyUNO* me = (PyUNO*) object;
             OUString attrName = OUString::createFromAscii(name);
             Reference< XIdlMethod > xMethod;
-            if (! me->members->xInvocation->hasMethod (attrName))
+            bool hasMethod = false;
+            {
+                PyThreadDetach antiguard;
+                hasMethod = me->members->xInvocation->hasMethod (attrName);
+            }
+            if (! hasMethod)
             {
                 xMethod = findReflectedMethod( me, attrName, runtime );
                 if (! xMethod.is())
@@ -534,7 +539,15 @@ PyObject* PyUNO_getattr (PyObject* self, PyObject* 
attr_name)
 
         OUString attrName( OUString::createFromAscii( name ) );
         //We need to find out if it's a method...
-        if (me->members->xInvocation->hasMethod (attrName))
+        bool isMethod = false;
+        bool isProperty = false;
+        {
+            PyThreadDetach antiguard;
+            isMethod = me->members->xInvocation->hasMethod (attrName);
+            if (! isMethod)
+                isProperty = me->members->xInvocation->hasProperty (attrName);
+        }
+        if (isMethod)
         {
             //Create a callable object to invoke this...
             PyRef ret = PyUNO_callable_new (
@@ -546,7 +559,7 @@ PyObject* PyUNO_getattr (PyObject* self, PyObject* 
attr_name)
         }
 
         //or a property
-        if (me->members->xInvocation->hasProperty ( attrName))
+        if (isProperty)
         {
             //Return the value of the property
             Any anyRet;
@@ -656,7 +669,10 @@ static PyObject *PyUNO_dir( PyObject *self, PyObject *that 
)
     {
         Reference< XInvocation2 > inv2( me->members->xInvocation, UNO_QUERY );
         if( inv2.is() )
+        {
+            PyThreadDetach antiguard;
             oo_member_list = inv2->getMemberNames ();
+        }
         else
         {
             Runtime runtime;

Reply via email to