1edb35d95SEugene Zelenko //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===//
22c1f46dcSZachary Turner //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62c1f46dcSZachary Turner //
72c1f46dcSZachary Turner //===----------------------------------------------------------------------===//
82c1f46dcSZachary Turner 
9085328eeSLawrence D'Anna //
10085328eeSLawrence D'Anna // !! FIXME FIXME FIXME !!
11085328eeSLawrence D'Anna //
12085328eeSLawrence D'Anna // Python APIs nearly all can return an exception.   They do this
13085328eeSLawrence D'Anna // by returning NULL, or -1, or some such value and setting
14085328eeSLawrence D'Anna // the exception state with PyErr_Set*().   Exceptions must be
15085328eeSLawrence D'Anna // handled before further python API functions are called.   Failure
16085328eeSLawrence D'Anna // to do so will result in asserts on debug builds of python.
17085328eeSLawrence D'Anna // It will also sometimes, but not usually result in crashes of
18085328eeSLawrence D'Anna // release builds.
19085328eeSLawrence D'Anna //
20085328eeSLawrence D'Anna // Nearly all the code in this header does not handle python exceptions
21085328eeSLawrence D'Anna // correctly.  It should all be converted to return Expected<> or
22085328eeSLawrence D'Anna // Error types to capture the exception.
23085328eeSLawrence D'Anna //
24085328eeSLawrence D'Anna // Everything in this file except functions that return Error or
25085328eeSLawrence D'Anna // Expected<> is considered deprecated and should not be
26085328eeSLawrence D'Anna // used in new code.  If you need to use it, fix it first.
27085328eeSLawrence D'Anna //
28d3bd5b3dSLawrence D'Anna //
29d3bd5b3dSLawrence D'Anna // TODOs for this file
30d3bd5b3dSLawrence D'Anna //
31d3bd5b3dSLawrence D'Anna // * Make all methods safe for exceptions.
32d3bd5b3dSLawrence D'Anna //
33d3bd5b3dSLawrence D'Anna // * Eliminate method signatures that must translate exceptions into
34d3bd5b3dSLawrence D'Anna //   empty objects or NULLs.   Almost everything here should return
35d3bd5b3dSLawrence D'Anna //   Expected<>.   It should be acceptable for certain operations that
36d3bd5b3dSLawrence D'Anna //   can never fail to assert instead, such as the creation of
37d3bd5b3dSLawrence D'Anna //   PythonString from a string literal.
38d3bd5b3dSLawrence D'Anna //
39e9264b74SKazuaki Ishizaki // * Eliminate Reset(), and make all non-default constructors private.
40d3bd5b3dSLawrence D'Anna //   Python objects should be created with Retain<> or Take<>, and they
41d3bd5b3dSLawrence D'Anna //   should be assigned with operator=
42d3bd5b3dSLawrence D'Anna //
43d3bd5b3dSLawrence D'Anna // * Eliminate default constructors, make python objects always
44d3bd5b3dSLawrence D'Anna //   nonnull, and use optionals where necessary.
45d3bd5b3dSLawrence D'Anna //
46d3bd5b3dSLawrence D'Anna 
47085328eeSLawrence D'Anna 
482c1f46dcSZachary Turner #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
492c1f46dcSZachary Turner #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
502c1f46dcSZachary Turner 
5159998b7bSJonas Devlieghere #include "lldb/Host/Config.h"
5259998b7bSJonas Devlieghere 
534e26cf2cSJonas Devlieghere #if LLDB_ENABLE_PYTHON
54d68983e3SPavel Labath 
5541de9a97SKate Stone // LLDB Python header must be included first
5641de9a97SKate Stone #include "lldb-python.h"
5741de9a97SKate Stone 
589c40264fSZachary Turner #include "lldb/Host/File.h"
59f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
602c1f46dcSZachary Turner 
615a72c02bSZachary Turner #include "llvm/ADT/ArrayRef.h"
625a72c02bSZachary Turner 
632c1f46dcSZachary Turner namespace lldb_private {
6404edd189SLawrence D'Anna namespace python {
65edb35d95SEugene Zelenko 
66085328eeSLawrence D'Anna class PythonObject;
675a72c02bSZachary Turner class PythonBytes;
682c1f46dcSZachary Turner class PythonString;
692c1f46dcSZachary Turner class PythonList;
702c1f46dcSZachary Turner class PythonDictionary;
712c1f46dcSZachary Turner class PythonInteger;
72085328eeSLawrence D'Anna class PythonException;
732c1f46dcSZachary Turner 
74bbef51ebSLawrence D'Anna class GIL {
75bbef51ebSLawrence D'Anna public:
76bbef51ebSLawrence D'Anna   GIL() {
77bbef51ebSLawrence D'Anna     m_state = PyGILState_Ensure();
78bbef51ebSLawrence D'Anna     assert(!PyErr_Occurred());
79bbef51ebSLawrence D'Anna   }
80bbef51ebSLawrence D'Anna   ~GIL() { PyGILState_Release(m_state); }
81bbef51ebSLawrence D'Anna 
82bbef51ebSLawrence D'Anna protected:
83bbef51ebSLawrence D'Anna   PyGILState_STATE m_state;
84bbef51ebSLawrence D'Anna };
85bbef51ebSLawrence D'Anna 
86b9c1b51eSKate Stone class StructuredPythonObject : public StructuredData::Generic {
872c1f46dcSZachary Turner public:
88b9c1b51eSKate Stone   StructuredPythonObject() : StructuredData::Generic() {}
892c1f46dcSZachary Turner 
90b9c1b51eSKate Stone   StructuredPythonObject(void *obj) : StructuredData::Generic(obj) {
91*a6598575SRalf Grosse-Kunstleve     assert(PyGILState_Check());
922c1f46dcSZachary Turner     Py_XINCREF(GetValue());
932c1f46dcSZachary Turner   }
942c1f46dcSZachary Turner 
95b9c1b51eSKate Stone   ~StructuredPythonObject() override {
96*a6598575SRalf Grosse-Kunstleve     if (Py_IsInitialized()) {
97*a6598575SRalf Grosse-Kunstleve       if (_Py_IsFinalizing()) {
98*a6598575SRalf Grosse-Kunstleve         // Leak GetValue() rather than crashing the process.
99*a6598575SRalf Grosse-Kunstleve         // https://docs.python.org/3/c-api/init.html#c.PyGILState_Ensure
100*a6598575SRalf Grosse-Kunstleve       } else {
101*a6598575SRalf Grosse-Kunstleve         PyGILState_STATE state = PyGILState_Ensure();
1022c1f46dcSZachary Turner         Py_XDECREF(GetValue());
103*a6598575SRalf Grosse-Kunstleve         PyGILState_Release(state);
104*a6598575SRalf Grosse-Kunstleve       }
105*a6598575SRalf Grosse-Kunstleve     }
1062c1f46dcSZachary Turner     SetValue(nullptr);
1072c1f46dcSZachary Turner   }
1082c1f46dcSZachary Turner 
109b9c1b51eSKate Stone   bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
1102c1f46dcSZachary Turner 
1112783d817SJonas Devlieghere   void Serialize(llvm::json::OStream &s) const override;
1122c1f46dcSZachary Turner 
1132c1f46dcSZachary Turner private:
114eaebcbc6SKonrad Kleine   StructuredPythonObject(const StructuredPythonObject &) = delete;
115eaebcbc6SKonrad Kleine   const StructuredPythonObject &
116eaebcbc6SKonrad Kleine   operator=(const StructuredPythonObject &) = delete;
1172c1f46dcSZachary Turner };
1182c1f46dcSZachary Turner 
119b9c1b51eSKate Stone enum class PyObjectType {
1202c1f46dcSZachary Turner   Unknown,
1212c1f46dcSZachary Turner   None,
122b81d715cSTatyana Krasnukha   Boolean,
1232c1f46dcSZachary Turner   Integer,
1242c1f46dcSZachary Turner   Dictionary,
1252c1f46dcSZachary Turner   List,
1269c40264fSZachary Turner   String,
1275a72c02bSZachary Turner   Bytes,
128f9d6d204SZachary Turner   ByteArray,
1297841efbbSZachary Turner   Module,
130a1405147SZachary Turner   Callable,
131a1405147SZachary Turner   Tuple,
1329c40264fSZachary Turner   File
1332c1f46dcSZachary Turner };
1342c1f46dcSZachary Turner 
135b9c1b51eSKate Stone enum class PyRefType {
136f8b22f8fSZachary Turner   Borrowed, // We are not given ownership of the incoming PyObject.
137f8b22f8fSZachary Turner             // We cannot safely hold it without calling Py_INCREF.
138f8b22f8fSZachary Turner   Owned     // We have ownership of the incoming PyObject.  We should
139f8b22f8fSZachary Turner             // not call Py_INCREF.
140f8b22f8fSZachary Turner };
141f8b22f8fSZachary Turner 
142085328eeSLawrence D'Anna 
143085328eeSLawrence D'Anna // Take a reference that you already own, and turn it into
144085328eeSLawrence D'Anna // a PythonObject.
145085328eeSLawrence D'Anna //
146085328eeSLawrence D'Anna // Most python API methods will return a +1 reference
147085328eeSLawrence D'Anna // if they succeed or NULL if and only if
148085328eeSLawrence D'Anna // they set an exception.   Use this to collect such return
149085328eeSLawrence D'Anna // values, after checking for NULL.
150085328eeSLawrence D'Anna //
151085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be
152085328eeSLawrence D'Anna // checked to be of the correct type.
153085328eeSLawrence D'Anna template <typename T> T Take(PyObject *obj) {
154085328eeSLawrence D'Anna   assert(obj);
155085328eeSLawrence D'Anna   assert(!PyErr_Occurred());
156085328eeSLawrence D'Anna   T thing(PyRefType::Owned, obj);
157085328eeSLawrence D'Anna   assert(thing.IsValid());
1581dfb1a85SPavel Labath   return thing;
159085328eeSLawrence D'Anna }
160085328eeSLawrence D'Anna 
161085328eeSLawrence D'Anna // Retain a reference you have borrowed, and turn it into
162085328eeSLawrence D'Anna // a PythonObject.
163085328eeSLawrence D'Anna //
164085328eeSLawrence D'Anna // A minority of python APIs return a borrowed reference
165085328eeSLawrence D'Anna // instead of a +1.   They will also return NULL if and only
166085328eeSLawrence D'Anna // if they set an exception.   Use this to collect such return
167085328eeSLawrence D'Anna // values, after checking for NULL.
168085328eeSLawrence D'Anna //
169085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be
170085328eeSLawrence D'Anna // checked to be of the correct type.
171085328eeSLawrence D'Anna template <typename T> T Retain(PyObject *obj) {
172085328eeSLawrence D'Anna   assert(obj);
173085328eeSLawrence D'Anna   assert(!PyErr_Occurred());
174085328eeSLawrence D'Anna   T thing(PyRefType::Borrowed, obj);
175085328eeSLawrence D'Anna   assert(thing.IsValid());
1761dfb1a85SPavel Labath   return thing;
177085328eeSLawrence D'Anna }
178085328eeSLawrence D'Anna 
179722b6189SLawrence D'Anna // This class can be used like a utility function to convert from
180722b6189SLawrence D'Anna // a llvm-friendly Twine into a null-terminated const char *,
181722b6189SLawrence D'Anna // which is the form python C APIs want their strings in.
182722b6189SLawrence D'Anna //
183722b6189SLawrence D'Anna // Example:
184722b6189SLawrence D'Anna // const llvm::Twine &some_twine;
185722b6189SLawrence D'Anna // PyFoo_Bar(x, y, z, NullTerminated(some_twine));
186722b6189SLawrence D'Anna //
187722b6189SLawrence D'Anna // Why a class instead of a function?  If the twine isn't already null
188722b6189SLawrence D'Anna // terminated, it will need a temporary buffer to copy the string
189722b6189SLawrence D'Anna // into.   We need that buffer to stick around for the lifetime of the
190722b6189SLawrence D'Anna // statement.
191722b6189SLawrence D'Anna class NullTerminated {
192722b6189SLawrence D'Anna   const char *str;
193722b6189SLawrence D'Anna   llvm::SmallString<32> storage;
194722b6189SLawrence D'Anna 
195722b6189SLawrence D'Anna public:
196722b6189SLawrence D'Anna   NullTerminated(const llvm::Twine &twine) {
197722b6189SLawrence D'Anna     llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
198722b6189SLawrence D'Anna     str = ref.begin();
199722b6189SLawrence D'Anna   }
200722b6189SLawrence D'Anna   operator const char *() { return str; }
201722b6189SLawrence D'Anna };
202722b6189SLawrence D'Anna 
20304edd189SLawrence D'Anna inline llvm::Error nullDeref() {
20404edd189SLawrence D'Anna   return llvm::createStringError(llvm::inconvertibleErrorCode(),
20504edd189SLawrence D'Anna                                  "A NULL PyObject* was dereferenced");
20604edd189SLawrence D'Anna }
20704edd189SLawrence D'Anna 
20804edd189SLawrence D'Anna inline llvm::Error exception(const char *s = nullptr) {
20904edd189SLawrence D'Anna   return llvm::make_error<PythonException>(s);
21004edd189SLawrence D'Anna }
21104edd189SLawrence D'Anna 
21204edd189SLawrence D'Anna inline llvm::Error keyError() {
21304edd189SLawrence D'Anna   return llvm::createStringError(llvm::inconvertibleErrorCode(),
21404edd189SLawrence D'Anna                                  "key not in dict");
21504edd189SLawrence D'Anna }
216085328eeSLawrence D'Anna 
2176a93a12aSLawrence D'Anna #if PY_MAJOR_VERSION < 3
2186a93a12aSLawrence D'Anna // The python 2 API declares some arguments as char* that should
2196a93a12aSLawrence D'Anna // be const char *, but it doesn't actually modify them.
2206a93a12aSLawrence D'Anna inline char *py2_const_cast(const char *s) { return const_cast<char *>(s); }
2216a93a12aSLawrence D'Anna #else
2226a93a12aSLawrence D'Anna inline const char *py2_const_cast(const char *s) { return s; }
2236a93a12aSLawrence D'Anna #endif
2246a93a12aSLawrence D'Anna 
225b9c1b51eSKate Stone enum class PyInitialValue { Invalid, Empty };
226f8b22f8fSZachary Turner 
227085328eeSLawrence D'Anna template <typename T, typename Enable = void> struct PythonFormat;
228085328eeSLawrence D'Anna 
229085328eeSLawrence D'Anna template <> struct PythonFormat<unsigned long long> {
230085328eeSLawrence D'Anna   static constexpr char format = 'K';
231085328eeSLawrence D'Anna   static auto get(unsigned long long value) { return value; }
232085328eeSLawrence D'Anna };
233085328eeSLawrence D'Anna 
234085328eeSLawrence D'Anna template <> struct PythonFormat<long long> {
235085328eeSLawrence D'Anna   static constexpr char format = 'L';
236085328eeSLawrence D'Anna   static auto get(long long value) { return value; }
237085328eeSLawrence D'Anna };
238085328eeSLawrence D'Anna 
23904edd189SLawrence D'Anna template <> struct PythonFormat<PyObject *> {
24004edd189SLawrence D'Anna   static constexpr char format = 'O';
24104edd189SLawrence D'Anna   static auto get(PyObject *value) { return value; }
24204edd189SLawrence D'Anna };
24304edd189SLawrence D'Anna 
244085328eeSLawrence D'Anna template <typename T>
245085328eeSLawrence D'Anna struct PythonFormat<
246085328eeSLawrence D'Anna     T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
247085328eeSLawrence D'Anna   static constexpr char format = 'O';
248085328eeSLawrence D'Anna   static auto get(const T &value) { return value.get(); }
249085328eeSLawrence D'Anna };
250085328eeSLawrence D'Anna 
251b9c1b51eSKate Stone class PythonObject {
2522c1f46dcSZachary Turner public:
253fd2433e1SJonas Devlieghere   PythonObject() = default;
2542c1f46dcSZachary Turner 
25504edd189SLawrence D'Anna   PythonObject(PyRefType type, PyObject *py_obj) {
25604edd189SLawrence D'Anna     m_py_obj = py_obj;
25704edd189SLawrence D'Anna     // If this is a borrowed reference, we need to convert it to
25804edd189SLawrence D'Anna     // an owned reference by incrementing it.  If it is an owned
25904edd189SLawrence D'Anna     // reference (for example the caller allocated it with PyDict_New()
26004edd189SLawrence D'Anna     // then we must *not* increment it.
26104edd189SLawrence D'Anna     if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
26204edd189SLawrence D'Anna       Py_XINCREF(m_py_obj);
2632c1f46dcSZachary Turner   }
2642c1f46dcSZachary Turner 
26503819d1cSLawrence D'Anna   PythonObject(const PythonObject &rhs)
26603819d1cSLawrence D'Anna       : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
2672c1f46dcSZachary Turner 
268085328eeSLawrence D'Anna   PythonObject(PythonObject &&rhs) {
269085328eeSLawrence D'Anna     m_py_obj = rhs.m_py_obj;
270085328eeSLawrence D'Anna     rhs.m_py_obj = nullptr;
271085328eeSLawrence D'Anna   }
272085328eeSLawrence D'Anna 
273d3bd5b3dSLawrence D'Anna   ~PythonObject() { Reset(); }
2742c1f46dcSZachary Turner 
275b9c1b51eSKate Stone   void Reset() {
276*a6598575SRalf Grosse-Kunstleve     if (m_py_obj && Py_IsInitialized()) {
277*a6598575SRalf Grosse-Kunstleve       if (_Py_IsFinalizing()) {
278*a6598575SRalf Grosse-Kunstleve         // Leak m_py_obj rather than crashing the process.
279*a6598575SRalf Grosse-Kunstleve         // https://docs.python.org/3/c-api/init.html#c.PyGILState_Ensure
280*a6598575SRalf Grosse-Kunstleve       } else {
281*a6598575SRalf Grosse-Kunstleve         PyGILState_STATE state = PyGILState_Ensure();
282085328eeSLawrence D'Anna         Py_DECREF(m_py_obj);
283*a6598575SRalf Grosse-Kunstleve         PyGILState_Release(state);
284*a6598575SRalf Grosse-Kunstleve       }
285*a6598575SRalf Grosse-Kunstleve     }
286f8b22f8fSZachary Turner     m_py_obj = nullptr;
2872c1f46dcSZachary Turner   }
288f8b22f8fSZachary Turner 
289b9c1b51eSKate Stone   void Dump() const {
2902c1f46dcSZachary Turner     if (m_py_obj)
2912c1f46dcSZachary Turner       _PyObject_Dump(m_py_obj);
2922c1f46dcSZachary Turner     else
2932c1f46dcSZachary Turner       puts("NULL");
2942c1f46dcSZachary Turner   }
2952c1f46dcSZachary Turner 
296b9c1b51eSKate Stone   void Dump(Stream &strm) const;
2972c1f46dcSZachary Turner 
298b9c1b51eSKate Stone   PyObject *get() const { return m_py_obj; }
2992c1f46dcSZachary Turner 
300b9c1b51eSKate Stone   PyObject *release() {
30160c24f70SZachary Turner     PyObject *result = m_py_obj;
30260c24f70SZachary Turner     m_py_obj = nullptr;
30360c24f70SZachary Turner     return result;
30460c24f70SZachary Turner   }
30560c24f70SZachary Turner 
30603819d1cSLawrence D'Anna   PythonObject &operator=(PythonObject other) {
307085328eeSLawrence D'Anna     Reset();
30803819d1cSLawrence D'Anna     m_py_obj = std::exchange(other.m_py_obj, nullptr);
309085328eeSLawrence D'Anna     return *this;
310085328eeSLawrence D'Anna   }
311085328eeSLawrence D'Anna 
312b9c1b51eSKate Stone   PyObjectType GetObjectType() const;
3137841efbbSZachary Turner 
314b9c1b51eSKate Stone   PythonString Repr() const;
3157841efbbSZachary Turner 
316b9c1b51eSKate Stone   PythonString Str() const;
3177841efbbSZachary Turner 
318b9c1b51eSKate Stone   static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
319b9c1b51eSKate Stone                                                 const PythonDictionary &dict);
3207841efbbSZachary Turner 
321b58fb2f4SZachary Turner   template <typename T>
322b9c1b51eSKate Stone   static T ResolveNameWithDictionary(llvm::StringRef name,
323b9c1b51eSKate Stone                                      const PythonDictionary &dict) {
324b58fb2f4SZachary Turner     return ResolveNameWithDictionary(name, dict).AsType<T>();
325b58fb2f4SZachary Turner   }
326b58fb2f4SZachary Turner 
327b9c1b51eSKate Stone   PythonObject ResolveName(llvm::StringRef name) const;
3287841efbbSZachary Turner 
329b9c1b51eSKate Stone   template <typename T> T ResolveName(llvm::StringRef name) const {
330b58fb2f4SZachary Turner     return ResolveName(name).AsType<T>();
331b58fb2f4SZachary Turner   }
332b58fb2f4SZachary Turner 
333b9c1b51eSKate Stone   bool HasAttribute(llvm::StringRef attribute) const;
3349c40264fSZachary Turner 
335b9c1b51eSKate Stone   PythonObject GetAttributeValue(llvm::StringRef attribute) const;
3367d6d218eSZachary Turner 
337085328eeSLawrence D'Anna   bool IsNone() const { return m_py_obj == Py_None; }
338f8b22f8fSZachary Turner 
339085328eeSLawrence D'Anna   bool IsValid() const { return m_py_obj != nullptr; }
340f8b22f8fSZachary Turner 
341085328eeSLawrence D'Anna   bool IsAllocated() const { return IsValid() && !IsNone(); }
342085328eeSLawrence D'Anna 
343085328eeSLawrence D'Anna   explicit operator bool() const { return IsValid() && !IsNone(); }
3442c1f46dcSZachary Turner 
345b9c1b51eSKate Stone   template <typename T> T AsType() const {
3467d6d218eSZachary Turner     if (!T::Check(m_py_obj))
3477d6d218eSZachary Turner       return T();
3487d6d218eSZachary Turner     return T(PyRefType::Borrowed, m_py_obj);
3497d6d218eSZachary Turner   }
3507d6d218eSZachary Turner 
351b9c1b51eSKate Stone   StructuredData::ObjectSP CreateStructuredObject() const;
3522c1f46dcSZachary Turner 
353085328eeSLawrence D'Anna   template <typename... T>
354085328eeSLawrence D'Anna   llvm::Expected<PythonObject> CallMethod(const char *name,
355085328eeSLawrence D'Anna                                           const T &... t) const {
356085328eeSLawrence D'Anna     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
357085328eeSLawrence D'Anna     PyObject *obj =
358c86a6acaSLawrence D'Anna         PyObject_CallMethod(m_py_obj, py2_const_cast(name),
359c86a6acaSLawrence D'Anna                             py2_const_cast(format), PythonFormat<T>::get(t)...);
360c86a6acaSLawrence D'Anna     if (!obj)
361c86a6acaSLawrence D'Anna       return exception();
362c86a6acaSLawrence D'Anna     return python::Take<PythonObject>(obj);
363c86a6acaSLawrence D'Anna   }
364c86a6acaSLawrence D'Anna 
365c86a6acaSLawrence D'Anna   template <typename... T>
366c86a6acaSLawrence D'Anna   llvm::Expected<PythonObject> Call(const T &... t) const {
367c86a6acaSLawrence D'Anna     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
368c86a6acaSLawrence D'Anna     PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
369c86a6acaSLawrence D'Anna                                           PythonFormat<T>::get(t)...);
370085328eeSLawrence D'Anna     if (!obj)
371085328eeSLawrence D'Anna       return exception();
372085328eeSLawrence D'Anna     return python::Take<PythonObject>(obj);
373085328eeSLawrence D'Anna   }
374085328eeSLawrence D'Anna 
375722b6189SLawrence D'Anna   llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
376085328eeSLawrence D'Anna     if (!m_py_obj)
377085328eeSLawrence D'Anna       return nullDeref();
378722b6189SLawrence D'Anna     PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
379085328eeSLawrence D'Anna     if (!obj)
380085328eeSLawrence D'Anna       return exception();
381085328eeSLawrence D'Anna     return python::Take<PythonObject>(obj);
382085328eeSLawrence D'Anna   }
383085328eeSLawrence D'Anna 
384085328eeSLawrence D'Anna   llvm::Expected<bool> IsTrue() {
385085328eeSLawrence D'Anna     if (!m_py_obj)
386085328eeSLawrence D'Anna       return nullDeref();
387085328eeSLawrence D'Anna     int r = PyObject_IsTrue(m_py_obj);
388085328eeSLawrence D'Anna     if (r < 0)
389085328eeSLawrence D'Anna       return exception();
390085328eeSLawrence D'Anna     return !!r;
391085328eeSLawrence D'Anna   }
392085328eeSLawrence D'Anna 
39352712d3fSLawrence D'Anna   llvm::Expected<long long> AsLongLong() const;
39452712d3fSLawrence D'Anna 
39552712d3fSLawrence D'Anna   llvm::Expected<long long> AsUnsignedLongLong() const;
39652712d3fSLawrence D'Anna 
39752712d3fSLawrence D'Anna   // wraps on overflow, instead of raising an error.
39852712d3fSLawrence D'Anna   llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
399085328eeSLawrence D'Anna 
400085328eeSLawrence D'Anna   llvm::Expected<bool> IsInstance(const PythonObject &cls) {
401085328eeSLawrence D'Anna     if (!m_py_obj || !cls.IsValid())
402085328eeSLawrence D'Anna       return nullDeref();
403085328eeSLawrence D'Anna     int r = PyObject_IsInstance(m_py_obj, cls.get());
404085328eeSLawrence D'Anna     if (r < 0)
405085328eeSLawrence D'Anna       return exception();
406085328eeSLawrence D'Anna     return !!r;
407085328eeSLawrence D'Anna   }
408085328eeSLawrence D'Anna 
409085328eeSLawrence D'Anna protected:
4109494c510SJonas Devlieghere   PyObject *m_py_obj = nullptr;
4112c1f46dcSZachary Turner };
4122c1f46dcSZachary Turner 
413085328eeSLawrence D'Anna 
414085328eeSLawrence D'Anna // This is why C++ needs monads.
415085328eeSLawrence D'Anna template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
416085328eeSLawrence D'Anna   if (!obj)
417085328eeSLawrence D'Anna     return obj.takeError();
418085328eeSLawrence D'Anna   if (!T::Check(obj.get().get()))
419085328eeSLawrence D'Anna     return llvm::createStringError(llvm::inconvertibleErrorCode(),
420085328eeSLawrence D'Anna                                    "type error");
421085328eeSLawrence D'Anna   return T(PyRefType::Borrowed, std::move(obj.get().get()));
422085328eeSLawrence D'Anna }
423085328eeSLawrence D'Anna 
424085328eeSLawrence D'Anna template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
425085328eeSLawrence D'Anna 
426085328eeSLawrence D'Anna template <>
427085328eeSLawrence D'Anna llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
428085328eeSLawrence D'Anna 
429c86a6acaSLawrence D'Anna template <>
43052712d3fSLawrence D'Anna llvm::Expected<unsigned long long>
43152712d3fSLawrence D'Anna As<unsigned long long>(llvm::Expected<PythonObject> &&obj);
43252712d3fSLawrence D'Anna 
43352712d3fSLawrence D'Anna template <>
434c86a6acaSLawrence D'Anna llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
435c86a6acaSLawrence D'Anna 
436085328eeSLawrence D'Anna 
437d3bd5b3dSLawrence D'Anna template <class T> class TypedPythonObject : public PythonObject {
4385a72c02bSZachary Turner public:
439d3bd5b3dSLawrence D'Anna   // override to perform implicit type conversions on Reset
440d3bd5b3dSLawrence D'Anna   // This can be eliminated once we drop python 2 support.
441d3bd5b3dSLawrence D'Anna   static void Convert(PyRefType &type, PyObject *&py_obj) {}
442d3bd5b3dSLawrence D'Anna 
443722b6189SLawrence D'Anna   TypedPythonObject(PyRefType type, PyObject *py_obj) {
444d3bd5b3dSLawrence D'Anna     if (!py_obj)
445d3bd5b3dSLawrence D'Anna       return;
446d3bd5b3dSLawrence D'Anna     T::Convert(type, py_obj);
447d3bd5b3dSLawrence D'Anna     if (T::Check(py_obj))
44804edd189SLawrence D'Anna       PythonObject::operator=(PythonObject(type, py_obj));
449d3bd5b3dSLawrence D'Anna     else if (type == PyRefType::Owned)
450d3bd5b3dSLawrence D'Anna       Py_DECREF(py_obj);
451d3bd5b3dSLawrence D'Anna   }
452d3bd5b3dSLawrence D'Anna 
453fd2433e1SJonas Devlieghere   TypedPythonObject() = default;
454d3bd5b3dSLawrence D'Anna };
455d3bd5b3dSLawrence D'Anna 
456d3bd5b3dSLawrence D'Anna class PythonBytes : public TypedPythonObject<PythonBytes> {
457d3bd5b3dSLawrence D'Anna public:
458d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
4595a72c02bSZachary Turner   explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
4605a72c02bSZachary Turner   PythonBytes(const uint8_t *bytes, size_t length);
4615a72c02bSZachary Turner 
462b9c1b51eSKate Stone   static bool Check(PyObject *py_obj);
4635a72c02bSZachary Turner 
464b9c1b51eSKate Stone   llvm::ArrayRef<uint8_t> GetBytes() const;
4655a72c02bSZachary Turner 
466b9c1b51eSKate Stone   size_t GetSize() const;
4675a72c02bSZachary Turner 
468b9c1b51eSKate Stone   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4695a72c02bSZachary Turner 
470b9c1b51eSKate Stone   StructuredData::StringSP CreateStructuredString() const;
4715a72c02bSZachary Turner };
4725a72c02bSZachary Turner 
473d3bd5b3dSLawrence D'Anna class PythonByteArray : public TypedPythonObject<PythonByteArray> {
474f9d6d204SZachary Turner public:
475d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
476f9d6d204SZachary Turner   explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
477f9d6d204SZachary Turner   PythonByteArray(const uint8_t *bytes, size_t length);
478f9d6d204SZachary Turner   PythonByteArray(const PythonBytes &object);
479f9d6d204SZachary Turner 
480b9c1b51eSKate Stone   static bool Check(PyObject *py_obj);
481f9d6d204SZachary Turner 
482b9c1b51eSKate Stone   llvm::ArrayRef<uint8_t> GetBytes() const;
483f9d6d204SZachary Turner 
484b9c1b51eSKate Stone   size_t GetSize() const;
485f9d6d204SZachary Turner 
486b9c1b51eSKate Stone   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
487f9d6d204SZachary Turner 
488b9c1b51eSKate Stone   StructuredData::StringSP CreateStructuredString() const;
489f9d6d204SZachary Turner };
490f9d6d204SZachary Turner 
491d3bd5b3dSLawrence D'Anna class PythonString : public TypedPythonObject<PythonString> {
4922c1f46dcSZachary Turner public:
493d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
494085328eeSLawrence D'Anna   static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
495085328eeSLawrence D'Anna 
496d3bd5b3dSLawrence D'Anna   PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
497edb35d95SEugene Zelenko 
498d3bd5b3dSLawrence D'Anna   explicit PythonString(llvm::StringRef string); // safe, null on error
4992c1f46dcSZachary Turner 
50022c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
501d3bd5b3dSLawrence D'Anna   static void Convert(PyRefType &type, PyObject *&py_obj);
5022c1f46dcSZachary Turner 
503085328eeSLawrence D'Anna   llvm::StringRef GetString() const; // safe, empty string on error
504085328eeSLawrence D'Anna 
505085328eeSLawrence D'Anna   llvm::Expected<llvm::StringRef> AsUTF8() const;
5062c1f46dcSZachary Turner 
507b9c1b51eSKate Stone   size_t GetSize() const;
5082c1f46dcSZachary Turner 
509085328eeSLawrence D'Anna   void SetString(llvm::StringRef string); // safe, null on error
5102c1f46dcSZachary Turner 
5112c1f46dcSZachary Turner   StructuredData::StringSP CreateStructuredString() const;
5122c1f46dcSZachary Turner };
5132c1f46dcSZachary Turner 
514d3bd5b3dSLawrence D'Anna class PythonInteger : public TypedPythonObject<PythonInteger> {
5152c1f46dcSZachary Turner public:
516d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
517edb35d95SEugene Zelenko 
518d3bd5b3dSLawrence D'Anna   PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
519d3bd5b3dSLawrence D'Anna 
520d3bd5b3dSLawrence D'Anna   explicit PythonInteger(int64_t value);
5212c1f46dcSZachary Turner 
52222c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
523d3bd5b3dSLawrence D'Anna   static void Convert(PyRefType &type, PyObject *&py_obj);
5242c1f46dcSZachary Turner 
525b9c1b51eSKate Stone   void SetInteger(int64_t value);
5262c1f46dcSZachary Turner 
5272c1f46dcSZachary Turner   StructuredData::IntegerSP CreateStructuredInteger() const;
5282c1f46dcSZachary Turner };
5292c1f46dcSZachary Turner 
530d3bd5b3dSLawrence D'Anna class PythonBoolean : public TypedPythonObject<PythonBoolean> {
531b81d715cSTatyana Krasnukha public:
532d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
533b81d715cSTatyana Krasnukha 
534d3bd5b3dSLawrence D'Anna   explicit PythonBoolean(bool value);
535b81d715cSTatyana Krasnukha 
536b81d715cSTatyana Krasnukha   static bool Check(PyObject *py_obj);
537b81d715cSTatyana Krasnukha 
538b81d715cSTatyana Krasnukha   bool GetValue() const;
539b81d715cSTatyana Krasnukha 
540b81d715cSTatyana Krasnukha   void SetValue(bool value);
541b81d715cSTatyana Krasnukha 
542b81d715cSTatyana Krasnukha   StructuredData::BooleanSP CreateStructuredBoolean() const;
543b81d715cSTatyana Krasnukha };
544b81d715cSTatyana Krasnukha 
545d3bd5b3dSLawrence D'Anna class PythonList : public TypedPythonObject<PythonList> {
5462c1f46dcSZachary Turner public:
547d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
548d3bd5b3dSLawrence D'Anna 
549d3bd5b3dSLawrence D'Anna   PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
550d3bd5b3dSLawrence D'Anna 
55187f47729SZachary Turner   explicit PythonList(PyInitialValue value);
55287f47729SZachary Turner   explicit PythonList(int list_size);
5532c1f46dcSZachary Turner 
55422c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
55522c8efcdSZachary Turner 
5562c1f46dcSZachary Turner   uint32_t GetSize() const;
5572c1f46dcSZachary Turner 
5582c1f46dcSZachary Turner   PythonObject GetItemAtIndex(uint32_t index) const;
5592c1f46dcSZachary Turner 
560f8b22f8fSZachary Turner   void SetItemAtIndex(uint32_t index, const PythonObject &object);
5612c1f46dcSZachary Turner 
562f8b22f8fSZachary Turner   void AppendItem(const PythonObject &object);
5632c1f46dcSZachary Turner 
5642c1f46dcSZachary Turner   StructuredData::ArraySP CreateStructuredArray() const;
5652c1f46dcSZachary Turner };
5662c1f46dcSZachary Turner 
567d3bd5b3dSLawrence D'Anna class PythonTuple : public TypedPythonObject<PythonTuple> {
568a1405147SZachary Turner public:
569d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
570d3bd5b3dSLawrence D'Anna 
571a1405147SZachary Turner   explicit PythonTuple(PyInitialValue value);
572a1405147SZachary Turner   explicit PythonTuple(int tuple_size);
573a1405147SZachary Turner   PythonTuple(std::initializer_list<PythonObject> objects);
574a1405147SZachary Turner   PythonTuple(std::initializer_list<PyObject *> objects);
575a1405147SZachary Turner 
576a1405147SZachary Turner   static bool Check(PyObject *py_obj);
577a1405147SZachary Turner 
578a1405147SZachary Turner   uint32_t GetSize() const;
579a1405147SZachary Turner 
580a1405147SZachary Turner   PythonObject GetItemAtIndex(uint32_t index) const;
581a1405147SZachary Turner 
582a1405147SZachary Turner   void SetItemAtIndex(uint32_t index, const PythonObject &object);
583a1405147SZachary Turner 
584a1405147SZachary Turner   StructuredData::ArraySP CreateStructuredArray() const;
585a1405147SZachary Turner };
586a1405147SZachary Turner 
587d3bd5b3dSLawrence D'Anna class PythonDictionary : public TypedPythonObject<PythonDictionary> {
5882c1f46dcSZachary Turner public:
589d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
590edb35d95SEugene Zelenko 
591d3bd5b3dSLawrence D'Anna   PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
592d3bd5b3dSLawrence D'Anna 
593d3bd5b3dSLawrence D'Anna   explicit PythonDictionary(PyInitialValue value);
5942c1f46dcSZachary Turner 
59522c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
59622c8efcdSZachary Turner 
5972c1f46dcSZachary Turner   uint32_t GetSize() const;
5982c1f46dcSZachary Turner 
599f8b22f8fSZachary Turner   PythonList GetKeys() const;
6002c1f46dcSZachary Turner 
601c86a6acaSLawrence D'Anna   PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
602c86a6acaSLawrence D'Anna   void SetItemForKey(const PythonObject &key,
603c86a6acaSLawrence D'Anna                      const PythonObject &value); // DEPRECATED
604c86a6acaSLawrence D'Anna 
605c86a6acaSLawrence D'Anna   llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
606722b6189SLawrence D'Anna   llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
607c86a6acaSLawrence D'Anna   llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
608722b6189SLawrence D'Anna   llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
6092c1f46dcSZachary Turner 
6102c1f46dcSZachary Turner   StructuredData::DictionarySP CreateStructuredDictionary() const;
6112c1f46dcSZachary Turner };
61287f47729SZachary Turner 
613d3bd5b3dSLawrence D'Anna class PythonModule : public TypedPythonObject<PythonModule> {
6147841efbbSZachary Turner public:
615d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
6167841efbbSZachary Turner 
6177841efbbSZachary Turner   static bool Check(PyObject *py_obj);
6187841efbbSZachary Turner 
619b9c1b51eSKate Stone   static PythonModule BuiltinsModule();
620a1405147SZachary Turner 
621b9c1b51eSKate Stone   static PythonModule MainModule();
622a1405147SZachary Turner 
623b9c1b51eSKate Stone   static PythonModule AddModule(llvm::StringRef module);
6247841efbbSZachary Turner 
625085328eeSLawrence D'Anna   // safe, returns invalid on error;
626085328eeSLawrence D'Anna   static PythonModule ImportModule(llvm::StringRef name) {
627adcd0268SBenjamin Kramer     std::string s = std::string(name);
628085328eeSLawrence D'Anna     auto mod = Import(s.c_str());
629085328eeSLawrence D'Anna     if (!mod) {
630085328eeSLawrence D'Anna       llvm::consumeError(mod.takeError());
631085328eeSLawrence D'Anna       return PythonModule();
632085328eeSLawrence D'Anna     }
633085328eeSLawrence D'Anna     return std::move(mod.get());
634085328eeSLawrence D'Anna   }
635085328eeSLawrence D'Anna 
636722b6189SLawrence D'Anna   static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
637085328eeSLawrence D'Anna 
638722b6189SLawrence D'Anna   llvm::Expected<PythonObject> Get(const llvm::Twine &name);
6392419f1d5SZachary Turner 
6407841efbbSZachary Turner   PythonDictionary GetDictionary() const;
6417841efbbSZachary Turner };
6427841efbbSZachary Turner 
643d3bd5b3dSLawrence D'Anna class PythonCallable : public TypedPythonObject<PythonCallable> {
644a1405147SZachary Turner public:
645d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
646d3bd5b3dSLawrence D'Anna 
647b58fb2f4SZachary Turner   struct ArgInfo {
6482386537cSLawrence D'Anna     /* the largest number of positional arguments this callable
6492386537cSLawrence D'Anna      * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
6502386537cSLawrence D'Anna      * function and can accept an arbitrary number */
6512386537cSLawrence D'Anna     unsigned max_positional_args;
6522386537cSLawrence D'Anna     static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
653b58fb2f4SZachary Turner   };
654b58fb2f4SZachary Turner 
655b9c1b51eSKate Stone   static bool Check(PyObject *py_obj);
656a1405147SZachary Turner 
657c86a6acaSLawrence D'Anna   llvm::Expected<ArgInfo> GetArgInfo() const;
658c86a6acaSLawrence D'Anna 
659b9c1b51eSKate Stone   PythonObject operator()();
660a1405147SZachary Turner 
661b9c1b51eSKate Stone   PythonObject operator()(std::initializer_list<PyObject *> args);
662a1405147SZachary Turner 
663b9c1b51eSKate Stone   PythonObject operator()(std::initializer_list<PythonObject> args);
664b58fb2f4SZachary Turner 
665b58fb2f4SZachary Turner   template <typename Arg, typename... Args>
666b9c1b51eSKate Stone   PythonObject operator()(const Arg &arg, Args... args) {
667b58fb2f4SZachary Turner     return operator()({arg, args...});
668b58fb2f4SZachary Turner   }
669a1405147SZachary Turner };
670a1405147SZachary Turner 
671d3bd5b3dSLawrence D'Anna class PythonFile : public TypedPythonObject<PythonFile> {
6729c40264fSZachary Turner public:
673d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
674edb35d95SEugene Zelenko 
675d3bd5b3dSLawrence D'Anna   PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
6769c40264fSZachary Turner 
6779c40264fSZachary Turner   static bool Check(PyObject *py_obj);
6789c40264fSZachary Turner 
679d9b553ecSLawrence D'Anna   static llvm::Expected<PythonFile> FromFile(File &file,
680d9b553ecSLawrence D'Anna                                              const char *mode = nullptr);
681d9b553ecSLawrence D'Anna 
682085328eeSLawrence D'Anna   llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
683085328eeSLawrence D'Anna   llvm::Expected<lldb::FileSP>
684085328eeSLawrence D'Anna   ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
6859c40264fSZachary Turner };
6869c40264fSZachary Turner 
687085328eeSLawrence D'Anna class PythonException : public llvm::ErrorInfo<PythonException> {
688085328eeSLawrence D'Anna private:
689085328eeSLawrence D'Anna   PyObject *m_exception_type, *m_exception, *m_traceback;
690085328eeSLawrence D'Anna   PyObject *m_repr_bytes;
691085328eeSLawrence D'Anna 
692085328eeSLawrence D'Anna public:
693085328eeSLawrence D'Anna   static char ID;
694085328eeSLawrence D'Anna   const char *toCString() const;
695085328eeSLawrence D'Anna   PythonException(const char *caller = nullptr);
696085328eeSLawrence D'Anna   void Restore();
697085328eeSLawrence D'Anna   ~PythonException();
698085328eeSLawrence D'Anna   void log(llvm::raw_ostream &OS) const override;
699085328eeSLawrence D'Anna   std::error_code convertToErrorCode() const override;
70004edd189SLawrence D'Anna   bool Matches(PyObject *exc) const;
70104edd189SLawrence D'Anna   std::string ReadBacktrace() const;
702085328eeSLawrence D'Anna };
703085328eeSLawrence D'Anna 
704085328eeSLawrence D'Anna // This extracts the underlying T out of an Expected<T> and returns it.
705085328eeSLawrence D'Anna // If the Expected is an Error instead of a T, that error will be converted
706085328eeSLawrence D'Anna // into a python exception, and this will return a default-constructed T.
707085328eeSLawrence D'Anna //
708085328eeSLawrence D'Anna // This is appropriate for use right at the boundary of python calling into
709085328eeSLawrence D'Anna // C++, such as in a SWIG typemap.   In such a context you should simply
710085328eeSLawrence D'Anna // check if the returned T is valid, and if it is, return a NULL back
711085328eeSLawrence D'Anna // to python.   This will result in the Error being raised as an exception
712085328eeSLawrence D'Anna // from python code's point of view.
713085328eeSLawrence D'Anna //
714085328eeSLawrence D'Anna // For example:
715085328eeSLawrence D'Anna // ```
716085328eeSLawrence D'Anna // Expected<Foo *> efoop = some_cpp_function();
717085328eeSLawrence D'Anna // Foo *foop = unwrapOrSetPythonException(efoop);
718085328eeSLawrence D'Anna // if (!foop)
719085328eeSLawrence D'Anna //    return NULL;
720085328eeSLawrence D'Anna // do_something(*foop);
721085328eeSLawrence D'Anna //
722085328eeSLawrence D'Anna // If the Error returned was itself created because a python exception was
723085328eeSLawrence D'Anna // raised when C++ code called into python, then the original exception
724085328eeSLawrence D'Anna // will be restored.   Otherwise a simple string exception will be raised.
725085328eeSLawrence D'Anna template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
726085328eeSLawrence D'Anna   if (expected)
727085328eeSLawrence D'Anna     return expected.get();
728085328eeSLawrence D'Anna   llvm::handleAllErrors(
729085328eeSLawrence D'Anna       expected.takeError(), [](PythonException &E) { E.Restore(); },
730085328eeSLawrence D'Anna       [](const llvm::ErrorInfoBase &E) {
731085328eeSLawrence D'Anna         PyErr_SetString(PyExc_Exception, E.message().c_str());
732085328eeSLawrence D'Anna       });
733085328eeSLawrence D'Anna   return T();
734085328eeSLawrence D'Anna }
735085328eeSLawrence D'Anna 
736722b6189SLawrence D'Anna // This is only here to help incrementally migrate old, exception-unsafe
737722b6189SLawrence D'Anna // code.
738722b6189SLawrence D'Anna template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
739722b6189SLawrence D'Anna   if (expected)
740722b6189SLawrence D'Anna     return std::move(expected.get());
741722b6189SLawrence D'Anna   llvm::consumeError(expected.takeError());
742722b6189SLawrence D'Anna   return T();
743722b6189SLawrence D'Anna }
744722b6189SLawrence D'Anna 
74504edd189SLawrence D'Anna llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
74604edd189SLawrence D'Anna                                               const PythonDictionary &globals,
74704edd189SLawrence D'Anna                                               const PythonDictionary &locals);
74804edd189SLawrence D'Anna 
74904edd189SLawrence D'Anna llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
75004edd189SLawrence D'Anna                                                 const PythonDictionary &globals,
75104edd189SLawrence D'Anna                                                 const PythonDictionary &locals);
75204edd189SLawrence D'Anna 
75304edd189SLawrence D'Anna // Sometimes the best way to interact with a python interpreter is
75404edd189SLawrence D'Anna // to run some python code.   You construct a PythonScript with
75504edd189SLawrence D'Anna // script string.   The script assigns some function to `_function_`
75604edd189SLawrence D'Anna // and you get a C++ callable object that calls the python function.
75704edd189SLawrence D'Anna //
75804edd189SLawrence D'Anna // Example:
75904edd189SLawrence D'Anna //
76004edd189SLawrence D'Anna // const char script[] = R"(
76104edd189SLawrence D'Anna // def main(x, y):
76204edd189SLawrence D'Anna //    ....
76304edd189SLawrence D'Anna // )";
76404edd189SLawrence D'Anna //
76504edd189SLawrence D'Anna // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
76604edd189SLawrence D'Anna //   // no need to synchronize access to this global, we already have the GIL
76704edd189SLawrence D'Anna //   static PythonScript foo(script)
76804edd189SLawrence D'Anna //   return  foo(x, y);
76904edd189SLawrence D'Anna // }
77004edd189SLawrence D'Anna class PythonScript {
77104edd189SLawrence D'Anna   const char *script;
77204edd189SLawrence D'Anna   PythonCallable function;
77304edd189SLawrence D'Anna 
77404edd189SLawrence D'Anna   llvm::Error Init();
77504edd189SLawrence D'Anna 
77604edd189SLawrence D'Anna public:
77704edd189SLawrence D'Anna   PythonScript(const char *script) : script(script), function() {}
77804edd189SLawrence D'Anna 
77904edd189SLawrence D'Anna   template <typename... Args>
78004edd189SLawrence D'Anna   llvm::Expected<PythonObject> operator()(Args &&... args) {
78104edd189SLawrence D'Anna     if (llvm::Error error = Init())
78204edd189SLawrence D'Anna       return std::move(error);
78304edd189SLawrence D'Anna     return function.Call(std::forward<Args>(args)...);
78404edd189SLawrence D'Anna   }
78504edd189SLawrence D'Anna };
78604edd189SLawrence D'Anna 
78704edd189SLawrence D'Anna } // namespace python
7882c1f46dcSZachary Turner } // namespace lldb_private
7892c1f46dcSZachary Turner 
790a281b42bSZachary Turner #endif
791d68983e3SPavel Labath 
792d68983e3SPavel Labath #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
793