xref: /src/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1e81d9d49SDimitry Andric //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===//
2e81d9d49SDimitry Andric //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e81d9d49SDimitry Andric //
7e81d9d49SDimitry Andric //===----------------------------------------------------------------------===//
8e81d9d49SDimitry Andric 
9ead24645SDimitry Andric //
10ead24645SDimitry Andric // !! FIXME FIXME FIXME !!
11ead24645SDimitry Andric //
12ead24645SDimitry Andric // Python APIs nearly all can return an exception.   They do this
13ead24645SDimitry Andric // by returning NULL, or -1, or some such value and setting
14ead24645SDimitry Andric // the exception state with PyErr_Set*().   Exceptions must be
15ead24645SDimitry Andric // handled before further python API functions are called.   Failure
16ead24645SDimitry Andric // to do so will result in asserts on debug builds of python.
17ead24645SDimitry Andric // It will also sometimes, but not usually result in crashes of
18ead24645SDimitry Andric // release builds.
19ead24645SDimitry Andric //
20ead24645SDimitry Andric // Nearly all the code in this header does not handle python exceptions
21ead24645SDimitry Andric // correctly.  It should all be converted to return Expected<> or
22ead24645SDimitry Andric // Error types to capture the exception.
23ead24645SDimitry Andric //
24ead24645SDimitry Andric // Everything in this file except functions that return Error or
25ead24645SDimitry Andric // Expected<> is considered deprecated and should not be
26ead24645SDimitry Andric // used in new code.  If you need to use it, fix it first.
27ead24645SDimitry Andric //
28ead24645SDimitry Andric //
29ead24645SDimitry Andric // TODOs for this file
30ead24645SDimitry Andric //
31ead24645SDimitry Andric // * Make all methods safe for exceptions.
32ead24645SDimitry Andric //
33ead24645SDimitry Andric // * Eliminate method signatures that must translate exceptions into
34ead24645SDimitry Andric //   empty objects or NULLs.   Almost everything here should return
35ead24645SDimitry Andric //   Expected<>.   It should be acceptable for certain operations that
36ead24645SDimitry Andric //   can never fail to assert instead, such as the creation of
37ead24645SDimitry Andric //   PythonString from a string literal.
38ead24645SDimitry Andric //
39cfca06d7SDimitry Andric // * Eliminate Reset(), and make all non-default constructors private.
40ead24645SDimitry Andric //   Python objects should be created with Retain<> or Take<>, and they
41ead24645SDimitry Andric //   should be assigned with operator=
42ead24645SDimitry Andric //
43ead24645SDimitry Andric // * Eliminate default constructors, make python objects always
44ead24645SDimitry Andric //   nonnull, and use optionals where necessary.
45ead24645SDimitry Andric //
46ead24645SDimitry Andric 
47ead24645SDimitry Andric 
48e81d9d49SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
49e81d9d49SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
50e81d9d49SDimitry Andric 
51706b4fc4SDimitry Andric #include "lldb/Host/Config.h"
52706b4fc4SDimitry Andric 
53706b4fc4SDimitry Andric #if LLDB_ENABLE_PYTHON
54e81d9d49SDimitry Andric 
5514f1b3e8SDimitry Andric // LLDB Python header must be included first
5614f1b3e8SDimitry Andric #include "lldb-python.h"
5714f1b3e8SDimitry Andric 
58e81d9d49SDimitry Andric #include "lldb/Host/File.h"
591b306c26SDimitry Andric #include "lldb/Utility/StructuredData.h"
60e81d9d49SDimitry Andric 
617fed546dSDimitry Andric #include "llvm/ADT/ArrayRef.h"
627fed546dSDimitry Andric 
63e81d9d49SDimitry Andric namespace lldb_private {
64ead24645SDimitry Andric namespace python {
65e81d9d49SDimitry Andric 
66ead24645SDimitry Andric class PythonObject;
677fed546dSDimitry Andric class PythonBytes;
68e81d9d49SDimitry Andric class PythonString;
69e81d9d49SDimitry Andric class PythonList;
70e81d9d49SDimitry Andric class PythonDictionary;
71e81d9d49SDimitry Andric class PythonInteger;
72ead24645SDimitry Andric class PythonException;
73e81d9d49SDimitry Andric 
74c0981da4SDimitry Andric class GIL {
75c0981da4SDimitry Andric public:
GIL()76c0981da4SDimitry Andric   GIL() {
77c0981da4SDimitry Andric     m_state = PyGILState_Ensure();
78c0981da4SDimitry Andric     assert(!PyErr_Occurred());
79c0981da4SDimitry Andric   }
~GIL()80c0981da4SDimitry Andric   ~GIL() { PyGILState_Release(m_state); }
81c0981da4SDimitry Andric 
82c0981da4SDimitry Andric protected:
83c0981da4SDimitry Andric   PyGILState_STATE m_state;
84c0981da4SDimitry Andric };
85c0981da4SDimitry Andric 
8614f1b3e8SDimitry Andric enum class PyObjectType {
87e81d9d49SDimitry Andric   Unknown,
88e81d9d49SDimitry Andric   None,
895f29bb8aSDimitry Andric   Boolean,
90e81d9d49SDimitry Andric   Integer,
91e81d9d49SDimitry Andric   Dictionary,
92e81d9d49SDimitry Andric   List,
93e81d9d49SDimitry Andric   String,
947fed546dSDimitry Andric   Bytes,
95f3fbd1c0SDimitry Andric   ByteArray,
96e81d9d49SDimitry Andric   Module,
97e81d9d49SDimitry Andric   Callable,
98e81d9d49SDimitry Andric   Tuple,
99e81d9d49SDimitry Andric   File
100e81d9d49SDimitry Andric };
101e81d9d49SDimitry Andric 
10214f1b3e8SDimitry Andric enum class PyRefType {
103e81d9d49SDimitry Andric   Borrowed, // We are not given ownership of the incoming PyObject.
104e81d9d49SDimitry Andric             // We cannot safely hold it without calling Py_INCREF.
105e81d9d49SDimitry Andric   Owned     // We have ownership of the incoming PyObject.  We should
106e81d9d49SDimitry Andric             // not call Py_INCREF.
107e81d9d49SDimitry Andric };
108e81d9d49SDimitry Andric 
109ead24645SDimitry Andric 
110ead24645SDimitry Andric // Take a reference that you already own, and turn it into
111ead24645SDimitry Andric // a PythonObject.
112ead24645SDimitry Andric //
113ead24645SDimitry Andric // Most python API methods will return a +1 reference
114ead24645SDimitry Andric // if they succeed or NULL if and only if
115ead24645SDimitry Andric // they set an exception.   Use this to collect such return
116ead24645SDimitry Andric // values, after checking for NULL.
117ead24645SDimitry Andric //
118ead24645SDimitry Andric // If T is not just PythonObject, then obj must be already be
119ead24645SDimitry Andric // checked to be of the correct type.
Take(PyObject * obj)120ead24645SDimitry Andric template <typename T> T Take(PyObject *obj) {
121ead24645SDimitry Andric   assert(obj);
122ead24645SDimitry Andric   assert(!PyErr_Occurred());
123ead24645SDimitry Andric   T thing(PyRefType::Owned, obj);
124ead24645SDimitry Andric   assert(thing.IsValid());
125706b4fc4SDimitry Andric   return thing;
126ead24645SDimitry Andric }
127ead24645SDimitry Andric 
128ead24645SDimitry Andric // Retain a reference you have borrowed, and turn it into
129ead24645SDimitry Andric // a PythonObject.
130ead24645SDimitry Andric //
131ead24645SDimitry Andric // A minority of python APIs return a borrowed reference
132ead24645SDimitry Andric // instead of a +1.   They will also return NULL if and only
133ead24645SDimitry Andric // if they set an exception.   Use this to collect such return
134ead24645SDimitry Andric // values, after checking for NULL.
135ead24645SDimitry Andric //
136ead24645SDimitry Andric // If T is not just PythonObject, then obj must be already be
137ead24645SDimitry Andric // checked to be of the correct type.
Retain(PyObject * obj)138ead24645SDimitry Andric template <typename T> T Retain(PyObject *obj) {
139ead24645SDimitry Andric   assert(obj);
140ead24645SDimitry Andric   assert(!PyErr_Occurred());
141ead24645SDimitry Andric   T thing(PyRefType::Borrowed, obj);
142ead24645SDimitry Andric   assert(thing.IsValid());
143706b4fc4SDimitry Andric   return thing;
144ead24645SDimitry Andric }
145ead24645SDimitry Andric 
146ead24645SDimitry Andric // This class can be used like a utility function to convert from
147ead24645SDimitry Andric // a llvm-friendly Twine into a null-terminated const char *,
148ead24645SDimitry Andric // which is the form python C APIs want their strings in.
149ead24645SDimitry Andric //
150ead24645SDimitry Andric // Example:
151ead24645SDimitry Andric // const llvm::Twine &some_twine;
152ead24645SDimitry Andric // PyFoo_Bar(x, y, z, NullTerminated(some_twine));
153ead24645SDimitry Andric //
154ead24645SDimitry Andric // Why a class instead of a function?  If the twine isn't already null
155ead24645SDimitry Andric // terminated, it will need a temporary buffer to copy the string
156ead24645SDimitry Andric // into.   We need that buffer to stick around for the lifetime of the
157ead24645SDimitry Andric // statement.
158ead24645SDimitry Andric class NullTerminated {
159ead24645SDimitry Andric   const char *str;
160ead24645SDimitry Andric   llvm::SmallString<32> storage;
161ead24645SDimitry Andric 
162ead24645SDimitry Andric public:
NullTerminated(const llvm::Twine & twine)163ead24645SDimitry Andric   NullTerminated(const llvm::Twine &twine) {
164ead24645SDimitry Andric     llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
165ead24645SDimitry Andric     str = ref.begin();
166ead24645SDimitry Andric   }
167ead24645SDimitry Andric   operator const char *() { return str; }
168ead24645SDimitry Andric };
169ead24645SDimitry Andric 
nullDeref()170ead24645SDimitry Andric inline llvm::Error nullDeref() {
171ead24645SDimitry Andric   return llvm::createStringError(llvm::inconvertibleErrorCode(),
172ead24645SDimitry Andric                                  "A NULL PyObject* was dereferenced");
173ead24645SDimitry Andric }
174ead24645SDimitry Andric 
175ead24645SDimitry Andric inline llvm::Error exception(const char *s = nullptr) {
176ead24645SDimitry Andric   return llvm::make_error<PythonException>(s);
177ead24645SDimitry Andric }
178ead24645SDimitry Andric 
keyError()179ead24645SDimitry Andric inline llvm::Error keyError() {
180ead24645SDimitry Andric   return llvm::createStringError(llvm::inconvertibleErrorCode(),
181ead24645SDimitry Andric                                  "key not in dict");
182ead24645SDimitry Andric }
183ead24645SDimitry Andric 
py2_const_cast(const char * s)184706b4fc4SDimitry Andric inline const char *py2_const_cast(const char *s) { return s; }
185706b4fc4SDimitry Andric 
18614f1b3e8SDimitry Andric enum class PyInitialValue { Invalid, Empty };
187e81d9d49SDimitry Andric 
188e3b55780SDimitry Andric // DOC: https://docs.python.org/3/c-api/arg.html#building-values
189ead24645SDimitry Andric template <typename T, typename Enable = void> struct PythonFormat;
190ead24645SDimitry Andric 
191e3b55780SDimitry Andric template <typename T, char F> struct PassthroughFormat {
192e3b55780SDimitry Andric   static constexpr char format = F;
getPassthroughFormat193e3b55780SDimitry Andric   static constexpr T get(T t) { return t; }
194ead24645SDimitry Andric };
195ead24645SDimitry Andric 
196e3b55780SDimitry Andric template <> struct PythonFormat<char *> : PassthroughFormat<char *, 's'> {};
197ac9a064cSDimitry Andric template <> struct PythonFormat<const char *> :
198ac9a064cSDimitry Andric     PassthroughFormat<const char *, 's'> {};
199e3b55780SDimitry Andric template <> struct PythonFormat<char> : PassthroughFormat<char, 'b'> {};
200e3b55780SDimitry Andric template <>
201e3b55780SDimitry Andric struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {};
202e3b55780SDimitry Andric template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {};
203e3b55780SDimitry Andric template <>
204e3b55780SDimitry Andric struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {};
205e3b55780SDimitry Andric template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {};
2067fa27ce4SDimitry Andric template <> struct PythonFormat<bool> : PassthroughFormat<bool, 'p'> {};
207e3b55780SDimitry Andric template <>
208e3b55780SDimitry Andric struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {};
209e3b55780SDimitry Andric template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {};
210e3b55780SDimitry Andric template <>
211e3b55780SDimitry Andric struct PythonFormat<unsigned long> : PassthroughFormat<unsigned long, 'k'> {};
212e3b55780SDimitry Andric template <>
213e3b55780SDimitry Andric struct PythonFormat<long long> : PassthroughFormat<long long, 'L'> {};
214e3b55780SDimitry Andric template <>
215e3b55780SDimitry Andric struct PythonFormat<unsigned long long>
216e3b55780SDimitry Andric     : PassthroughFormat<unsigned long long, 'K'> {};
217e3b55780SDimitry Andric template <>
218e3b55780SDimitry Andric struct PythonFormat<PyObject *> : PassthroughFormat<PyObject *, 'O'> {};
219ead24645SDimitry Andric 
220ead24645SDimitry Andric template <typename T>
221ead24645SDimitry Andric struct PythonFormat<
222ead24645SDimitry Andric     T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
223ead24645SDimitry Andric   static constexpr char format = 'O';
224ead24645SDimitry Andric   static auto get(const T &value) { return value.get(); }
225ead24645SDimitry Andric };
226ead24645SDimitry Andric 
22714f1b3e8SDimitry Andric class PythonObject {
228e81d9d49SDimitry Andric public:
229344a3780SDimitry Andric   PythonObject() = default;
230e81d9d49SDimitry Andric 
231ead24645SDimitry Andric   PythonObject(PyRefType type, PyObject *py_obj) {
232e81d9d49SDimitry Andric     m_py_obj = py_obj;
233e81d9d49SDimitry Andric     // If this is a borrowed reference, we need to convert it to
234e81d9d49SDimitry Andric     // an owned reference by incrementing it.  If it is an owned
235e81d9d49SDimitry Andric     // reference (for example the caller allocated it with PyDict_New()
236e81d9d49SDimitry Andric     // then we must *not* increment it.
237ead24645SDimitry Andric     if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
238e81d9d49SDimitry Andric       Py_XINCREF(m_py_obj);
239e81d9d49SDimitry Andric   }
240e81d9d49SDimitry Andric 
241ead24645SDimitry Andric   PythonObject(const PythonObject &rhs)
242ead24645SDimitry Andric       : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
243ead24645SDimitry Andric 
244ead24645SDimitry Andric   PythonObject(PythonObject &&rhs) {
245ead24645SDimitry Andric     m_py_obj = rhs.m_py_obj;
246ead24645SDimitry Andric     rhs.m_py_obj = nullptr;
247ead24645SDimitry Andric   }
248ead24645SDimitry Andric 
249ead24645SDimitry Andric   ~PythonObject() { Reset(); }
250ead24645SDimitry Andric 
2516f8fc217SDimitry Andric   void Reset();
252ead24645SDimitry Andric 
25314f1b3e8SDimitry Andric   void Dump() const {
254e81d9d49SDimitry Andric     if (m_py_obj)
255e81d9d49SDimitry Andric       _PyObject_Dump(m_py_obj);
256e81d9d49SDimitry Andric     else
257e81d9d49SDimitry Andric       puts("NULL");
258e81d9d49SDimitry Andric   }
259e81d9d49SDimitry Andric 
26014f1b3e8SDimitry Andric   void Dump(Stream &strm) const;
261e81d9d49SDimitry Andric 
26214f1b3e8SDimitry Andric   PyObject *get() const { return m_py_obj; }
263e81d9d49SDimitry Andric 
26414f1b3e8SDimitry Andric   PyObject *release() {
265e81d9d49SDimitry Andric     PyObject *result = m_py_obj;
266e81d9d49SDimitry Andric     m_py_obj = nullptr;
267e81d9d49SDimitry Andric     return result;
268e81d9d49SDimitry Andric   }
269e81d9d49SDimitry Andric 
270ead24645SDimitry Andric   PythonObject &operator=(PythonObject other) {
271ead24645SDimitry Andric     Reset();
272ead24645SDimitry Andric     m_py_obj = std::exchange(other.m_py_obj, nullptr);
273e81d9d49SDimitry Andric     return *this;
274e81d9d49SDimitry Andric   }
275e81d9d49SDimitry Andric 
27614f1b3e8SDimitry Andric   PyObjectType GetObjectType() const;
277e81d9d49SDimitry Andric 
27814f1b3e8SDimitry Andric   PythonString Repr() const;
279e81d9d49SDimitry Andric 
28014f1b3e8SDimitry Andric   PythonString Str() const;
281e81d9d49SDimitry Andric 
28214f1b3e8SDimitry Andric   static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
28314f1b3e8SDimitry Andric                                                 const PythonDictionary &dict);
284e81d9d49SDimitry Andric 
285e81d9d49SDimitry Andric   template <typename T>
28614f1b3e8SDimitry Andric   static T ResolveNameWithDictionary(llvm::StringRef name,
28714f1b3e8SDimitry Andric                                      const PythonDictionary &dict) {
288e81d9d49SDimitry Andric     return ResolveNameWithDictionary(name, dict).AsType<T>();
289e81d9d49SDimitry Andric   }
290e81d9d49SDimitry Andric 
29114f1b3e8SDimitry Andric   PythonObject ResolveName(llvm::StringRef name) const;
292e81d9d49SDimitry Andric 
29314f1b3e8SDimitry Andric   template <typename T> T ResolveName(llvm::StringRef name) const {
294e81d9d49SDimitry Andric     return ResolveName(name).AsType<T>();
295e81d9d49SDimitry Andric   }
296e81d9d49SDimitry Andric 
29714f1b3e8SDimitry Andric   bool HasAttribute(llvm::StringRef attribute) const;
298e81d9d49SDimitry Andric 
29914f1b3e8SDimitry Andric   PythonObject GetAttributeValue(llvm::StringRef attribute) const;
300e81d9d49SDimitry Andric 
301ead24645SDimitry Andric   bool IsNone() const { return m_py_obj == Py_None; }
302e81d9d49SDimitry Andric 
303ead24645SDimitry Andric   bool IsValid() const { return m_py_obj != nullptr; }
304e81d9d49SDimitry Andric 
305ead24645SDimitry Andric   bool IsAllocated() const { return IsValid() && !IsNone(); }
306ead24645SDimitry Andric 
307ead24645SDimitry Andric   explicit operator bool() const { return IsValid() && !IsNone(); }
308e81d9d49SDimitry Andric 
30914f1b3e8SDimitry Andric   template <typename T> T AsType() const {
310e81d9d49SDimitry Andric     if (!T::Check(m_py_obj))
311e81d9d49SDimitry Andric       return T();
312e81d9d49SDimitry Andric     return T(PyRefType::Borrowed, m_py_obj);
313e81d9d49SDimitry Andric   }
314e81d9d49SDimitry Andric 
31514f1b3e8SDimitry Andric   StructuredData::ObjectSP CreateStructuredObject() const;
316e81d9d49SDimitry Andric 
317ead24645SDimitry Andric   template <typename... T>
318ead24645SDimitry Andric   llvm::Expected<PythonObject> CallMethod(const char *name,
319ead24645SDimitry Andric                                           const T &... t) const {
320ead24645SDimitry Andric     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
321ead24645SDimitry Andric     PyObject *obj =
322ead24645SDimitry Andric         PyObject_CallMethod(m_py_obj, py2_const_cast(name),
323ead24645SDimitry Andric                             py2_const_cast(format), PythonFormat<T>::get(t)...);
324ead24645SDimitry Andric     if (!obj)
325ead24645SDimitry Andric       return exception();
326ead24645SDimitry Andric     return python::Take<PythonObject>(obj);
327ead24645SDimitry Andric   }
328ead24645SDimitry Andric 
329ead24645SDimitry Andric   template <typename... T>
330ead24645SDimitry Andric   llvm::Expected<PythonObject> Call(const T &... t) const {
331ead24645SDimitry Andric     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
332ead24645SDimitry Andric     PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
333ead24645SDimitry Andric                                           PythonFormat<T>::get(t)...);
334ead24645SDimitry Andric     if (!obj)
335ead24645SDimitry Andric       return exception();
336ead24645SDimitry Andric     return python::Take<PythonObject>(obj);
337ead24645SDimitry Andric   }
338ead24645SDimitry Andric 
339ead24645SDimitry Andric   llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
340ead24645SDimitry Andric     if (!m_py_obj)
341ead24645SDimitry Andric       return nullDeref();
342ead24645SDimitry Andric     PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
343ead24645SDimitry Andric     if (!obj)
344ead24645SDimitry Andric       return exception();
345ead24645SDimitry Andric     return python::Take<PythonObject>(obj);
346ead24645SDimitry Andric   }
347ead24645SDimitry Andric 
3487fa27ce4SDimitry Andric   llvm::Expected<PythonObject> GetType() const {
3497fa27ce4SDimitry Andric     if (!m_py_obj)
3507fa27ce4SDimitry Andric       return nullDeref();
3517fa27ce4SDimitry Andric     PyObject *obj = PyObject_Type(m_py_obj);
3527fa27ce4SDimitry Andric     if (!obj)
3537fa27ce4SDimitry Andric       return exception();
3547fa27ce4SDimitry Andric     return python::Take<PythonObject>(obj);
3557fa27ce4SDimitry Andric   }
3567fa27ce4SDimitry Andric 
357ead24645SDimitry Andric   llvm::Expected<bool> IsTrue() {
358ead24645SDimitry Andric     if (!m_py_obj)
359ead24645SDimitry Andric       return nullDeref();
360ead24645SDimitry Andric     int r = PyObject_IsTrue(m_py_obj);
361ead24645SDimitry Andric     if (r < 0)
362ead24645SDimitry Andric       return exception();
363ead24645SDimitry Andric     return !!r;
364ead24645SDimitry Andric   }
365ead24645SDimitry Andric 
366cfca06d7SDimitry Andric   llvm::Expected<long long> AsLongLong() const;
367cfca06d7SDimitry Andric 
3687fa27ce4SDimitry Andric   llvm::Expected<unsigned long long> AsUnsignedLongLong() const;
369cfca06d7SDimitry Andric 
370cfca06d7SDimitry Andric   // wraps on overflow, instead of raising an error.
371cfca06d7SDimitry Andric   llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
372ead24645SDimitry Andric 
373ead24645SDimitry Andric   llvm::Expected<bool> IsInstance(const PythonObject &cls) {
374ead24645SDimitry Andric     if (!m_py_obj || !cls.IsValid())
375ead24645SDimitry Andric       return nullDeref();
376ead24645SDimitry Andric     int r = PyObject_IsInstance(m_py_obj, cls.get());
377ead24645SDimitry Andric     if (r < 0)
378ead24645SDimitry Andric       return exception();
379ead24645SDimitry Andric     return !!r;
380ead24645SDimitry Andric   }
381ead24645SDimitry Andric 
382ead24645SDimitry Andric protected:
383344a3780SDimitry Andric   PyObject *m_py_obj = nullptr;
384e81d9d49SDimitry Andric };
385e81d9d49SDimitry Andric 
386ead24645SDimitry Andric 
387ead24645SDimitry Andric // This is why C++ needs monads.
388ead24645SDimitry Andric template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
389ead24645SDimitry Andric   if (!obj)
390ead24645SDimitry Andric     return obj.takeError();
391ead24645SDimitry Andric   if (!T::Check(obj.get().get()))
392ead24645SDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
393ead24645SDimitry Andric                                    "type error");
394ead24645SDimitry Andric   return T(PyRefType::Borrowed, std::move(obj.get().get()));
395ead24645SDimitry Andric }
396ead24645SDimitry Andric 
397ead24645SDimitry Andric template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
398ead24645SDimitry Andric 
399ead24645SDimitry Andric template <>
400ead24645SDimitry Andric llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
401ead24645SDimitry Andric 
402ead24645SDimitry Andric template <>
403cfca06d7SDimitry Andric llvm::Expected<unsigned long long>
404cfca06d7SDimitry Andric As<unsigned long long>(llvm::Expected<PythonObject> &&obj);
405cfca06d7SDimitry Andric 
406cfca06d7SDimitry Andric template <>
407ead24645SDimitry Andric llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
408ead24645SDimitry Andric 
409ead24645SDimitry Andric 
410ead24645SDimitry Andric template <class T> class TypedPythonObject : public PythonObject {
4117fed546dSDimitry Andric public:
412ead24645SDimitry Andric   TypedPythonObject(PyRefType type, PyObject *py_obj) {
413ead24645SDimitry Andric     if (!py_obj)
414ead24645SDimitry Andric       return;
415ead24645SDimitry Andric     if (T::Check(py_obj))
416ead24645SDimitry Andric       PythonObject::operator=(PythonObject(type, py_obj));
417ead24645SDimitry Andric     else if (type == PyRefType::Owned)
418ead24645SDimitry Andric       Py_DECREF(py_obj);
419ead24645SDimitry Andric   }
420ead24645SDimitry Andric 
421344a3780SDimitry Andric   TypedPythonObject() = default;
422ead24645SDimitry Andric };
423ead24645SDimitry Andric 
424ead24645SDimitry Andric class PythonBytes : public TypedPythonObject<PythonBytes> {
425ead24645SDimitry Andric public:
426ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
4277fed546dSDimitry Andric   explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
4287fed546dSDimitry Andric   PythonBytes(const uint8_t *bytes, size_t length);
4297fed546dSDimitry Andric 
43014f1b3e8SDimitry Andric   static bool Check(PyObject *py_obj);
4317fed546dSDimitry Andric 
43214f1b3e8SDimitry Andric   llvm::ArrayRef<uint8_t> GetBytes() const;
4337fed546dSDimitry Andric 
43414f1b3e8SDimitry Andric   size_t GetSize() const;
4357fed546dSDimitry Andric 
43614f1b3e8SDimitry Andric   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4377fed546dSDimitry Andric 
43814f1b3e8SDimitry Andric   StructuredData::StringSP CreateStructuredString() const;
4397fed546dSDimitry Andric };
4407fed546dSDimitry Andric 
441ead24645SDimitry Andric class PythonByteArray : public TypedPythonObject<PythonByteArray> {
442f3fbd1c0SDimitry Andric public:
443ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
444f3fbd1c0SDimitry Andric   explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
445f3fbd1c0SDimitry Andric   PythonByteArray(const uint8_t *bytes, size_t length);
446f3fbd1c0SDimitry Andric   PythonByteArray(const PythonBytes &object);
447f3fbd1c0SDimitry Andric 
44814f1b3e8SDimitry Andric   static bool Check(PyObject *py_obj);
449f3fbd1c0SDimitry Andric 
45014f1b3e8SDimitry Andric   llvm::ArrayRef<uint8_t> GetBytes() const;
451f3fbd1c0SDimitry Andric 
45214f1b3e8SDimitry Andric   size_t GetSize() const;
453f3fbd1c0SDimitry Andric 
45414f1b3e8SDimitry Andric   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
455f3fbd1c0SDimitry Andric 
45614f1b3e8SDimitry Andric   StructuredData::StringSP CreateStructuredString() const;
457f3fbd1c0SDimitry Andric };
458f3fbd1c0SDimitry Andric 
459ead24645SDimitry Andric class PythonString : public TypedPythonObject<PythonString> {
460e81d9d49SDimitry Andric public:
461ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
462ead24645SDimitry Andric   static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
463e81d9d49SDimitry Andric 
464ead24645SDimitry Andric   PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
465ead24645SDimitry Andric 
466ead24645SDimitry Andric   explicit PythonString(llvm::StringRef string); // safe, null on error
467e81d9d49SDimitry Andric 
468e81d9d49SDimitry Andric   static bool Check(PyObject *py_obj);
469e81d9d49SDimitry Andric 
470ead24645SDimitry Andric   llvm::StringRef GetString() const; // safe, empty string on error
471e81d9d49SDimitry Andric 
472ead24645SDimitry Andric   llvm::Expected<llvm::StringRef> AsUTF8() const;
473e81d9d49SDimitry Andric 
47414f1b3e8SDimitry Andric   size_t GetSize() const;
475e81d9d49SDimitry Andric 
476ead24645SDimitry Andric   void SetString(llvm::StringRef string); // safe, null on error
477e81d9d49SDimitry Andric 
478e81d9d49SDimitry Andric   StructuredData::StringSP CreateStructuredString() const;
479e81d9d49SDimitry Andric };
480e81d9d49SDimitry Andric 
481ead24645SDimitry Andric class PythonInteger : public TypedPythonObject<PythonInteger> {
482e81d9d49SDimitry Andric public:
483ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
484e81d9d49SDimitry Andric 
485ead24645SDimitry Andric   PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
486ead24645SDimitry Andric 
487ead24645SDimitry Andric   explicit PythonInteger(int64_t value);
488e81d9d49SDimitry Andric 
489e81d9d49SDimitry Andric   static bool Check(PyObject *py_obj);
490e81d9d49SDimitry Andric 
49114f1b3e8SDimitry Andric   void SetInteger(int64_t value);
492e81d9d49SDimitry Andric 
493e81d9d49SDimitry Andric   StructuredData::IntegerSP CreateStructuredInteger() const;
4947fa27ce4SDimitry Andric 
4957fa27ce4SDimitry Andric   StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const;
4967fa27ce4SDimitry Andric 
4977fa27ce4SDimitry Andric   StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const;
498e81d9d49SDimitry Andric };
499e81d9d49SDimitry Andric 
500ead24645SDimitry Andric class PythonBoolean : public TypedPythonObject<PythonBoolean> {
5015f29bb8aSDimitry Andric public:
502ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
5035f29bb8aSDimitry Andric 
504ead24645SDimitry Andric   explicit PythonBoolean(bool value);
5055f29bb8aSDimitry Andric 
5065f29bb8aSDimitry Andric   static bool Check(PyObject *py_obj);
5075f29bb8aSDimitry Andric 
5085f29bb8aSDimitry Andric   bool GetValue() const;
5095f29bb8aSDimitry Andric 
5105f29bb8aSDimitry Andric   void SetValue(bool value);
5115f29bb8aSDimitry Andric 
5125f29bb8aSDimitry Andric   StructuredData::BooleanSP CreateStructuredBoolean() const;
5135f29bb8aSDimitry Andric };
5145f29bb8aSDimitry Andric 
515ead24645SDimitry Andric class PythonList : public TypedPythonObject<PythonList> {
516e81d9d49SDimitry Andric public:
517ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
518ead24645SDimitry Andric 
519ead24645SDimitry Andric   PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
520ead24645SDimitry Andric 
521e81d9d49SDimitry Andric   explicit PythonList(PyInitialValue value);
522e81d9d49SDimitry Andric   explicit PythonList(int list_size);
523e81d9d49SDimitry Andric 
524e81d9d49SDimitry Andric   static bool Check(PyObject *py_obj);
525e81d9d49SDimitry Andric 
526e81d9d49SDimitry Andric   uint32_t GetSize() const;
527e81d9d49SDimitry Andric 
528e81d9d49SDimitry Andric   PythonObject GetItemAtIndex(uint32_t index) const;
529e81d9d49SDimitry Andric 
530e81d9d49SDimitry Andric   void SetItemAtIndex(uint32_t index, const PythonObject &object);
531e81d9d49SDimitry Andric 
532e81d9d49SDimitry Andric   void AppendItem(const PythonObject &object);
533e81d9d49SDimitry Andric 
534e81d9d49SDimitry Andric   StructuredData::ArraySP CreateStructuredArray() const;
535e81d9d49SDimitry Andric };
536e81d9d49SDimitry Andric 
537ead24645SDimitry Andric class PythonTuple : public TypedPythonObject<PythonTuple> {
538e81d9d49SDimitry Andric public:
539ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
540ead24645SDimitry Andric 
541e81d9d49SDimitry Andric   explicit PythonTuple(PyInitialValue value);
542e81d9d49SDimitry Andric   explicit PythonTuple(int tuple_size);
543e81d9d49SDimitry Andric   PythonTuple(std::initializer_list<PythonObject> objects);
544e81d9d49SDimitry Andric   PythonTuple(std::initializer_list<PyObject *> objects);
545e81d9d49SDimitry Andric 
546e81d9d49SDimitry Andric   static bool Check(PyObject *py_obj);
547e81d9d49SDimitry Andric 
548e81d9d49SDimitry Andric   uint32_t GetSize() const;
549e81d9d49SDimitry Andric 
550e81d9d49SDimitry Andric   PythonObject GetItemAtIndex(uint32_t index) const;
551e81d9d49SDimitry Andric 
552e81d9d49SDimitry Andric   void SetItemAtIndex(uint32_t index, const PythonObject &object);
553e81d9d49SDimitry Andric 
554e81d9d49SDimitry Andric   StructuredData::ArraySP CreateStructuredArray() const;
555e81d9d49SDimitry Andric };
556e81d9d49SDimitry Andric 
557ead24645SDimitry Andric class PythonDictionary : public TypedPythonObject<PythonDictionary> {
558e81d9d49SDimitry Andric public:
559ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
560e81d9d49SDimitry Andric 
561ead24645SDimitry Andric   PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
562ead24645SDimitry Andric 
563ead24645SDimitry Andric   explicit PythonDictionary(PyInitialValue value);
564e81d9d49SDimitry Andric 
565e81d9d49SDimitry Andric   static bool Check(PyObject *py_obj);
566e81d9d49SDimitry Andric 
567b1c73532SDimitry Andric   bool HasKey(const llvm::Twine &key) const;
568b1c73532SDimitry Andric 
569e81d9d49SDimitry Andric   uint32_t GetSize() const;
570e81d9d49SDimitry Andric 
571e81d9d49SDimitry Andric   PythonList GetKeys() const;
572e81d9d49SDimitry Andric 
573ead24645SDimitry Andric   PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
574ead24645SDimitry Andric   void SetItemForKey(const PythonObject &key,
575ead24645SDimitry Andric                      const PythonObject &value); // DEPRECATED
576ead24645SDimitry Andric 
577ead24645SDimitry Andric   llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
578ead24645SDimitry Andric   llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
579ead24645SDimitry Andric   llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
580ead24645SDimitry Andric   llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
581e81d9d49SDimitry Andric 
582e81d9d49SDimitry Andric   StructuredData::DictionarySP CreateStructuredDictionary() const;
583e81d9d49SDimitry Andric };
584e81d9d49SDimitry Andric 
585ead24645SDimitry Andric class PythonModule : public TypedPythonObject<PythonModule> {
586e81d9d49SDimitry Andric public:
587ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
588e81d9d49SDimitry Andric 
589e81d9d49SDimitry Andric   static bool Check(PyObject *py_obj);
590e81d9d49SDimitry Andric 
59114f1b3e8SDimitry Andric   static PythonModule BuiltinsModule();
592e81d9d49SDimitry Andric 
59314f1b3e8SDimitry Andric   static PythonModule MainModule();
594e81d9d49SDimitry Andric 
59514f1b3e8SDimitry Andric   static PythonModule AddModule(llvm::StringRef module);
596e81d9d49SDimitry Andric 
597ead24645SDimitry Andric   // safe, returns invalid on error;
598ead24645SDimitry Andric   static PythonModule ImportModule(llvm::StringRef name) {
599cfca06d7SDimitry Andric     std::string s = std::string(name);
600ead24645SDimitry Andric     auto mod = Import(s.c_str());
601ead24645SDimitry Andric     if (!mod) {
602ead24645SDimitry Andric       llvm::consumeError(mod.takeError());
603ead24645SDimitry Andric       return PythonModule();
604ead24645SDimitry Andric     }
605ead24645SDimitry Andric     return std::move(mod.get());
606ead24645SDimitry Andric   }
607e81d9d49SDimitry Andric 
608ead24645SDimitry Andric   static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
609e81d9d49SDimitry Andric 
610ead24645SDimitry Andric   llvm::Expected<PythonObject> Get(const llvm::Twine &name);
611e81d9d49SDimitry Andric 
612e81d9d49SDimitry Andric   PythonDictionary GetDictionary() const;
613e81d9d49SDimitry Andric };
614e81d9d49SDimitry Andric 
615ead24645SDimitry Andric class PythonCallable : public TypedPythonObject<PythonCallable> {
616e81d9d49SDimitry Andric public:
617ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
618ead24645SDimitry Andric 
619e81d9d49SDimitry Andric   struct ArgInfo {
620ead24645SDimitry Andric     /* the largest number of positional arguments this callable
621ead24645SDimitry Andric      * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
622ead24645SDimitry Andric      * function and can accept an arbitrary number */
623ead24645SDimitry Andric     unsigned max_positional_args;
624ead24645SDimitry Andric     static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
625e81d9d49SDimitry Andric   };
626e81d9d49SDimitry Andric 
62714f1b3e8SDimitry Andric   static bool Check(PyObject *py_obj);
628e81d9d49SDimitry Andric 
629ead24645SDimitry Andric   llvm::Expected<ArgInfo> GetArgInfo() const;
630e81d9d49SDimitry Andric 
63114f1b3e8SDimitry Andric   PythonObject operator()();
632e81d9d49SDimitry Andric 
63314f1b3e8SDimitry Andric   PythonObject operator()(std::initializer_list<PyObject *> args);
634e81d9d49SDimitry Andric 
63514f1b3e8SDimitry Andric   PythonObject operator()(std::initializer_list<PythonObject> args);
636e81d9d49SDimitry Andric 
637e81d9d49SDimitry Andric   template <typename Arg, typename... Args>
63814f1b3e8SDimitry Andric   PythonObject operator()(const Arg &arg, Args... args) {
639e81d9d49SDimitry Andric     return operator()({arg, args...});
640e81d9d49SDimitry Andric   }
641e81d9d49SDimitry Andric };
642e81d9d49SDimitry Andric 
643ead24645SDimitry Andric class PythonFile : public TypedPythonObject<PythonFile> {
644e81d9d49SDimitry Andric public:
645ead24645SDimitry Andric   using TypedPythonObject::TypedPythonObject;
646e81d9d49SDimitry Andric 
647ead24645SDimitry Andric   PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
648e81d9d49SDimitry Andric 
649e81d9d49SDimitry Andric   static bool Check(PyObject *py_obj);
650e81d9d49SDimitry Andric 
651ead24645SDimitry Andric   static llvm::Expected<PythonFile> FromFile(File &file,
652ead24645SDimitry Andric                                              const char *mode = nullptr);
653e81d9d49SDimitry Andric 
654ead24645SDimitry Andric   llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
655ead24645SDimitry Andric   llvm::Expected<lldb::FileSP>
656ead24645SDimitry Andric   ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
657e81d9d49SDimitry Andric };
658e81d9d49SDimitry Andric 
659ead24645SDimitry Andric class PythonException : public llvm::ErrorInfo<PythonException> {
660ead24645SDimitry Andric private:
661ead24645SDimitry Andric   PyObject *m_exception_type, *m_exception, *m_traceback;
662ead24645SDimitry Andric   PyObject *m_repr_bytes;
663ead24645SDimitry Andric 
664ead24645SDimitry Andric public:
665ead24645SDimitry Andric   static char ID;
666ead24645SDimitry Andric   const char *toCString() const;
667ead24645SDimitry Andric   PythonException(const char *caller = nullptr);
668ead24645SDimitry Andric   void Restore();
669145449b1SDimitry Andric   ~PythonException() override;
670ead24645SDimitry Andric   void log(llvm::raw_ostream &OS) const override;
671ead24645SDimitry Andric   std::error_code convertToErrorCode() const override;
672ead24645SDimitry Andric   bool Matches(PyObject *exc) const;
673ead24645SDimitry Andric   std::string ReadBacktrace() const;
674ead24645SDimitry Andric };
675ead24645SDimitry Andric 
676ead24645SDimitry Andric // This extracts the underlying T out of an Expected<T> and returns it.
677ead24645SDimitry Andric // If the Expected is an Error instead of a T, that error will be converted
678ead24645SDimitry Andric // into a python exception, and this will return a default-constructed T.
679ead24645SDimitry Andric //
680ead24645SDimitry Andric // This is appropriate for use right at the boundary of python calling into
681ead24645SDimitry Andric // C++, such as in a SWIG typemap.   In such a context you should simply
682ead24645SDimitry Andric // check if the returned T is valid, and if it is, return a NULL back
683ead24645SDimitry Andric // to python.   This will result in the Error being raised as an exception
684ead24645SDimitry Andric // from python code's point of view.
685ead24645SDimitry Andric //
686ead24645SDimitry Andric // For example:
687ead24645SDimitry Andric // ```
688ead24645SDimitry Andric // Expected<Foo *> efoop = some_cpp_function();
689ead24645SDimitry Andric // Foo *foop = unwrapOrSetPythonException(efoop);
690ead24645SDimitry Andric // if (!foop)
691ead24645SDimitry Andric //    return NULL;
692ead24645SDimitry Andric // do_something(*foop);
693ead24645SDimitry Andric //
694ead24645SDimitry Andric // If the Error returned was itself created because a python exception was
695ead24645SDimitry Andric // raised when C++ code called into python, then the original exception
696ead24645SDimitry Andric // will be restored.   Otherwise a simple string exception will be raised.
697ead24645SDimitry Andric template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
698ead24645SDimitry Andric   if (expected)
699ead24645SDimitry Andric     return expected.get();
700ead24645SDimitry Andric   llvm::handleAllErrors(
701ead24645SDimitry Andric       expected.takeError(), [](PythonException &E) { E.Restore(); },
702ead24645SDimitry Andric       [](const llvm::ErrorInfoBase &E) {
703ead24645SDimitry Andric         PyErr_SetString(PyExc_Exception, E.message().c_str());
704ead24645SDimitry Andric       });
705ead24645SDimitry Andric   return T();
706ead24645SDimitry Andric }
707ead24645SDimitry Andric 
708ead24645SDimitry Andric // This is only here to help incrementally migrate old, exception-unsafe
709ead24645SDimitry Andric // code.
710ead24645SDimitry Andric template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
711ead24645SDimitry Andric   if (expected)
712ead24645SDimitry Andric     return std::move(expected.get());
713ead24645SDimitry Andric   llvm::consumeError(expected.takeError());
714ead24645SDimitry Andric   return T();
715ead24645SDimitry Andric }
716ead24645SDimitry Andric 
717ead24645SDimitry Andric llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
718ead24645SDimitry Andric                                               const PythonDictionary &globals,
719ead24645SDimitry Andric                                               const PythonDictionary &locals);
720ead24645SDimitry Andric 
721ead24645SDimitry Andric llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
722ead24645SDimitry Andric                                                 const PythonDictionary &globals,
723ead24645SDimitry Andric                                                 const PythonDictionary &locals);
724ead24645SDimitry Andric 
725ead24645SDimitry Andric // Sometimes the best way to interact with a python interpreter is
726ead24645SDimitry Andric // to run some python code.   You construct a PythonScript with
727ead24645SDimitry Andric // script string.   The script assigns some function to `_function_`
728ead24645SDimitry Andric // and you get a C++ callable object that calls the python function.
729ead24645SDimitry Andric //
730ead24645SDimitry Andric // Example:
731ead24645SDimitry Andric //
732ead24645SDimitry Andric // const char script[] = R"(
733ead24645SDimitry Andric // def main(x, y):
734ead24645SDimitry Andric //    ....
735ead24645SDimitry Andric // )";
736ead24645SDimitry Andric //
737ead24645SDimitry Andric // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
738ead24645SDimitry Andric //   // no need to synchronize access to this global, we already have the GIL
739ead24645SDimitry Andric //   static PythonScript foo(script)
740ead24645SDimitry Andric //   return  foo(x, y);
741ead24645SDimitry Andric // }
742ead24645SDimitry Andric class PythonScript {
743ead24645SDimitry Andric   const char *script;
744ead24645SDimitry Andric   PythonCallable function;
745ead24645SDimitry Andric 
746ead24645SDimitry Andric   llvm::Error Init();
747ead24645SDimitry Andric 
748ead24645SDimitry Andric public:
749ead24645SDimitry Andric   PythonScript(const char *script) : script(script), function() {}
750ead24645SDimitry Andric 
751ead24645SDimitry Andric   template <typename... Args>
752ead24645SDimitry Andric   llvm::Expected<PythonObject> operator()(Args &&... args) {
753ead24645SDimitry Andric     if (llvm::Error error = Init())
754ead24645SDimitry Andric       return std::move(error);
755ead24645SDimitry Andric     return function.Call(std::forward<Args>(args)...);
756ead24645SDimitry Andric   }
757ead24645SDimitry Andric };
758ead24645SDimitry Andric 
7596f8fc217SDimitry Andric class StructuredPythonObject : public StructuredData::Generic {
7606f8fc217SDimitry Andric public:
7616f8fc217SDimitry Andric   StructuredPythonObject() : StructuredData::Generic() {}
7626f8fc217SDimitry Andric 
7636f8fc217SDimitry Andric   // Take ownership of the object we received.
7646f8fc217SDimitry Andric   StructuredPythonObject(PythonObject obj)
7656f8fc217SDimitry Andric       : StructuredData::Generic(obj.release()) {}
7666f8fc217SDimitry Andric 
7676f8fc217SDimitry Andric   ~StructuredPythonObject() override {
7686f8fc217SDimitry Andric     // Hand ownership back to a (temporary) PythonObject instance and let it
7696f8fc217SDimitry Andric     // take care of releasing it.
7706f8fc217SDimitry Andric     PythonObject(PyRefType::Owned, static_cast<PyObject *>(GetValue()));
7716f8fc217SDimitry Andric   }
7726f8fc217SDimitry Andric 
7736f8fc217SDimitry Andric   bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
7746f8fc217SDimitry Andric 
7756f8fc217SDimitry Andric   void Serialize(llvm::json::OStream &s) const override;
7766f8fc217SDimitry Andric 
7776f8fc217SDimitry Andric private:
7786f8fc217SDimitry Andric   StructuredPythonObject(const StructuredPythonObject &) = delete;
7796f8fc217SDimitry Andric   const StructuredPythonObject &
7806f8fc217SDimitry Andric   operator=(const StructuredPythonObject &) = delete;
7816f8fc217SDimitry Andric };
7826f8fc217SDimitry Andric 
783ead24645SDimitry Andric } // namespace python
784e81d9d49SDimitry Andric } // namespace lldb_private
785e81d9d49SDimitry Andric 
786e81d9d49SDimitry Andric #endif
787e81d9d49SDimitry Andric 
788e81d9d49SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
789