[Lldb-commits] [lldb] 04edd18 - remove multi-argument form of PythonObject::Reset()

Lawrence D'Anna via lldb-commits lldb-commits at lists.llvm.org
Mon Oct 21 19:31:24 PDT 2019


Author: Lawrence D'Anna
Date: 2019-10-22T02:32:37Z
New Revision: 04edd1893c2d0f35880fd5f81e78dc23979df0b9

URL: https://github.com/llvm/llvm-project/commit/04edd1893c2d0f35880fd5f81e78dc23979df0b9
DIFF: https://github.com/llvm/llvm-project/commit/04edd1893c2d0f35880fd5f81e78dc23979df0b9.diff

LOG: remove multi-argument form of PythonObject::Reset()

Summary:
With this patch, only the no-argument form of `Reset()` remains in
PythonDataObjects.   It also deletes PythonExceptionState in favor of
PythonException, because the only call-site of PythonExceptionState was
also using Reset, so I cleaned up both while I was there.

Reviewers: JDevlieghere, clayborg, labath, jingham

Reviewed By: labath

Subscribers: mgorny, lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D69214

llvm-svn: 375475

Added: 
    

Modified: 
    lldb/include/lldb/Interpreter/ScriptInterpreter.h
    lldb/scripts/Python/python-extensions.swig
    lldb/scripts/Python/python-typemaps.swig
    lldb/scripts/Python/python-wrapper.swig
    lldb/scripts/lldb.swig
    lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
    lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
    lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
    lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
    lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
    lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt
    lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Removed: 
    lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
    lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
    lldb/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp


################################################################################
diff  --git a/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
index 3dd75b558508..23fadf02e591 100644
--- a/lldb/include/lldb/Interpreter/ScriptInterpreter.h
+++ b/lldb/include/lldb/Interpreter/ScriptInterpreter.h
@@ -65,6 +65,9 @@ class ScriptInterpreter : public PluginInterface {
 
     bool GetSetLLDBGlobals() const { return m_set_lldb_globals; }
 
+    // If this is true then any exceptions raised by the script will be
+    // cleared with PyErr_Clear().   If false then they will be left for
+    // the caller to clean up
     bool GetMaskoutErrors() const { return m_maskout_errors; }
 
     ExecuteScriptOptions &SetEnableIO(bool enable) {

diff  --git a/lldb/scripts/Python/python-extensions.swig b/lldb/scripts/Python/python-extensions.swig
index 7823dc4ad1a0..c10c32b44877 100644
--- a/lldb/scripts/Python/python-extensions.swig
+++ b/lldb/scripts/Python/python-extensions.swig
@@ -8,10 +8,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -24,10 +21,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -40,10 +34,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 
@@ -71,10 +62,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -88,10 +76,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -121,10 +106,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 
@@ -150,10 +132,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
     %pythoncode %{
@@ -179,10 +158,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -195,10 +171,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -211,10 +184,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 
@@ -242,10 +212,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -258,10 +225,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -274,10 +238,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -290,10 +251,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 
@@ -321,10 +279,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -337,10 +292,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -353,10 +305,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 
@@ -384,10 +333,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -401,10 +347,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 
@@ -432,10 +375,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -449,10 +389,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -466,10 +403,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -482,10 +416,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 
@@ -526,10 +457,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
     %pythoncode %{
@@ -555,10 +483,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -571,10 +496,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -588,10 +510,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 
@@ -619,10 +538,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -635,10 +551,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -651,10 +564,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
     %pythoncode %{
@@ -680,10 +590,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -696,10 +603,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -712,10 +616,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -728,10 +629,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -744,10 +642,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
     %pythoncode %{
@@ -773,10 +668,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
     %pythoncode %{
@@ -802,10 +694,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
     %pythoncode %{
@@ -831,10 +720,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
     %pythoncode %{
@@ -860,10 +746,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -885,10 +768,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }
@@ -901,10 +781,7 @@
                 size_t desc_len = description.GetSize();
                 if (desc_len > 0 && (desc[desc_len-1] == '\n' || desc[desc_len-1] == '\r'))
                     --desc_len;
-                if (desc_len > 0)
-                    return lldb_private::PythonString(llvm::StringRef(desc, desc_len)).release();
-                else
-                    return lldb_private::PythonString("").release();
+                return PythonString(llvm::StringRef(desc, desc_len)).release();
         }
         %clearnothreadallow;
 }

diff  --git a/lldb/scripts/Python/python-typemaps.swig b/lldb/scripts/Python/python-typemaps.swig
index 8ff178bc5e52..2ba380bdf0d5 100644
--- a/lldb/scripts/Python/python-typemaps.swig
+++ b/lldb/scripts/Python/python-typemaps.swig
@@ -1,7 +1,6 @@
 /* Typemap definitions, to allow SWIG to properly handle 'char**' data types. */
 
 %typemap(in) char ** {
-  using namespace lldb_private;
   /* Check if is a list  */
   if (PythonList::Check($input)) {
     PythonList list(PyRefType::Borrowed, $input);
@@ -30,7 +29,6 @@
 %typemap(typecheck) char ** {
   /* Check if is a list  */
   $1 = 1;
-  using namespace lldb_private;
   if (PythonList::Check($input)) {
     PythonList list(PyRefType::Borrowed, $input);
     int size = list.GetSize();
@@ -55,7 +53,6 @@
   int i;
   len = 0;
   while ($1[len]) len++;
-  using namespace lldb_private;
   PythonList list(len);
   for (i = 0; i < len; i++)
     list.SetItemAtIndex(i, PythonString($1[i]));
@@ -64,7 +61,6 @@
 
 
 %typemap(in) lldb::tid_t {
-  using namespace lldb_private;
   if (PythonInteger::Check($input))
   {
     PythonInteger py_int(PyRefType::Borrowed, $input);
@@ -78,7 +74,6 @@
 }
 
 %typemap(in) lldb::StateType {
-  using namespace lldb_private;
   if (PythonInteger::Check($input))
   {
     PythonInteger py_int(PyRefType::Borrowed, $input);
@@ -122,12 +117,12 @@
 %typemap(argout) (char *dst, size_t dst_len) {
    Py_XDECREF($result);   /* Blow away any previous result */
    if (result == 0) {
-      lldb_private::PythonString string("");
+      PythonString string("");
       $result = string.release();
       Py_INCREF($result);
    } else {
       llvm::StringRef ref(static_cast<const char*>($1), result);
-      lldb_private::PythonString string(ref);
+      PythonString string(ref);
       $result = string.release();
    }
    free($1);
@@ -142,7 +137,6 @@
 // Ditto for SBProcess::PutSTDIN(const char *src, size_t src_len).
 %typemap(in) (const char *cstr, uint32_t cstr_len),
              (const char *src, size_t src_len) {
-   using namespace lldb_private;
    if (PythonString::Check($input)) {
       PythonString str(PyRefType::Borrowed, $input);
       $1 = (char*)str.GetString().data();
@@ -166,7 +160,6 @@
 // For SBProcess::WriteMemory, SBTarget::GetInstructions and SBDebugger::DispatchInput.
 %typemap(in) (const void *buf, size_t size),
              (const void *data, size_t data_len) {
-   using namespace lldb_private;
    if (PythonString::Check($input)) {
       PythonString str(PyRefType::Borrowed, $input);
       $1 = (void*)str.GetString().data();
@@ -214,7 +207,7 @@
       $result = Py_None;
       Py_INCREF($result);
    } else {
-      lldb_private::PythonBytes bytes(static_cast<const uint8_t*>($1), result);
+      PythonBytes bytes(static_cast<const uint8_t*>($1), result);
       $result = bytes.release();
    }
    free($1);
@@ -374,7 +367,6 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
 
 
 %typemap(in) lldb::FileSP {
-  using namespace lldb_private;
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
     PyErr_SetString(PyExc_TypeError, "not a file");
@@ -387,7 +379,6 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
 }
 
 %typemap(in) lldb::FileSP FORCE_IO_METHODS {
-  using namespace lldb_private;
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
     PyErr_SetString(PyExc_TypeError, "not a file");
@@ -400,7 +391,6 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
 }
 
 %typemap(in) lldb::FileSP BORROWED {
- using namespace lldb_private;
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
     PyErr_SetString(PyExc_TypeError, "not a file");
@@ -413,7 +403,6 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
 }
 
 %typemap(in) lldb::FileSP BORROWED_FORCE_IO_METHODS {
-  using namespace lldb_private;
   PythonFile py_file(PyRefType::Borrowed, $input);
   if (!py_file) {
     PyErr_SetString(PyExc_TypeError, "not a file");
@@ -426,7 +415,7 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
 }
 
 %typecheck(SWIG_TYPECHECK_POINTER) lldb::FileSP {
-  if (lldb_private::PythonFile::Check($input)) {
+  if (PythonFile::Check($input)) {
     $1 = 1;
   } else {
     PyErr_Clear();
@@ -435,7 +424,6 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
 }
 
 %typemap(out) lldb::FileSP {
-  using namespace lldb_private;
   $result = nullptr;
   lldb::FileSP &sp = $1;
   if (sp) {
@@ -452,7 +440,6 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
 }
 
 %typemap(in) (const char* string, int len) {
-    using namespace lldb_private;
     if ($input == Py_None)
     {
         $1 = NULL;

diff  --git a/lldb/scripts/Python/python-wrapper.swig b/lldb/scripts/Python/python-wrapper.swig
index 277b8657d344..8bb746477419 100644
--- a/lldb/scripts/Python/python-wrapper.swig
+++ b/lldb/scripts/Python/python-wrapper.swig
@@ -48,7 +48,6 @@ LLDBSwigPythonBreakpointCallbackFunction
     const lldb::BreakpointLocationSP& bp_loc_sp
 )
 {
-    using namespace lldb_private;
     lldb::SBFrame sb_frame (frame_sp);
     lldb::SBBreakpointLocation sb_bp_loc(bp_loc_sp);
 
@@ -83,7 +82,6 @@ LLDBSwigPythonWatchpointCallbackFunction
     const lldb::WatchpointSP& wp_sp
 )
 {
-    using namespace lldb_private;
     lldb::SBFrame sb_frame (frame_sp);
     lldb::SBWatchpoint sb_wp(wp_sp);
 
@@ -118,7 +116,6 @@ LLDBSwigPythonCallTypeScript
     std::string& retval
 )
 {
-    using namespace lldb_private;
     lldb::SBValue sb_value (valobj_sp);
     lldb::SBTypeSummaryOptions sb_options(options_sp.get());
 
@@ -190,8 +187,6 @@ LLDBSwigPythonCreateSyntheticProvider
     const lldb::ValueObjectSP& valobj_sp
 )
 {
-    using namespace lldb_private;
-
     if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
         Py_RETURN_NONE;
 
@@ -228,8 +223,6 @@ LLDBSwigPythonCreateCommandObject
     const lldb::DebuggerSP debugger_sp
 )
 {
-    using namespace lldb_private;
-
     if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
         Py_RETURN_NONE;
 
@@ -260,8 +253,6 @@ LLDBSwigPythonCreateScriptedThreadPlan
     const lldb::ThreadPlanSP& thread_plan_sp
 )
 {
-    using namespace lldb_private;
-
     if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
         Py_RETURN_NONE;
 
@@ -319,8 +310,6 @@ LLDBSWIGPythonCallThreadPlan
     bool &got_error
 )
 {
-    using namespace lldb_private;
-
     got_error = false;
 
     PyErr_Cleaner py_err_cleaner(false);
@@ -368,8 +357,6 @@ LLDBSwigPythonCreateScriptedBreakpointResolver
     lldb::BreakpointSP &breakpoint_sp
 )
 {
-    using namespace lldb_private;
-
     if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
         Py_RETURN_NONE;
 
@@ -412,8 +399,6 @@ LLDBSwigPythonCallBreakpointResolver
     lldb_private::SymbolContext *sym_ctx
 )
 {
-    using namespace lldb_private;
-
     PyErr_Cleaner py_err_cleaner(false);
     PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
     auto pfunc = self.ResolveName<PythonCallable>(method_name);
@@ -464,8 +449,6 @@ LLDBSwigPython_CallOptionalMember
     bool* was_found = NULL
 )
 {
-    using namespace lldb_private;
-
     PyErr_Cleaner py_err_cleaner(false);
 
     PythonObject self(PyRefType::Borrowed, static_cast<PyObject*>(implementor));
@@ -493,8 +476,6 @@ LLDBSwigPython_CalculateNumChildren
     uint32_t max
 )
 {
-    using namespace lldb_private;
-
     PythonObject self(PyRefType::Borrowed, implementor);
     auto pfunc = self.ResolveName<PythonCallable>("num_children");
 
@@ -536,7 +517,6 @@ LLDBSwigPython_GetChildAtIndex
     uint32_t idx
 )
 {
-    using namespace lldb_private;
     PyErr_Cleaner py_err_cleaner(true);
 
     PythonObject self(PyRefType::Borrowed, implementor);
@@ -567,7 +547,6 @@ LLDBSwigPython_GetIndexOfChildWithName
     const char* child_name
 )
 {
-    using namespace lldb_private;
     PyErr_Cleaner py_err_cleaner(true);
 
     PythonObject self(PyRefType::Borrowed, implementor);
@@ -687,7 +666,6 @@ LLDBSwigPythonCallCommand
     lldb::ExecutionContextRefSP exe_ctx_ref_sp
 )
 {
-    using namespace lldb_private;
     lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
     lldb::SBDebugger debugger_sb(debugger);
     lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
@@ -728,7 +706,6 @@ LLDBSwigPythonCallCommandObject
     lldb::ExecutionContextRefSP exe_ctx_ref_sp
 )
 {
-    using namespace lldb_private;
     lldb::SBCommandReturnObject cmd_retobj_sb(cmd_retobj);
     lldb::SBDebugger debugger_sb(debugger);
     lldb::SBExecutionContext exe_ctx_sb(exe_ctx_ref_sp);
@@ -760,8 +737,6 @@ LLDBSWIGPythonCreateOSPlugin
     const lldb::ProcessSP& process_sp
 )
 {
-    using namespace lldb_private;
-
     if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
         Py_RETURN_NONE;
 
@@ -795,8 +770,6 @@ LLDBSWIGPython_CreateFrameRecognizer
     const char *session_dictionary_name
 )
 {
-    using namespace lldb_private;
-
     if (python_class_name == NULL || python_class_name[0] == '\0' || !session_dictionary_name)
         Py_RETURN_NONE;
 
@@ -823,8 +796,6 @@ LLDBSwigPython_GetRecognizedArguments
     const lldb::StackFrameSP& frame_sp
 )
 {
-    using namespace lldb_private;
-
     static char callee_name[] = "get_recognized_arguments";
 
     lldb::SBFrame frame_sb(frame_sp);
@@ -839,8 +810,6 @@ LLDBSwigPython_GetRecognizedArguments
 SWIGEXPORT void*
 LLDBSWIGPython_GetDynamicSetting (void* module, const char* setting, const lldb::TargetSP& target_sp)
 {
-    using namespace lldb_private;
-
     if (!module || !setting)
         Py_RETURN_NONE;
 
@@ -866,8 +835,6 @@ lldb::ProcessSP& process,
 std::string& output)
 
 {
-    using namespace lldb_private;
-
     if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
         return false;
 
@@ -896,8 +863,6 @@ lldb::ThreadSP& thread,
 std::string& output)
 
 {
-    using namespace lldb_private;
-
     if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
         return false;
 
@@ -926,8 +891,6 @@ lldb::TargetSP& target,
 std::string& output)
 
 {
-    using namespace lldb_private;
-
     if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
         return false;
 
@@ -956,8 +919,6 @@ lldb::StackFrameSP& frame,
 std::string& output)
 
 {
-    using namespace lldb_private;
-
     if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
         return false;
 
@@ -986,8 +947,6 @@ lldb::ValueObjectSP& value,
 std::string& output)
 
 {
-    using namespace lldb_private;
-
     if (python_function_name == NULL || python_function_name[0] == '\0' || !session_dictionary_name)
         return false;
 
@@ -1016,8 +975,6 @@ LLDBSwigPythonCallModuleInit
     lldb::DebuggerSP& debugger
 )
 {
-    using namespace lldb_private;
-
     std::string python_function_name_string = python_module_name;
     python_function_name_string += ".__lldb_init_module";
     const char* python_function_name = python_function_name_string.c_str();

diff  --git a/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig
index 1634e1884afe..7bbf7f1eec35 100644
--- a/lldb/scripts/lldb.swig
+++ b/lldb/scripts/lldb.swig
@@ -174,6 +174,11 @@ def lldb_iter(obj, getsize, getelem):
 #include "../source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
 
 #include "../scripts/Python/python-swigsafecast.swig"
+
+using namespace lldb_private;
+using namespace lldb_private::python;
+using namespace lldb;
+
 %}
 
 /* Various liblldb typedefs that SWIG needs to know about.  */

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
index 2c5071bc7655..54b5c236f752 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt
@@ -5,7 +5,6 @@ add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${LLDB_PYTHON_RELATIVE_PATH}")
 
 add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN
   PythonDataObjects.cpp
-  PythonExceptionState.cpp
   ScriptInterpreterPython.cpp
 
   LINK_LIBS

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
index d0d593656efd..70d93424fdec 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp
@@ -261,8 +261,7 @@ size_t PythonBytes::GetSize() const {
 
 void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
   const char *data = reinterpret_cast<const char *>(bytes.data());
-  PyObject *py_bytes = PyBytes_FromStringAndSize(data, bytes.size());
-  PythonObject::Reset(PyRefType::Owned, py_bytes);
+  *this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size()));
 }
 
 StructuredData::StringSP PythonBytes::CreateStructuredString() const {
@@ -486,7 +485,7 @@ int64_t PythonInteger::GetInteger() const {
 }
 
 void PythonInteger::SetInteger(int64_t value) {
-  PythonObject::Reset(PyRefType::Owned, PyLong_FromLongLong(value));
+  *this = Take<PythonInteger>(PyLong_FromLongLong(value));
 }
 
 StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const {
@@ -510,7 +509,7 @@ bool PythonBoolean::GetValue() const {
 }
 
 void PythonBoolean::SetValue(bool value) {
-  PythonObject::Reset(PyRefType::Owned, PyBool_FromLong(value));
+  *this = Take<PythonBoolean>(PyBool_FromLong(value));
 }
 
 StructuredData::BooleanSP PythonBoolean::CreateStructuredBoolean() const {
@@ -826,7 +825,7 @@ static const char get_arg_info_script[] = R"(
 from inspect import signature, Parameter, ismethod
 from collections import namedtuple
 ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs', 'is_bound_method'])
-def get_arg_info(f):
+def main(f):
     count = 0
     varargs = False
     for parameter in signature(f).parameters.values():
@@ -852,28 +851,9 @@ Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
 
 #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
 
-  // this global is protected by the GIL
-  static PythonCallable get_arg_info;
-
-  if (!get_arg_info.IsValid()) {
-    PythonDictionary globals(PyInitialValue::Empty);
-
-    auto builtins = PythonModule::BuiltinsModule();
-    Error error = globals.SetItem("__builtins__", builtins);
-    if (error)
-      return std::move(error);
-    PyObject *o = PyRun_String(get_arg_info_script, Py_file_input,
-                               globals.get(), globals.get());
-    if (!o)
-      return exception();
-    Take<PythonObject>(o);
-    auto function = As<PythonCallable>(globals.GetItem("get_arg_info"));
-    if (!function)
-      return function.takeError();
-    get_arg_info = std::move(function.get());
-  }
-
-  Expected<PythonObject> pyarginfo = get_arg_info.Call(*this);
+  // no need to synchronize access to this global, we already have the GIL
+  static PythonScript get_arg_info(get_arg_info_script);
+  Expected<PythonObject> pyarginfo = get_arg_info(*this);
   if (!pyarginfo)
     return pyarginfo.takeError();
   result.count = cantFail(As<long long>(pyarginfo.get().GetAttribute("count")));
@@ -1056,6 +1036,44 @@ std::error_code PythonException::convertToErrorCode() const {
   return llvm::inconvertibleErrorCode();
 }
 
+bool PythonException::Matches(PyObject *exc) const {
+  return PyErr_GivenExceptionMatches(m_exception_type, exc);
+}
+
+const char read_exception_script[] = R"(
+import sys
+from traceback import print_exception
+if sys.version_info.major < 3:
+  from StringIO import StringIO
+else:
+  from io import StringIO
+def main(exc_type, exc_value, tb):
+  f = StringIO()
+  print_exception(exc_type, exc_value, tb, file=f)
+  return f.getvalue()
+)";
+
+std::string PythonException::ReadBacktrace() const {
+
+  if (!m_traceback)
+    return toCString();
+
+  // no need to synchronize access to this global, we already have the GIL
+  static PythonScript read_exception(read_exception_script);
+
+  Expected<std::string> backtrace = As<std::string>(
+      read_exception(m_exception_type, m_exception, m_traceback));
+
+  if (!backtrace) {
+    std::string message =
+        std::string(toCString()) + "\n" +
+        "Traceback unavailble, an error occurred while reading it:\n";
+    return (message + llvm::toString(backtrace.takeError()));
+  }
+
+  return std::move(backtrace.get());
+}
+
 char PythonException::ID = 0;
 
 llvm::Expected<File::OpenOptions>
@@ -1496,4 +1514,69 @@ Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) {
   return Take<PythonFile>(file_obj);
 }
 
+Error PythonScript::Init() {
+  if (function.IsValid())
+    return Error::success();
+
+  PythonDictionary globals(PyInitialValue::Empty);
+  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());
+  if (!o)
+    return exception();
+  Take<PythonObject>(o);
+  auto f = As<PythonCallable>(globals.GetItem("main"));
+  if (!f)
+    return f.takeError();
+  function = std::move(f.get());
+
+  return Error::success();
+}
+
+llvm::Expected<PythonObject>
+python::runStringOneLine(const llvm::Twine &string,
+                         const PythonDictionary &globals,
+                         const PythonDictionary &locals) {
+  if (!globals.IsValid() || !locals.IsValid())
+    return nullDeref();
+
+  PyObject *code =
+      Py_CompileString(NullTerminated(string), "<string>", Py_eval_input);
+  if (!code) {
+    PyErr_Clear();
+    code =
+        Py_CompileString(NullTerminated(string), "<string>", Py_single_input);
+  }
+  if (!code)
+    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();
+
+  return Take<PythonObject>(result);
+}
+
+llvm::Expected<PythonObject>
+python::runStringMultiLine(const llvm::Twine &string,
+                           const PythonDictionary &globals,
+                           const PythonDictionary &locals) {
+  if (!globals.IsValid() || !locals.IsValid())
+    return nullDeref();
+  PyObject *result = PyRun_String(NullTerminated(string), Py_file_input,
+                                  globals.get(), locals.get());
+  if (!result)
+    return exception();
+  return Take<PythonObject>(result);
+}
+
 #endif

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
index 634d6e896015..373d3212697d 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h
@@ -59,6 +59,7 @@
 #include "llvm/ADT/ArrayRef.h"
 
 namespace lldb_private {
+namespace python {
 
 class PythonObject;
 class PythonBytes;
@@ -113,7 +114,6 @@ enum class PyRefType {
             // not call Py_INCREF.
 };
 
-namespace python {
 
 // Take a reference that you already own, and turn it into
 // a PythonObject.
@@ -175,7 +175,19 @@ class NullTerminated {
   operator const char *() { return str; }
 };
 
-} // namespace python
+inline llvm::Error nullDeref() {
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                 "A NULL PyObject* was dereferenced");
+}
+
+inline llvm::Error exception(const char *s = nullptr) {
+  return llvm::make_error<PythonException>(s);
+}
+
+inline llvm::Error keyError() {
+  return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                 "key not in dict");
+}
 
 enum class PyInitialValue { Invalid, Empty };
 
@@ -191,6 +203,11 @@ template <> struct PythonFormat<long long> {
   static auto get(long long value) { return value; }
 };
 
+template <> struct PythonFormat<PyObject *> {
+  static constexpr char format = 'O';
+  static auto get(PyObject *value) { return value; }
+};
+
 template <typename T>
 struct PythonFormat<
     T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
@@ -202,8 +219,14 @@ class PythonObject {
 public:
   PythonObject() : m_py_obj(nullptr) {}
 
-  PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) {
-    Reset(type, py_obj);
+  PythonObject(PyRefType type, PyObject *py_obj) {
+    m_py_obj = py_obj;
+    // If this is a borrowed reference, we need to convert it to
+    // an owned reference by incrementing it.  If it is an owned
+    // reference (for example the caller allocated it with PyDict_New()
+    // then we must *not* increment it.
+    if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
+      Py_XINCREF(m_py_obj);
   }
 
   PythonObject(const PythonObject &rhs)
@@ -222,23 +245,6 @@ class PythonObject {
     m_py_obj = nullptr;
   }
 
-  void Reset(PyRefType type, PyObject *py_obj) {
-    if (py_obj == m_py_obj)
-      return;
-
-    if (Py_IsInitialized())
-      Py_XDECREF(m_py_obj);
-
-    m_py_obj = py_obj;
-
-    // If this is a borrowed reference, we need to convert it to
-    // an owned reference by incrementing it.  If it is an owned
-    // reference (for example the caller allocated it with PyDict_New()
-    // then we must *not* increment it.
-    if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
-      Py_XINCREF(m_py_obj);
-  }
-
   void Dump() const {
     if (m_py_obj)
       _PyObject_Dump(m_py_obj);
@@ -304,17 +310,6 @@ class PythonObject {
   StructuredData::ObjectSP CreateStructuredObject() const;
 
 protected:
-  static llvm::Error nullDeref() {
-    return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                   "A NULL PyObject* was dereferenced");
-  }
-  static llvm::Error exception(const char *s = nullptr) {
-    return llvm::make_error<PythonException>(s);
-  }
-  static llvm::Error keyError() {
-    return llvm::createStringError(llvm::inconvertibleErrorCode(),
-                                   "key not in dict");
-  }
 
 #if PY_MAJOR_VERSION < 3
   // The python 2 API declares some arguments as char* that should
@@ -348,7 +343,6 @@ class PythonObject {
   }
 
   llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
-    using namespace python;
     if (!m_py_obj)
       return nullDeref();
     PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
@@ -389,7 +383,6 @@ class PythonObject {
   PyObject *m_py_obj;
 };
 
-namespace python {
 
 // This is why C++ needs monads.
 template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
@@ -409,7 +402,6 @@ llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
 template <>
 llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
 
-} // namespace python
 
 template <class T> class TypedPythonObject : public PythonObject {
 public:
@@ -417,16 +409,12 @@ template <class T> class TypedPythonObject : public PythonObject {
   // This can be eliminated once we drop python 2 support.
   static void Convert(PyRefType &type, PyObject *&py_obj) {}
 
-  void Reset() { PythonObject::Reset(); }
-
-  void Reset(PyRefType type, PyObject *py_obj) = delete;
-
   TypedPythonObject(PyRefType type, PyObject *py_obj) {
     if (!py_obj)
       return;
     T::Convert(type, py_obj);
     if (T::Check(py_obj))
-      PythonObject::Reset(type, py_obj);
+      PythonObject::operator=(PythonObject(type, py_obj));
     else if (type == PyRefType::Owned)
       Py_DECREF(py_obj);
   }
@@ -698,6 +686,8 @@ class PythonException : public llvm::ErrorInfo<PythonException> {
   ~PythonException();
   void log(llvm::raw_ostream &OS) const override;
   std::error_code convertToErrorCode() const override;
+  bool Matches(PyObject *exc) const;
+  std::string ReadBacktrace() const;
 };
 
 // This extracts the underlying T out of an Expected<T> and returns it.
@@ -732,7 +722,6 @@ template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
   return T();
 }
 
-namespace python {
 // This is only here to help incrementally migrate old, exception-unsafe
 // code.
 template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
@@ -741,8 +730,50 @@ template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
   llvm::consumeError(expected.takeError());
   return T();
 }
-} // namespace python
 
+llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
+                                              const PythonDictionary &globals,
+                                              const PythonDictionary &locals);
+
+llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
+                                                const PythonDictionary &globals,
+                                                const PythonDictionary &locals);
+
+// Sometimes the best way to interact with a python interpreter is
+// to run some python code.   You construct a PythonScript with
+// script string.   The script assigns some function to `_function_`
+// and you get a C++ callable object that calls the python function.
+//
+// Example:
+//
+// const char script[] = R"(
+// def main(x, y):
+//    ....
+// )";
+//
+// Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
+//   // no need to synchronize access to this global, we already have the GIL
+//   static PythonScript foo(script)
+//   return  foo(x, y);
+// }
+class PythonScript {
+  const char *script;
+  PythonCallable function;
+
+  llvm::Error Init();
+
+public:
+  PythonScript(const char *script) : script(script), function() {}
+
+  template <typename... Args>
+  llvm::Expected<PythonObject> operator()(Args &&... args) {
+    if (llvm::Error error = Init())
+      return std::move(error);
+    return function.Call(std::forward<Args>(args)...);
+  }
+};
+
+} // namespace python
 } // namespace lldb_private
 
 #endif

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
deleted file mode 100644
index c9d834ce6868..000000000000
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-//===-- PythonExceptionState.cpp --------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_DISABLE_PYTHON
-
-// LLDB Python header must be included first
-#include "lldb-python.h"
-
-#include "PythonExceptionState.h"
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace lldb_private;
-
-PythonExceptionState::PythonExceptionState(bool restore_on_exit)
-    : m_restore_on_exit(restore_on_exit) {
-  Acquire(restore_on_exit);
-}
-
-PythonExceptionState::~PythonExceptionState() {
-  if (m_restore_on_exit)
-    Restore();
-}
-
-void PythonExceptionState::Acquire(bool restore_on_exit) {
-  // If a state is already acquired, the user needs to decide whether they want
-  // to discard or restore it.  Don't allow the potential silent loss of a
-  // valid state.
-  assert(!IsError());
-
-  if (!HasErrorOccurred())
-    return;
-
-  PyObject *py_type = nullptr;
-  PyObject *py_value = nullptr;
-  PyObject *py_traceback = nullptr;
-  PyErr_Fetch(&py_type, &py_value, &py_traceback);
-  // PyErr_Fetch clears the error flag.
-  assert(!HasErrorOccurred());
-
-  // Ownership of the objects returned by `PyErr_Fetch` is transferred to us.
-  m_type.Reset(PyRefType::Owned, py_type);
-  m_value.Reset(PyRefType::Owned, py_value);
-  m_traceback.Reset(PyRefType::Owned, py_traceback);
-  m_restore_on_exit = restore_on_exit;
-}
-
-void PythonExceptionState::Restore() {
-  if (m_type.IsValid()) {
-    // The documentation for PyErr_Restore says "Do not pass a null type and
-    // non-null value or traceback.  So only restore if type was non-null to
-    // begin with.  In this case we're passing ownership back to Python so
-    // release them all.
-    PyErr_Restore(m_type.release(), m_value.release(), m_traceback.release());
-  }
-
-  // After we restore, we should not hold onto the exception state.  Demand
-  // that it be re-acquired.
-  Discard();
-}
-
-void PythonExceptionState::Discard() {
-  m_type.Reset();
-  m_value.Reset();
-  m_traceback.Reset();
-}
-
-void PythonExceptionState::Reset() {
-  if (m_restore_on_exit)
-    Restore();
-  else
-    Discard();
-}
-
-bool PythonExceptionState::HasErrorOccurred() { return PyErr_Occurred(); }
-
-bool PythonExceptionState::IsError() const {
-  return m_type.IsValid() || m_value.IsValid() || m_traceback.IsValid();
-}
-
-PythonObject PythonExceptionState::GetType() const { return m_type; }
-
-PythonObject PythonExceptionState::GetValue() const { return m_value; }
-
-PythonObject PythonExceptionState::GetTraceback() const { return m_traceback; }
-
-std::string PythonExceptionState::Format() const {
-  // Don't allow this function to modify the error state.
-  PythonExceptionState state(true);
-
-  std::string backtrace = ReadBacktrace();
-  if (!IsError())
-    return std::string();
-
-  // It's possible that ReadPythonBacktrace generated another exception. If
-  // this happens we have to clear the exception, because otherwise
-  // PyObject_Str() will assert below.  That's why we needed to do the save /
-  // restore at the beginning of this function.
-  PythonExceptionState bt_error_state(false);
-
-  std::string error_string;
-  llvm::raw_string_ostream error_stream(error_string);
-  error_stream << m_value.Str().GetString() << "\n";
-
-  if (!bt_error_state.IsError()) {
-    // If we were able to read the backtrace, just append it.
-    error_stream << backtrace << "\n";
-  } else {
-    // Otherwise, append some information about why we were unable to obtain
-    // the backtrace.
-    PythonString bt_error = bt_error_state.GetValue().Str();
-    error_stream << "An error occurred while retrieving the backtrace: "
-                 << bt_error.GetString() << "\n";
-  }
-  return error_stream.str();
-}
-
-std::string PythonExceptionState::ReadBacktrace() const {
-  std::string retval("backtrace unavailable");
-
-  auto traceback_module = PythonModule::ImportModule("traceback");
-#if PY_MAJOR_VERSION >= 3
-  auto stringIO_module = PythonModule::ImportModule("io");
-#else
-  auto stringIO_module = PythonModule::ImportModule("StringIO");
-#endif
-  if (!m_traceback.IsAllocated())
-    return retval;
-
-  if (!traceback_module.IsAllocated() || !stringIO_module.IsAllocated())
-    return retval;
-
-  auto stringIO_builder =
-      stringIO_module.ResolveName<PythonCallable>("StringIO");
-  if (!stringIO_builder.IsAllocated())
-    return retval;
-
-  auto stringIO_buffer = stringIO_builder();
-  if (!stringIO_buffer.IsAllocated())
-    return retval;
-
-  auto printTB = traceback_module.ResolveName<PythonCallable>("print_tb");
-  if (!printTB.IsAllocated())
-    return retval;
-
-  auto printTB_result =
-      printTB(m_traceback.get(), Py_None, stringIO_buffer.get());
-  auto stringIO_getvalue =
-      stringIO_buffer.ResolveName<PythonCallable>("getvalue");
-  if (!stringIO_getvalue.IsAllocated())
-    return retval;
-
-  auto printTB_string = stringIO_getvalue().AsType<PythonString>();
-  if (!printTB_string.IsAllocated())
-    return retval;
-
-  llvm::StringRef string_data(printTB_string.GetString());
-  retval.assign(string_data.data(), string_data.size());
-
-  return retval;
-}
-
-#endif

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h b/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
deleted file mode 100644
index 3a88aa037776..000000000000
--- a/lldb/source/Plugins/ScriptInterpreter/Python/PythonExceptionState.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- PythonExceptionState.h ----------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONEXCEPTIONSTATE_H
-#define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONEXCEPTIONSTATE_H
-
-#ifndef LLDB_DISABLE_PYTHON
-
-#include "PythonDataObjects.h"
-
-namespace lldb_private {
-
-class PythonExceptionState {
-public:
-  explicit PythonExceptionState(bool restore_on_exit);
-  ~PythonExceptionState();
-
-  void Acquire(bool restore_on_exit);
-
-  void Restore();
-
-  void Discard();
-
-  void Reset();
-
-  static bool HasErrorOccurred();
-
-  bool IsError() const;
-
-  PythonObject GetType() const;
-
-  PythonObject GetValue() const;
-
-  PythonObject GetTraceback() const;
-
-  std::string Format() const;
-
-private:
-  std::string ReadBacktrace() const;
-
-  bool m_restore_on_exit;
-
-  PythonObject m_type;
-  PythonObject m_value;
-  PythonObject m_traceback;
-};
-}
-
-#endif
-
-#endif

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index 8f7133524163..3eee52184142 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -16,7 +16,6 @@
 #include "lldb-python.h"
 
 #include "PythonDataObjects.h"
-#include "PythonExceptionState.h"
 #include "ScriptInterpreterPythonImpl.h"
 
 #include "lldb/API/SBFrame.h"
@@ -56,6 +55,7 @@
 using namespace lldb;
 using namespace lldb_private;
 using namespace lldb_private::python;
+using llvm::Expected;
 
 // Defined in the SWIG source file
 #if PY_MAJOR_VERSION >= 3
@@ -747,9 +747,9 @@ bool ScriptInterpreterPythonImpl::EnterSession(uint16_t on_entry_flags,
   return true;
 }
 
-PythonObject &ScriptInterpreterPythonImpl::GetMainModule() {
+PythonModule &ScriptInterpreterPythonImpl::GetMainModule() {
   if (!m_main_module.IsValid())
-    m_main_module.Reset(PyRefType::Borrowed, PyImport_AddModule("__main__"));
+    m_main_module = unwrapIgnoringErrors(PythonModule::Import("__main__"));
   return m_main_module;
 }
 
@@ -1030,6 +1030,7 @@ bool ScriptInterpreterPythonImpl::Interrupt() {
             "can't interrupt");
   return false;
 }
+
 bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
     llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type,
     void *ret_value, const ExecuteScriptOptions &options) {
@@ -1040,151 +1041,111 @@ bool ScriptInterpreterPythonImpl::ExecuteOneLineWithReturn(
                     Locker::NoSTDIN,
                 Locker::FreeAcquiredLock | Locker::TearDownSession);
 
-  PythonObject py_return;
-  PythonObject &main_module = GetMainModule();
-  PythonDictionary globals(PyRefType::Borrowed,
-                           PyModule_GetDict(main_module.get()));
-  PythonObject py_error;
-  bool ret_success = false;
-  int success;
+  PythonModule &main_module = GetMainModule();
+  PythonDictionary globals = main_module.GetDictionary();
 
   PythonDictionary locals = GetSessionDictionary();
-
-  if (!locals.IsValid()) {
+  if (!locals.IsValid())
     locals = unwrapIgnoringErrors(
         As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
-  }
-
   if (!locals.IsValid())
     locals = globals;
 
-  py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
-  if (py_error.IsValid())
-    PyErr_Clear();
-
-  std::string as_string = in_string.str();
-  { // scope for PythonInputReaderManager
-    // PythonInputReaderManager py_input(options.GetEnableIO() ? this : NULL);
-    py_return.Reset(PyRefType::Owned,
-                    PyRun_String(as_string.c_str(), Py_eval_input,
-                                 globals.get(), locals.get()));
-    if (!py_return.IsValid()) {
-      py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
-      if (py_error.IsValid())
-        PyErr_Clear();
-
-      py_return.Reset(PyRefType::Owned,
-                      PyRun_String(as_string.c_str(), Py_single_input,
-                                   globals.get(), locals.get()));
-    }
+  Expected<PythonObject> maybe_py_return =
+      runStringOneLine(in_string, globals, locals);
+
+  if (!maybe_py_return) {
+    llvm::handleAllErrors(
+        maybe_py_return.takeError(),
+        [&](PythonException &E) {
+          E.Restore();
+          if (options.GetMaskoutErrors()) {
+            if (E.Matches(PyExc_SyntaxError)) {
+              PyErr_Print();
+            }
+            PyErr_Clear();
+          }
+        },
+        [](const llvm::ErrorInfoBase &E) {});
+    return false;
   }
 
-  if (py_return.IsValid()) {
-    switch (return_type) {
-    case eScriptReturnTypeCharPtr: // "char *"
-    {
-      const char format[3] = "s#";
-      success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
-      break;
-    }
-    case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
-                                         // Py_None
-    {
-      const char format[3] = "z";
-      success = PyArg_Parse(py_return.get(), format, (char **)ret_value);
-      break;
-    }
-    case eScriptReturnTypeBool: {
-      const char format[2] = "b";
-      success = PyArg_Parse(py_return.get(), format, (bool *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeShortInt: {
-      const char format[2] = "h";
-      success = PyArg_Parse(py_return.get(), format, (short *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeShortIntUnsigned: {
-      const char format[2] = "H";
-      success =
-          PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeInt: {
-      const char format[2] = "i";
-      success = PyArg_Parse(py_return.get(), format, (int *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeIntUnsigned: {
-      const char format[2] = "I";
-      success = PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeLongInt: {
-      const char format[2] = "l";
-      success = PyArg_Parse(py_return.get(), format, (long *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeLongIntUnsigned: {
-      const char format[2] = "k";
-      success =
-          PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeLongLong: {
-      const char format[2] = "L";
-      success = PyArg_Parse(py_return.get(), format, (long long *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeLongLongUnsigned: {
-      const char format[2] = "K";
-      success =
-          PyArg_Parse(py_return.get(), format, (unsigned long long *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeFloat: {
-      const char format[2] = "f";
-      success = PyArg_Parse(py_return.get(), format, (float *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeDouble: {
-      const char format[2] = "d";
-      success = PyArg_Parse(py_return.get(), format, (double *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeChar: {
-      const char format[2] = "c";
-      success = PyArg_Parse(py_return.get(), format, (char *)ret_value);
-      break;
-    }
-    case eScriptReturnTypeOpaqueObject: {
-      success = true;
-      PyObject *saved_value = py_return.get();
-      Py_XINCREF(saved_value);
-      *((PyObject **)ret_value) = saved_value;
-      break;
-    }
-    }
+  PythonObject py_return = std::move(maybe_py_return.get());
+  assert(py_return.IsValid());
 
-    ret_success = success;
+  switch (return_type) {
+  case eScriptReturnTypeCharPtr: // "char *"
+  {
+    const char format[3] = "s#";
+    return PyArg_Parse(py_return.get(), format, (char **)ret_value);
+  }
+  case eScriptReturnTypeCharStrOrNone: // char* or NULL if py_return ==
+                                       // Py_None
+  {
+    const char format[3] = "z";
+    return PyArg_Parse(py_return.get(), format, (char **)ret_value);
+  }
+  case eScriptReturnTypeBool: {
+    const char format[2] = "b";
+    return PyArg_Parse(py_return.get(), format, (bool *)ret_value);
+  }
+  case eScriptReturnTypeShortInt: {
+    const char format[2] = "h";
+    return PyArg_Parse(py_return.get(), format, (short *)ret_value);
+  }
+  case eScriptReturnTypeShortIntUnsigned: {
+    const char format[2] = "H";
+    return PyArg_Parse(py_return.get(), format, (unsigned short *)ret_value);
+  }
+  case eScriptReturnTypeInt: {
+    const char format[2] = "i";
+    return PyArg_Parse(py_return.get(), format, (int *)ret_value);
+  }
+  case eScriptReturnTypeIntUnsigned: {
+    const char format[2] = "I";
+    return PyArg_Parse(py_return.get(), format, (unsigned int *)ret_value);
+  }
+  case eScriptReturnTypeLongInt: {
+    const char format[2] = "l";
+    return PyArg_Parse(py_return.get(), format, (long *)ret_value);
+  }
+  case eScriptReturnTypeLongIntUnsigned: {
+    const char format[2] = "k";
+    return PyArg_Parse(py_return.get(), format, (unsigned long *)ret_value);
+  }
+  case eScriptReturnTypeLongLong: {
+    const char format[2] = "L";
+    return PyArg_Parse(py_return.get(), format, (long long *)ret_value);
+  }
+  case eScriptReturnTypeLongLongUnsigned: {
+    const char format[2] = "K";
+    return PyArg_Parse(py_return.get(), format,
+                       (unsigned long long *)ret_value);
+  }
+  case eScriptReturnTypeFloat: {
+    const char format[2] = "f";
+    return PyArg_Parse(py_return.get(), format, (float *)ret_value);
+  }
+  case eScriptReturnTypeDouble: {
+    const char format[2] = "d";
+    return PyArg_Parse(py_return.get(), format, (double *)ret_value);
+  }
+  case eScriptReturnTypeChar: {
+    const char format[2] = "c";
+    return PyArg_Parse(py_return.get(), format, (char *)ret_value);
+  }
+  case eScriptReturnTypeOpaqueObject: {
+    *((PyObject **)ret_value) = py_return.release();
+    return true;
   }
-
-  py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
-  if (py_error.IsValid()) {
-    ret_success = false;
-    if (options.GetMaskoutErrors()) {
-      if (PyErr_GivenExceptionMatches(py_error.get(), PyExc_SyntaxError))
-        PyErr_Print();
-      PyErr_Clear();
-    }
   }
-
-  return ret_success;
 }
 
 Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
     const char *in_string, const ExecuteScriptOptions &options) {
-  Status error;
+
+  if (in_string == nullptr)
+    return Status();
 
   Locker locker(this,
                 Locker::AcquireLock | Locker::InitSession |
@@ -1192,51 +1153,32 @@ Status ScriptInterpreterPythonImpl::ExecuteMultipleLines(
                     Locker::NoSTDIN,
                 Locker::FreeAcquiredLock | Locker::TearDownSession);
 
-  PythonObject return_value;
-  PythonObject &main_module = GetMainModule();
-  PythonDictionary globals(PyRefType::Borrowed,
-                           PyModule_GetDict(main_module.get()));
-  PythonObject py_error;
+  PythonModule &main_module = GetMainModule();
+  PythonDictionary globals = main_module.GetDictionary();
 
   PythonDictionary locals = GetSessionDictionary();
-
   if (!locals.IsValid())
     locals = unwrapIgnoringErrors(
         As<PythonDictionary>(globals.GetAttribute(m_dictionary_name)));
-
   if (!locals.IsValid())
     locals = globals;
 
-  py_error.Reset(PyRefType::Borrowed, PyErr_Occurred());
-  if (py_error.IsValid())
-    PyErr_Clear();
-
-  if (in_string != nullptr) {
-    PythonObject code_object;
-    code_object.Reset(PyRefType::Owned,
-                      Py_CompileString(in_string, "temp.py", Py_file_input));
+  Expected<PythonObject> return_value =
+      runStringMultiLine(in_string, globals, locals);
 
-    if (code_object.IsValid()) {
-// In Python 2.x, PyEval_EvalCode takes a PyCodeObject, but in Python 3.x, it
-// takes a PyObject.  They are convertible (hence the function
-// PyCode_Check(PyObject*), so we have to do the cast for Python 2.x
-#if PY_MAJOR_VERSION >= 3
-      PyObject *py_code_obj = code_object.get();
-#else
-      PyCodeObject *py_code_obj =
-          reinterpret_cast<PyCodeObject *>(code_object.get());
-#endif
-      return_value.Reset(
-          PyRefType::Owned,
-          PyEval_EvalCode(py_code_obj, globals.get(), locals.get()));
-    }
+  if (!return_value) {
+    llvm::Error error =
+        llvm::handleErrors(return_value.takeError(), [&](PythonException &E) {
+          llvm::Error error = llvm::createStringError(
+              llvm::inconvertibleErrorCode(), E.ReadBacktrace());
+          if (!options.GetMaskoutErrors())
+            E.Restore();
+          return error;
+        });
+    return Status(std::move(error));
   }
 
-  PythonExceptionState exception_state(!options.GetMaskoutErrors());
-  if (exception_state.IsError())
-    error.SetErrorString(exception_state.Format().c_str());
-
-  return error;
+  return Status();
 }
 
 void ScriptInterpreterPythonImpl::CollectDataForBreakpointCommandCallback(
@@ -2030,15 +1972,22 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings(
   if (!generic)
     return StructuredData::DictionarySP();
 
-  PythonObject reply_pyobj;
   Locker py_lock(this,
                  Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
   TargetSP target_sp(target->shared_from_this());
-  reply_pyobj.Reset(PyRefType::Owned,
-                    (PyObject *)LLDBSWIGPython_GetDynamicSetting(
-                        generic->GetValue(), setting_name, target_sp));
 
-  PythonDictionary py_dict(PyRefType::Borrowed, reply_pyobj.get());
+  auto setting = (PyObject *)LLDBSWIGPython_GetDynamicSetting(
+      generic->GetValue(), setting_name, target_sp);
+
+  if (!setting)
+    return StructuredData::DictionarySP();
+
+  PythonDictionary py_dict =
+      unwrapIgnoringErrors(As<PythonDictionary>(Take<PythonObject>(setting)));
+
+  if (!py_dict)
+    return StructuredData::DictionarySP();
+
   return py_dict.CreateStructuredDictionary();
 }
 

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
index 373513f8e47d..929567e579d8 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h
@@ -363,25 +363,25 @@ class ScriptInterpreterPythonImpl : public ScriptInterpreterPython {
     eIOHandlerWatchpoint
   };
 
-  PythonObject &GetMainModule();
+  python::PythonModule &GetMainModule();
 
-  PythonDictionary &GetSessionDictionary();
+  python::PythonDictionary &GetSessionDictionary();
 
-  PythonDictionary &GetSysModuleDictionary();
+  python::PythonDictionary &GetSysModuleDictionary();
 
   bool GetEmbeddedInterpreterModuleObjects();
 
   bool SetStdHandle(lldb::FileSP file, const char *py_name,
-                    PythonObject &save_file, const char *mode);
-
-  PythonObject m_saved_stdin;
-  PythonObject m_saved_stdout;
-  PythonObject m_saved_stderr;
-  PythonObject m_main_module;
-  PythonDictionary m_session_dict;
-  PythonDictionary m_sys_module_dict;
-  PythonObject m_run_one_line_function;
-  PythonObject m_run_one_line_str_global;
+                    python::PythonObject &save_file, const char *mode);
+
+  python::PythonObject m_saved_stdin;
+  python::PythonObject m_saved_stdout;
+  python::PythonObject m_saved_stderr;
+  python::PythonModule m_main_module;
+  python::PythonDictionary m_session_dict;
+  python::PythonDictionary m_sys_module_dict;
+  python::PythonObject m_run_one_line_function;
+  python::PythonObject m_run_one_line_str_global;
   std::string m_dictionary_name;
   ActiveIOHandler m_active_io_handler;
   bool m_session_is_active;

diff  --git a/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt b/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt
index 618767de91ed..471f4c6dbc35 100644
--- a/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt
+++ b/lldb/unittests/ScriptInterpreter/Python/CMakeLists.txt
@@ -1,6 +1,5 @@
 add_lldb_unittest(ScriptInterpreterPythonTests
   PythonDataObjectsTests.cpp
-  PythonExceptionStateTests.cpp
   PythonTestSuite.cpp
 
   LINK_LIBS

diff  --git a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
index c01dade44408..b676b42da666 100644
--- a/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
+++ b/lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp
@@ -21,6 +21,8 @@
 
 using namespace lldb_private;
 using namespace lldb_private::python;
+using llvm::Error;
+using llvm::Expected;
 
 class PythonDataObjectsTest : public PythonTestSuite {
 public:
@@ -771,4 +773,86 @@ bar_unbound = Foo.bar
   }
 
 #endif
+}
+
+TEST_F(PythonDataObjectsTest, TestScript) {
+
+  static const char script[] = R"(
+def factorial(n):
+  if n > 1:
+    return n * factorial(n-1)
+  else:
+    return 1;
+main = factorial
+)";
+
+  PythonScript factorial(script);
+
+  EXPECT_THAT_EXPECTED(As<long long>(factorial(5ll)), llvm::HasValue(120));
+}
+
+TEST_F(PythonDataObjectsTest, TestExceptions) {
+
+  static const char script[] = R"(
+def foo():
+  return bar()
+def bar():
+  return baz()
+def baz():
+  return 1 / 0
+main = foo
+)";
+
+  PythonScript foo(script);
+
+  EXPECT_THAT_EXPECTED(foo(),
+                       llvm::Failed<PythonException>(testing::Property(
+                           &PythonException::ReadBacktrace,
+                           testing::ContainsRegex("line 3, in foo..*"
+                                                  "line 5, in bar.*"
+                                                  "line 7, in baz.*"
+                                                  "ZeroDivisionError"))));
+
+  static const char script2[] = R"(
+class MyError(Exception):
+  def __str__(self):
+    return self.my_message
+
+def main():
+  raise MyError("lol")
+
+)";
+
+  PythonScript lol(script2);
+
+  EXPECT_THAT_EXPECTED(lol(),
+                       llvm::Failed<PythonException>(testing::Property(
+                           &PythonException::ReadBacktrace,
+                           testing::ContainsRegex("unprintable MyError"))));
+}
+
+TEST_F(PythonDataObjectsTest, TestRun) {
+
+  PythonDictionary globals(PyInitialValue::Empty);
+
+  auto x = As<long long>(runStringOneLine("40 + 2", globals, globals));
+  ASSERT_THAT_EXPECTED(x, llvm::Succeeded());
+  EXPECT_EQ(x.get(), 42l);
+
+  Expected<PythonObject> r = runStringOneLine("n = 42", globals, globals);
+  ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
+  auto y = As<long long>(globals.GetItem("n"));
+  ASSERT_THAT_EXPECTED(y, llvm::Succeeded());
+  EXPECT_EQ(y.get(), 42l);
+
+  const char script[] = R"(
+def foobar():
+  return "foo" + "bar" + "baz"
+g = foobar()
+)";
+
+  r = runStringMultiLine(script, globals, globals);
+  ASSERT_THAT_EXPECTED(r, llvm::Succeeded());
+  auto g = As<std::string>(globals.GetItem("g"));
+  ASSERT_THAT_EXPECTED(g, llvm::HasValue("foobarbaz"));
 }
\ No newline at end of file

diff  --git a/lldb/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp b/lldb/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp
deleted file mode 100644
index 8334e64738e8..000000000000
--- a/lldb/unittests/ScriptInterpreter/Python/PythonExceptionStateTests.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-//===-- PythonExceptionStateTest.cpp ------------------------------*- C++
-//-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "gtest/gtest.h"
-
-#include "Plugins/ScriptInterpreter/Python/PythonDataObjects.h"
-#include "Plugins/ScriptInterpreter/Python/PythonExceptionState.h"
-#include "Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h"
-#include "Plugins/ScriptInterpreter/Python/lldb-python.h"
-
-#include "PythonTestSuite.h"
-
-using namespace lldb_private;
-
-class PythonExceptionStateTest : public PythonTestSuite {
-public:
-protected:
-  void RaiseException() {
-    PyErr_SetString(PyExc_RuntimeError, "PythonExceptionStateTest test error");
-  }
-};
-
-TEST_F(PythonExceptionStateTest, TestExceptionStateChecking) {
-  PyErr_Clear();
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-
-  RaiseException();
-  EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
-
-  PyErr_Clear();
-}
-
-TEST_F(PythonExceptionStateTest, TestAcquisitionSemantics) {
-  PyErr_Clear();
-  PythonExceptionState no_error(false);
-  EXPECT_FALSE(no_error.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-
-  PyErr_Clear();
-  RaiseException();
-  PythonExceptionState error(false);
-  EXPECT_TRUE(error.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-  error.Discard();
-
-  PyErr_Clear();
-  RaiseException();
-  error.Acquire(false);
-  EXPECT_TRUE(error.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-
-  PyErr_Clear();
-}
-
-TEST_F(PythonExceptionStateTest, TestDiscardSemantics) {
-  PyErr_Clear();
-
-  // Test that discarding an exception does not restore the exception
-  // state even when auto-restore==true is set
-  RaiseException();
-  PythonExceptionState error(true);
-  EXPECT_TRUE(error.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-
-  error.Discard();
-  EXPECT_FALSE(error.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-}
-
-TEST_F(PythonExceptionStateTest, TestResetSemantics) {
-  PyErr_Clear();
-
-  // Resetting when auto-restore is true should restore.
-  RaiseException();
-  PythonExceptionState error(true);
-  EXPECT_TRUE(error.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-  error.Reset();
-  EXPECT_FALSE(error.IsError());
-  EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
-
-  PyErr_Clear();
-
-  // Resetting when auto-restore is false should discard.
-  RaiseException();
-  PythonExceptionState error2(false);
-  EXPECT_TRUE(error2.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-  error2.Reset();
-  EXPECT_FALSE(error2.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-
-  PyErr_Clear();
-}
-
-TEST_F(PythonExceptionStateTest, TestManualRestoreSemantics) {
-  PyErr_Clear();
-  RaiseException();
-  PythonExceptionState error(false);
-  EXPECT_TRUE(error.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-
-  error.Restore();
-  EXPECT_FALSE(error.IsError());
-  EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
-
-  PyErr_Clear();
-}
-
-TEST_F(PythonExceptionStateTest, TestAutoRestoreSemantics) {
-  PyErr_Clear();
-  // Test that using the auto-restore flag correctly restores the exception
-  // state on destruction, and not using the auto-restore flag correctly
-  // does NOT restore the state on destruction.
-  {
-    RaiseException();
-    PythonExceptionState error(false);
-    EXPECT_TRUE(error.IsError());
-    EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-  }
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-
-  PyErr_Clear();
-  {
-    RaiseException();
-    PythonExceptionState error(true);
-    EXPECT_TRUE(error.IsError());
-    EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-  }
-  EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
-
-  PyErr_Clear();
-}
-
-TEST_F(PythonExceptionStateTest, TestAutoRestoreChanged) {
-  // Test that if we re-acquire with 
diff erent auto-restore semantics,
-  // that the new semantics are respected.
-  PyErr_Clear();
-
-  RaiseException();
-  PythonExceptionState error(false);
-  EXPECT_TRUE(error.IsError());
-
-  error.Reset();
-  EXPECT_FALSE(error.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-
-  RaiseException();
-  error.Acquire(true);
-  EXPECT_TRUE(error.IsError());
-  EXPECT_FALSE(PythonExceptionState::HasErrorOccurred());
-
-  error.Reset();
-  EXPECT_FALSE(error.IsError());
-  EXPECT_TRUE(PythonExceptionState::HasErrorOccurred());
-
-  PyErr_Clear();
-}


        


More information about the lldb-commits mailing list