This revision was automatically updated to reflect the committed changes.
Closed by commit rG90537673302f: Remove Python 2 support from the 
ScriptInterpreter plugin (authored by JDevlieghere).
Herald added a project: LLDB.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D124429/new/

https://reviews.llvm.org/D124429

Files:
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
  lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
  lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
  lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp

Index: lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
===================================================================
--- lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonTestSuite.cpp
@@ -51,11 +51,7 @@
 // callbacks. Because they're defined in libLLDB which we cannot link for the
 // unit test, we have a 'default' implementation here.
 
-#if PY_MAJOR_VERSION >= 3
 extern "C" PyObject *PyInit__lldb(void) { return nullptr; }
-#else
-extern "C" void init_lldb(void) {}
-#endif
 
 llvm::Expected<bool> lldb_private::LLDBSwigPythonBreakpointCallbackFunction(
     const char *python_function_name, const char *session_dictionary_name,
Index: lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
===================================================================
--- lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -164,18 +164,6 @@
 TEST_F(PythonDataObjectsTest, TestPythonInteger) {
   // Test that integers behave correctly when wrapped by a PythonInteger.
 
-#if PY_MAJOR_VERSION < 3
-  // Verify that `PythonInt` works correctly when given a PyInt object.
-  // Note that PyInt doesn't exist in Python 3.x, so this is only for 2.x
-  PyObject *py_int = PyInt_FromLong(12);
-  EXPECT_TRUE(PythonInteger::Check(py_int));
-  PythonInteger python_int(PyRefType::Owned, py_int);
-
-  EXPECT_EQ(PyObjectType::Integer, python_int.GetObjectType());
-  auto python_int_value = As<long long>(python_int);
-  EXPECT_THAT_EXPECTED(python_int_value, llvm::HasValue(12));
-#endif
-
   // Verify that `PythonInteger` works correctly when given a PyLong object.
   PyObject *py_long = PyLong_FromLong(12);
   EXPECT_TRUE(PythonInteger::Check(py_long));
@@ -225,13 +213,8 @@
   EXPECT_TRUE(PythonBytes::Check(py_bytes));
   PythonBytes python_bytes(PyRefType::Owned, py_bytes);
 
-#if PY_MAJOR_VERSION < 3
-  EXPECT_TRUE(PythonString::Check(py_bytes));
-  EXPECT_EQ(PyObjectType::String, python_bytes.GetObjectType());
-#else
   EXPECT_FALSE(PythonString::Check(py_bytes));
   EXPECT_EQ(PyObjectType::Bytes, python_bytes.GetObjectType());
-#endif
 
   llvm::ArrayRef<uint8_t> bytes = python_bytes.GetBytes();
   EXPECT_EQ(bytes.size(), strlen(test_bytes));
@@ -258,23 +241,12 @@
   static const char *test_string = "PythonDataObjectsTest::TestPythonString1";
   static const char *test_string2 = "PythonDataObjectsTest::TestPythonString2";
 
-#if PY_MAJOR_VERSION < 3
-  // Verify that `PythonString` works correctly when given a PyString object.
-  // Note that PyString doesn't exist in Python 3.x, so this is only for 2.x
-  PyObject *py_string = PyString_FromString(test_string);
-  EXPECT_TRUE(PythonString::Check(py_string));
-  PythonString python_string(PyRefType::Owned, py_string);
-
-  EXPECT_EQ(PyObjectType::String, python_string.GetObjectType());
-  EXPECT_STREQ(test_string, python_string.GetString().data());
-#else
   // Verify that `PythonString` works correctly when given a PyUnicode object.
   PyObject *py_unicode = PyUnicode_FromString(test_string);
   EXPECT_TRUE(PythonString::Check(py_unicode));
   PythonString python_unicode(PyRefType::Owned, py_unicode);
   EXPECT_EQ(PyObjectType::String, python_unicode.GetObjectType());
   EXPECT_STREQ(test_string, python_unicode.GetString().data());
-#endif
 
   // Test that creating a `PythonString` object works correctly with the
   // string constructor
Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -60,17 +60,10 @@
 LLDB_PLUGIN_DEFINE(ScriptInterpreterPython)
 
 // Defined in the SWIG source file
-#if PY_MAJOR_VERSION >= 3
 extern "C" PyObject *PyInit__lldb(void);
 
 #define LLDBSwigPyInit PyInit__lldb
 
-#else
-extern "C" void init_lldb(void);
-
-#define LLDBSwigPyInit init_lldb
-#endif
-
 #if defined(_WIN32)
 // Don't mess with the signal handlers on Windows.
 #define LLDB_USE_PYTHON_SET_INTERRUPT 0
@@ -145,11 +138,7 @@
 private:
   void InitializePythonHome() {
 #if LLDB_EMBED_PYTHON_HOME
-#if PY_MAJOR_VERSION >= 3
-    typedef wchar_t* str_type;
-#else
-    typedef char* str_type;
-#endif
+    typedef wchar_t *str_type;
     static str_type g_python_home = []() -> str_type {
       const char *lldb_python_home = LLDB_PYTHON_HOME;
       const char *absolute_python_home = nullptr;
@@ -164,27 +153,12 @@
         llvm::sys::path::append(path, lldb_python_home);
         absolute_python_home = path.c_str();
       }
-#if PY_MAJOR_VERSION >= 3
       size_t size = 0;
       return Py_DecodeLocale(absolute_python_home, &size);
-#else
-      return strdup(absolute_python_home);
-#endif
     }();
     if (g_python_home != nullptr) {
       Py_SetPythonHome(g_python_home);
     }
-#else
-#if defined(__APPLE__) && PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION == 7
-    // For Darwin, the only Python version supported is the one shipped in the
-    // OS OS and linked with lldb. Other installation of Python may have higher
-    // priorities in the path, overriding PYTHONHOME and causing
-    // problems/incompatibilities. In order to avoid confusion, always hardcode
-    // the PythonHome to be right, as it's not going to change.
-    static char path[] =
-        "/System/Library/Frameworks/Python.framework/Versions/2.7";
-    Py_SetPythonHome(path);
-#endif
 #endif
   }
 
Index: lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/PythonReadline.cpp
@@ -22,7 +22,6 @@
 PyDoc_STRVAR(moduleDocumentation,
              "Simple readline module implementation based on libedit.");
 
-#if PY_MAJOR_VERSION >= 3
 static struct PyModuleDef readline_module = {
     PyModuleDef_HEAD_INIT, // m_base
     "lldb_editline",       // m_name
@@ -34,26 +33,13 @@
     nullptr,               // m_clear
     nullptr,               // m_free
 };
-#else
-static struct PyMethodDef moduleMethods[] = {{nullptr, nullptr, 0, nullptr}};
-#endif
 
-static char *
-#if PY_MAJOR_VERSION >= 3
-simple_readline(FILE *stdin, FILE *stdout, const char *prompt)
-#else
-simple_readline(FILE *stdin, FILE *stdout, char *prompt)
-#endif
-{
+static char *simple_readline(FILE *stdin, FILE *stdout, const char *prompt) {
   rl_instream = stdin;
   rl_outstream = stdout;
   char *line = readline(prompt);
   if (!line) {
-#if PY_MAJOR_VERSION >= 3
     char *ret = (char *)PyMem_RawMalloc(1);
-#else
-    char *ret = (char *)PyMem_Malloc(1);
-#endif
     if (ret != NULL)
       *ret = '\0';
     return ret;
@@ -61,11 +47,7 @@
   if (*line)
     add_history(line);
   int n = strlen(line);
-#if PY_MAJOR_VERSION >= 3
   char *ret = (char *)PyMem_RawMalloc(n + 2);
-#else
-  char *ret = (char *)PyMem_Malloc(n + 2);
-#endif
   if (ret) {
     memcpy(ret, line, n);
     free(line);
@@ -78,11 +60,6 @@
 PyMODINIT_FUNC initlldb_readline(void) {
   PyOS_ReadlineFunctionPointer = simple_readline;
 
-#if PY_MAJOR_VERSION >= 3
   return PyModule_Create(&readline_module);
-#else
-  Py_InitModule4("readline", moduleMethods, moduleDocumentation,
-                 static_cast<PyObject *>(NULL), PYTHON_API_VERSION);
-#endif
 }
 #endif
Index: lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -181,13 +181,7 @@
                                  "key not in dict");
 }
 
-#if PY_MAJOR_VERSION < 3
-// The python 2 API declares some arguments as char* that should
-// be const char *, but it doesn't actually modify them.
-inline char *py2_const_cast(const char *s) { return const_cast<char *>(s); }
-#else
 inline const char *py2_const_cast(const char *s) { return s; }
-#endif
 
 enum class PyInitialValue { Invalid, Empty };
 
@@ -391,14 +385,9 @@
 
 template <class T> class TypedPythonObject : public PythonObject {
 public:
-  // override to perform implicit type conversions on Reset
-  // This can be eliminated once we drop python 2 support.
-  static void Convert(PyRefType &type, PyObject *&py_obj) {}
-
   TypedPythonObject(PyRefType type, PyObject *py_obj) {
     if (!py_obj)
       return;
-    T::Convert(type, py_obj);
     if (T::Check(py_obj))
       PythonObject::operator=(PythonObject(type, py_obj));
     else if (type == PyRefType::Owned)
@@ -453,7 +442,6 @@
   explicit PythonString(llvm::StringRef string); // safe, null on error
 
   static bool Check(PyObject *py_obj);
-  static void Convert(PyRefType &type, PyObject *&py_obj);
 
   llvm::StringRef GetString() const; // safe, empty string on error
 
@@ -475,7 +463,6 @@
   explicit PythonInteger(int64_t value);
 
   static bool Check(PyObject *py_obj);
-  static void Convert(PyRefType &type, PyObject *&py_obj);
 
   void SetInteger(int64_t value);
 
Index: lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -71,9 +71,7 @@
 }
 
 static bool python_is_finalizing() {
-#if PY_MAJOR_VERSION == 2
-  return false;
-#elif PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7
+#if PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7
   return _Py_Finalizing != nullptr;
 #else
   return _Py_IsFinalizing();
@@ -97,12 +95,6 @@
 Expected<long long> PythonObject::AsLongLong() const {
   if (!m_py_obj)
     return nullDeref();
-#if PY_MAJOR_VERSION < 3
-  if (!PyLong_Check(m_py_obj)) {
-    PythonInteger i(PyRefType::Borrowed, m_py_obj);
-    return i.AsLongLong();
-  }
-#endif
   assert(!PyErr_Occurred());
   long long r = PyLong_AsLongLong(m_py_obj);
   if (PyErr_Occurred())
@@ -113,12 +105,6 @@
 Expected<long long> PythonObject::AsUnsignedLongLong() const {
   if (!m_py_obj)
     return nullDeref();
-#if PY_MAJOR_VERSION < 3
-  if (!PyLong_Check(m_py_obj)) {
-    PythonInteger i(PyRefType::Borrowed, m_py_obj);
-    return i.AsUnsignedLongLong();
-  }
-#endif
   assert(!PyErr_Occurred());
   long long r = PyLong_AsUnsignedLongLong(m_py_obj);
   if (PyErr_Occurred())
@@ -130,12 +116,6 @@
 Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const {
   if (!m_py_obj)
     return nullDeref();
-#if PY_MAJOR_VERSION < 3
-  if (!PyLong_Check(m_py_obj)) {
-    PythonInteger i(PyRefType::Borrowed, m_py_obj);
-    return i.AsModuloUnsignedLongLong();
-  }
-#endif
   assert(!PyErr_Occurred());
   unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
   if (PyErr_Occurred())
@@ -183,10 +163,8 @@
     return PyObjectType::Dictionary;
   if (PythonString::Check(m_py_obj))
     return PyObjectType::String;
-#if PY_MAJOR_VERSION >= 3
   if (PythonBytes::Check(m_py_obj))
     return PyObjectType::Bytes;
-#endif
   if (PythonByteArray::Check(m_py_obj))
     return PyObjectType::ByteArray;
   if (PythonBoolean::Check(m_py_obj))
@@ -282,9 +260,7 @@
 }
 
 StructuredData::ObjectSP PythonObject::CreateStructuredObject() const {
-#if PY_MAJOR_VERSION >= 3
   assert(PyGILState_Check());
-#endif
   switch (GetObjectType()) {
   case PyObjectType::Dictionary:
     return PythonDictionary(PyRefType::Borrowed, m_py_obj)
@@ -398,11 +374,7 @@
 // PythonString
 
 Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) {
-#if PY_MAJOR_VERSION >= 3
   PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size());
-#else
-  PyObject *str = PyString_FromStringAndSize(string.data(), string.size());
-#endif
   if (!str)
     return llvm::make_error<PythonException>();
   return Take<PythonString>(str);
@@ -416,35 +388,9 @@
 
   if (PyUnicode_Check(py_obj))
     return true;
-#if PY_MAJOR_VERSION < 3
-  if (PyString_Check(py_obj))
-    return true;
-#endif
   return false;
 }
 
-void PythonString::Convert(PyRefType &type, PyObject *&py_obj) {
-#if PY_MAJOR_VERSION < 3
-  // In Python 2, Don't store PyUnicode objects directly, because we need
-  // access to their underlying character buffers which Python 2 doesn't
-  // provide.
-  if (PyUnicode_Check(py_obj)) {
-    PyObject *s = PyUnicode_AsUTF8String(py_obj);
-    if (s == nullptr) {
-      PyErr_Clear();
-      if (type == PyRefType::Owned)
-        Py_DECREF(py_obj);
-      return;
-    }
-    if (type == PyRefType::Owned)
-      Py_DECREF(py_obj);
-    else
-      type = PyRefType::Owned;
-    py_obj = s;
-  }
-#endif
-}
-
 llvm::StringRef PythonString::GetString() const {
   auto s = AsUTF8();
   if (!s) {
@@ -461,15 +407,7 @@
   Py_ssize_t size;
   const char *data;
 
-#if PY_MAJOR_VERSION >= 3
   data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
-#else
-  char *c = NULL;
-  int r = PyString_AsStringAndSize(m_py_obj, &c, &size);
-  if (r < 0)
-    c = NULL;
-  data = c;
-#endif
 
   if (!data)
     return exception();
@@ -479,14 +417,10 @@
 
 size_t PythonString::GetSize() const {
   if (IsValid()) {
-#if PY_MAJOR_VERSION >= 3
 #if PY_MINOR_VERSION >= 3
     return PyUnicode_GetLength(m_py_obj);
 #else
     return PyUnicode_GetSize(m_py_obj);
-#endif
-#else
-    return PyString_Size(m_py_obj);
 #endif
   }
   return 0;
@@ -516,41 +450,9 @@
   if (!py_obj)
     return false;
 
-#if PY_MAJOR_VERSION >= 3
   // Python 3 does not have PyInt_Check.  There is only one type of integral
   // value, long.
   return PyLong_Check(py_obj);
-#else
-  return PyLong_Check(py_obj) || PyInt_Check(py_obj);
-#endif
-}
-
-void PythonInteger::Convert(PyRefType &type, PyObject *&py_obj) {
-#if PY_MAJOR_VERSION < 3
-  // Always store this as a PyLong, which makes interoperability between Python
-  // 2.x and Python 3.x easier.  This is only necessary in 2.x, since 3.x
-  // doesn't even have a PyInt.
-  if (PyInt_Check(py_obj)) {
-    // Since we converted the original object to a different type, the new
-    // object is an owned object regardless of the ownership semantics
-    // requested by the user.
-    long long value = PyInt_AsLong(py_obj);
-    PyObject *l = nullptr;
-    if (!PyErr_Occurred())
-      l = PyLong_FromLongLong(value);
-    if (l == nullptr) {
-      PyErr_Clear();
-      if (type == PyRefType::Owned)
-        Py_DECREF(py_obj);
-      return;
-    }
-    if (type == PyRefType::Owned)
-      Py_DECREF(py_obj);
-    else
-      type = PyRefType::Owned;
-    py_obj = l;
-  }
-#endif
 }
 
 void PythonInteger::SetInteger(int64_t value) {
@@ -762,13 +664,9 @@
 PythonDictionary::GetItem(const PythonObject &key) const {
   if (!IsValid())
     return nullDeref();
-#if PY_MAJOR_VERSION >= 3
   PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
   if (PyErr_Occurred())
     return exception();
-#else
-  PyObject *o = PyDict_GetItem(m_py_obj, key.get());
-#endif
   if (!o)
     return keyError();
   return Retain<PythonObject>(o);
@@ -826,13 +724,7 @@
   return result;
 }
 
-PythonModule PythonModule::BuiltinsModule() {
-#if PY_MAJOR_VERSION >= 3
-  return AddModule("builtins");
-#else
-  return AddModule("__builtin__");
-#endif
-}
+PythonModule PythonModule::BuiltinsModule() { return AddModule("builtins"); }
 
 PythonModule PythonModule::MainModule() { return AddModule("__main__"); }
 
@@ -1000,9 +892,6 @@
 bool PythonFile::Check(PyObject *py_obj) {
   if (!py_obj)
     return false;
-#if PY_MAJOR_VERSION < 3
-  return PyFile_Check(py_obj);
-#else
   // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
   // first-class object type anymore.  `PyFile_FromFd` is just a thin wrapper
   // over `io.open()`, which returns some object derived from `io.IOBase`. As a
@@ -1024,7 +913,6 @@
     return false;
   }
   return !!r;
-#endif
 }
 
 const char *PythonException::toCString() const {
@@ -1121,7 +1009,6 @@
 
 llvm::Expected<File::OpenOptions>
 GetOptionsForPyObject(const PythonObject &obj) {
-#if PY_MAJOR_VERSION >= 3
   auto options = File::OpenOptions(0);
   auto readable = As<bool>(obj.CallMethod("readable"));
   if (!readable)
@@ -1136,10 +1023,6 @@
   else if (readable.get())
     options |= File::eOpenOptionReadOnly;
   return options;
-#else
-  PythonString py_mode = obj.GetAttributeValue("mode").AsType<PythonString>();
-  return File::GetOptionsFromMode(py_mode.GetString());
-#endif
 }
 
 // Base class template for python files.   All it knows how to do
@@ -1223,8 +1106,6 @@
 char SimplePythonFile::ID = 0;
 } // namespace
 
-#if PY_MAJOR_VERSION >= 3
-
 namespace {
 class PythonBuffer {
 public:
@@ -1414,8 +1295,6 @@
 };
 } // namespace
 
-#endif
-
 llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) {
   if (!IsValid())
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
@@ -1466,13 +1345,6 @@
     return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                    "invalid PythonFile");
 
-#if PY_MAJOR_VERSION < 3
-
-  return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                 "not supported on python 2");
-
-#else
-
   int fd = PyObject_AsFileDescriptor(m_py_obj);
   if (fd < 0) {
     PyErr_Clear();
@@ -1522,8 +1394,6 @@
                                    "invalid File");
 
   return file_sp;
-
-#endif
 }
 
 Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) {
@@ -1533,10 +1403,8 @@
 
   if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
     return Retain<PythonFile>(simple->GetPythonObject());
-#if PY_MAJOR_VERSION >= 3
   if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
     return Retain<PythonFile>(pythonio->GetPythonObject());
-#endif
 
   if (!mode) {
     auto m = file.GetOpenMode();
@@ -1546,26 +1414,8 @@
   }
 
   PyObject *file_obj;
-#if PY_MAJOR_VERSION >= 3
   file_obj = PyFile_FromFd(file.GetDescriptor(), nullptr, mode, -1, nullptr,
                            "ignore", nullptr, /*closefd=*/0);
-#else
-  // I'd like to pass ::fflush here if the file is writable,  so that
-  // when the python side destructs the file object it will be flushed.
-  // However, this would be dangerous.    It can cause fflush to be called
-  // after fclose if the python program keeps a reference to the file after
-  // the original lldb_private::File has been destructed.
-  //
-  // It's all well and good to ask a python program not to use a closed file
-  // but asking a python program to make sure objects get released in a
-  // particular order is not safe.
-  //
-  // The tradeoff here is that if a python 2 program wants to make sure this
-  // file gets flushed, they'll have to do it explicitly or wait untill the
-  // original lldb File itself gets flushed.
-  file_obj = PyFile_FromFile(file.GetStream(), py2_const_cast(""),
-                             py2_const_cast(mode), [](FILE *) { return 0; });
-#endif
 
   if (!file_obj)
     return exception();
@@ -1612,12 +1462,7 @@
     return exception();
   auto code_ref = Take<PythonObject>(code);
 
-#if PY_MAJOR_VERSION < 3
-  PyObject *result =
-      PyEval_EvalCode((PyCodeObject *)code, globals.get(), locals.get());
-#else
   PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
-#endif
 
   if (!result)
     return exception();
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to