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 enum class PyObjectType {
872c1f46dcSZachary Turner   Unknown,
882c1f46dcSZachary Turner   None,
89b81d715cSTatyana Krasnukha   Boolean,
902c1f46dcSZachary Turner   Integer,
912c1f46dcSZachary Turner   Dictionary,
922c1f46dcSZachary Turner   List,
939c40264fSZachary Turner   String,
945a72c02bSZachary Turner   Bytes,
95f9d6d204SZachary Turner   ByteArray,
967841efbbSZachary Turner   Module,
97a1405147SZachary Turner   Callable,
98a1405147SZachary Turner   Tuple,
999c40264fSZachary Turner   File
1002c1f46dcSZachary Turner };
1012c1f46dcSZachary Turner 
102b9c1b51eSKate Stone enum class PyRefType {
103f8b22f8fSZachary Turner   Borrowed, // We are not given ownership of the incoming PyObject.
104f8b22f8fSZachary Turner             // We cannot safely hold it without calling Py_INCREF.
105f8b22f8fSZachary Turner   Owned     // We have ownership of the incoming PyObject.  We should
106f8b22f8fSZachary Turner             // not call Py_INCREF.
107f8b22f8fSZachary Turner };
108f8b22f8fSZachary Turner 
109085328eeSLawrence D'Anna 
110085328eeSLawrence D'Anna // Take a reference that you already own, and turn it into
111085328eeSLawrence D'Anna // a PythonObject.
112085328eeSLawrence D'Anna //
113085328eeSLawrence D'Anna // Most python API methods will return a +1 reference
114085328eeSLawrence D'Anna // if they succeed or NULL if and only if
115085328eeSLawrence D'Anna // they set an exception.   Use this to collect such return
116085328eeSLawrence D'Anna // values, after checking for NULL.
117085328eeSLawrence D'Anna //
118085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be
119085328eeSLawrence D'Anna // checked to be of the correct type.
120085328eeSLawrence D'Anna template <typename T> T Take(PyObject *obj) {
121085328eeSLawrence D'Anna   assert(obj);
122085328eeSLawrence D'Anna   assert(!PyErr_Occurred());
123085328eeSLawrence D'Anna   T thing(PyRefType::Owned, obj);
124085328eeSLawrence D'Anna   assert(thing.IsValid());
1251dfb1a85SPavel Labath   return thing;
126085328eeSLawrence D'Anna }
127085328eeSLawrence D'Anna 
128085328eeSLawrence D'Anna // Retain a reference you have borrowed, and turn it into
129085328eeSLawrence D'Anna // a PythonObject.
130085328eeSLawrence D'Anna //
131085328eeSLawrence D'Anna // A minority of python APIs return a borrowed reference
132085328eeSLawrence D'Anna // instead of a +1.   They will also return NULL if and only
133085328eeSLawrence D'Anna // if they set an exception.   Use this to collect such return
134085328eeSLawrence D'Anna // values, after checking for NULL.
135085328eeSLawrence D'Anna //
136085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be
137085328eeSLawrence D'Anna // checked to be of the correct type.
138085328eeSLawrence D'Anna template <typename T> T Retain(PyObject *obj) {
139085328eeSLawrence D'Anna   assert(obj);
140085328eeSLawrence D'Anna   assert(!PyErr_Occurred());
141085328eeSLawrence D'Anna   T thing(PyRefType::Borrowed, obj);
142085328eeSLawrence D'Anna   assert(thing.IsValid());
1431dfb1a85SPavel Labath   return thing;
144085328eeSLawrence D'Anna }
145085328eeSLawrence D'Anna 
146722b6189SLawrence D'Anna // This class can be used like a utility function to convert from
147722b6189SLawrence D'Anna // a llvm-friendly Twine into a null-terminated const char *,
148722b6189SLawrence D'Anna // which is the form python C APIs want their strings in.
149722b6189SLawrence D'Anna //
150722b6189SLawrence D'Anna // Example:
151722b6189SLawrence D'Anna // const llvm::Twine &some_twine;
152722b6189SLawrence D'Anna // PyFoo_Bar(x, y, z, NullTerminated(some_twine));
153722b6189SLawrence D'Anna //
154722b6189SLawrence D'Anna // Why a class instead of a function?  If the twine isn't already null
155722b6189SLawrence D'Anna // terminated, it will need a temporary buffer to copy the string
156722b6189SLawrence D'Anna // into.   We need that buffer to stick around for the lifetime of the
157722b6189SLawrence D'Anna // statement.
158722b6189SLawrence D'Anna class NullTerminated {
159722b6189SLawrence D'Anna   const char *str;
160722b6189SLawrence D'Anna   llvm::SmallString<32> storage;
161722b6189SLawrence D'Anna 
162722b6189SLawrence D'Anna public:
163722b6189SLawrence D'Anna   NullTerminated(const llvm::Twine &twine) {
164722b6189SLawrence D'Anna     llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
165722b6189SLawrence D'Anna     str = ref.begin();
166722b6189SLawrence D'Anna   }
167722b6189SLawrence D'Anna   operator const char *() { return str; }
168722b6189SLawrence D'Anna };
169722b6189SLawrence D'Anna 
17004edd189SLawrence D'Anna inline llvm::Error nullDeref() {
17104edd189SLawrence D'Anna   return llvm::createStringError(llvm::inconvertibleErrorCode(),
17204edd189SLawrence D'Anna                                  "A NULL PyObject* was dereferenced");
17304edd189SLawrence D'Anna }
17404edd189SLawrence D'Anna 
17504edd189SLawrence D'Anna inline llvm::Error exception(const char *s = nullptr) {
17604edd189SLawrence D'Anna   return llvm::make_error<PythonException>(s);
17704edd189SLawrence D'Anna }
17804edd189SLawrence D'Anna 
17904edd189SLawrence D'Anna inline llvm::Error keyError() {
18004edd189SLawrence D'Anna   return llvm::createStringError(llvm::inconvertibleErrorCode(),
18104edd189SLawrence D'Anna                                  "key not in dict");
18204edd189SLawrence D'Anna }
183085328eeSLawrence D'Anna 
1846a93a12aSLawrence D'Anna #if PY_MAJOR_VERSION < 3
1856a93a12aSLawrence D'Anna // The python 2 API declares some arguments as char* that should
1866a93a12aSLawrence D'Anna // be const char *, but it doesn't actually modify them.
1876a93a12aSLawrence D'Anna inline char *py2_const_cast(const char *s) { return const_cast<char *>(s); }
1886a93a12aSLawrence D'Anna #else
1896a93a12aSLawrence D'Anna inline const char *py2_const_cast(const char *s) { return s; }
1906a93a12aSLawrence D'Anna #endif
1916a93a12aSLawrence D'Anna 
192b9c1b51eSKate Stone enum class PyInitialValue { Invalid, Empty };
193f8b22f8fSZachary Turner 
194085328eeSLawrence D'Anna template <typename T, typename Enable = void> struct PythonFormat;
195085328eeSLawrence D'Anna 
196085328eeSLawrence D'Anna template <> struct PythonFormat<unsigned long long> {
197085328eeSLawrence D'Anna   static constexpr char format = 'K';
198085328eeSLawrence D'Anna   static auto get(unsigned long long value) { return value; }
199085328eeSLawrence D'Anna };
200085328eeSLawrence D'Anna 
201085328eeSLawrence D'Anna template <> struct PythonFormat<long long> {
202085328eeSLawrence D'Anna   static constexpr char format = 'L';
203085328eeSLawrence D'Anna   static auto get(long long value) { return value; }
204085328eeSLawrence D'Anna };
205085328eeSLawrence D'Anna 
20604edd189SLawrence D'Anna template <> struct PythonFormat<PyObject *> {
20704edd189SLawrence D'Anna   static constexpr char format = 'O';
20804edd189SLawrence D'Anna   static auto get(PyObject *value) { return value; }
20904edd189SLawrence D'Anna };
21004edd189SLawrence D'Anna 
211085328eeSLawrence D'Anna template <typename T>
212085328eeSLawrence D'Anna struct PythonFormat<
213085328eeSLawrence D'Anna     T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
214085328eeSLawrence D'Anna   static constexpr char format = 'O';
215085328eeSLawrence D'Anna   static auto get(const T &value) { return value.get(); }
216085328eeSLawrence D'Anna };
217085328eeSLawrence D'Anna 
218b9c1b51eSKate Stone class PythonObject {
2192c1f46dcSZachary Turner public:
220fd2433e1SJonas Devlieghere   PythonObject() = default;
2212c1f46dcSZachary Turner 
22204edd189SLawrence D'Anna   PythonObject(PyRefType type, PyObject *py_obj) {
22304edd189SLawrence D'Anna     m_py_obj = py_obj;
22404edd189SLawrence D'Anna     // If this is a borrowed reference, we need to convert it to
22504edd189SLawrence D'Anna     // an owned reference by incrementing it.  If it is an owned
22604edd189SLawrence D'Anna     // reference (for example the caller allocated it with PyDict_New()
22704edd189SLawrence D'Anna     // then we must *not* increment it.
22804edd189SLawrence D'Anna     if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
22904edd189SLawrence D'Anna       Py_XINCREF(m_py_obj);
2302c1f46dcSZachary Turner   }
2312c1f46dcSZachary Turner 
23203819d1cSLawrence D'Anna   PythonObject(const PythonObject &rhs)
23303819d1cSLawrence D'Anna       : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
2342c1f46dcSZachary Turner 
235085328eeSLawrence D'Anna   PythonObject(PythonObject &&rhs) {
236085328eeSLawrence D'Anna     m_py_obj = rhs.m_py_obj;
237085328eeSLawrence D'Anna     rhs.m_py_obj = nullptr;
238085328eeSLawrence D'Anna   }
239085328eeSLawrence D'Anna 
240d3bd5b3dSLawrence D'Anna   ~PythonObject() { Reset(); }
2412c1f46dcSZachary Turner 
242*6ff4af8eSPavel Labath   void Reset();
243f8b22f8fSZachary Turner 
244b9c1b51eSKate Stone   void Dump() const {
2452c1f46dcSZachary Turner     if (m_py_obj)
2462c1f46dcSZachary Turner       _PyObject_Dump(m_py_obj);
2472c1f46dcSZachary Turner     else
2482c1f46dcSZachary Turner       puts("NULL");
2492c1f46dcSZachary Turner   }
2502c1f46dcSZachary Turner 
251b9c1b51eSKate Stone   void Dump(Stream &strm) const;
2522c1f46dcSZachary Turner 
253b9c1b51eSKate Stone   PyObject *get() const { return m_py_obj; }
2542c1f46dcSZachary Turner 
255b9c1b51eSKate Stone   PyObject *release() {
25660c24f70SZachary Turner     PyObject *result = m_py_obj;
25760c24f70SZachary Turner     m_py_obj = nullptr;
25860c24f70SZachary Turner     return result;
25960c24f70SZachary Turner   }
26060c24f70SZachary Turner 
26103819d1cSLawrence D'Anna   PythonObject &operator=(PythonObject other) {
262085328eeSLawrence D'Anna     Reset();
26303819d1cSLawrence D'Anna     m_py_obj = std::exchange(other.m_py_obj, nullptr);
264085328eeSLawrence D'Anna     return *this;
265085328eeSLawrence D'Anna   }
266085328eeSLawrence D'Anna 
267b9c1b51eSKate Stone   PyObjectType GetObjectType() const;
2687841efbbSZachary Turner 
269b9c1b51eSKate Stone   PythonString Repr() const;
2707841efbbSZachary Turner 
271b9c1b51eSKate Stone   PythonString Str() const;
2727841efbbSZachary Turner 
273b9c1b51eSKate Stone   static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
274b9c1b51eSKate Stone                                                 const PythonDictionary &dict);
2757841efbbSZachary Turner 
276b58fb2f4SZachary Turner   template <typename T>
277b9c1b51eSKate Stone   static T ResolveNameWithDictionary(llvm::StringRef name,
278b9c1b51eSKate Stone                                      const PythonDictionary &dict) {
279b58fb2f4SZachary Turner     return ResolveNameWithDictionary(name, dict).AsType<T>();
280b58fb2f4SZachary Turner   }
281b58fb2f4SZachary Turner 
282b9c1b51eSKate Stone   PythonObject ResolveName(llvm::StringRef name) const;
2837841efbbSZachary Turner 
284b9c1b51eSKate Stone   template <typename T> T ResolveName(llvm::StringRef name) const {
285b58fb2f4SZachary Turner     return ResolveName(name).AsType<T>();
286b58fb2f4SZachary Turner   }
287b58fb2f4SZachary Turner 
288b9c1b51eSKate Stone   bool HasAttribute(llvm::StringRef attribute) const;
2899c40264fSZachary Turner 
290b9c1b51eSKate Stone   PythonObject GetAttributeValue(llvm::StringRef attribute) const;
2917d6d218eSZachary Turner 
292085328eeSLawrence D'Anna   bool IsNone() const { return m_py_obj == Py_None; }
293f8b22f8fSZachary Turner 
294085328eeSLawrence D'Anna   bool IsValid() const { return m_py_obj != nullptr; }
295f8b22f8fSZachary Turner 
296085328eeSLawrence D'Anna   bool IsAllocated() const { return IsValid() && !IsNone(); }
297085328eeSLawrence D'Anna 
298085328eeSLawrence D'Anna   explicit operator bool() const { return IsValid() && !IsNone(); }
2992c1f46dcSZachary Turner 
300b9c1b51eSKate Stone   template <typename T> T AsType() const {
3017d6d218eSZachary Turner     if (!T::Check(m_py_obj))
3027d6d218eSZachary Turner       return T();
3037d6d218eSZachary Turner     return T(PyRefType::Borrowed, m_py_obj);
3047d6d218eSZachary Turner   }
3057d6d218eSZachary Turner 
306b9c1b51eSKate Stone   StructuredData::ObjectSP CreateStructuredObject() const;
3072c1f46dcSZachary Turner 
308085328eeSLawrence D'Anna   template <typename... T>
309085328eeSLawrence D'Anna   llvm::Expected<PythonObject> CallMethod(const char *name,
310085328eeSLawrence D'Anna                                           const T &... t) const {
311085328eeSLawrence D'Anna     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
312085328eeSLawrence D'Anna     PyObject *obj =
313c86a6acaSLawrence D'Anna         PyObject_CallMethod(m_py_obj, py2_const_cast(name),
314c86a6acaSLawrence D'Anna                             py2_const_cast(format), PythonFormat<T>::get(t)...);
315c86a6acaSLawrence D'Anna     if (!obj)
316c86a6acaSLawrence D'Anna       return exception();
317c86a6acaSLawrence D'Anna     return python::Take<PythonObject>(obj);
318c86a6acaSLawrence D'Anna   }
319c86a6acaSLawrence D'Anna 
320c86a6acaSLawrence D'Anna   template <typename... T>
321c86a6acaSLawrence D'Anna   llvm::Expected<PythonObject> Call(const T &... t) const {
322c86a6acaSLawrence D'Anna     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
323c86a6acaSLawrence D'Anna     PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
324c86a6acaSLawrence D'Anna                                           PythonFormat<T>::get(t)...);
325085328eeSLawrence D'Anna     if (!obj)
326085328eeSLawrence D'Anna       return exception();
327085328eeSLawrence D'Anna     return python::Take<PythonObject>(obj);
328085328eeSLawrence D'Anna   }
329085328eeSLawrence D'Anna 
330722b6189SLawrence D'Anna   llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
331085328eeSLawrence D'Anna     if (!m_py_obj)
332085328eeSLawrence D'Anna       return nullDeref();
333722b6189SLawrence D'Anna     PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
334085328eeSLawrence D'Anna     if (!obj)
335085328eeSLawrence D'Anna       return exception();
336085328eeSLawrence D'Anna     return python::Take<PythonObject>(obj);
337085328eeSLawrence D'Anna   }
338085328eeSLawrence D'Anna 
339085328eeSLawrence D'Anna   llvm::Expected<bool> IsTrue() {
340085328eeSLawrence D'Anna     if (!m_py_obj)
341085328eeSLawrence D'Anna       return nullDeref();
342085328eeSLawrence D'Anna     int r = PyObject_IsTrue(m_py_obj);
343085328eeSLawrence D'Anna     if (r < 0)
344085328eeSLawrence D'Anna       return exception();
345085328eeSLawrence D'Anna     return !!r;
346085328eeSLawrence D'Anna   }
347085328eeSLawrence D'Anna 
34852712d3fSLawrence D'Anna   llvm::Expected<long long> AsLongLong() const;
34952712d3fSLawrence D'Anna 
35052712d3fSLawrence D'Anna   llvm::Expected<long long> AsUnsignedLongLong() const;
35152712d3fSLawrence D'Anna 
35252712d3fSLawrence D'Anna   // wraps on overflow, instead of raising an error.
35352712d3fSLawrence D'Anna   llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
354085328eeSLawrence D'Anna 
355085328eeSLawrence D'Anna   llvm::Expected<bool> IsInstance(const PythonObject &cls) {
356085328eeSLawrence D'Anna     if (!m_py_obj || !cls.IsValid())
357085328eeSLawrence D'Anna       return nullDeref();
358085328eeSLawrence D'Anna     int r = PyObject_IsInstance(m_py_obj, cls.get());
359085328eeSLawrence D'Anna     if (r < 0)
360085328eeSLawrence D'Anna       return exception();
361085328eeSLawrence D'Anna     return !!r;
362085328eeSLawrence D'Anna   }
363085328eeSLawrence D'Anna 
364085328eeSLawrence D'Anna protected:
3659494c510SJonas Devlieghere   PyObject *m_py_obj = nullptr;
3662c1f46dcSZachary Turner };
3672c1f46dcSZachary Turner 
368085328eeSLawrence D'Anna 
369085328eeSLawrence D'Anna // This is why C++ needs monads.
370085328eeSLawrence D'Anna template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
371085328eeSLawrence D'Anna   if (!obj)
372085328eeSLawrence D'Anna     return obj.takeError();
373085328eeSLawrence D'Anna   if (!T::Check(obj.get().get()))
374085328eeSLawrence D'Anna     return llvm::createStringError(llvm::inconvertibleErrorCode(),
375085328eeSLawrence D'Anna                                    "type error");
376085328eeSLawrence D'Anna   return T(PyRefType::Borrowed, std::move(obj.get().get()));
377085328eeSLawrence D'Anna }
378085328eeSLawrence D'Anna 
379085328eeSLawrence D'Anna template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
380085328eeSLawrence D'Anna 
381085328eeSLawrence D'Anna template <>
382085328eeSLawrence D'Anna llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
383085328eeSLawrence D'Anna 
384c86a6acaSLawrence D'Anna template <>
38552712d3fSLawrence D'Anna llvm::Expected<unsigned long long>
38652712d3fSLawrence D'Anna As<unsigned long long>(llvm::Expected<PythonObject> &&obj);
38752712d3fSLawrence D'Anna 
38852712d3fSLawrence D'Anna template <>
389c86a6acaSLawrence D'Anna llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
390c86a6acaSLawrence D'Anna 
391085328eeSLawrence D'Anna 
392d3bd5b3dSLawrence D'Anna template <class T> class TypedPythonObject : public PythonObject {
3935a72c02bSZachary Turner public:
394d3bd5b3dSLawrence D'Anna   // override to perform implicit type conversions on Reset
395d3bd5b3dSLawrence D'Anna   // This can be eliminated once we drop python 2 support.
396d3bd5b3dSLawrence D'Anna   static void Convert(PyRefType &type, PyObject *&py_obj) {}
397d3bd5b3dSLawrence D'Anna 
398722b6189SLawrence D'Anna   TypedPythonObject(PyRefType type, PyObject *py_obj) {
399d3bd5b3dSLawrence D'Anna     if (!py_obj)
400d3bd5b3dSLawrence D'Anna       return;
401d3bd5b3dSLawrence D'Anna     T::Convert(type, py_obj);
402d3bd5b3dSLawrence D'Anna     if (T::Check(py_obj))
40304edd189SLawrence D'Anna       PythonObject::operator=(PythonObject(type, py_obj));
404d3bd5b3dSLawrence D'Anna     else if (type == PyRefType::Owned)
405d3bd5b3dSLawrence D'Anna       Py_DECREF(py_obj);
406d3bd5b3dSLawrence D'Anna   }
407d3bd5b3dSLawrence D'Anna 
408fd2433e1SJonas Devlieghere   TypedPythonObject() = default;
409d3bd5b3dSLawrence D'Anna };
410d3bd5b3dSLawrence D'Anna 
411d3bd5b3dSLawrence D'Anna class PythonBytes : public TypedPythonObject<PythonBytes> {
412d3bd5b3dSLawrence D'Anna public:
413d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
4145a72c02bSZachary Turner   explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
4155a72c02bSZachary Turner   PythonBytes(const uint8_t *bytes, size_t length);
4165a72c02bSZachary Turner 
417b9c1b51eSKate Stone   static bool Check(PyObject *py_obj);
4185a72c02bSZachary Turner 
419b9c1b51eSKate Stone   llvm::ArrayRef<uint8_t> GetBytes() const;
4205a72c02bSZachary Turner 
421b9c1b51eSKate Stone   size_t GetSize() const;
4225a72c02bSZachary Turner 
423b9c1b51eSKate Stone   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4245a72c02bSZachary Turner 
425b9c1b51eSKate Stone   StructuredData::StringSP CreateStructuredString() const;
4265a72c02bSZachary Turner };
4275a72c02bSZachary Turner 
428d3bd5b3dSLawrence D'Anna class PythonByteArray : public TypedPythonObject<PythonByteArray> {
429f9d6d204SZachary Turner public:
430d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
431f9d6d204SZachary Turner   explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
432f9d6d204SZachary Turner   PythonByteArray(const uint8_t *bytes, size_t length);
433f9d6d204SZachary Turner   PythonByteArray(const PythonBytes &object);
434f9d6d204SZachary Turner 
435b9c1b51eSKate Stone   static bool Check(PyObject *py_obj);
436f9d6d204SZachary Turner 
437b9c1b51eSKate Stone   llvm::ArrayRef<uint8_t> GetBytes() const;
438f9d6d204SZachary Turner 
439b9c1b51eSKate Stone   size_t GetSize() const;
440f9d6d204SZachary Turner 
441b9c1b51eSKate Stone   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
442f9d6d204SZachary Turner 
443b9c1b51eSKate Stone   StructuredData::StringSP CreateStructuredString() const;
444f9d6d204SZachary Turner };
445f9d6d204SZachary Turner 
446d3bd5b3dSLawrence D'Anna class PythonString : public TypedPythonObject<PythonString> {
4472c1f46dcSZachary Turner public:
448d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
449085328eeSLawrence D'Anna   static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
450085328eeSLawrence D'Anna 
451d3bd5b3dSLawrence D'Anna   PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
452edb35d95SEugene Zelenko 
453d3bd5b3dSLawrence D'Anna   explicit PythonString(llvm::StringRef string); // safe, null on error
4542c1f46dcSZachary Turner 
45522c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
456d3bd5b3dSLawrence D'Anna   static void Convert(PyRefType &type, PyObject *&py_obj);
4572c1f46dcSZachary Turner 
458085328eeSLawrence D'Anna   llvm::StringRef GetString() const; // safe, empty string on error
459085328eeSLawrence D'Anna 
460085328eeSLawrence D'Anna   llvm::Expected<llvm::StringRef> AsUTF8() const;
4612c1f46dcSZachary Turner 
462b9c1b51eSKate Stone   size_t GetSize() const;
4632c1f46dcSZachary Turner 
464085328eeSLawrence D'Anna   void SetString(llvm::StringRef string); // safe, null on error
4652c1f46dcSZachary Turner 
4662c1f46dcSZachary Turner   StructuredData::StringSP CreateStructuredString() const;
4672c1f46dcSZachary Turner };
4682c1f46dcSZachary Turner 
469d3bd5b3dSLawrence D'Anna class PythonInteger : public TypedPythonObject<PythonInteger> {
4702c1f46dcSZachary Turner public:
471d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
472edb35d95SEugene Zelenko 
473d3bd5b3dSLawrence D'Anna   PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
474d3bd5b3dSLawrence D'Anna 
475d3bd5b3dSLawrence D'Anna   explicit PythonInteger(int64_t value);
4762c1f46dcSZachary Turner 
47722c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
478d3bd5b3dSLawrence D'Anna   static void Convert(PyRefType &type, PyObject *&py_obj);
4792c1f46dcSZachary Turner 
480b9c1b51eSKate Stone   void SetInteger(int64_t value);
4812c1f46dcSZachary Turner 
4822c1f46dcSZachary Turner   StructuredData::IntegerSP CreateStructuredInteger() const;
4832c1f46dcSZachary Turner };
4842c1f46dcSZachary Turner 
485d3bd5b3dSLawrence D'Anna class PythonBoolean : public TypedPythonObject<PythonBoolean> {
486b81d715cSTatyana Krasnukha public:
487d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
488b81d715cSTatyana Krasnukha 
489d3bd5b3dSLawrence D'Anna   explicit PythonBoolean(bool value);
490b81d715cSTatyana Krasnukha 
491b81d715cSTatyana Krasnukha   static bool Check(PyObject *py_obj);
492b81d715cSTatyana Krasnukha 
493b81d715cSTatyana Krasnukha   bool GetValue() const;
494b81d715cSTatyana Krasnukha 
495b81d715cSTatyana Krasnukha   void SetValue(bool value);
496b81d715cSTatyana Krasnukha 
497b81d715cSTatyana Krasnukha   StructuredData::BooleanSP CreateStructuredBoolean() const;
498b81d715cSTatyana Krasnukha };
499b81d715cSTatyana Krasnukha 
500d3bd5b3dSLawrence D'Anna class PythonList : public TypedPythonObject<PythonList> {
5012c1f46dcSZachary Turner public:
502d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
503d3bd5b3dSLawrence D'Anna 
504d3bd5b3dSLawrence D'Anna   PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
505d3bd5b3dSLawrence D'Anna 
50687f47729SZachary Turner   explicit PythonList(PyInitialValue value);
50787f47729SZachary Turner   explicit PythonList(int list_size);
5082c1f46dcSZachary Turner 
50922c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
51022c8efcdSZachary Turner 
5112c1f46dcSZachary Turner   uint32_t GetSize() const;
5122c1f46dcSZachary Turner 
5132c1f46dcSZachary Turner   PythonObject GetItemAtIndex(uint32_t index) const;
5142c1f46dcSZachary Turner 
515f8b22f8fSZachary Turner   void SetItemAtIndex(uint32_t index, const PythonObject &object);
5162c1f46dcSZachary Turner 
517f8b22f8fSZachary Turner   void AppendItem(const PythonObject &object);
5182c1f46dcSZachary Turner 
5192c1f46dcSZachary Turner   StructuredData::ArraySP CreateStructuredArray() const;
5202c1f46dcSZachary Turner };
5212c1f46dcSZachary Turner 
522d3bd5b3dSLawrence D'Anna class PythonTuple : public TypedPythonObject<PythonTuple> {
523a1405147SZachary Turner public:
524d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
525d3bd5b3dSLawrence D'Anna 
526a1405147SZachary Turner   explicit PythonTuple(PyInitialValue value);
527a1405147SZachary Turner   explicit PythonTuple(int tuple_size);
528a1405147SZachary Turner   PythonTuple(std::initializer_list<PythonObject> objects);
529a1405147SZachary Turner   PythonTuple(std::initializer_list<PyObject *> objects);
530a1405147SZachary Turner 
531a1405147SZachary Turner   static bool Check(PyObject *py_obj);
532a1405147SZachary Turner 
533a1405147SZachary Turner   uint32_t GetSize() const;
534a1405147SZachary Turner 
535a1405147SZachary Turner   PythonObject GetItemAtIndex(uint32_t index) const;
536a1405147SZachary Turner 
537a1405147SZachary Turner   void SetItemAtIndex(uint32_t index, const PythonObject &object);
538a1405147SZachary Turner 
539a1405147SZachary Turner   StructuredData::ArraySP CreateStructuredArray() const;
540a1405147SZachary Turner };
541a1405147SZachary Turner 
542d3bd5b3dSLawrence D'Anna class PythonDictionary : public TypedPythonObject<PythonDictionary> {
5432c1f46dcSZachary Turner public:
544d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
545edb35d95SEugene Zelenko 
546d3bd5b3dSLawrence D'Anna   PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
547d3bd5b3dSLawrence D'Anna 
548d3bd5b3dSLawrence D'Anna   explicit PythonDictionary(PyInitialValue value);
5492c1f46dcSZachary Turner 
55022c8efcdSZachary Turner   static bool Check(PyObject *py_obj);
55122c8efcdSZachary Turner 
5522c1f46dcSZachary Turner   uint32_t GetSize() const;
5532c1f46dcSZachary Turner 
554f8b22f8fSZachary Turner   PythonList GetKeys() const;
5552c1f46dcSZachary Turner 
556c86a6acaSLawrence D'Anna   PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
557c86a6acaSLawrence D'Anna   void SetItemForKey(const PythonObject &key,
558c86a6acaSLawrence D'Anna                      const PythonObject &value); // DEPRECATED
559c86a6acaSLawrence D'Anna 
560c86a6acaSLawrence D'Anna   llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
561722b6189SLawrence D'Anna   llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
562c86a6acaSLawrence D'Anna   llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
563722b6189SLawrence D'Anna   llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
5642c1f46dcSZachary Turner 
5652c1f46dcSZachary Turner   StructuredData::DictionarySP CreateStructuredDictionary() const;
5662c1f46dcSZachary Turner };
56787f47729SZachary Turner 
568d3bd5b3dSLawrence D'Anna class PythonModule : public TypedPythonObject<PythonModule> {
5697841efbbSZachary Turner public:
570d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
5717841efbbSZachary Turner 
5727841efbbSZachary Turner   static bool Check(PyObject *py_obj);
5737841efbbSZachary Turner 
574b9c1b51eSKate Stone   static PythonModule BuiltinsModule();
575a1405147SZachary Turner 
576b9c1b51eSKate Stone   static PythonModule MainModule();
577a1405147SZachary Turner 
578b9c1b51eSKate Stone   static PythonModule AddModule(llvm::StringRef module);
5797841efbbSZachary Turner 
580085328eeSLawrence D'Anna   // safe, returns invalid on error;
581085328eeSLawrence D'Anna   static PythonModule ImportModule(llvm::StringRef name) {
582adcd0268SBenjamin Kramer     std::string s = std::string(name);
583085328eeSLawrence D'Anna     auto mod = Import(s.c_str());
584085328eeSLawrence D'Anna     if (!mod) {
585085328eeSLawrence D'Anna       llvm::consumeError(mod.takeError());
586085328eeSLawrence D'Anna       return PythonModule();
587085328eeSLawrence D'Anna     }
588085328eeSLawrence D'Anna     return std::move(mod.get());
589085328eeSLawrence D'Anna   }
590085328eeSLawrence D'Anna 
591722b6189SLawrence D'Anna   static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
592085328eeSLawrence D'Anna 
593722b6189SLawrence D'Anna   llvm::Expected<PythonObject> Get(const llvm::Twine &name);
5942419f1d5SZachary Turner 
5957841efbbSZachary Turner   PythonDictionary GetDictionary() const;
5967841efbbSZachary Turner };
5977841efbbSZachary Turner 
598d3bd5b3dSLawrence D'Anna class PythonCallable : public TypedPythonObject<PythonCallable> {
599a1405147SZachary Turner public:
600d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
601d3bd5b3dSLawrence D'Anna 
602b58fb2f4SZachary Turner   struct ArgInfo {
6032386537cSLawrence D'Anna     /* the largest number of positional arguments this callable
6042386537cSLawrence D'Anna      * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
6052386537cSLawrence D'Anna      * function and can accept an arbitrary number */
6062386537cSLawrence D'Anna     unsigned max_positional_args;
6072386537cSLawrence D'Anna     static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
608b58fb2f4SZachary Turner   };
609b58fb2f4SZachary Turner 
610b9c1b51eSKate Stone   static bool Check(PyObject *py_obj);
611a1405147SZachary Turner 
612c86a6acaSLawrence D'Anna   llvm::Expected<ArgInfo> GetArgInfo() const;
613c86a6acaSLawrence D'Anna 
614b9c1b51eSKate Stone   PythonObject operator()();
615a1405147SZachary Turner 
616b9c1b51eSKate Stone   PythonObject operator()(std::initializer_list<PyObject *> args);
617a1405147SZachary Turner 
618b9c1b51eSKate Stone   PythonObject operator()(std::initializer_list<PythonObject> args);
619b58fb2f4SZachary Turner 
620b58fb2f4SZachary Turner   template <typename Arg, typename... Args>
621b9c1b51eSKate Stone   PythonObject operator()(const Arg &arg, Args... args) {
622b58fb2f4SZachary Turner     return operator()({arg, args...});
623b58fb2f4SZachary Turner   }
624a1405147SZachary Turner };
625a1405147SZachary Turner 
626d3bd5b3dSLawrence D'Anna class PythonFile : public TypedPythonObject<PythonFile> {
6279c40264fSZachary Turner public:
628d3bd5b3dSLawrence D'Anna   using TypedPythonObject::TypedPythonObject;
629edb35d95SEugene Zelenko 
630d3bd5b3dSLawrence D'Anna   PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
6319c40264fSZachary Turner 
6329c40264fSZachary Turner   static bool Check(PyObject *py_obj);
6339c40264fSZachary Turner 
634d9b553ecSLawrence D'Anna   static llvm::Expected<PythonFile> FromFile(File &file,
635d9b553ecSLawrence D'Anna                                              const char *mode = nullptr);
636d9b553ecSLawrence D'Anna 
637085328eeSLawrence D'Anna   llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
638085328eeSLawrence D'Anna   llvm::Expected<lldb::FileSP>
639085328eeSLawrence D'Anna   ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
6409c40264fSZachary Turner };
6419c40264fSZachary Turner 
642085328eeSLawrence D'Anna class PythonException : public llvm::ErrorInfo<PythonException> {
643085328eeSLawrence D'Anna private:
644085328eeSLawrence D'Anna   PyObject *m_exception_type, *m_exception, *m_traceback;
645085328eeSLawrence D'Anna   PyObject *m_repr_bytes;
646085328eeSLawrence D'Anna 
647085328eeSLawrence D'Anna public:
648085328eeSLawrence D'Anna   static char ID;
649085328eeSLawrence D'Anna   const char *toCString() const;
650085328eeSLawrence D'Anna   PythonException(const char *caller = nullptr);
651085328eeSLawrence D'Anna   void Restore();
652085328eeSLawrence D'Anna   ~PythonException();
653085328eeSLawrence D'Anna   void log(llvm::raw_ostream &OS) const override;
654085328eeSLawrence D'Anna   std::error_code convertToErrorCode() const override;
65504edd189SLawrence D'Anna   bool Matches(PyObject *exc) const;
65604edd189SLawrence D'Anna   std::string ReadBacktrace() const;
657085328eeSLawrence D'Anna };
658085328eeSLawrence D'Anna 
659085328eeSLawrence D'Anna // This extracts the underlying T out of an Expected<T> and returns it.
660085328eeSLawrence D'Anna // If the Expected is an Error instead of a T, that error will be converted
661085328eeSLawrence D'Anna // into a python exception, and this will return a default-constructed T.
662085328eeSLawrence D'Anna //
663085328eeSLawrence D'Anna // This is appropriate for use right at the boundary of python calling into
664085328eeSLawrence D'Anna // C++, such as in a SWIG typemap.   In such a context you should simply
665085328eeSLawrence D'Anna // check if the returned T is valid, and if it is, return a NULL back
666085328eeSLawrence D'Anna // to python.   This will result in the Error being raised as an exception
667085328eeSLawrence D'Anna // from python code's point of view.
668085328eeSLawrence D'Anna //
669085328eeSLawrence D'Anna // For example:
670085328eeSLawrence D'Anna // ```
671085328eeSLawrence D'Anna // Expected<Foo *> efoop = some_cpp_function();
672085328eeSLawrence D'Anna // Foo *foop = unwrapOrSetPythonException(efoop);
673085328eeSLawrence D'Anna // if (!foop)
674085328eeSLawrence D'Anna //    return NULL;
675085328eeSLawrence D'Anna // do_something(*foop);
676085328eeSLawrence D'Anna //
677085328eeSLawrence D'Anna // If the Error returned was itself created because a python exception was
678085328eeSLawrence D'Anna // raised when C++ code called into python, then the original exception
679085328eeSLawrence D'Anna // will be restored.   Otherwise a simple string exception will be raised.
680085328eeSLawrence D'Anna template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
681085328eeSLawrence D'Anna   if (expected)
682085328eeSLawrence D'Anna     return expected.get();
683085328eeSLawrence D'Anna   llvm::handleAllErrors(
684085328eeSLawrence D'Anna       expected.takeError(), [](PythonException &E) { E.Restore(); },
685085328eeSLawrence D'Anna       [](const llvm::ErrorInfoBase &E) {
686085328eeSLawrence D'Anna         PyErr_SetString(PyExc_Exception, E.message().c_str());
687085328eeSLawrence D'Anna       });
688085328eeSLawrence D'Anna   return T();
689085328eeSLawrence D'Anna }
690085328eeSLawrence D'Anna 
691722b6189SLawrence D'Anna // This is only here to help incrementally migrate old, exception-unsafe
692722b6189SLawrence D'Anna // code.
693722b6189SLawrence D'Anna template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
694722b6189SLawrence D'Anna   if (expected)
695722b6189SLawrence D'Anna     return std::move(expected.get());
696722b6189SLawrence D'Anna   llvm::consumeError(expected.takeError());
697722b6189SLawrence D'Anna   return T();
698722b6189SLawrence D'Anna }
699722b6189SLawrence D'Anna 
70004edd189SLawrence D'Anna llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
70104edd189SLawrence D'Anna                                               const PythonDictionary &globals,
70204edd189SLawrence D'Anna                                               const PythonDictionary &locals);
70304edd189SLawrence D'Anna 
70404edd189SLawrence D'Anna llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
70504edd189SLawrence D'Anna                                                 const PythonDictionary &globals,
70604edd189SLawrence D'Anna                                                 const PythonDictionary &locals);
70704edd189SLawrence D'Anna 
70804edd189SLawrence D'Anna // Sometimes the best way to interact with a python interpreter is
70904edd189SLawrence D'Anna // to run some python code.   You construct a PythonScript with
71004edd189SLawrence D'Anna // script string.   The script assigns some function to `_function_`
71104edd189SLawrence D'Anna // and you get a C++ callable object that calls the python function.
71204edd189SLawrence D'Anna //
71304edd189SLawrence D'Anna // Example:
71404edd189SLawrence D'Anna //
71504edd189SLawrence D'Anna // const char script[] = R"(
71604edd189SLawrence D'Anna // def main(x, y):
71704edd189SLawrence D'Anna //    ....
71804edd189SLawrence D'Anna // )";
71904edd189SLawrence D'Anna //
72004edd189SLawrence D'Anna // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
72104edd189SLawrence D'Anna //   // no need to synchronize access to this global, we already have the GIL
72204edd189SLawrence D'Anna //   static PythonScript foo(script)
72304edd189SLawrence D'Anna //   return  foo(x, y);
72404edd189SLawrence D'Anna // }
72504edd189SLawrence D'Anna class PythonScript {
72604edd189SLawrence D'Anna   const char *script;
72704edd189SLawrence D'Anna   PythonCallable function;
72804edd189SLawrence D'Anna 
72904edd189SLawrence D'Anna   llvm::Error Init();
73004edd189SLawrence D'Anna 
73104edd189SLawrence D'Anna public:
73204edd189SLawrence D'Anna   PythonScript(const char *script) : script(script), function() {}
73304edd189SLawrence D'Anna 
73404edd189SLawrence D'Anna   template <typename... Args>
73504edd189SLawrence D'Anna   llvm::Expected<PythonObject> operator()(Args &&... args) {
73604edd189SLawrence D'Anna     if (llvm::Error error = Init())
73704edd189SLawrence D'Anna       return std::move(error);
73804edd189SLawrence D'Anna     return function.Call(std::forward<Args>(args)...);
73904edd189SLawrence D'Anna   }
74004edd189SLawrence D'Anna };
74104edd189SLawrence D'Anna 
742c154f397SPavel Labath class StructuredPythonObject : public StructuredData::Generic {
743c154f397SPavel Labath public:
744c154f397SPavel Labath   StructuredPythonObject() : StructuredData::Generic() {}
745c154f397SPavel Labath 
746c154f397SPavel Labath   // Take ownership of the object we received.
747c154f397SPavel Labath   StructuredPythonObject(PythonObject obj)
748c154f397SPavel Labath       : StructuredData::Generic(obj.release()) {}
749c154f397SPavel Labath 
750c154f397SPavel Labath   ~StructuredPythonObject() override {
751c154f397SPavel Labath     // Hand ownership back to a (temporary) PythonObject instance and let it
752c154f397SPavel Labath     // take care of releasing it.
753c154f397SPavel Labath     PythonObject(PyRefType::Owned, static_cast<PyObject *>(GetValue()));
754c154f397SPavel Labath   }
755c154f397SPavel Labath 
756c154f397SPavel Labath   bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
757c154f397SPavel Labath 
758c154f397SPavel Labath   void Serialize(llvm::json::OStream &s) const override;
759c154f397SPavel Labath 
760c154f397SPavel Labath private:
761c154f397SPavel Labath   StructuredPythonObject(const StructuredPythonObject &) = delete;
762c154f397SPavel Labath   const StructuredPythonObject &
763c154f397SPavel Labath   operator=(const StructuredPythonObject &) = delete;
764c154f397SPavel Labath };
765c154f397SPavel Labath 
76604edd189SLawrence D'Anna } // namespace python
7672c1f46dcSZachary Turner } // namespace lldb_private
7682c1f46dcSZachary Turner 
769a281b42bSZachary Turner #endif
770d68983e3SPavel Labath 
771d68983e3SPavel Labath #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
772