xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h (revision 9dba64be9536c28e4800e06512b7f29b43ade345)
10b57cec5SDimitry Andric //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
9*9dba64beSDimitry Andric //
10*9dba64beSDimitry Andric // !! FIXME FIXME FIXME !!
11*9dba64beSDimitry Andric //
12*9dba64beSDimitry Andric // Python APIs nearly all can return an exception.   They do this
13*9dba64beSDimitry Andric // by returning NULL, or -1, or some such value and setting
14*9dba64beSDimitry Andric // the exception state with PyErr_Set*().   Exceptions must be
15*9dba64beSDimitry Andric // handled before further python API functions are called.   Failure
16*9dba64beSDimitry Andric // to do so will result in asserts on debug builds of python.
17*9dba64beSDimitry Andric // It will also sometimes, but not usually result in crashes of
18*9dba64beSDimitry Andric // release builds.
19*9dba64beSDimitry Andric //
20*9dba64beSDimitry Andric // Nearly all the code in this header does not handle python exceptions
21*9dba64beSDimitry Andric // correctly.  It should all be converted to return Expected<> or
22*9dba64beSDimitry Andric // Error types to capture the exception.
23*9dba64beSDimitry Andric //
24*9dba64beSDimitry Andric // Everything in this file except functions that return Error or
25*9dba64beSDimitry Andric // Expected<> is considered deprecated and should not be
26*9dba64beSDimitry Andric // used in new code.  If you need to use it, fix it first.
27*9dba64beSDimitry Andric //
28*9dba64beSDimitry Andric //
29*9dba64beSDimitry Andric // TODOs for this file
30*9dba64beSDimitry Andric //
31*9dba64beSDimitry Andric // * Make all methods safe for exceptions.
32*9dba64beSDimitry Andric //
33*9dba64beSDimitry Andric // * Eliminate method signatures that must translate exceptions into
34*9dba64beSDimitry Andric //   empty objects or NULLs.   Almost everything here should return
35*9dba64beSDimitry Andric //   Expected<>.   It should be acceptable for certain operations that
36*9dba64beSDimitry Andric //   can never fail to assert instead, such as the creation of
37*9dba64beSDimitry Andric //   PythonString from a string literal.
38*9dba64beSDimitry Andric //
39*9dba64beSDimitry Andric // * Elimintate Reset(), and make all non-default constructors private.
40*9dba64beSDimitry Andric //   Python objects should be created with Retain<> or Take<>, and they
41*9dba64beSDimitry Andric //   should be assigned with operator=
42*9dba64beSDimitry Andric //
43*9dba64beSDimitry Andric // * Eliminate default constructors, make python objects always
44*9dba64beSDimitry Andric //   nonnull, and use optionals where necessary.
45*9dba64beSDimitry Andric //
46*9dba64beSDimitry Andric 
47*9dba64beSDimitry Andric 
480b57cec5SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
490b57cec5SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric #ifndef LLDB_DISABLE_PYTHON
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric // LLDB Python header must be included first
540b57cec5SDimitry Andric #include "lldb-python.h"
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric #include "lldb/Host/File.h"
570b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h"
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric namespace lldb_private {
62*9dba64beSDimitry Andric namespace python {
630b57cec5SDimitry Andric 
64*9dba64beSDimitry Andric class PythonObject;
650b57cec5SDimitry Andric class PythonBytes;
660b57cec5SDimitry Andric class PythonString;
670b57cec5SDimitry Andric class PythonList;
680b57cec5SDimitry Andric class PythonDictionary;
690b57cec5SDimitry Andric class PythonInteger;
70*9dba64beSDimitry Andric class PythonException;
710b57cec5SDimitry Andric 
720b57cec5SDimitry Andric class StructuredPythonObject : public StructuredData::Generic {
730b57cec5SDimitry Andric public:
740b57cec5SDimitry Andric   StructuredPythonObject() : StructuredData::Generic() {}
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   StructuredPythonObject(void *obj) : StructuredData::Generic(obj) {
770b57cec5SDimitry Andric     Py_XINCREF(GetValue());
780b57cec5SDimitry Andric   }
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric   ~StructuredPythonObject() override {
810b57cec5SDimitry Andric     if (Py_IsInitialized())
820b57cec5SDimitry Andric       Py_XDECREF(GetValue());
830b57cec5SDimitry Andric     SetValue(nullptr);
840b57cec5SDimitry Andric   }
850b57cec5SDimitry Andric 
860b57cec5SDimitry Andric   bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
870b57cec5SDimitry Andric 
88*9dba64beSDimitry Andric   void Serialize(llvm::json::OStream &s) const override;
890b57cec5SDimitry Andric 
900b57cec5SDimitry Andric private:
910b57cec5SDimitry Andric   DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject);
920b57cec5SDimitry Andric };
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric enum class PyObjectType {
950b57cec5SDimitry Andric   Unknown,
960b57cec5SDimitry Andric   None,
970b57cec5SDimitry Andric   Boolean,
980b57cec5SDimitry Andric   Integer,
990b57cec5SDimitry Andric   Dictionary,
1000b57cec5SDimitry Andric   List,
1010b57cec5SDimitry Andric   String,
1020b57cec5SDimitry Andric   Bytes,
1030b57cec5SDimitry Andric   ByteArray,
1040b57cec5SDimitry Andric   Module,
1050b57cec5SDimitry Andric   Callable,
1060b57cec5SDimitry Andric   Tuple,
1070b57cec5SDimitry Andric   File
1080b57cec5SDimitry Andric };
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric enum class PyRefType {
1110b57cec5SDimitry Andric   Borrowed, // We are not given ownership of the incoming PyObject.
1120b57cec5SDimitry Andric             // We cannot safely hold it without calling Py_INCREF.
1130b57cec5SDimitry Andric   Owned     // We have ownership of the incoming PyObject.  We should
1140b57cec5SDimitry Andric             // not call Py_INCREF.
1150b57cec5SDimitry Andric };
1160b57cec5SDimitry Andric 
117*9dba64beSDimitry Andric 
118*9dba64beSDimitry Andric // Take a reference that you already own, and turn it into
119*9dba64beSDimitry Andric // a PythonObject.
120*9dba64beSDimitry Andric //
121*9dba64beSDimitry Andric // Most python API methods will return a +1 reference
122*9dba64beSDimitry Andric // if they succeed or NULL if and only if
123*9dba64beSDimitry Andric // they set an exception.   Use this to collect such return
124*9dba64beSDimitry Andric // values, after checking for NULL.
125*9dba64beSDimitry Andric //
126*9dba64beSDimitry Andric // If T is not just PythonObject, then obj must be already be
127*9dba64beSDimitry Andric // checked to be of the correct type.
128*9dba64beSDimitry Andric template <typename T> T Take(PyObject *obj) {
129*9dba64beSDimitry Andric   assert(obj);
130*9dba64beSDimitry Andric   assert(!PyErr_Occurred());
131*9dba64beSDimitry Andric   T thing(PyRefType::Owned, obj);
132*9dba64beSDimitry Andric   assert(thing.IsValid());
133*9dba64beSDimitry Andric   return std::move(thing);
134*9dba64beSDimitry Andric }
135*9dba64beSDimitry Andric 
136*9dba64beSDimitry Andric // Retain a reference you have borrowed, and turn it into
137*9dba64beSDimitry Andric // a PythonObject.
138*9dba64beSDimitry Andric //
139*9dba64beSDimitry Andric // A minority of python APIs return a borrowed reference
140*9dba64beSDimitry Andric // instead of a +1.   They will also return NULL if and only
141*9dba64beSDimitry Andric // if they set an exception.   Use this to collect such return
142*9dba64beSDimitry Andric // values, after checking for NULL.
143*9dba64beSDimitry Andric //
144*9dba64beSDimitry Andric // If T is not just PythonObject, then obj must be already be
145*9dba64beSDimitry Andric // checked to be of the correct type.
146*9dba64beSDimitry Andric template <typename T> T Retain(PyObject *obj) {
147*9dba64beSDimitry Andric   assert(obj);
148*9dba64beSDimitry Andric   assert(!PyErr_Occurred());
149*9dba64beSDimitry Andric   T thing(PyRefType::Borrowed, obj);
150*9dba64beSDimitry Andric   assert(thing.IsValid());
151*9dba64beSDimitry Andric   return std::move(thing);
152*9dba64beSDimitry Andric }
153*9dba64beSDimitry Andric 
154*9dba64beSDimitry Andric // This class can be used like a utility function to convert from
155*9dba64beSDimitry Andric // a llvm-friendly Twine into a null-terminated const char *,
156*9dba64beSDimitry Andric // which is the form python C APIs want their strings in.
157*9dba64beSDimitry Andric //
158*9dba64beSDimitry Andric // Example:
159*9dba64beSDimitry Andric // const llvm::Twine &some_twine;
160*9dba64beSDimitry Andric // PyFoo_Bar(x, y, z, NullTerminated(some_twine));
161*9dba64beSDimitry Andric //
162*9dba64beSDimitry Andric // Why a class instead of a function?  If the twine isn't already null
163*9dba64beSDimitry Andric // terminated, it will need a temporary buffer to copy the string
164*9dba64beSDimitry Andric // into.   We need that buffer to stick around for the lifetime of the
165*9dba64beSDimitry Andric // statement.
166*9dba64beSDimitry Andric class NullTerminated {
167*9dba64beSDimitry Andric   const char *str;
168*9dba64beSDimitry Andric   llvm::SmallString<32> storage;
169*9dba64beSDimitry Andric 
170*9dba64beSDimitry Andric public:
171*9dba64beSDimitry Andric   NullTerminated(const llvm::Twine &twine) {
172*9dba64beSDimitry Andric     llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
173*9dba64beSDimitry Andric     str = ref.begin();
174*9dba64beSDimitry Andric   }
175*9dba64beSDimitry Andric   operator const char *() { return str; }
176*9dba64beSDimitry Andric };
177*9dba64beSDimitry Andric 
178*9dba64beSDimitry Andric inline llvm::Error nullDeref() {
179*9dba64beSDimitry Andric   return llvm::createStringError(llvm::inconvertibleErrorCode(),
180*9dba64beSDimitry Andric                                  "A NULL PyObject* was dereferenced");
181*9dba64beSDimitry Andric }
182*9dba64beSDimitry Andric 
183*9dba64beSDimitry Andric inline llvm::Error exception(const char *s = nullptr) {
184*9dba64beSDimitry Andric   return llvm::make_error<PythonException>(s);
185*9dba64beSDimitry Andric }
186*9dba64beSDimitry Andric 
187*9dba64beSDimitry Andric inline llvm::Error keyError() {
188*9dba64beSDimitry Andric   return llvm::createStringError(llvm::inconvertibleErrorCode(),
189*9dba64beSDimitry Andric                                  "key not in dict");
190*9dba64beSDimitry Andric }
191*9dba64beSDimitry Andric 
1920b57cec5SDimitry Andric enum class PyInitialValue { Invalid, Empty };
1930b57cec5SDimitry Andric 
194*9dba64beSDimitry Andric template <typename T, typename Enable = void> struct PythonFormat;
195*9dba64beSDimitry Andric 
196*9dba64beSDimitry Andric template <> struct PythonFormat<unsigned long long> {
197*9dba64beSDimitry Andric   static constexpr char format = 'K';
198*9dba64beSDimitry Andric   static auto get(unsigned long long value) { return value; }
199*9dba64beSDimitry Andric };
200*9dba64beSDimitry Andric 
201*9dba64beSDimitry Andric template <> struct PythonFormat<long long> {
202*9dba64beSDimitry Andric   static constexpr char format = 'L';
203*9dba64beSDimitry Andric   static auto get(long long value) { return value; }
204*9dba64beSDimitry Andric };
205*9dba64beSDimitry Andric 
206*9dba64beSDimitry Andric template <> struct PythonFormat<PyObject *> {
207*9dba64beSDimitry Andric   static constexpr char format = 'O';
208*9dba64beSDimitry Andric   static auto get(PyObject *value) { return value; }
209*9dba64beSDimitry Andric };
210*9dba64beSDimitry Andric 
211*9dba64beSDimitry Andric template <typename T>
212*9dba64beSDimitry Andric struct PythonFormat<
213*9dba64beSDimitry Andric     T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
214*9dba64beSDimitry Andric   static constexpr char format = 'O';
215*9dba64beSDimitry Andric   static auto get(const T &value) { return value.get(); }
216*9dba64beSDimitry Andric };
217*9dba64beSDimitry Andric 
2180b57cec5SDimitry Andric class PythonObject {
2190b57cec5SDimitry Andric public:
2200b57cec5SDimitry Andric   PythonObject() : m_py_obj(nullptr) {}
2210b57cec5SDimitry Andric 
222*9dba64beSDimitry Andric   PythonObject(PyRefType type, PyObject *py_obj) {
2230b57cec5SDimitry Andric     m_py_obj = py_obj;
2240b57cec5SDimitry Andric     // If this is a borrowed reference, we need to convert it to
2250b57cec5SDimitry Andric     // an owned reference by incrementing it.  If it is an owned
2260b57cec5SDimitry Andric     // reference (for example the caller allocated it with PyDict_New()
2270b57cec5SDimitry Andric     // then we must *not* increment it.
228*9dba64beSDimitry Andric     if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
2290b57cec5SDimitry Andric       Py_XINCREF(m_py_obj);
2300b57cec5SDimitry Andric   }
2310b57cec5SDimitry Andric 
232*9dba64beSDimitry Andric   PythonObject(const PythonObject &rhs)
233*9dba64beSDimitry Andric       : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
234*9dba64beSDimitry Andric 
235*9dba64beSDimitry Andric   PythonObject(PythonObject &&rhs) {
236*9dba64beSDimitry Andric     m_py_obj = rhs.m_py_obj;
237*9dba64beSDimitry Andric     rhs.m_py_obj = nullptr;
238*9dba64beSDimitry Andric   }
239*9dba64beSDimitry Andric 
240*9dba64beSDimitry Andric   ~PythonObject() { Reset(); }
241*9dba64beSDimitry Andric 
242*9dba64beSDimitry Andric   void Reset() {
243*9dba64beSDimitry Andric     if (m_py_obj && Py_IsInitialized())
244*9dba64beSDimitry Andric       Py_DECREF(m_py_obj);
245*9dba64beSDimitry Andric     m_py_obj = nullptr;
246*9dba64beSDimitry Andric   }
247*9dba64beSDimitry Andric 
2480b57cec5SDimitry Andric   void Dump() const {
2490b57cec5SDimitry Andric     if (m_py_obj)
2500b57cec5SDimitry Andric       _PyObject_Dump(m_py_obj);
2510b57cec5SDimitry Andric     else
2520b57cec5SDimitry Andric       puts("NULL");
2530b57cec5SDimitry Andric   }
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   void Dump(Stream &strm) const;
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric   PyObject *get() const { return m_py_obj; }
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   PyObject *release() {
2600b57cec5SDimitry Andric     PyObject *result = m_py_obj;
2610b57cec5SDimitry Andric     m_py_obj = nullptr;
2620b57cec5SDimitry Andric     return result;
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
265*9dba64beSDimitry Andric   PythonObject &operator=(PythonObject other) {
266*9dba64beSDimitry Andric     Reset();
267*9dba64beSDimitry Andric     m_py_obj = std::exchange(other.m_py_obj, nullptr);
2680b57cec5SDimitry Andric     return *this;
2690b57cec5SDimitry Andric   }
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric   PyObjectType GetObjectType() const;
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   PythonString Repr() const;
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric   PythonString Str() const;
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
2780b57cec5SDimitry Andric                                                 const PythonDictionary &dict);
2790b57cec5SDimitry Andric 
2800b57cec5SDimitry Andric   template <typename T>
2810b57cec5SDimitry Andric   static T ResolveNameWithDictionary(llvm::StringRef name,
2820b57cec5SDimitry Andric                                      const PythonDictionary &dict) {
2830b57cec5SDimitry Andric     return ResolveNameWithDictionary(name, dict).AsType<T>();
2840b57cec5SDimitry Andric   }
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   PythonObject ResolveName(llvm::StringRef name) const;
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric   template <typename T> T ResolveName(llvm::StringRef name) const {
2890b57cec5SDimitry Andric     return ResolveName(name).AsType<T>();
2900b57cec5SDimitry Andric   }
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   bool HasAttribute(llvm::StringRef attribute) const;
2930b57cec5SDimitry Andric 
2940b57cec5SDimitry Andric   PythonObject GetAttributeValue(llvm::StringRef attribute) const;
2950b57cec5SDimitry Andric 
296*9dba64beSDimitry Andric   bool IsNone() const { return m_py_obj == Py_None; }
2970b57cec5SDimitry Andric 
298*9dba64beSDimitry Andric   bool IsValid() const { return m_py_obj != nullptr; }
2990b57cec5SDimitry Andric 
300*9dba64beSDimitry Andric   bool IsAllocated() const { return IsValid() && !IsNone(); }
301*9dba64beSDimitry Andric 
302*9dba64beSDimitry Andric   explicit operator bool() const { return IsValid() && !IsNone(); }
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   template <typename T> T AsType() const {
3050b57cec5SDimitry Andric     if (!T::Check(m_py_obj))
3060b57cec5SDimitry Andric       return T();
3070b57cec5SDimitry Andric     return T(PyRefType::Borrowed, m_py_obj);
3080b57cec5SDimitry Andric   }
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   StructuredData::ObjectSP CreateStructuredObject() const;
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric protected:
313*9dba64beSDimitry Andric 
314*9dba64beSDimitry Andric #if PY_MAJOR_VERSION < 3
315*9dba64beSDimitry Andric   // The python 2 API declares some arguments as char* that should
316*9dba64beSDimitry Andric   // be const char *, but it doesn't actually modify them.
317*9dba64beSDimitry Andric   static char *py2_const_cast(const char *s) { return const_cast<char *>(s); }
318*9dba64beSDimitry Andric #else
319*9dba64beSDimitry Andric   static const char *py2_const_cast(const char *s) { return s; }
320*9dba64beSDimitry Andric #endif
321*9dba64beSDimitry Andric 
322*9dba64beSDimitry Andric public:
323*9dba64beSDimitry Andric   template <typename... T>
324*9dba64beSDimitry Andric   llvm::Expected<PythonObject> CallMethod(const char *name,
325*9dba64beSDimitry Andric                                           const T &... t) const {
326*9dba64beSDimitry Andric     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
327*9dba64beSDimitry Andric     PyObject *obj =
328*9dba64beSDimitry Andric         PyObject_CallMethod(m_py_obj, py2_const_cast(name),
329*9dba64beSDimitry Andric                             py2_const_cast(format), PythonFormat<T>::get(t)...);
330*9dba64beSDimitry Andric     if (!obj)
331*9dba64beSDimitry Andric       return exception();
332*9dba64beSDimitry Andric     return python::Take<PythonObject>(obj);
333*9dba64beSDimitry Andric   }
334*9dba64beSDimitry Andric 
335*9dba64beSDimitry Andric   template <typename... T>
336*9dba64beSDimitry Andric   llvm::Expected<PythonObject> Call(const T &... t) const {
337*9dba64beSDimitry Andric     const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
338*9dba64beSDimitry Andric     PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
339*9dba64beSDimitry Andric                                           PythonFormat<T>::get(t)...);
340*9dba64beSDimitry Andric     if (!obj)
341*9dba64beSDimitry Andric       return exception();
342*9dba64beSDimitry Andric     return python::Take<PythonObject>(obj);
343*9dba64beSDimitry Andric   }
344*9dba64beSDimitry Andric 
345*9dba64beSDimitry Andric   llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
346*9dba64beSDimitry Andric     if (!m_py_obj)
347*9dba64beSDimitry Andric       return nullDeref();
348*9dba64beSDimitry Andric     PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
349*9dba64beSDimitry Andric     if (!obj)
350*9dba64beSDimitry Andric       return exception();
351*9dba64beSDimitry Andric     return python::Take<PythonObject>(obj);
352*9dba64beSDimitry Andric   }
353*9dba64beSDimitry Andric 
354*9dba64beSDimitry Andric   llvm::Expected<bool> IsTrue() {
355*9dba64beSDimitry Andric     if (!m_py_obj)
356*9dba64beSDimitry Andric       return nullDeref();
357*9dba64beSDimitry Andric     int r = PyObject_IsTrue(m_py_obj);
358*9dba64beSDimitry Andric     if (r < 0)
359*9dba64beSDimitry Andric       return exception();
360*9dba64beSDimitry Andric     return !!r;
361*9dba64beSDimitry Andric   }
362*9dba64beSDimitry Andric 
363*9dba64beSDimitry Andric   llvm::Expected<long long> AsLongLong() {
364*9dba64beSDimitry Andric     if (!m_py_obj)
365*9dba64beSDimitry Andric       return nullDeref();
366*9dba64beSDimitry Andric     assert(!PyErr_Occurred());
367*9dba64beSDimitry Andric     long long r = PyLong_AsLongLong(m_py_obj);
368*9dba64beSDimitry Andric     if (PyErr_Occurred())
369*9dba64beSDimitry Andric       return exception();
370*9dba64beSDimitry Andric     return r;
371*9dba64beSDimitry Andric   }
372*9dba64beSDimitry Andric 
373*9dba64beSDimitry Andric   llvm::Expected<bool> IsInstance(const PythonObject &cls) {
374*9dba64beSDimitry Andric     if (!m_py_obj || !cls.IsValid())
375*9dba64beSDimitry Andric       return nullDeref();
376*9dba64beSDimitry Andric     int r = PyObject_IsInstance(m_py_obj, cls.get());
377*9dba64beSDimitry Andric     if (r < 0)
378*9dba64beSDimitry Andric       return exception();
379*9dba64beSDimitry Andric     return !!r;
380*9dba64beSDimitry Andric   }
381*9dba64beSDimitry Andric 
382*9dba64beSDimitry Andric protected:
3830b57cec5SDimitry Andric   PyObject *m_py_obj;
3840b57cec5SDimitry Andric };
3850b57cec5SDimitry Andric 
386*9dba64beSDimitry Andric 
387*9dba64beSDimitry Andric // This is why C++ needs monads.
388*9dba64beSDimitry Andric template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
389*9dba64beSDimitry Andric   if (!obj)
390*9dba64beSDimitry Andric     return obj.takeError();
391*9dba64beSDimitry Andric   if (!T::Check(obj.get().get()))
392*9dba64beSDimitry Andric     return llvm::createStringError(llvm::inconvertibleErrorCode(),
393*9dba64beSDimitry Andric                                    "type error");
394*9dba64beSDimitry Andric   return T(PyRefType::Borrowed, std::move(obj.get().get()));
395*9dba64beSDimitry Andric }
396*9dba64beSDimitry Andric 
397*9dba64beSDimitry Andric template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
398*9dba64beSDimitry Andric 
399*9dba64beSDimitry Andric template <>
400*9dba64beSDimitry Andric llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
401*9dba64beSDimitry Andric 
402*9dba64beSDimitry Andric template <>
403*9dba64beSDimitry Andric llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
404*9dba64beSDimitry Andric 
405*9dba64beSDimitry Andric 
406*9dba64beSDimitry Andric template <class T> class TypedPythonObject : public PythonObject {
4070b57cec5SDimitry Andric public:
408*9dba64beSDimitry Andric   // override to perform implicit type conversions on Reset
409*9dba64beSDimitry Andric   // This can be eliminated once we drop python 2 support.
410*9dba64beSDimitry Andric   static void Convert(PyRefType &type, PyObject *&py_obj) {}
411*9dba64beSDimitry Andric 
412*9dba64beSDimitry Andric   TypedPythonObject(PyRefType type, PyObject *py_obj) {
413*9dba64beSDimitry Andric     if (!py_obj)
414*9dba64beSDimitry Andric       return;
415*9dba64beSDimitry Andric     T::Convert(type, py_obj);
416*9dba64beSDimitry Andric     if (T::Check(py_obj))
417*9dba64beSDimitry Andric       PythonObject::operator=(PythonObject(type, py_obj));
418*9dba64beSDimitry Andric     else if (type == PyRefType::Owned)
419*9dba64beSDimitry Andric       Py_DECREF(py_obj);
420*9dba64beSDimitry Andric   }
421*9dba64beSDimitry Andric 
422*9dba64beSDimitry Andric   TypedPythonObject() {}
423*9dba64beSDimitry Andric };
424*9dba64beSDimitry Andric 
425*9dba64beSDimitry Andric class PythonBytes : public TypedPythonObject<PythonBytes> {
426*9dba64beSDimitry Andric public:
427*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
4280b57cec5SDimitry Andric   explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
4290b57cec5SDimitry Andric   PythonBytes(const uint8_t *bytes, size_t length);
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
4320b57cec5SDimitry Andric 
4330b57cec5SDimitry Andric   llvm::ArrayRef<uint8_t> GetBytes() const;
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   size_t GetSize() const;
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4380b57cec5SDimitry Andric 
4390b57cec5SDimitry Andric   StructuredData::StringSP CreateStructuredString() const;
4400b57cec5SDimitry Andric };
4410b57cec5SDimitry Andric 
442*9dba64beSDimitry Andric class PythonByteArray : public TypedPythonObject<PythonByteArray> {
4430b57cec5SDimitry Andric public:
444*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
4450b57cec5SDimitry Andric   explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
4460b57cec5SDimitry Andric   PythonByteArray(const uint8_t *bytes, size_t length);
4470b57cec5SDimitry Andric   PythonByteArray(const PythonBytes &object);
4480b57cec5SDimitry Andric 
4490b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   llvm::ArrayRef<uint8_t> GetBytes() const;
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   size_t GetSize() const;
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric   StructuredData::StringSP CreateStructuredString() const;
4580b57cec5SDimitry Andric };
4590b57cec5SDimitry Andric 
460*9dba64beSDimitry Andric class PythonString : public TypedPythonObject<PythonString> {
4610b57cec5SDimitry Andric public:
462*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
463*9dba64beSDimitry Andric   static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
4640b57cec5SDimitry Andric 
465*9dba64beSDimitry Andric   PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
466*9dba64beSDimitry Andric 
467*9dba64beSDimitry Andric   explicit PythonString(llvm::StringRef string); // safe, null on error
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
470*9dba64beSDimitry Andric   static void Convert(PyRefType &type, PyObject *&py_obj);
4710b57cec5SDimitry Andric 
472*9dba64beSDimitry Andric   llvm::StringRef GetString() const; // safe, empty string on error
4730b57cec5SDimitry Andric 
474*9dba64beSDimitry Andric   llvm::Expected<llvm::StringRef> AsUTF8() const;
4750b57cec5SDimitry Andric 
4760b57cec5SDimitry Andric   size_t GetSize() const;
4770b57cec5SDimitry Andric 
478*9dba64beSDimitry Andric   void SetString(llvm::StringRef string); // safe, null on error
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric   StructuredData::StringSP CreateStructuredString() const;
4810b57cec5SDimitry Andric };
4820b57cec5SDimitry Andric 
483*9dba64beSDimitry Andric class PythonInteger : public TypedPythonObject<PythonInteger> {
4840b57cec5SDimitry Andric public:
485*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
4860b57cec5SDimitry Andric 
487*9dba64beSDimitry Andric   PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
488*9dba64beSDimitry Andric 
489*9dba64beSDimitry Andric   explicit PythonInteger(int64_t value);
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
492*9dba64beSDimitry Andric   static void Convert(PyRefType &type, PyObject *&py_obj);
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric   int64_t GetInteger() const;
4950b57cec5SDimitry Andric 
4960b57cec5SDimitry Andric   void SetInteger(int64_t value);
4970b57cec5SDimitry Andric 
4980b57cec5SDimitry Andric   StructuredData::IntegerSP CreateStructuredInteger() const;
4990b57cec5SDimitry Andric };
5000b57cec5SDimitry Andric 
501*9dba64beSDimitry Andric class PythonBoolean : public TypedPythonObject<PythonBoolean> {
5020b57cec5SDimitry Andric public:
503*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
5040b57cec5SDimitry Andric 
505*9dba64beSDimitry Andric   explicit PythonBoolean(bool value);
5060b57cec5SDimitry Andric 
5070b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric   bool GetValue() const;
5100b57cec5SDimitry Andric 
5110b57cec5SDimitry Andric   void SetValue(bool value);
5120b57cec5SDimitry Andric 
5130b57cec5SDimitry Andric   StructuredData::BooleanSP CreateStructuredBoolean() const;
5140b57cec5SDimitry Andric };
5150b57cec5SDimitry Andric 
516*9dba64beSDimitry Andric class PythonList : public TypedPythonObject<PythonList> {
5170b57cec5SDimitry Andric public:
518*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
519*9dba64beSDimitry Andric 
520*9dba64beSDimitry Andric   PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
521*9dba64beSDimitry Andric 
5220b57cec5SDimitry Andric   explicit PythonList(PyInitialValue value);
5230b57cec5SDimitry Andric   explicit PythonList(int list_size);
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric   uint32_t GetSize() const;
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric   PythonObject GetItemAtIndex(uint32_t index) const;
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric   void SetItemAtIndex(uint32_t index, const PythonObject &object);
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   void AppendItem(const PythonObject &object);
5340b57cec5SDimitry Andric 
5350b57cec5SDimitry Andric   StructuredData::ArraySP CreateStructuredArray() const;
5360b57cec5SDimitry Andric };
5370b57cec5SDimitry Andric 
538*9dba64beSDimitry Andric class PythonTuple : public TypedPythonObject<PythonTuple> {
5390b57cec5SDimitry Andric public:
540*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
541*9dba64beSDimitry Andric 
5420b57cec5SDimitry Andric   explicit PythonTuple(PyInitialValue value);
5430b57cec5SDimitry Andric   explicit PythonTuple(int tuple_size);
5440b57cec5SDimitry Andric   PythonTuple(std::initializer_list<PythonObject> objects);
5450b57cec5SDimitry Andric   PythonTuple(std::initializer_list<PyObject *> objects);
5460b57cec5SDimitry Andric 
5470b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   uint32_t GetSize() const;
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric   PythonObject GetItemAtIndex(uint32_t index) const;
5520b57cec5SDimitry Andric 
5530b57cec5SDimitry Andric   void SetItemAtIndex(uint32_t index, const PythonObject &object);
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric   StructuredData::ArraySP CreateStructuredArray() const;
5560b57cec5SDimitry Andric };
5570b57cec5SDimitry Andric 
558*9dba64beSDimitry Andric class PythonDictionary : public TypedPythonObject<PythonDictionary> {
5590b57cec5SDimitry Andric public:
560*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
5610b57cec5SDimitry Andric 
562*9dba64beSDimitry Andric   PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
563*9dba64beSDimitry Andric 
564*9dba64beSDimitry Andric   explicit PythonDictionary(PyInitialValue value);
5650b57cec5SDimitry Andric 
5660b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   uint32_t GetSize() const;
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric   PythonList GetKeys() const;
5710b57cec5SDimitry Andric 
572*9dba64beSDimitry Andric   PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
573*9dba64beSDimitry Andric   void SetItemForKey(const PythonObject &key,
574*9dba64beSDimitry Andric                      const PythonObject &value); // DEPRECATED
575*9dba64beSDimitry Andric 
576*9dba64beSDimitry Andric   llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
577*9dba64beSDimitry Andric   llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
578*9dba64beSDimitry Andric   llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
579*9dba64beSDimitry Andric   llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric   StructuredData::DictionarySP CreateStructuredDictionary() const;
5820b57cec5SDimitry Andric };
5830b57cec5SDimitry Andric 
584*9dba64beSDimitry Andric class PythonModule : public TypedPythonObject<PythonModule> {
5850b57cec5SDimitry Andric public:
586*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
5870b57cec5SDimitry Andric 
5880b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric   static PythonModule BuiltinsModule();
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric   static PythonModule MainModule();
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric   static PythonModule AddModule(llvm::StringRef module);
5950b57cec5SDimitry Andric 
596*9dba64beSDimitry Andric   // safe, returns invalid on error;
597*9dba64beSDimitry Andric   static PythonModule ImportModule(llvm::StringRef name) {
598*9dba64beSDimitry Andric     std::string s = name;
599*9dba64beSDimitry Andric     auto mod = Import(s.c_str());
600*9dba64beSDimitry Andric     if (!mod) {
601*9dba64beSDimitry Andric       llvm::consumeError(mod.takeError());
602*9dba64beSDimitry Andric       return PythonModule();
603*9dba64beSDimitry Andric     }
604*9dba64beSDimitry Andric     return std::move(mod.get());
605*9dba64beSDimitry Andric   }
6060b57cec5SDimitry Andric 
607*9dba64beSDimitry Andric   static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
6080b57cec5SDimitry Andric 
609*9dba64beSDimitry Andric   llvm::Expected<PythonObject> Get(const llvm::Twine &name);
6100b57cec5SDimitry Andric 
6110b57cec5SDimitry Andric   PythonDictionary GetDictionary() const;
6120b57cec5SDimitry Andric };
6130b57cec5SDimitry Andric 
614*9dba64beSDimitry Andric class PythonCallable : public TypedPythonObject<PythonCallable> {
6150b57cec5SDimitry Andric public:
616*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
617*9dba64beSDimitry Andric 
6180b57cec5SDimitry Andric   struct ArgInfo {
619*9dba64beSDimitry Andric     /* the largest number of positional arguments this callable
620*9dba64beSDimitry Andric      * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
621*9dba64beSDimitry Andric      * function and can accept an arbitrary number */
622*9dba64beSDimitry Andric     unsigned max_positional_args;
623*9dba64beSDimitry Andric     static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
624*9dba64beSDimitry Andric     /* the number of positional arguments, including optional ones,
625*9dba64beSDimitry Andric      * and excluding varargs.  If this is a bound method, then the
626*9dba64beSDimitry Andric      * count will still include a +1 for self.
627*9dba64beSDimitry Andric      *
628*9dba64beSDimitry Andric      * FIXME. That's crazy.  This should be replaced with
629*9dba64beSDimitry Andric      * an accurate min and max for positional args.
630*9dba64beSDimitry Andric      */
631*9dba64beSDimitry Andric     int count;
632*9dba64beSDimitry Andric     /* does the callable have positional varargs? */
633*9dba64beSDimitry Andric     bool has_varargs : 1; // FIXME delete this
6340b57cec5SDimitry Andric   };
6350b57cec5SDimitry Andric 
6360b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
6370b57cec5SDimitry Andric 
638*9dba64beSDimitry Andric   llvm::Expected<ArgInfo> GetArgInfo() const;
6390b57cec5SDimitry Andric 
640*9dba64beSDimitry Andric   llvm::Expected<ArgInfo> GetInitArgInfo() const;
6410b57cec5SDimitry Andric 
642*9dba64beSDimitry Andric   ArgInfo GetNumArguments() const; // DEPRECATED
643*9dba64beSDimitry Andric 
644*9dba64beSDimitry Andric   // If the callable is a Py_Class, then find the number of arguments
645*9dba64beSDimitry Andric   // of the __init__ method.
646*9dba64beSDimitry Andric   ArgInfo GetNumInitArguments() const; // DEPRECATED
6470b57cec5SDimitry Andric 
6480b57cec5SDimitry Andric   PythonObject operator()();
6490b57cec5SDimitry Andric 
6500b57cec5SDimitry Andric   PythonObject operator()(std::initializer_list<PyObject *> args);
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric   PythonObject operator()(std::initializer_list<PythonObject> args);
6530b57cec5SDimitry Andric 
6540b57cec5SDimitry Andric   template <typename Arg, typename... Args>
6550b57cec5SDimitry Andric   PythonObject operator()(const Arg &arg, Args... args) {
6560b57cec5SDimitry Andric     return operator()({arg, args...});
6570b57cec5SDimitry Andric   }
6580b57cec5SDimitry Andric };
6590b57cec5SDimitry Andric 
660*9dba64beSDimitry Andric class PythonFile : public TypedPythonObject<PythonFile> {
6610b57cec5SDimitry Andric public:
662*9dba64beSDimitry Andric   using TypedPythonObject::TypedPythonObject;
6630b57cec5SDimitry Andric 
664*9dba64beSDimitry Andric   PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
6650b57cec5SDimitry Andric 
6660b57cec5SDimitry Andric   static bool Check(PyObject *py_obj);
6670b57cec5SDimitry Andric 
668*9dba64beSDimitry Andric   static llvm::Expected<PythonFile> FromFile(File &file,
669*9dba64beSDimitry Andric                                              const char *mode = nullptr);
6700b57cec5SDimitry Andric 
671*9dba64beSDimitry Andric   llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
672*9dba64beSDimitry Andric   llvm::Expected<lldb::FileSP>
673*9dba64beSDimitry Andric   ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
6740b57cec5SDimitry Andric };
6750b57cec5SDimitry Andric 
676*9dba64beSDimitry Andric class PythonException : public llvm::ErrorInfo<PythonException> {
677*9dba64beSDimitry Andric private:
678*9dba64beSDimitry Andric   PyObject *m_exception_type, *m_exception, *m_traceback;
679*9dba64beSDimitry Andric   PyObject *m_repr_bytes;
680*9dba64beSDimitry Andric 
681*9dba64beSDimitry Andric public:
682*9dba64beSDimitry Andric   static char ID;
683*9dba64beSDimitry Andric   const char *toCString() const;
684*9dba64beSDimitry Andric   PythonException(const char *caller = nullptr);
685*9dba64beSDimitry Andric   void Restore();
686*9dba64beSDimitry Andric   ~PythonException();
687*9dba64beSDimitry Andric   void log(llvm::raw_ostream &OS) const override;
688*9dba64beSDimitry Andric   std::error_code convertToErrorCode() const override;
689*9dba64beSDimitry Andric   bool Matches(PyObject *exc) const;
690*9dba64beSDimitry Andric   std::string ReadBacktrace() const;
691*9dba64beSDimitry Andric };
692*9dba64beSDimitry Andric 
693*9dba64beSDimitry Andric // This extracts the underlying T out of an Expected<T> and returns it.
694*9dba64beSDimitry Andric // If the Expected is an Error instead of a T, that error will be converted
695*9dba64beSDimitry Andric // into a python exception, and this will return a default-constructed T.
696*9dba64beSDimitry Andric //
697*9dba64beSDimitry Andric // This is appropriate for use right at the boundary of python calling into
698*9dba64beSDimitry Andric // C++, such as in a SWIG typemap.   In such a context you should simply
699*9dba64beSDimitry Andric // check if the returned T is valid, and if it is, return a NULL back
700*9dba64beSDimitry Andric // to python.   This will result in the Error being raised as an exception
701*9dba64beSDimitry Andric // from python code's point of view.
702*9dba64beSDimitry Andric //
703*9dba64beSDimitry Andric // For example:
704*9dba64beSDimitry Andric // ```
705*9dba64beSDimitry Andric // Expected<Foo *> efoop = some_cpp_function();
706*9dba64beSDimitry Andric // Foo *foop = unwrapOrSetPythonException(efoop);
707*9dba64beSDimitry Andric // if (!foop)
708*9dba64beSDimitry Andric //    return NULL;
709*9dba64beSDimitry Andric // do_something(*foop);
710*9dba64beSDimitry Andric //
711*9dba64beSDimitry Andric // If the Error returned was itself created because a python exception was
712*9dba64beSDimitry Andric // raised when C++ code called into python, then the original exception
713*9dba64beSDimitry Andric // will be restored.   Otherwise a simple string exception will be raised.
714*9dba64beSDimitry Andric template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
715*9dba64beSDimitry Andric   if (expected)
716*9dba64beSDimitry Andric     return expected.get();
717*9dba64beSDimitry Andric   llvm::handleAllErrors(
718*9dba64beSDimitry Andric       expected.takeError(), [](PythonException &E) { E.Restore(); },
719*9dba64beSDimitry Andric       [](const llvm::ErrorInfoBase &E) {
720*9dba64beSDimitry Andric         PyErr_SetString(PyExc_Exception, E.message().c_str());
721*9dba64beSDimitry Andric       });
722*9dba64beSDimitry Andric   return T();
723*9dba64beSDimitry Andric }
724*9dba64beSDimitry Andric 
725*9dba64beSDimitry Andric // This is only here to help incrementally migrate old, exception-unsafe
726*9dba64beSDimitry Andric // code.
727*9dba64beSDimitry Andric template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
728*9dba64beSDimitry Andric   if (expected)
729*9dba64beSDimitry Andric     return std::move(expected.get());
730*9dba64beSDimitry Andric   llvm::consumeError(expected.takeError());
731*9dba64beSDimitry Andric   return T();
732*9dba64beSDimitry Andric }
733*9dba64beSDimitry Andric 
734*9dba64beSDimitry Andric llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
735*9dba64beSDimitry Andric                                               const PythonDictionary &globals,
736*9dba64beSDimitry Andric                                               const PythonDictionary &locals);
737*9dba64beSDimitry Andric 
738*9dba64beSDimitry Andric llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
739*9dba64beSDimitry Andric                                                 const PythonDictionary &globals,
740*9dba64beSDimitry Andric                                                 const PythonDictionary &locals);
741*9dba64beSDimitry Andric 
742*9dba64beSDimitry Andric // Sometimes the best way to interact with a python interpreter is
743*9dba64beSDimitry Andric // to run some python code.   You construct a PythonScript with
744*9dba64beSDimitry Andric // script string.   The script assigns some function to `_function_`
745*9dba64beSDimitry Andric // and you get a C++ callable object that calls the python function.
746*9dba64beSDimitry Andric //
747*9dba64beSDimitry Andric // Example:
748*9dba64beSDimitry Andric //
749*9dba64beSDimitry Andric // const char script[] = R"(
750*9dba64beSDimitry Andric // def main(x, y):
751*9dba64beSDimitry Andric //    ....
752*9dba64beSDimitry Andric // )";
753*9dba64beSDimitry Andric //
754*9dba64beSDimitry Andric // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
755*9dba64beSDimitry Andric //   // no need to synchronize access to this global, we already have the GIL
756*9dba64beSDimitry Andric //   static PythonScript foo(script)
757*9dba64beSDimitry Andric //   return  foo(x, y);
758*9dba64beSDimitry Andric // }
759*9dba64beSDimitry Andric class PythonScript {
760*9dba64beSDimitry Andric   const char *script;
761*9dba64beSDimitry Andric   PythonCallable function;
762*9dba64beSDimitry Andric 
763*9dba64beSDimitry Andric   llvm::Error Init();
764*9dba64beSDimitry Andric 
765*9dba64beSDimitry Andric public:
766*9dba64beSDimitry Andric   PythonScript(const char *script) : script(script), function() {}
767*9dba64beSDimitry Andric 
768*9dba64beSDimitry Andric   template <typename... Args>
769*9dba64beSDimitry Andric   llvm::Expected<PythonObject> operator()(Args &&... args) {
770*9dba64beSDimitry Andric     if (llvm::Error error = Init())
771*9dba64beSDimitry Andric       return std::move(error);
772*9dba64beSDimitry Andric     return function.Call(std::forward<Args>(args)...);
773*9dba64beSDimitry Andric   }
774*9dba64beSDimitry Andric };
775*9dba64beSDimitry Andric 
776*9dba64beSDimitry Andric } // namespace python
7770b57cec5SDimitry Andric } // namespace lldb_private
7780b57cec5SDimitry Andric 
7790b57cec5SDimitry Andric #endif
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
782