Skip to content

Commit af0788c

Browse files
committed
Revert "[lldb] Make Python >= 3.8 required for LLDB 21 (llvm#124735)"
This reverts commit 9ea64dd.
1 parent eba03c4 commit af0788c

File tree

6 files changed

+93
-8
lines changed

6 files changed

+93
-8
lines changed

lldb/docs/resources/build.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ CMake configuration error.
6262
+-------------------+--------------------------------------------------------------+--------------------------+
6363
| Libxml2 | XML | ``LLDB_ENABLE_LIBXML2`` |
6464
+-------------------+--------------------------------------------------------------+--------------------------+
65-
| Python | Python scripting. >= 3.8 is required. | ``LLDB_ENABLE_PYTHON`` |
65+
| Python | Python scripting. >= 3.0 is required, >= 3.8 is recommended. | ``LLDB_ENABLE_PYTHON`` |
6666
+-------------------+--------------------------------------------------------------+--------------------------+
6767
| Lua | Lua scripting. Lua 5.3 and 5.4 are supported. | ``LLDB_ENABLE_LUA`` |
6868
+-------------------+--------------------------------------------------------------+--------------------------+

lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
7373
static bool python_is_finalizing() {
7474
#if PY_VERSION_HEX >= 0x030d0000
7575
return Py_IsFinalizing();
76-
#else
76+
#elif PY_VERSION_HEX >= 0x03070000
7777
return _Py_IsFinalizing();
78+
#else
79+
return _Py_Finalizing != nullptr;
7880
#endif
7981
}
8082

@@ -808,6 +810,7 @@ bool PythonCallable::Check(PyObject *py_obj) {
808810
return PyCallable_Check(py_obj);
809811
}
810812

813+
#if PY_VERSION_HEX >= 0x03030000
811814
static const char get_arg_info_script[] = R"(
812815
from inspect import signature, Parameter, ismethod
813816
from collections import namedtuple
@@ -829,12 +832,15 @@ def main(f):
829832
raise Exception(f'unknown parameter kind: {kind}')
830833
return ArgInfo(count, varargs)
831834
)";
835+
#endif
832836

833837
Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
834838
ArgInfo result = {};
835839
if (!IsValid())
836840
return nullDeref();
837841

842+
#if PY_VERSION_HEX >= 0x03030000
843+
838844
// no need to synchronize access to this global, we already have the GIL
839845
static PythonScript get_arg_info(get_arg_info_script);
840846
Expected<PythonObject> pyarginfo = get_arg_info(*this);
@@ -846,6 +852,57 @@ Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
846852
cantFail(As<bool>(pyarginfo.get().GetAttribute("has_varargs")));
847853
result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count;
848854

855+
#else
856+
PyObject *py_func_obj;
857+
bool is_bound_method = false;
858+
bool is_class = false;
859+
860+
if (PyType_Check(m_py_obj) || PyClass_Check(m_py_obj)) {
861+
auto init = GetAttribute("__init__");
862+
if (!init)
863+
return init.takeError();
864+
py_func_obj = init.get().get();
865+
is_class = true;
866+
} else {
867+
py_func_obj = m_py_obj;
868+
}
869+
870+
if (PyMethod_Check(py_func_obj)) {
871+
py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
872+
PythonObject im_self = GetAttributeValue("im_self");
873+
if (im_self.IsValid() && !im_self.IsNone())
874+
is_bound_method = true;
875+
} else {
876+
// see if this is a callable object with an __call__ method
877+
if (!PyFunction_Check(py_func_obj)) {
878+
PythonObject __call__ = GetAttributeValue("__call__");
879+
if (__call__.IsValid()) {
880+
auto __callable__ = __call__.AsType<PythonCallable>();
881+
if (__callable__.IsValid()) {
882+
py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
883+
PythonObject im_self = __callable__.GetAttributeValue("im_self");
884+
if (im_self.IsValid() && !im_self.IsNone())
885+
is_bound_method = true;
886+
}
887+
}
888+
}
889+
}
890+
891+
if (!py_func_obj)
892+
return result;
893+
894+
PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj);
895+
if (!code)
896+
return result;
897+
898+
auto count = code->co_argcount;
899+
bool has_varargs = !!(code->co_flags & CO_VARARGS);
900+
result.max_positional_args =
901+
has_varargs ? ArgInfo::UNBOUNDED
902+
: (count - (int)is_bound_method) - (int)is_class;
903+
904+
#endif
905+
849906
return result;
850907
}
851908

lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ extern "C" PyObject *PyInit__lldb(void);
7272
// Don't mess with the signal handlers on Windows.
7373
#define LLDB_USE_PYTHON_SET_INTERRUPT 0
7474
#else
75-
#define LLDB_USE_PYTHON_SET_INTERRUPT 1
75+
// PyErr_SetInterrupt was introduced in 3.2.
76+
#define LLDB_USE_PYTHON_SET_INTERRUPT PY_VERSION_HEX >= 0x03020000
7677
#endif
7778

7879
static ScriptInterpreterPythonImpl *GetPythonInterpreter(Debugger &debugger) {
@@ -92,8 +93,10 @@ namespace {
9293
struct InitializePythonRAII {
9394
public:
9495
InitializePythonRAII() {
96+
#if PY_VERSION_HEX >= 0x03080000
9597
PyConfig config;
9698
PyConfig_InitPythonConfig(&config);
99+
#endif
97100

98101
#if LLDB_EMBED_PYTHON_HOME
99102
static std::string g_python_home = []() -> std::string {
@@ -107,7 +110,14 @@ struct InitializePythonRAII {
107110
return spec.GetPath();
108111
}();
109112
if (!g_python_home.empty()) {
113+
#if PY_VERSION_HEX >= 0x03080000
110114
PyConfig_SetBytesString(&config, &config.home, g_python_home.c_str());
115+
#else
116+
size_t size = 0;
117+
wchar_t *python_home_w = Py_DecodeLocale(g_python_home.c_str(), &size);
118+
Py_SetPythonHome(python_home_w);
119+
PyMem_RawFree(python_home_w);
120+
#endif
111121
}
112122
#endif
113123

@@ -134,10 +144,23 @@ struct InitializePythonRAII {
134144
PyImport_AppendInittab("_lldb", LLDBSwigPyInit);
135145
}
136146

147+
#if PY_VERSION_HEX >= 0x03080000
137148
config.install_signal_handlers = 0;
138149
Py_InitializeFromConfig(&config);
139150
PyConfig_Clear(&config);
140151
InitializeThreadsPrivate();
152+
#else
153+
// Python < 3.2 and Python >= 3.2 reversed the ordering requirements for
154+
// calling `Py_Initialize` and `PyEval_InitThreads`. < 3.2 requires that you
155+
// call `PyEval_InitThreads` first, and >= 3.2 requires that you call it last.
156+
#if PY_VERSION_HEX >= 0x03020000
157+
Py_InitializeEx(0);
158+
InitializeThreadsPrivate();
159+
#else
160+
InitializeThreadsPrivate();
161+
Py_InitializeEx(0);
162+
#endif
163+
#endif
141164
}
142165

143166
~InitializePythonRAII() {
@@ -161,10 +184,11 @@ struct InitializePythonRAII {
161184
// `PyGILState_Ensure/Release` flow would be executed instead of unlocking
162185
// GIL with `PyEval_SaveThread`. When an another thread calls
163186
// `PyGILState_Ensure` it would get stuck in deadlock.
164-
187+
#if PY_VERSION_HEX >= 0x03070000
165188
// The only case we should go further and acquire the GIL: it is unlocked.
166189
if (PyGILState_Check())
167190
return;
191+
#endif
168192

169193
// `PyEval_ThreadsInitialized` was deprecated in Python 3.9 and removed in
170194
// Python 3.13. It has been returning `true` always since Python 3.7.

lldb/source/Plugins/ScriptInterpreter/Python/lldb-python.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ static llvm::Expected<bool> *g_fcxx_modules_workaround [[maybe_unused]];
5050

5151
// Provide a meaningful diagnostic error if someone tries to compile this file
5252
// with a version of Python we don't support.
53-
static_assert(PY_VERSION_HEX >= 0x03080000,
54-
"LLDB requires at least Python 3.8");
53+
static_assert(PY_VERSION_HEX >= 0x03000000,
54+
"LLDB requires at least Python 3.0");
5555
#endif
5656

5757
#endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_LLDB_PYTHON_H

lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,10 @@ class NewStyle(object):
760760
EXPECT_EQ(arginfo.get().max_positional_args, 3u);
761761
}
762762

763+
#if PY_VERSION_HEX >= 0x03030000
764+
765+
// the old implementation of GetArgInfo just doesn't work on builtins.
766+
763767
{
764768
auto builtins = PythonModule::BuiltinsModule();
765769
auto hex = As<PythonCallable>(builtins.GetAttribute("hex"));
@@ -768,6 +772,8 @@ class NewStyle(object):
768772
ASSERT_THAT_EXPECTED(arginfo, llvm::Succeeded());
769773
EXPECT_EQ(arginfo.get().max_positional_args, 1u);
770774
}
775+
776+
#endif
771777
}
772778

773779
TEST_F(PythonDataObjectsTest, TestScript) {

llvm/docs/ReleaseNotes.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,8 +288,6 @@ Changes to the LLVM tools
288288
Changes to LLDB
289289
---------------------------------
290290

291-
* When building LLDB with Python support, the minimum version of Python is now
292-
3.8.
293291
* LLDB now supports hardware watchpoints for AArch64 Windows targets. Windows
294292
does not provide API to query the number of supported hardware watchpoints.
295293
Therefore current implementation allows only 1 watchpoint, as tested with

0 commit comments

Comments
 (0)