https://github.com/JDevlieghere updated 
https://github.com/llvm/llvm-project/pull/151761

>From cb8d0d2f28a736c6c4808e73f1f60103ee535478 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jo...@devlieghere.com>
Date: Fri, 1 Aug 2025 12:48:47 -0700
Subject: [PATCH] [lldb] Reimplment PyRun_String using the Python stable C API

Reimplement PyRun_String using Py_CompileString and PyEval_EvalCode,
which are part of the stable C API.

Part of #151617
---
 .../Python/PythonDataObjects.cpp              | 41 ++++++++++++++-----
 .../Python/PythonDataObjects.h                |  7 +++-
 .../Python/PythonDataObjectsTests.cpp         | 22 +++++-----
 3 files changed, 46 insertions(+), 24 deletions(-)

diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp 
b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index 98c9b61c11980..9fe282415459a 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -498,9 +498,7 @@ PythonInteger::CreateStructuredSignedInteger() const {
 
 // PythonBoolean
 
-PythonBoolean::PythonBoolean(bool value) {
-  SetValue(value);
-}
+PythonBoolean::PythonBoolean(bool value) { SetValue(value); }
 
 bool PythonBoolean::Check(PyObject *py_obj) {
   return py_obj ? PyBool_Check(py_obj) : false;
@@ -856,15 +854,15 @@ PythonObject PythonCallable::operator()() {
   return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, 
nullptr));
 }
 
-PythonObject PythonCallable::
-operator()(std::initializer_list<PyObject *> args) {
+PythonObject
+PythonCallable::operator()(std::initializer_list<PyObject *> args) {
   PythonTuple arg_tuple(args);
   return PythonObject(PyRefType::Owned,
                       PyObject_CallObject(m_py_obj, arg_tuple.get()));
 }
 
-PythonObject PythonCallable::
-operator()(std::initializer_list<PythonObject> args) {
+PythonObject
+PythonCallable::operator()(std::initializer_list<PythonObject> args) {
   PythonTuple arg_tuple(args);
   return PythonObject(PyRefType::Owned,
                       PyObject_CallObject(m_py_obj, arg_tuple.get()));
@@ -1424,8 +1422,7 @@ Error PythonScript::Init() {
   auto builtins = PythonModule::BuiltinsModule();
   if (Error error = globals.SetItem("__builtins__", builtins))
     return error;
-  PyObject *o =
-      PyRun_String(script, Py_file_input, globals.get(), globals.get());
+  PyObject *o = RunString(script, Py_file_input, globals.get(), globals.get());
   if (!o)
     return exception();
   Take<PythonObject>(o);
@@ -1469,11 +1466,33 @@ python::runStringMultiLine(const llvm::Twine &string,
                            const PythonDictionary &locals) {
   if (!globals.IsValid() || !locals.IsValid())
     return nullDeref();
-  PyObject *result = PyRun_String(NullTerminated(string), Py_file_input,
-                                  globals.get(), locals.get());
+  PyObject *result = RunString(NullTerminated(string), Py_file_input,
+                               globals.get(), locals.get());
   if (!result)
     return exception();
   return Take<PythonObject>(result);
 }
 
+namespace lldb_private {
+namespace python {
+PyObject *RunString(const char *str, int start, PyObject *globals,
+                    PyObject *locals) {
+  const char *filename = "<string>";
+
+  // Compile the string into a code object.
+  PyObject *code = Py_CompileString(str, filename, start);
+  if (!code)
+    return nullptr;
+
+  // Execute the code object.
+  PyObject *result = PyEval_EvalCode(code, globals, locals);
+
+  // Clean up the code object.
+  Py_DECREF(code);
+
+  return result;
+}
+} // namespace python
+} // namespace lldb_private
+
 #endif
diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h 
b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 88c1bb7e729e7..6a5dd43096363 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -194,8 +194,8 @@ template <typename T, char F> struct PassthroughFormat {
 };
 
 template <> struct PythonFormat<char *> : PassthroughFormat<char *, 's'> {};
-template <> struct PythonFormat<const char *> : 
-    PassthroughFormat<const char *, 's'> {};
+template <>
+struct PythonFormat<const char *> : PassthroughFormat<const char *, 's'> {};
 template <> struct PythonFormat<char> : PassthroughFormat<char, 'b'> {};
 template <>
 struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {};
@@ -780,6 +780,9 @@ class StructuredPythonObject : public 
StructuredData::Generic {
   operator=(const StructuredPythonObject &) = delete;
 };
 
+PyObject *RunString(const char *str, int start, PyObject *globals,
+                    PyObject *locals);
+
 } // namespace python
 } // namespace lldb_private
 
diff --git a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp 
b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
index 2dd92fc00fea1..0d4b04b7a1284 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -632,8 +632,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
   ASSERT_FALSE(error);
 
   {
-    PyObject *o = PyRun_String("lambda x : x", Py_eval_input, globals.get(),
-                               globals.get());
+    PyObject *o =
+        RunString("lambda x : x", Py_eval_input, globals.get(), globals.get());
     ASSERT_FALSE(o == NULL);
     auto lambda = Take<PythonCallable>(o);
     auto arginfo = lambda.GetArgInfo();
@@ -642,8 +642,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
   }
 
   {
-    PyObject *o = PyRun_String("lambda x,y=0: x", Py_eval_input, globals.get(),
-                               globals.get());
+    PyObject *o = RunString("lambda x,y=0: x", Py_eval_input, globals.get(),
+                            globals.get());
     ASSERT_FALSE(o == NULL);
     auto lambda = Take<PythonCallable>(o);
     auto arginfo = lambda.GetArgInfo();
@@ -652,8 +652,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
   }
 
   {
-    PyObject *o = PyRun_String("lambda x,y=0, **kw: x", Py_eval_input,
-                               globals.get(), globals.get());
+    PyObject *o = RunString("lambda x,y=0, **kw: x", Py_eval_input,
+                            globals.get(), globals.get());
     ASSERT_FALSE(o == NULL);
     auto lambda = Take<PythonCallable>(o);
     auto arginfo = lambda.GetArgInfo();
@@ -662,8 +662,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
   }
 
   {
-    PyObject *o = PyRun_String("lambda x,y,*a: x", Py_eval_input, 
globals.get(),
-                               globals.get());
+    PyObject *o = RunString("lambda x,y,*a: x", Py_eval_input, globals.get(),
+                            globals.get());
     ASSERT_FALSE(o == NULL);
     auto lambda = Take<PythonCallable>(o);
     auto arginfo = lambda.GetArgInfo();
@@ -673,8 +673,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
   }
 
   {
-    PyObject *o = PyRun_String("lambda x,y,*a,**kw: x", Py_eval_input,
-                               globals.get(), globals.get());
+    PyObject *o = RunString("lambda x,y,*a,**kw: x", Py_eval_input,
+                            globals.get(), globals.get());
     ASSERT_FALSE(o == NULL);
     auto lambda = Take<PythonCallable>(o);
     auto arginfo = lambda.GetArgInfo();
@@ -713,7 +713,7 @@ class NewStyle(object):
 
 )";
     PyObject *o =
-        PyRun_String(script, Py_file_input, globals.get(), globals.get());
+        RunString(script, Py_file_input, globals.get(), globals.get());
     ASSERT_FALSE(o == NULL);
     Take<PythonObject>(o);
 

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to