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 //
39d3bd5b3dSLawrence D'Anna // * Elimintate 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 
51d68983e3SPavel Labath #ifndef LLDB_DISABLE_PYTHON
52d68983e3SPavel Labath 
5341de9a97SKate Stone // LLDB Python header must be included first
5441de9a97SKate Stone #include "lldb-python.h"
5541de9a97SKate Stone 
569c40264fSZachary Turner #include "lldb/Host/File.h"
57f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h"
582c1f46dcSZachary Turner 
595a72c02bSZachary Turner #include "llvm/ADT/ArrayRef.h"
605a72c02bSZachary Turner 
612c1f46dcSZachary Turner namespace lldb_private {
62edb35d95SEugene Zelenko 
63085328eeSLawrence D'Anna class PythonObject;
645a72c02bSZachary Turner class PythonBytes;
652c1f46dcSZachary Turner class PythonString;
662c1f46dcSZachary Turner class PythonList;
672c1f46dcSZachary Turner class PythonDictionary;
682c1f46dcSZachary Turner class PythonInteger;
69085328eeSLawrence D'Anna class PythonException;
702c1f46dcSZachary Turner 
71b9c1b51eSKate Stone class StructuredPythonObject : public StructuredData::Generic {
722c1f46dcSZachary Turner public:
73b9c1b51eSKate Stone   StructuredPythonObject() : StructuredData::Generic() {}
742c1f46dcSZachary Turner 
75b9c1b51eSKate Stone   StructuredPythonObject(void *obj) : StructuredData::Generic(obj) {
762c1f46dcSZachary Turner     Py_XINCREF(GetValue());
772c1f46dcSZachary Turner   }
782c1f46dcSZachary Turner 
79b9c1b51eSKate Stone   ~StructuredPythonObject() override {
802c1f46dcSZachary Turner     if (Py_IsInitialized())
812c1f46dcSZachary Turner       Py_XDECREF(GetValue());
822c1f46dcSZachary Turner     SetValue(nullptr);
832c1f46dcSZachary Turner   }
842c1f46dcSZachary Turner 
85b9c1b51eSKate Stone   bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
862c1f46dcSZachary Turner 
872783d817SJonas Devlieghere   void Serialize(llvm::json::OStream &s) const override;
882c1f46dcSZachary Turner 
892c1f46dcSZachary Turner private:
902c1f46dcSZachary Turner   DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
912c1f46dcSZachary Turner };
922c1f46dcSZachary Turner 
93b9c1b51eSKate Stone enum class PyObjectType {
942c1f46dcSZachary Turner   Unknown,
952c1f46dcSZachary Turner   None,
96b81d715cSTatyana Krasnukha   Boolean,
972c1f46dcSZachary Turner   Integer,
982c1f46dcSZachary Turner   Dictionary,
992c1f46dcSZachary Turner   List,
1009c40264fSZachary Turner   String,
1015a72c02bSZachary Turner   Bytes,
102f9d6d204SZachary Turner   ByteArray,
1037841efbbSZachary Turner   Module,
104a1405147SZachary Turner   Callable,
105a1405147SZachary Turner   Tuple,
1069c40264fSZachary Turner   File
1072c1f46dcSZachary Turner };
1082c1f46dcSZachary Turner 
109b9c1b51eSKate Stone enum class PyRefType {
110f8b22f8fSZachary Turner   Borrowed, // We are not given ownership of the incoming PyObject.
111f8b22f8fSZachary Turner             // We cannot safely hold it without calling Py_INCREF.
112f8b22f8fSZachary Turner   Owned     // We have ownership of the incoming PyObject.  We should
113f8b22f8fSZachary Turner             // not call Py_INCREF.
114f8b22f8fSZachary Turner };
115f8b22f8fSZachary Turner 
116085328eeSLawrence D'Anna namespace python {
117085328eeSLawrence D'Anna 
118085328eeSLawrence D'Anna // Take a reference that you already own, and turn it into
119085328eeSLawrence D'Anna // a PythonObject.
120085328eeSLawrence D'Anna //
121085328eeSLawrence D'Anna // Most python API methods will return a +1 reference
122085328eeSLawrence D'Anna // if they succeed or NULL if and only if
123085328eeSLawrence D'Anna // they set an exception.   Use this to collect such return
124085328eeSLawrence D'Anna // values, after checking for NULL.
125085328eeSLawrence D'Anna //
126085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be
127085328eeSLawrence D'Anna // checked to be of the correct type.
128085328eeSLawrence D'Anna template <typename T> T Take(PyObject *obj) {
129085328eeSLawrence D'Anna   assert(obj);
130085328eeSLawrence D'Anna   assert(!PyErr_Occurred());
131085328eeSLawrence D'Anna   T thing(PyRefType::Owned, obj);
132085328eeSLawrence D'Anna   assert(thing.IsValid());
133085328eeSLawrence D'Anna   return std::move(thing);
134085328eeSLawrence D'Anna }
135085328eeSLawrence D'Anna 
136085328eeSLawrence D'Anna // Retain a reference you have borrowed, and turn it into
137085328eeSLawrence D'Anna // a PythonObject.
138085328eeSLawrence D'Anna //
139085328eeSLawrence D'Anna // A minority of python APIs return a borrowed reference
140085328eeSLawrence D'Anna // instead of a +1.   They will also return NULL if and only
141085328eeSLawrence D'Anna // if they set an exception.   Use this to collect such return
142085328eeSLawrence D'Anna // values, after checking for NULL.
143085328eeSLawrence D'Anna //
144085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be
145085328eeSLawrence D'Anna // checked to be of the correct type.
146085328eeSLawrence D'Anna template <typename T> T Retain(PyObject *obj) {
147085328eeSLawrence D'Anna   assert(obj);
148085328eeSLawrence D'Anna   assert(!PyErr_Occurred());
149085328eeSLawrence D'Anna   T thing(PyRefType::Borrowed, obj);
150085328eeSLawrence D'Anna   assert(thing.IsValid());
151085328eeSLawrence D'Anna   return std::move(thing);
152085328eeSLawrence D'Anna }
153085328eeSLawrence D'Anna 
154*722b6189SLawrence D'Anna // This class can be used like a utility function to convert from
155*722b6189SLawrence D'Anna // a llvm-friendly Twine into a null-terminated const char *,
156*722b6189SLawrence D'Anna // which is the form python C APIs want their strings in.
157*722b6189SLawrence D'Anna //
158*722b6189SLawrence D'Anna // Example:
159*722b6189SLawrence D'Anna // const llvm::Twine &some_twine;
160*722b6189SLawrence D'Anna // PyFoo_Bar(x, y, z, NullTerminated(some_twine));
161*722b6189SLawrence D'Anna //
162*722b6189SLawrence D'Anna // Why a class instead of a function?  If the twine isn't already null
163*722b6189SLawrence D'Anna // terminated, it will need a temporary buffer to copy the string
164*722b6189SLawrence D'Anna // into.   We need that buffer to stick around for the lifetime of the
165*722b6189SLawrence D'Anna // statement.
166*722b6189SLawrence D'Anna class NullTerminated {
167*722b6189SLawrence D'Anna   const char *str;
168*722b6189SLawrence D'Anna   llvm::SmallString<32> storage;
169*722b6189SLawrence D'Anna 
170*722b6189SLawrence D'Anna public:
171*722b6189SLawrence D'Anna   NullTerminated(const llvm::Twine &twine) {
172*722b6189SLawrence D'Anna     llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
173*722b6189SLawrence D'Anna     str = ref.begin();
174*722b6189SLawrence D'Anna   }
175*722b6189SLawrence D'Anna   operator const char *() { return str; }
176*722b6189SLawrence D'Anna };
177*722b6189SLawrence D'Anna 
178085328eeSLawrence D'Anna } // namespace python
179085328eeSLawrence D'Anna 
180b9c1b51eSKate Stone enum class PyInitialValue { Invalid, Empty };
181f8b22f8fSZachary Turner 
182085328eeSLawrence D'Anna template <typename T, typename Enable = void> struct PythonFormat;
183085328eeSLawrence D'Anna 
184085328eeSLawrence D'Anna template <> struct PythonFormat<unsigned long long> {
185085328eeSLawrence D'Anna   static constexpr char format = 'K';
186085328eeSLawrence D'Anna   static auto get(unsigned long long value) { return value; }
187085328eeSLawrence D'Anna };
188085328eeSLawrence D'Anna 
189085328eeSLawrence D'Anna template <> struct PythonFormat<long long> {
190085328eeSLawrence D'Anna   static constexpr char format = 'L';
191085328eeSLawrence D'Anna   static auto get(long long value) { return value; }
192085328eeSLawrence D'Anna };
193085328eeSLawrence D'Anna 
194085328eeSLawrence D'Anna template <typename T>
195085328eeSLawrence D'Anna struct PythonFormat<
196085328eeSLawrence D'Anna     T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
197085328eeSLawrence D'Anna   static constexpr char format = 'O';
198085328eeSLawrence D'Anna   static auto get(const T &value) { return value.get(); }
199085328eeSLawrence D'Anna };
200085328eeSLawrence D'Anna 
201b9c1b51eSKate Stone class PythonObject {
2022c1f46dcSZachary Turner public:
203b9c1b51eSKate Stone   PythonObject() : m_py_obj(nullptr) {}
2042c1f46dcSZachary Turner 
205b9c1b51eSKate Stone   PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) {
206f8b22f8fSZachary Turner     Reset(type, py_obj);
2072c1f46dcSZachary Turner   }
2082c1f46dcSZachary Turner 
20903819d1cSLawrence D'Anna   PythonObject(const PythonObject &rhs)
21003819d1cSLawrence D'Anna       : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
2112c1f46dcSZachary Turner 
212085328eeSLawrence D'Anna   PythonObject(PythonObject &&rhs) {
213085328eeSLawrence D'Anna     m_py_obj = rhs.m_py_obj;
214085328eeSLawrence D'Anna     rhs.m_py_obj = nullptr;
215085328eeSLawrence D'Anna   }
216085328eeSLawrence D'Anna 
217d3bd5b3dSLawrence D'Anna   ~PythonObject() { Reset(); }
2182c1f46dcSZachary Turner 
219b9c1b51eSKate Stone   void Reset() {
220085328eeSLawrence D'Anna     if (m_py_obj && Py_IsInitialized())
221085328eeSLawrence D'Anna       Py_DECREF(m_py_obj);
222f8b22f8fSZachary Turner     m_py_obj = nullptr;
2232c1f46dcSZachary Turner   }
224f8b22f8fSZachary Turner 
225d3bd5b3dSLawrence D'Anna   void Reset(PyRefType type, PyObject *py_obj) {
226f8b22f8fSZachary Turner     if (py_obj == m_py_obj)
227f8b22f8fSZachary Turner       return;
228f8b22f8fSZachary Turner 
229f8b22f8fSZachary Turner     if (Py_IsInitialized())
230f8b22f8fSZachary Turner       Py_XDECREF(m_py_obj);
231f8b22f8fSZachary Turner 
232f8b22f8fSZachary Turner     m_py_obj = py_obj;
233f8b22f8fSZachary Turner 
234f8b22f8fSZachary Turner     // If this is a borrowed reference, we need to convert it to
235f8b22f8fSZachary Turner     // an owned reference by incrementing it.  If it is an owned
236f8b22f8fSZachary Turner     // reference (for example the caller allocated it with PyDict_New()
237f8b22f8fSZachary Turner     // then we must *not* increment it.
238085328eeSLawrence D'Anna     if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
239f8b22f8fSZachary Turner       Py_XINCREF(m_py_obj);
2402c1f46dcSZachary Turner   }
2412c1f46dcSZachary Turner 
242b9c1b51eSKate Stone   void Dump() const {
2432c1f46dcSZachary Turner     if (m_py_obj)
2442c1f46dcSZachary Turner       _PyObject_Dump(m_py_obj);
2452c1f46dcSZachary Turner     else
2462c1f46dcSZachary Turner       puts("NULL");
2472c1f46dcSZachary Turner   }
2482c1f46dcSZachary Turner 
249b9c1b51eSKate Stone   void Dump(Stream &strm) const;
2502c1f46dcSZachary Turner 
251b9c1b51eSKate Stone   PyObject *get() const { return m_py_obj; }
2522c1f46dcSZachary Turner 
253b9c1b51eSKate Stone   PyObject *release() {
25460c24f70SZachary Turner     PyObject *result = m_py_obj;
25560c24f70SZachary Turner     m_py_obj = nullptr;
25660c24f70SZachary Turner     return result;
25760c24f70SZachary Turner   }
25860c24f70SZachary Turner 
25903819d1cSLawrence D'Anna   PythonObject &operator=(PythonObject other) {
260085328eeSLawrence D'Anna     Reset();
26103819d1cSLawrence D'Anna     m_py_obj = std::exchange(other.m_py_obj, nullptr);
262085328eeSLawrence D'Anna     return *this;
263085328eeSLawrence D'Anna   }
264085328eeSLawrence D'Anna 
265b9c1b51eSKate Stone   PyObjectType GetObjectType() const;
2667841efbbSZachary Turner 
267b9c1b51eSKate Stone   PythonString Repr() const;
2687841efbbSZachary Turner 
269b9c1b51eSKate Stone   PythonString Str() const;
2707841efbbSZachary Turner 
271b9c1b51eSKate Stone   static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
272b9c1b51eSKate Stone                                                 const PythonDictionary &dict);
2737841efbbSZachary Turner 
274b58fb2f4SZachary Turner   template <typename T>
275b9c1b51eSKate Stone   static T ResolveNameWithDictionary(llvm::StringRef name,
276b9c1b51eSKate Stone                                      const PythonDictionary &dict) {
277b58fb2f4SZachary Turner     return ResolveNameWithDictionary(name, dict).AsType<T>();
278b58fb2f4SZachary Turner   }
279b58fb2f4SZachary Turner 
280b9c1b51eSKate Stone   PythonObject ResolveName(llvm::StringRef name) const;
2817841efbbSZachary Turner 
282b9c1b51eSKate Stone   template <typename T> T ResolveName(llvm::StringRef name) const {
283b58fb2f4SZachary Turner     return ResolveName(name).AsType<T>();
284b58fb2f4SZachary Turner   }
285b58fb2f4SZachary Turner 
286b9c1b51eSKate Stone   bool HasAttribute(llvm::StringRef attribute) const;
2879c40264fSZachary Turner 
288b9c1b51eSKate Stone   PythonObject GetAttributeValue(llvm::StringRef attribute) const;
2897d6d218eSZachary Turner 
290085328eeSLawrence D'Anna   bool IsNone() const { return m_py_obj == Py_None; }
291f8b22f8fSZachary Turner 
292085328eeSLawrence D'Anna   bool IsValid() const { return m_py_obj != nullptr; }
293f8b22f8fSZachary Turner 
294085328eeSLawrence D'Anna   bool IsAllocated() const { return IsValid() && !IsNone(); }
295085328eeSLawrence D'Anna 
296085328eeSLawrence D'Anna   explicit operator bool() const { return IsValid() && !IsNone(); }
2972c1f46dcSZachary Turner 
298b9c1b51eSKate Stone   template <typename T> T AsType() const {
2997d6d218eSZachary Turner     if (!T::Check(m_py_obj))
3007d6d218eSZachary Turner       return T();
3017d6d218eSZachary Turner     return T(PyRefType::Borrowed, m_py_obj);
3027d6d218eSZachary Turner   }
3037d6d218eSZachary Turner 
304b9c1b51eSKate Stone   StructuredData::ObjectSP CreateStructuredObject() const;
3052c1f46dcSZachary Turner 
3062c1f46dcSZachary Turner protected:
307085328eeSLawrence D'Anna   static llvm::Error nullDeref() {
308085328eeSLawrence D'Anna     return llvm::createStringError(llvm::inconvertibleErrorCode(),
309085328eeSLawrence D'Anna                                    "A NULL PyObject* was dereferenced");
310085328eeSLawrence D'Anna   }
311085328eeSLawrence D'Anna   static llvm::Error exception(const char *s = nullptr) {
312085328eeSLawrence D'Anna     return llvm::make_error<PythonException>(s);
313085328eeSLawrence D'Anna   }
314c86a6acaSLawrence D'Anna   static llvm::Error keyError() {
315c86a6acaSLawrence D'Anna     return llvm::createStringError(llvm::inconvertibleErrorCode(),
316c86a6acaSLawrence D'Anna                                    "key not in dict");
317c86a6acaSLawrence D'Anna   }
318c86a6acaSLawrence D'Anna 
319c86a6acaSLawrence D'Anna #if PY_MAJOR_VERSION < 3
320c86a6acaSLawrence D'Anna   // The python 2 API declares some arguments as char* that should
321c86a6acaSLawrence D'Anna   // be const char *, but it doesn't actually modify them.
322c86a6acaSLawrence D'Anna   static char *py2_const_cast(const char *s) { return const_cast<char *>(s); }
323c86a6acaSLawrence D'Anna #else
324c86a6acaSLawrence D'Anna   static const char *py2_const_cast(const char *s) { return s; }
325c86a6acaSLawrence D'Anna #endif
326085328eeSLawrence D'Anna 
327085328eeSLawrence D'Anna public:
328085328eeSLawrence D'Anna   template <typename... T>
329085328eeSLawrence D'Anna   llvm::Expected<PythonObject> CallMethod(const char *name,
330085328eeSLawrence D'Anna                                           const T &... t) const {
331085328eeSLawrence D'Anna     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
332085328eeSLawrence D'Anna     PyObject *obj =
333c86a6acaSLawrence D'Anna         PyObject_CallMethod(m_py_obj, py2_const_cast(name),
334c86a6acaSLawrence D'Anna                             py2_const_cast(format), PythonFormat<T>::get(t)...);
335c86a6acaSLawrence D'Anna     if (!obj)
336c86a6acaSLawrence D'Anna       return exception();
337c86a6acaSLawrence D'Anna     return python::Take<PythonObject>(obj);
338c86a6acaSLawrence D'Anna   }
339c86a6acaSLawrence D'Anna 
340c86a6acaSLawrence D'Anna   template <typename... T>
341c86a6acaSLawrence D'Anna   llvm::Expected<PythonObject> Call(const T &... t) const {
342c86a6acaSLawrence D'Anna     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
343c86a6acaSLawrence D'Anna     PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
344c86a6acaSLawrence D'Anna                                           PythonFormat<T>::get(t)...);
345085328eeSLawrence D'Anna     if (!obj)
346085328eeSLawrence D'Anna       return exception();
347085328eeSLawrence D'Anna     return python::Take<PythonObject>(obj);
348085328eeSLawrence D'Anna   }
349085328eeSLawrence D'Anna 
350*722b6189SLawrence D'Anna   llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
351*722b6189SLawrence D'Anna     using namespace python;
352085328eeSLawrence D'Anna     if (!m_py_obj)
353085328eeSLawrence D'Anna       return nullDeref();
354*722b6189SLawrence D'Anna     PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
355085328eeSLawrence D'Anna     if (!obj)
356085328eeSLawrence D'Anna       return exception();
357085328eeSLawrence D'Anna     return python::Take<PythonObject>(obj);
358085328eeSLawrence D'Anna   }
359085328eeSLawrence D'Anna 
360085328eeSLawrence D'Anna   llvm::Expected<bool> IsTrue() {
361085328eeSLawrence D'Anna     if (!m_py_obj)
362085328eeSLawrence D'Anna       return nullDeref();
363085328eeSLawrence D'Anna     int r = PyObject_IsTrue(m_py_obj);
364085328eeSLawrence D'Anna     if (r < 0)
365085328eeSLawrence D'Anna       return exception();
366085328eeSLawrence D'Anna     return !!r;
367085328eeSLawrence D'Anna   }
368085328eeSLawrence D'Anna 
369085328eeSLawrence D'Anna   llvm::Expected<long long> AsLongLong() {
370085328eeSLawrence D'Anna     if (!m_py_obj)
371085328eeSLawrence D'Anna       return nullDeref();
372085328eeSLawrence D'Anna     assert(!PyErr_Occurred());
373085328eeSLawrence D'Anna     long long r = PyLong_AsLongLong(m_py_obj);
374085328eeSLawrence D'Anna     if (PyErr_Occurred())
375085328eeSLawrence D'Anna       return exception();
376085328eeSLawrence D'Anna     return r;
377085328eeSLawrence D'Anna   }
378085328eeSLawrence D'Anna 
379085328eeSLawrence D'Anna   llvm::Expected<bool> IsInstance(const PythonObject &cls) {
380085328eeSLawrence D'Anna     if (!m_py_obj || !cls.IsValid())
381085328eeSLawrence D'Anna       return nullDeref();
382085328eeSLawrence D'Anna     int r = PyObject_IsInstance(m_py_obj, cls.get());
383085328eeSLawrence D'Anna     if (r < 0)
384085328eeSLawrence D'Anna       return exception();
385085328eeSLawrence D'Anna     return !!r;
386085328eeSLawrence D'Anna   }
387085328eeSLawrence D'Anna 
388085328eeSLawrence D'Anna protected:
3892c1f46dcSZachary Turner   PyObject *m_py_obj;
3902c1f46dcSZachary Turner };
3912c1f46dcSZachary Turner 
392085328eeSLawrence D'Anna namespace python {
393085328eeSLawrence D'Anna 
394085328eeSLawrence D'Anna // This is why C++ needs monads.
395085328eeSLawrence D'Anna template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
396085328eeSLawrence D'Anna   if (!obj)
397085328eeSLawrence D'Anna     return obj.takeError();
398085328eeSLawrence D'Anna   if (!T::Check(obj.get().get()))
399085328eeSLawrence D'Anna     return llvm::createStringError(llvm::inconvertibleErrorCode(),
400085328eeSLawrence D'Anna                                    "type error");
401085328eeSLawrence D'Anna   return T(PyRefType::Borrowed, std::move(obj.get().get()));
402085328eeSLawrence D'Anna }
403085328eeSLawrence D'Anna 
404085328eeSLawrence D'Anna template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
405085328eeSLawrence D'Anna 
406085328eeSLawrence D'Anna template <>
407085328eeSLawrence D'Anna llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
408085328eeSLawrence D'Anna 
409c86a6acaSLawrence D'Anna template <>
410c86a6acaSLawrence D'Anna llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
411c86a6acaSLawrence D'Anna 
412085328eeSLawrence D'Anna } // namespace python
413085328eeSLawrence D'Anna 
414d3bd5b3dSLawrence D'Anna template <class T> class TypedPythonObject : public PythonObject {
4155a72c02bSZachary Turner public:
416d3bd5b3dSLawrence D'Anna   // override to perform implicit type conversions on Reset
417d3bd5b3dSLawrence D'Anna   // This can be eliminated once we drop python 2 support.
418d3bd5b3dSLawrence D'Anna   static void Convert(PyRefType &type, PyObject *&py_obj) {}
419d3bd5b3dSLawrence D'Anna 
420*722b6189SLawrence D'Anna   void Reset() { PythonObject::Reset(); }
421d3bd5b3dSLawrence D'Anna 
422*722b6189SLawrence D'Anna   void Reset(PyRefType type, PyObject *py_obj) = delete;
423*722b6189SLawrence D'Anna 
424*722b6189SLawrence D'Anna   TypedPythonObject(PyRefType type, PyObject *py_obj) {
425d3bd5b3dSLawrence D'Anna     if (!py_obj)
426d3bd5b3dSLawrence D'Anna       return;
427d3bd5b3dSLawrence D'Anna     T::Convert(type, py_obj);
428d3bd5b3dSLawrence D'Anna     if (T::Check(py_obj))
429d3bd5b3dSLawrence D'Anna       PythonObject::Reset(type, py_obj);
430d3bd5b3dSLawrence D'Anna     else if (type == PyRefType::Owned)
431d3bd5b3dSLawrence D'Anna       Py_DECREF(py_obj);
432d3bd5b3dSLawrence D'Anna   }
433d3bd5b3dSLawrence D'Anna 
434d3bd5b3dSLawrence D'Anna   TypedPythonObject() {}
435d3bd5b3dSLawrence D'Anna };
436d3bd5b3dSLawrence D'Anna 
437d3bd5b3dSLawrence D'Anna class PythonBytes : public TypedPythonObject<PythonBytes> {
438d3bd5b3dSLawrence D'Anna public:
439d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
4405a72c02bSZachary Turner   explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
4415a72c02bSZachary Turner   PythonBytes(const uint8_t *bytes, size_t length);
4425a72c02bSZachary Turner 
443b9c1b51eSKate Stone   static bool Check(PyObject *py_obj);
4445a72c02bSZachary Turner 
445b9c1b51eSKate Stone   llvm::ArrayRef<uint8_t> GetBytes() const;
4465a72c02bSZachary Turner 
447b9c1b51eSKate Stone   size_t GetSize() const;
4485a72c02bSZachary Turner 
449b9c1b51eSKate Stone   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4505a72c02bSZachary Turner 
451b9c1b51eSKate Stone   StructuredData::StringSP CreateStructuredString() const;
4525a72c02bSZachary Turner };
4535a72c02bSZachary Turner 
454d3bd5b3dSLawrence D'Anna class PythonByteArray : public TypedPythonObject<PythonByteArray> {
455f9d6d204SZachary Turner public:
456d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
457f9d6d204SZachary Turner   explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
458f9d6d204SZachary Turner   PythonByteArray(const uint8_t *bytes, size_t length);
459f9d6d204SZachary Turner   PythonByteArray(const PythonBytes &object);
460f9d6d204SZachary Turner 
461b9c1b51eSKate Stone   static bool Check(PyObject *py_obj);
462f9d6d204SZachary Turner 
463b9c1b51eSKate Stone   llvm::ArrayRef<uint8_t> GetBytes() const;
464f9d6d204SZachary Turner 
465b9c1b51eSKate Stone   size_t GetSize() const;
466f9d6d204SZachary Turner 
467b9c1b51eSKate Stone   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
468f9d6d204SZachary Turner 
469b9c1b51eSKate Stone   StructuredData::StringSP CreateStructuredString() const;
470f9d6d204SZachary Turner };
471f9d6d204SZachary Turner 
472d3bd5b3dSLawrence D'Anna class PythonString : public TypedPythonObject<PythonString> {
4732c1f46dcSZachary Turner public:
474d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
475085328eeSLawrence D'Anna   static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
476085328eeSLawrence D'Anna 
477d3bd5b3dSLawrence D'Anna   PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
478edb35d95SEugene Zelenko 
479d3bd5b3dSLawrence D'Anna   explicit PythonString(llvm::StringRef string); // safe, null on error
4802c1f46dcSZachary Turner 
48122c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
482d3bd5b3dSLawrence D'Anna   static void Convert(PyRefType &type, PyObject *&py_obj);
4832c1f46dcSZachary Turner 
484085328eeSLawrence D'Anna   llvm::StringRef GetString() const; // safe, empty string on error
485085328eeSLawrence D'Anna 
486085328eeSLawrence D'Anna   llvm::Expected<llvm::StringRef> AsUTF8() const;
4872c1f46dcSZachary Turner 
488b9c1b51eSKate Stone   size_t GetSize() const;
4892c1f46dcSZachary Turner 
490085328eeSLawrence D'Anna   void SetString(llvm::StringRef string); // safe, null on error
4912c1f46dcSZachary Turner 
4922c1f46dcSZachary Turner   StructuredData::StringSP CreateStructuredString() const;
4932c1f46dcSZachary Turner };
4942c1f46dcSZachary Turner 
495d3bd5b3dSLawrence D'Anna class PythonInteger : public TypedPythonObject<PythonInteger> {
4962c1f46dcSZachary Turner public:
497d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
498edb35d95SEugene Zelenko 
499d3bd5b3dSLawrence D'Anna   PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
500d3bd5b3dSLawrence D'Anna 
501d3bd5b3dSLawrence D'Anna   explicit PythonInteger(int64_t value);
5022c1f46dcSZachary Turner 
50322c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
504d3bd5b3dSLawrence D'Anna   static void Convert(PyRefType &type, PyObject *&py_obj);
5052c1f46dcSZachary Turner 
5062c1f46dcSZachary Turner   int64_t GetInteger() const;
5072c1f46dcSZachary Turner 
508b9c1b51eSKate Stone   void SetInteger(int64_t value);
5092c1f46dcSZachary Turner 
5102c1f46dcSZachary Turner   StructuredData::IntegerSP CreateStructuredInteger() const;
5112c1f46dcSZachary Turner };
5122c1f46dcSZachary Turner 
513d3bd5b3dSLawrence D'Anna class PythonBoolean : public TypedPythonObject<PythonBoolean> {
514b81d715cSTatyana Krasnukha public:
515d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
516b81d715cSTatyana Krasnukha 
517d3bd5b3dSLawrence D'Anna   explicit PythonBoolean(bool value);
518b81d715cSTatyana Krasnukha 
519b81d715cSTatyana Krasnukha   static bool Check(PyObject *py_obj);
520b81d715cSTatyana Krasnukha 
521b81d715cSTatyana Krasnukha   bool GetValue() const;
522b81d715cSTatyana Krasnukha 
523b81d715cSTatyana Krasnukha   void SetValue(bool value);
524b81d715cSTatyana Krasnukha 
525b81d715cSTatyana Krasnukha   StructuredData::BooleanSP CreateStructuredBoolean() const;
526b81d715cSTatyana Krasnukha };
527b81d715cSTatyana Krasnukha 
528d3bd5b3dSLawrence D'Anna class PythonList : public TypedPythonObject<PythonList> {
5292c1f46dcSZachary Turner public:
530d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
531d3bd5b3dSLawrence D'Anna 
532d3bd5b3dSLawrence D'Anna   PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
533d3bd5b3dSLawrence D'Anna 
53487f47729SZachary Turner   explicit PythonList(PyInitialValue value);
53587f47729SZachary Turner   explicit PythonList(int list_size);
5362c1f46dcSZachary Turner 
53722c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
53822c8efcdSZachary Turner 
5392c1f46dcSZachary Turner   uint32_t GetSize() const;
5402c1f46dcSZachary Turner 
5412c1f46dcSZachary Turner   PythonObject GetItemAtIndex(uint32_t index) const;
5422c1f46dcSZachary Turner 
543f8b22f8fSZachary Turner   void SetItemAtIndex(uint32_t index, const PythonObject &object);
5442c1f46dcSZachary Turner 
545f8b22f8fSZachary Turner   void AppendItem(const PythonObject &object);
5462c1f46dcSZachary Turner 
5472c1f46dcSZachary Turner   StructuredData::ArraySP CreateStructuredArray() const;
5482c1f46dcSZachary Turner };
5492c1f46dcSZachary Turner 
550d3bd5b3dSLawrence D'Anna class PythonTuple : public TypedPythonObject<PythonTuple> {
551a1405147SZachary Turner public:
552d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
553d3bd5b3dSLawrence D'Anna 
554a1405147SZachary Turner   explicit PythonTuple(PyInitialValue value);
555a1405147SZachary Turner   explicit PythonTuple(int tuple_size);
556a1405147SZachary Turner   PythonTuple(std::initializer_list<PythonObject> objects);
557a1405147SZachary Turner   PythonTuple(std::initializer_list<PyObject *> objects);
558a1405147SZachary Turner 
559a1405147SZachary Turner   static bool Check(PyObject *py_obj);
560a1405147SZachary Turner 
561a1405147SZachary Turner   uint32_t GetSize() const;
562a1405147SZachary Turner 
563a1405147SZachary Turner   PythonObject GetItemAtIndex(uint32_t index) const;
564a1405147SZachary Turner 
565a1405147SZachary Turner   void SetItemAtIndex(uint32_t index, const PythonObject &object);
566a1405147SZachary Turner 
567a1405147SZachary Turner   StructuredData::ArraySP CreateStructuredArray() const;
568a1405147SZachary Turner };
569a1405147SZachary Turner 
570d3bd5b3dSLawrence D'Anna class PythonDictionary : public TypedPythonObject<PythonDictionary> {
5712c1f46dcSZachary Turner public:
572d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
573edb35d95SEugene Zelenko 
574d3bd5b3dSLawrence D'Anna   PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
575d3bd5b3dSLawrence D'Anna 
576d3bd5b3dSLawrence D'Anna   explicit PythonDictionary(PyInitialValue value);
5772c1f46dcSZachary Turner 
57822c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
57922c8efcdSZachary Turner 
5802c1f46dcSZachary Turner   uint32_t GetSize() const;
5812c1f46dcSZachary Turner 
582f8b22f8fSZachary Turner   PythonList GetKeys() const;
5832c1f46dcSZachary Turner 
584c86a6acaSLawrence D'Anna   PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
585c86a6acaSLawrence D'Anna   void SetItemForKey(const PythonObject &key,
586c86a6acaSLawrence D'Anna                      const PythonObject &value); // DEPRECATED
587c86a6acaSLawrence D'Anna 
588c86a6acaSLawrence D'Anna   llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
589*722b6189SLawrence D'Anna   llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
590c86a6acaSLawrence D'Anna   llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
591*722b6189SLawrence D'Anna   llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
5922c1f46dcSZachary Turner 
5932c1f46dcSZachary Turner   StructuredData::DictionarySP CreateStructuredDictionary() const;
5942c1f46dcSZachary Turner };
59587f47729SZachary Turner 
596d3bd5b3dSLawrence D'Anna class PythonModule : public TypedPythonObject<PythonModule> {
5977841efbbSZachary Turner public:
598d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
5997841efbbSZachary Turner 
6007841efbbSZachary Turner   static bool Check(PyObject *py_obj);
6017841efbbSZachary Turner 
602b9c1b51eSKate Stone   static PythonModule BuiltinsModule();
603a1405147SZachary Turner 
604b9c1b51eSKate Stone   static PythonModule MainModule();
605a1405147SZachary Turner 
606b9c1b51eSKate Stone   static PythonModule AddModule(llvm::StringRef module);
6077841efbbSZachary Turner 
608085328eeSLawrence D'Anna   // safe, returns invalid on error;
609085328eeSLawrence D'Anna   static PythonModule ImportModule(llvm::StringRef name) {
610085328eeSLawrence D'Anna     std::string s = name;
611085328eeSLawrence D'Anna     auto mod = Import(s.c_str());
612085328eeSLawrence D'Anna     if (!mod) {
613085328eeSLawrence D'Anna       llvm::consumeError(mod.takeError());
614085328eeSLawrence D'Anna       return PythonModule();
615085328eeSLawrence D'Anna     }
616085328eeSLawrence D'Anna     return std::move(mod.get());
617085328eeSLawrence D'Anna   }
618085328eeSLawrence D'Anna 
619*722b6189SLawrence D'Anna   static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
620085328eeSLawrence D'Anna 
621*722b6189SLawrence D'Anna   llvm::Expected<PythonObject> Get(const llvm::Twine &name);
6222419f1d5SZachary Turner 
6237841efbbSZachary Turner   PythonDictionary GetDictionary() const;
6247841efbbSZachary Turner };
6257841efbbSZachary Turner 
626d3bd5b3dSLawrence D'Anna class PythonCallable : public TypedPythonObject<PythonCallable> {
627a1405147SZachary Turner public:
628d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
629d3bd5b3dSLawrence D'Anna 
630b58fb2f4SZachary Turner   struct ArgInfo {
6312386537cSLawrence D'Anna     /* the largest number of positional arguments this callable
6322386537cSLawrence D'Anna      * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
6332386537cSLawrence D'Anna      * function and can accept an arbitrary number */
6342386537cSLawrence D'Anna     unsigned max_positional_args;
6352386537cSLawrence D'Anna     static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
636c86a6acaSLawrence D'Anna     /* the number of positional arguments, including optional ones,
637c86a6acaSLawrence D'Anna      * and excluding varargs.  If this is a bound method, then the
638c86a6acaSLawrence D'Anna      * count will still include a +1 for self.
639c86a6acaSLawrence D'Anna      *
640c86a6acaSLawrence D'Anna      * FIXME. That's crazy.  This should be replaced with
641c86a6acaSLawrence D'Anna      * an accurate min and max for positional args.
642c86a6acaSLawrence D'Anna      */
643c86a6acaSLawrence D'Anna     int count;
644c86a6acaSLawrence D'Anna     /* does the callable have positional varargs? */
645c86a6acaSLawrence D'Anna     bool has_varargs : 1; // FIXME delete this
646b58fb2f4SZachary Turner   };
647b58fb2f4SZachary Turner 
648b9c1b51eSKate Stone   static bool Check(PyObject *py_obj);
649a1405147SZachary Turner 
650c86a6acaSLawrence D'Anna   llvm::Expected<ArgInfo> GetArgInfo() const;
651c86a6acaSLawrence D'Anna 
652c86a6acaSLawrence D'Anna   llvm::Expected<ArgInfo> GetInitArgInfo() const;
653c86a6acaSLawrence D'Anna 
654c86a6acaSLawrence D'Anna   ArgInfo GetNumArguments() const; // DEPRECATED
65527a14f19SJim Ingham 
65627a14f19SJim Ingham   // If the callable is a Py_Class, then find the number of arguments
65727a14f19SJim Ingham   // of the __init__ method.
658c86a6acaSLawrence D'Anna   ArgInfo GetNumInitArguments() const; // DEPRECATED
659b58fb2f4SZachary Turner 
660b9c1b51eSKate Stone   PythonObject operator()();
661a1405147SZachary Turner 
662b9c1b51eSKate Stone   PythonObject operator()(std::initializer_list<PyObject *> args);
663a1405147SZachary Turner 
664b9c1b51eSKate Stone   PythonObject operator()(std::initializer_list<PythonObject> args);
665b58fb2f4SZachary Turner 
666b58fb2f4SZachary Turner   template <typename Arg, typename... Args>
667b9c1b51eSKate Stone   PythonObject operator()(const Arg &arg, Args... args) {
668b58fb2f4SZachary Turner     return operator()({arg, args...});
669b58fb2f4SZachary Turner   }
670a1405147SZachary Turner };
671a1405147SZachary Turner 
672d3bd5b3dSLawrence D'Anna class PythonFile : public TypedPythonObject<PythonFile> {
6739c40264fSZachary Turner public:
674d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
675edb35d95SEugene Zelenko 
676d3bd5b3dSLawrence D'Anna   PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
6779c40264fSZachary Turner 
6789c40264fSZachary Turner   static bool Check(PyObject *py_obj);
6799c40264fSZachary Turner 
680d9b553ecSLawrence D'Anna   static llvm::Expected<PythonFile> FromFile(File &file,
681d9b553ecSLawrence D'Anna                                              const char *mode = nullptr);
682d9b553ecSLawrence D'Anna 
683085328eeSLawrence D'Anna   llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
684085328eeSLawrence D'Anna   llvm::Expected<lldb::FileSP>
685085328eeSLawrence D'Anna   ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
6869c40264fSZachary Turner };
6879c40264fSZachary Turner 
688085328eeSLawrence D'Anna class PythonException : public llvm::ErrorInfo<PythonException> {
689085328eeSLawrence D'Anna private:
690085328eeSLawrence D'Anna   PyObject *m_exception_type, *m_exception, *m_traceback;
691085328eeSLawrence D'Anna   PyObject *m_repr_bytes;
692085328eeSLawrence D'Anna 
693085328eeSLawrence D'Anna public:
694085328eeSLawrence D'Anna   static char ID;
695085328eeSLawrence D'Anna   const char *toCString() const;
696085328eeSLawrence D'Anna   PythonException(const char *caller = nullptr);
697085328eeSLawrence D'Anna   void Restore();
698085328eeSLawrence D'Anna   ~PythonException();
699085328eeSLawrence D'Anna   void log(llvm::raw_ostream &OS) const override;
700085328eeSLawrence D'Anna   std::error_code convertToErrorCode() const override;
701085328eeSLawrence D'Anna };
702085328eeSLawrence D'Anna 
703085328eeSLawrence D'Anna // This extracts the underlying T out of an Expected<T> and returns it.
704085328eeSLawrence D'Anna // If the Expected is an Error instead of a T, that error will be converted
705085328eeSLawrence D'Anna // into a python exception, and this will return a default-constructed T.
706085328eeSLawrence D'Anna //
707085328eeSLawrence D'Anna // This is appropriate for use right at the boundary of python calling into
708085328eeSLawrence D'Anna // C++, such as in a SWIG typemap.   In such a context you should simply
709085328eeSLawrence D'Anna // check if the returned T is valid, and if it is, return a NULL back
710085328eeSLawrence D'Anna // to python.   This will result in the Error being raised as an exception
711085328eeSLawrence D'Anna // from python code's point of view.
712085328eeSLawrence D'Anna //
713085328eeSLawrence D'Anna // For example:
714085328eeSLawrence D'Anna // ```
715085328eeSLawrence D'Anna // Expected<Foo *> efoop = some_cpp_function();
716085328eeSLawrence D'Anna // Foo *foop = unwrapOrSetPythonException(efoop);
717085328eeSLawrence D'Anna // if (!foop)
718085328eeSLawrence D'Anna //    return NULL;
719085328eeSLawrence D'Anna // do_something(*foop);
720085328eeSLawrence D'Anna //
721085328eeSLawrence D'Anna // If the Error returned was itself created because a python exception was
722085328eeSLawrence D'Anna // raised when C++ code called into python, then the original exception
723085328eeSLawrence D'Anna // will be restored.   Otherwise a simple string exception will be raised.
724085328eeSLawrence D'Anna template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
725085328eeSLawrence D'Anna   if (expected)
726085328eeSLawrence D'Anna     return expected.get();
727085328eeSLawrence D'Anna   llvm::handleAllErrors(
728085328eeSLawrence D'Anna       expected.takeError(), [](PythonException &E) { E.Restore(); },
729085328eeSLawrence D'Anna       [](const llvm::ErrorInfoBase &E) {
730085328eeSLawrence D'Anna         PyErr_SetString(PyExc_Exception, E.message().c_str());
731085328eeSLawrence D'Anna       });
732085328eeSLawrence D'Anna   return T();
733085328eeSLawrence D'Anna }
734085328eeSLawrence D'Anna 
735*722b6189SLawrence D'Anna namespace python {
736*722b6189SLawrence D'Anna // This is only here to help incrementally migrate old, exception-unsafe
737*722b6189SLawrence D'Anna // code.
738*722b6189SLawrence D'Anna template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
739*722b6189SLawrence D'Anna   if (expected)
740*722b6189SLawrence D'Anna     return std::move(expected.get());
741*722b6189SLawrence D'Anna   llvm::consumeError(expected.takeError());
742*722b6189SLawrence D'Anna   return T();
743*722b6189SLawrence D'Anna }
744*722b6189SLawrence D'Anna } // namespace python
745*722b6189SLawrence D'Anna 
7462c1f46dcSZachary Turner } // namespace lldb_private
7472c1f46dcSZachary Turner 
748a281b42bSZachary Turner #endif
749d68983e3SPavel Labath 
750d68983e3SPavel Labath #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
751