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
99dba64beSDimitry Andric //
109dba64beSDimitry Andric // !! FIXME FIXME FIXME !!
119dba64beSDimitry Andric //
129dba64beSDimitry Andric // Python APIs nearly all can return an exception. They do this
139dba64beSDimitry Andric // by returning NULL, or -1, or some such value and setting
149dba64beSDimitry Andric // the exception state with PyErr_Set*(). Exceptions must be
159dba64beSDimitry Andric // handled before further python API functions are called. Failure
169dba64beSDimitry Andric // to do so will result in asserts on debug builds of python.
179dba64beSDimitry Andric // It will also sometimes, but not usually result in crashes of
189dba64beSDimitry Andric // release builds.
199dba64beSDimitry Andric //
209dba64beSDimitry Andric // Nearly all the code in this header does not handle python exceptions
219dba64beSDimitry Andric // correctly. It should all be converted to return Expected<> or
229dba64beSDimitry Andric // Error types to capture the exception.
239dba64beSDimitry Andric //
249dba64beSDimitry Andric // Everything in this file except functions that return Error or
259dba64beSDimitry Andric // Expected<> is considered deprecated and should not be
269dba64beSDimitry Andric // used in new code. If you need to use it, fix it first.
279dba64beSDimitry Andric //
289dba64beSDimitry Andric //
299dba64beSDimitry Andric // TODOs for this file
309dba64beSDimitry Andric //
319dba64beSDimitry Andric // * Make all methods safe for exceptions.
329dba64beSDimitry Andric //
339dba64beSDimitry Andric // * Eliminate method signatures that must translate exceptions into
349dba64beSDimitry Andric // empty objects or NULLs. Almost everything here should return
359dba64beSDimitry Andric // Expected<>. It should be acceptable for certain operations that
369dba64beSDimitry Andric // can never fail to assert instead, such as the creation of
379dba64beSDimitry Andric // PythonString from a string literal.
389dba64beSDimitry Andric //
395ffd83dbSDimitry Andric // * Eliminate Reset(), and make all non-default constructors private.
409dba64beSDimitry Andric // Python objects should be created with Retain<> or Take<>, and they
419dba64beSDimitry Andric // should be assigned with operator=
429dba64beSDimitry Andric //
439dba64beSDimitry Andric // * Eliminate default constructors, make python objects always
449dba64beSDimitry Andric // nonnull, and use optionals where necessary.
459dba64beSDimitry Andric //
469dba64beSDimitry Andric
479dba64beSDimitry Andric
480b57cec5SDimitry Andric #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
490b57cec5SDimitry Andric #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
500b57cec5SDimitry Andric
51480093f4SDimitry Andric #include "lldb/Host/Config.h"
52480093f4SDimitry Andric
53480093f4SDimitry Andric #if LLDB_ENABLE_PYTHON
540b57cec5SDimitry Andric
550b57cec5SDimitry Andric // LLDB Python header must be included first
560b57cec5SDimitry Andric #include "lldb-python.h"
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric #include "lldb/Host/File.h"
590b57cec5SDimitry Andric #include "lldb/Utility/StructuredData.h"
600b57cec5SDimitry Andric
610b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
620b57cec5SDimitry Andric
630b57cec5SDimitry Andric namespace lldb_private {
649dba64beSDimitry Andric namespace python {
650b57cec5SDimitry Andric
669dba64beSDimitry Andric class PythonObject;
670b57cec5SDimitry Andric class PythonBytes;
680b57cec5SDimitry Andric class PythonString;
690b57cec5SDimitry Andric class PythonList;
700b57cec5SDimitry Andric class PythonDictionary;
710b57cec5SDimitry Andric class PythonInteger;
729dba64beSDimitry Andric class PythonException;
730b57cec5SDimitry Andric
74349cc55cSDimitry Andric class GIL {
75349cc55cSDimitry Andric public:
GIL()76349cc55cSDimitry Andric GIL() {
77349cc55cSDimitry Andric m_state = PyGILState_Ensure();
78349cc55cSDimitry Andric assert(!PyErr_Occurred());
79349cc55cSDimitry Andric }
~GIL()80349cc55cSDimitry Andric ~GIL() { PyGILState_Release(m_state); }
81349cc55cSDimitry Andric
82349cc55cSDimitry Andric protected:
83349cc55cSDimitry Andric PyGILState_STATE m_state;
84349cc55cSDimitry Andric };
85349cc55cSDimitry Andric
860b57cec5SDimitry Andric enum class PyObjectType {
870b57cec5SDimitry Andric Unknown,
880b57cec5SDimitry Andric None,
890b57cec5SDimitry Andric Boolean,
900b57cec5SDimitry Andric Integer,
910b57cec5SDimitry Andric Dictionary,
920b57cec5SDimitry Andric List,
930b57cec5SDimitry Andric String,
940b57cec5SDimitry Andric Bytes,
950b57cec5SDimitry Andric ByteArray,
960b57cec5SDimitry Andric Module,
970b57cec5SDimitry Andric Callable,
980b57cec5SDimitry Andric Tuple,
990b57cec5SDimitry Andric File
1000b57cec5SDimitry Andric };
1010b57cec5SDimitry Andric
1020b57cec5SDimitry Andric enum class PyRefType {
1030b57cec5SDimitry Andric Borrowed, // We are not given ownership of the incoming PyObject.
1040b57cec5SDimitry Andric // We cannot safely hold it without calling Py_INCREF.
1050b57cec5SDimitry Andric Owned // We have ownership of the incoming PyObject. We should
1060b57cec5SDimitry Andric // not call Py_INCREF.
1070b57cec5SDimitry Andric };
1080b57cec5SDimitry Andric
1099dba64beSDimitry Andric
1109dba64beSDimitry Andric // Take a reference that you already own, and turn it into
1119dba64beSDimitry Andric // a PythonObject.
1129dba64beSDimitry Andric //
1139dba64beSDimitry Andric // Most python API methods will return a +1 reference
1149dba64beSDimitry Andric // if they succeed or NULL if and only if
1159dba64beSDimitry Andric // they set an exception. Use this to collect such return
1169dba64beSDimitry Andric // values, after checking for NULL.
1179dba64beSDimitry Andric //
1189dba64beSDimitry Andric // If T is not just PythonObject, then obj must be already be
1199dba64beSDimitry Andric // checked to be of the correct type.
Take(PyObject * obj)1209dba64beSDimitry Andric template <typename T> T Take(PyObject *obj) {
1219dba64beSDimitry Andric assert(obj);
1229dba64beSDimitry Andric assert(!PyErr_Occurred());
1239dba64beSDimitry Andric T thing(PyRefType::Owned, obj);
1249dba64beSDimitry Andric assert(thing.IsValid());
125480093f4SDimitry Andric return thing;
1269dba64beSDimitry Andric }
1279dba64beSDimitry Andric
1289dba64beSDimitry Andric // Retain a reference you have borrowed, and turn it into
1299dba64beSDimitry Andric // a PythonObject.
1309dba64beSDimitry Andric //
1319dba64beSDimitry Andric // A minority of python APIs return a borrowed reference
1329dba64beSDimitry Andric // instead of a +1. They will also return NULL if and only
1339dba64beSDimitry Andric // if they set an exception. Use this to collect such return
1349dba64beSDimitry Andric // values, after checking for NULL.
1359dba64beSDimitry Andric //
1369dba64beSDimitry Andric // If T is not just PythonObject, then obj must be already be
1379dba64beSDimitry Andric // checked to be of the correct type.
Retain(PyObject * obj)1389dba64beSDimitry Andric template <typename T> T Retain(PyObject *obj) {
1399dba64beSDimitry Andric assert(obj);
1409dba64beSDimitry Andric assert(!PyErr_Occurred());
1419dba64beSDimitry Andric T thing(PyRefType::Borrowed, obj);
1429dba64beSDimitry Andric assert(thing.IsValid());
143480093f4SDimitry Andric return thing;
1449dba64beSDimitry Andric }
1459dba64beSDimitry Andric
1469dba64beSDimitry Andric // This class can be used like a utility function to convert from
1479dba64beSDimitry Andric // a llvm-friendly Twine into a null-terminated const char *,
1489dba64beSDimitry Andric // which is the form python C APIs want their strings in.
1499dba64beSDimitry Andric //
1509dba64beSDimitry Andric // Example:
1519dba64beSDimitry Andric // const llvm::Twine &some_twine;
1529dba64beSDimitry Andric // PyFoo_Bar(x, y, z, NullTerminated(some_twine));
1539dba64beSDimitry Andric //
1549dba64beSDimitry Andric // Why a class instead of a function? If the twine isn't already null
1559dba64beSDimitry Andric // terminated, it will need a temporary buffer to copy the string
1569dba64beSDimitry Andric // into. We need that buffer to stick around for the lifetime of the
1579dba64beSDimitry Andric // statement.
1589dba64beSDimitry Andric class NullTerminated {
1599dba64beSDimitry Andric const char *str;
1609dba64beSDimitry Andric llvm::SmallString<32> storage;
1619dba64beSDimitry Andric
1629dba64beSDimitry Andric public:
NullTerminated(const llvm::Twine & twine)1639dba64beSDimitry Andric NullTerminated(const llvm::Twine &twine) {
1649dba64beSDimitry Andric llvm::StringRef ref = twine.toNullTerminatedStringRef(storage);
1659dba64beSDimitry Andric str = ref.begin();
1669dba64beSDimitry Andric }
1679dba64beSDimitry Andric operator const char *() { return str; }
1689dba64beSDimitry Andric };
1699dba64beSDimitry Andric
nullDeref()1709dba64beSDimitry Andric inline llvm::Error nullDeref() {
1719dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),
1729dba64beSDimitry Andric "A NULL PyObject* was dereferenced");
1739dba64beSDimitry Andric }
1749dba64beSDimitry Andric
1759dba64beSDimitry Andric inline llvm::Error exception(const char *s = nullptr) {
1769dba64beSDimitry Andric return llvm::make_error<PythonException>(s);
1779dba64beSDimitry Andric }
1789dba64beSDimitry Andric
keyError()1799dba64beSDimitry Andric inline llvm::Error keyError() {
1809dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),
1819dba64beSDimitry Andric "key not in dict");
1829dba64beSDimitry Andric }
1839dba64beSDimitry Andric
py2_const_cast(const char * s)184480093f4SDimitry Andric inline const char *py2_const_cast(const char *s) { return s; }
185480093f4SDimitry Andric
1860b57cec5SDimitry Andric enum class PyInitialValue { Invalid, Empty };
1870b57cec5SDimitry Andric
188bdd1243dSDimitry Andric // DOC: https://docs.python.org/3/c-api/arg.html#building-values
1899dba64beSDimitry Andric template <typename T, typename Enable = void> struct PythonFormat;
1909dba64beSDimitry Andric
191bdd1243dSDimitry Andric template <typename T, char F> struct PassthroughFormat {
192bdd1243dSDimitry Andric static constexpr char format = F;
getPassthroughFormat193bdd1243dSDimitry Andric static constexpr T get(T t) { return t; }
1949dba64beSDimitry Andric };
1959dba64beSDimitry Andric
196bdd1243dSDimitry Andric template <> struct PythonFormat<char *> : PassthroughFormat<char *, 's'> {};
197bdd1243dSDimitry Andric template <> struct PythonFormat<char> : PassthroughFormat<char, 'b'> {};
198bdd1243dSDimitry Andric template <>
199bdd1243dSDimitry Andric struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {};
200bdd1243dSDimitry Andric template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {};
201bdd1243dSDimitry Andric template <>
202bdd1243dSDimitry Andric struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {};
203bdd1243dSDimitry Andric template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {};
204fe013be4SDimitry Andric template <> struct PythonFormat<bool> : PassthroughFormat<bool, 'p'> {};
205bdd1243dSDimitry Andric template <>
206bdd1243dSDimitry Andric struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {};
207bdd1243dSDimitry Andric template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {};
208bdd1243dSDimitry Andric template <>
209bdd1243dSDimitry Andric struct PythonFormat<unsigned long> : PassthroughFormat<unsigned long, 'k'> {};
210bdd1243dSDimitry Andric template <>
211bdd1243dSDimitry Andric struct PythonFormat<long long> : PassthroughFormat<long long, 'L'> {};
212bdd1243dSDimitry Andric template <>
213bdd1243dSDimitry Andric struct PythonFormat<unsigned long long>
214bdd1243dSDimitry Andric : PassthroughFormat<unsigned long long, 'K'> {};
215bdd1243dSDimitry Andric template <>
216bdd1243dSDimitry Andric struct PythonFormat<PyObject *> : PassthroughFormat<PyObject *, 'O'> {};
2179dba64beSDimitry Andric
2189dba64beSDimitry Andric template <typename T>
2199dba64beSDimitry Andric struct PythonFormat<
2209dba64beSDimitry Andric T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> {
2219dba64beSDimitry Andric static constexpr char format = 'O';
2229dba64beSDimitry Andric static auto get(const T &value) { return value.get(); }
2239dba64beSDimitry Andric };
2249dba64beSDimitry Andric
2250b57cec5SDimitry Andric class PythonObject {
2260b57cec5SDimitry Andric public:
227fe6060f1SDimitry Andric PythonObject() = default;
2280b57cec5SDimitry Andric
2299dba64beSDimitry Andric PythonObject(PyRefType type, PyObject *py_obj) {
2300b57cec5SDimitry Andric m_py_obj = py_obj;
2310b57cec5SDimitry Andric // If this is a borrowed reference, we need to convert it to
2320b57cec5SDimitry Andric // an owned reference by incrementing it. If it is an owned
2330b57cec5SDimitry Andric // reference (for example the caller allocated it with PyDict_New()
2340b57cec5SDimitry Andric // then we must *not* increment it.
2359dba64beSDimitry Andric if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed)
2360b57cec5SDimitry Andric Py_XINCREF(m_py_obj);
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric
2399dba64beSDimitry Andric PythonObject(const PythonObject &rhs)
2409dba64beSDimitry Andric : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {}
2419dba64beSDimitry Andric
2429dba64beSDimitry Andric PythonObject(PythonObject &&rhs) {
2439dba64beSDimitry Andric m_py_obj = rhs.m_py_obj;
2449dba64beSDimitry Andric rhs.m_py_obj = nullptr;
2459dba64beSDimitry Andric }
2469dba64beSDimitry Andric
2479dba64beSDimitry Andric ~PythonObject() { Reset(); }
2489dba64beSDimitry Andric
24904eeddc0SDimitry Andric void Reset();
2509dba64beSDimitry Andric
2510b57cec5SDimitry Andric void Dump() const {
2520b57cec5SDimitry Andric if (m_py_obj)
2530b57cec5SDimitry Andric _PyObject_Dump(m_py_obj);
2540b57cec5SDimitry Andric else
2550b57cec5SDimitry Andric puts("NULL");
2560b57cec5SDimitry Andric }
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andric void Dump(Stream &strm) const;
2590b57cec5SDimitry Andric
2600b57cec5SDimitry Andric PyObject *get() const { return m_py_obj; }
2610b57cec5SDimitry Andric
2620b57cec5SDimitry Andric PyObject *release() {
2630b57cec5SDimitry Andric PyObject *result = m_py_obj;
2640b57cec5SDimitry Andric m_py_obj = nullptr;
2650b57cec5SDimitry Andric return result;
2660b57cec5SDimitry Andric }
2670b57cec5SDimitry Andric
2689dba64beSDimitry Andric PythonObject &operator=(PythonObject other) {
2699dba64beSDimitry Andric Reset();
2709dba64beSDimitry Andric m_py_obj = std::exchange(other.m_py_obj, nullptr);
2710b57cec5SDimitry Andric return *this;
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric PyObjectType GetObjectType() const;
2750b57cec5SDimitry Andric
2760b57cec5SDimitry Andric PythonString Repr() const;
2770b57cec5SDimitry Andric
2780b57cec5SDimitry Andric PythonString Str() const;
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andric static PythonObject ResolveNameWithDictionary(llvm::StringRef name,
2810b57cec5SDimitry Andric const PythonDictionary &dict);
2820b57cec5SDimitry Andric
2830b57cec5SDimitry Andric template <typename T>
2840b57cec5SDimitry Andric static T ResolveNameWithDictionary(llvm::StringRef name,
2850b57cec5SDimitry Andric const PythonDictionary &dict) {
2860b57cec5SDimitry Andric return ResolveNameWithDictionary(name, dict).AsType<T>();
2870b57cec5SDimitry Andric }
2880b57cec5SDimitry Andric
2890b57cec5SDimitry Andric PythonObject ResolveName(llvm::StringRef name) const;
2900b57cec5SDimitry Andric
2910b57cec5SDimitry Andric template <typename T> T ResolveName(llvm::StringRef name) const {
2920b57cec5SDimitry Andric return ResolveName(name).AsType<T>();
2930b57cec5SDimitry Andric }
2940b57cec5SDimitry Andric
2950b57cec5SDimitry Andric bool HasAttribute(llvm::StringRef attribute) const;
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric PythonObject GetAttributeValue(llvm::StringRef attribute) const;
2980b57cec5SDimitry Andric
2999dba64beSDimitry Andric bool IsNone() const { return m_py_obj == Py_None; }
3000b57cec5SDimitry Andric
3019dba64beSDimitry Andric bool IsValid() const { return m_py_obj != nullptr; }
3020b57cec5SDimitry Andric
3039dba64beSDimitry Andric bool IsAllocated() const { return IsValid() && !IsNone(); }
3049dba64beSDimitry Andric
3059dba64beSDimitry Andric explicit operator bool() const { return IsValid() && !IsNone(); }
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric template <typename T> T AsType() const {
3080b57cec5SDimitry Andric if (!T::Check(m_py_obj))
3090b57cec5SDimitry Andric return T();
3100b57cec5SDimitry Andric return T(PyRefType::Borrowed, m_py_obj);
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric
3130b57cec5SDimitry Andric StructuredData::ObjectSP CreateStructuredObject() const;
3140b57cec5SDimitry Andric
3159dba64beSDimitry Andric template <typename... T>
3169dba64beSDimitry Andric llvm::Expected<PythonObject> CallMethod(const char *name,
3179dba64beSDimitry Andric const T &... t) const {
3189dba64beSDimitry Andric const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
3199dba64beSDimitry Andric PyObject *obj =
3209dba64beSDimitry Andric PyObject_CallMethod(m_py_obj, py2_const_cast(name),
3219dba64beSDimitry Andric py2_const_cast(format), PythonFormat<T>::get(t)...);
3229dba64beSDimitry Andric if (!obj)
3239dba64beSDimitry Andric return exception();
3249dba64beSDimitry Andric return python::Take<PythonObject>(obj);
3259dba64beSDimitry Andric }
3269dba64beSDimitry Andric
3279dba64beSDimitry Andric template <typename... T>
3289dba64beSDimitry Andric llvm::Expected<PythonObject> Call(const T &... t) const {
3299dba64beSDimitry Andric const char format[] = {'(', PythonFormat<T>::format..., ')', 0};
3309dba64beSDimitry Andric PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format),
3319dba64beSDimitry Andric PythonFormat<T>::get(t)...);
3329dba64beSDimitry Andric if (!obj)
3339dba64beSDimitry Andric return exception();
3349dba64beSDimitry Andric return python::Take<PythonObject>(obj);
3359dba64beSDimitry Andric }
3369dba64beSDimitry Andric
3379dba64beSDimitry Andric llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const {
3389dba64beSDimitry Andric if (!m_py_obj)
3399dba64beSDimitry Andric return nullDeref();
3409dba64beSDimitry Andric PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name));
3419dba64beSDimitry Andric if (!obj)
3429dba64beSDimitry Andric return exception();
3439dba64beSDimitry Andric return python::Take<PythonObject>(obj);
3449dba64beSDimitry Andric }
3459dba64beSDimitry Andric
346fe013be4SDimitry Andric llvm::Expected<PythonObject> GetType() const {
347fe013be4SDimitry Andric if (!m_py_obj)
348fe013be4SDimitry Andric return nullDeref();
349fe013be4SDimitry Andric PyObject *obj = PyObject_Type(m_py_obj);
350fe013be4SDimitry Andric if (!obj)
351fe013be4SDimitry Andric return exception();
352fe013be4SDimitry Andric return python::Take<PythonObject>(obj);
353fe013be4SDimitry Andric }
354fe013be4SDimitry Andric
3559dba64beSDimitry Andric llvm::Expected<bool> IsTrue() {
3569dba64beSDimitry Andric if (!m_py_obj)
3579dba64beSDimitry Andric return nullDeref();
3589dba64beSDimitry Andric int r = PyObject_IsTrue(m_py_obj);
3599dba64beSDimitry Andric if (r < 0)
3609dba64beSDimitry Andric return exception();
3619dba64beSDimitry Andric return !!r;
3629dba64beSDimitry Andric }
3639dba64beSDimitry Andric
3645ffd83dbSDimitry Andric llvm::Expected<long long> AsLongLong() const;
3655ffd83dbSDimitry Andric
366fe013be4SDimitry Andric llvm::Expected<unsigned long long> AsUnsignedLongLong() const;
3675ffd83dbSDimitry Andric
3685ffd83dbSDimitry Andric // wraps on overflow, instead of raising an error.
3695ffd83dbSDimitry Andric llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const;
3709dba64beSDimitry Andric
3719dba64beSDimitry Andric llvm::Expected<bool> IsInstance(const PythonObject &cls) {
3729dba64beSDimitry Andric if (!m_py_obj || !cls.IsValid())
3739dba64beSDimitry Andric return nullDeref();
3749dba64beSDimitry Andric int r = PyObject_IsInstance(m_py_obj, cls.get());
3759dba64beSDimitry Andric if (r < 0)
3769dba64beSDimitry Andric return exception();
3779dba64beSDimitry Andric return !!r;
3789dba64beSDimitry Andric }
3799dba64beSDimitry Andric
3809dba64beSDimitry Andric protected:
381fe6060f1SDimitry Andric PyObject *m_py_obj = nullptr;
3820b57cec5SDimitry Andric };
3830b57cec5SDimitry Andric
3849dba64beSDimitry Andric
3859dba64beSDimitry Andric // This is why C++ needs monads.
3869dba64beSDimitry Andric template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) {
3879dba64beSDimitry Andric if (!obj)
3889dba64beSDimitry Andric return obj.takeError();
3899dba64beSDimitry Andric if (!T::Check(obj.get().get()))
3909dba64beSDimitry Andric return llvm::createStringError(llvm::inconvertibleErrorCode(),
3919dba64beSDimitry Andric "type error");
3929dba64beSDimitry Andric return T(PyRefType::Borrowed, std::move(obj.get().get()));
3939dba64beSDimitry Andric }
3949dba64beSDimitry Andric
3959dba64beSDimitry Andric template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj);
3969dba64beSDimitry Andric
3979dba64beSDimitry Andric template <>
3989dba64beSDimitry Andric llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj);
3999dba64beSDimitry Andric
4009dba64beSDimitry Andric template <>
4015ffd83dbSDimitry Andric llvm::Expected<unsigned long long>
4025ffd83dbSDimitry Andric As<unsigned long long>(llvm::Expected<PythonObject> &&obj);
4035ffd83dbSDimitry Andric
4045ffd83dbSDimitry Andric template <>
4059dba64beSDimitry Andric llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj);
4069dba64beSDimitry Andric
4079dba64beSDimitry Andric
4089dba64beSDimitry Andric template <class T> class TypedPythonObject : public PythonObject {
4090b57cec5SDimitry Andric public:
4109dba64beSDimitry Andric TypedPythonObject(PyRefType type, PyObject *py_obj) {
4119dba64beSDimitry Andric if (!py_obj)
4129dba64beSDimitry Andric return;
4139dba64beSDimitry Andric if (T::Check(py_obj))
4149dba64beSDimitry Andric PythonObject::operator=(PythonObject(type, py_obj));
4159dba64beSDimitry Andric else if (type == PyRefType::Owned)
4169dba64beSDimitry Andric Py_DECREF(py_obj);
4179dba64beSDimitry Andric }
4189dba64beSDimitry Andric
419fe6060f1SDimitry Andric TypedPythonObject() = default;
4209dba64beSDimitry Andric };
4219dba64beSDimitry Andric
4229dba64beSDimitry Andric class PythonBytes : public TypedPythonObject<PythonBytes> {
4239dba64beSDimitry Andric public:
4249dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
4250b57cec5SDimitry Andric explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes);
4260b57cec5SDimitry Andric PythonBytes(const uint8_t *bytes, size_t length);
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
4290b57cec5SDimitry Andric
4300b57cec5SDimitry Andric llvm::ArrayRef<uint8_t> GetBytes() const;
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andric size_t GetSize() const;
4330b57cec5SDimitry Andric
4340b57cec5SDimitry Andric void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4350b57cec5SDimitry Andric
4360b57cec5SDimitry Andric StructuredData::StringSP CreateStructuredString() const;
4370b57cec5SDimitry Andric };
4380b57cec5SDimitry Andric
4399dba64beSDimitry Andric class PythonByteArray : public TypedPythonObject<PythonByteArray> {
4400b57cec5SDimitry Andric public:
4419dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
4420b57cec5SDimitry Andric explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes);
4430b57cec5SDimitry Andric PythonByteArray(const uint8_t *bytes, size_t length);
4440b57cec5SDimitry Andric PythonByteArray(const PythonBytes &object);
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
4470b57cec5SDimitry Andric
4480b57cec5SDimitry Andric llvm::ArrayRef<uint8_t> GetBytes() const;
4490b57cec5SDimitry Andric
4500b57cec5SDimitry Andric size_t GetSize() const;
4510b57cec5SDimitry Andric
4520b57cec5SDimitry Andric void SetBytes(llvm::ArrayRef<uint8_t> stringbytes);
4530b57cec5SDimitry Andric
4540b57cec5SDimitry Andric StructuredData::StringSP CreateStructuredString() const;
4550b57cec5SDimitry Andric };
4560b57cec5SDimitry Andric
4579dba64beSDimitry Andric class PythonString : public TypedPythonObject<PythonString> {
4580b57cec5SDimitry Andric public:
4599dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
4609dba64beSDimitry Andric static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string);
4610b57cec5SDimitry Andric
4629dba64beSDimitry Andric PythonString() : TypedPythonObject() {} // MSVC requires this for some reason
4639dba64beSDimitry Andric
4649dba64beSDimitry Andric explicit PythonString(llvm::StringRef string); // safe, null on error
4650b57cec5SDimitry Andric
4660b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
4670b57cec5SDimitry Andric
4689dba64beSDimitry Andric llvm::StringRef GetString() const; // safe, empty string on error
4690b57cec5SDimitry Andric
4709dba64beSDimitry Andric llvm::Expected<llvm::StringRef> AsUTF8() const;
4710b57cec5SDimitry Andric
4720b57cec5SDimitry Andric size_t GetSize() const;
4730b57cec5SDimitry Andric
4749dba64beSDimitry Andric void SetString(llvm::StringRef string); // safe, null on error
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andric StructuredData::StringSP CreateStructuredString() const;
4770b57cec5SDimitry Andric };
4780b57cec5SDimitry Andric
4799dba64beSDimitry Andric class PythonInteger : public TypedPythonObject<PythonInteger> {
4800b57cec5SDimitry Andric public:
4819dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
4820b57cec5SDimitry Andric
4839dba64beSDimitry Andric PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason
4849dba64beSDimitry Andric
4859dba64beSDimitry Andric explicit PythonInteger(int64_t value);
4860b57cec5SDimitry Andric
4870b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
4880b57cec5SDimitry Andric
4890b57cec5SDimitry Andric void SetInteger(int64_t value);
4900b57cec5SDimitry Andric
4910b57cec5SDimitry Andric StructuredData::IntegerSP CreateStructuredInteger() const;
492fe013be4SDimitry Andric
493fe013be4SDimitry Andric StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const;
494fe013be4SDimitry Andric
495fe013be4SDimitry Andric StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const;
4960b57cec5SDimitry Andric };
4970b57cec5SDimitry Andric
4989dba64beSDimitry Andric class PythonBoolean : public TypedPythonObject<PythonBoolean> {
4990b57cec5SDimitry Andric public:
5009dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
5010b57cec5SDimitry Andric
5029dba64beSDimitry Andric explicit PythonBoolean(bool value);
5030b57cec5SDimitry Andric
5040b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
5050b57cec5SDimitry Andric
5060b57cec5SDimitry Andric bool GetValue() const;
5070b57cec5SDimitry Andric
5080b57cec5SDimitry Andric void SetValue(bool value);
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric StructuredData::BooleanSP CreateStructuredBoolean() const;
5110b57cec5SDimitry Andric };
5120b57cec5SDimitry Andric
5139dba64beSDimitry Andric class PythonList : public TypedPythonObject<PythonList> {
5140b57cec5SDimitry Andric public:
5159dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
5169dba64beSDimitry Andric
5179dba64beSDimitry Andric PythonList() : TypedPythonObject() {} // MSVC requires this for some reason
5189dba64beSDimitry Andric
5190b57cec5SDimitry Andric explicit PythonList(PyInitialValue value);
5200b57cec5SDimitry Andric explicit PythonList(int list_size);
5210b57cec5SDimitry Andric
5220b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andric uint32_t GetSize() const;
5250b57cec5SDimitry Andric
5260b57cec5SDimitry Andric PythonObject GetItemAtIndex(uint32_t index) const;
5270b57cec5SDimitry Andric
5280b57cec5SDimitry Andric void SetItemAtIndex(uint32_t index, const PythonObject &object);
5290b57cec5SDimitry Andric
5300b57cec5SDimitry Andric void AppendItem(const PythonObject &object);
5310b57cec5SDimitry Andric
5320b57cec5SDimitry Andric StructuredData::ArraySP CreateStructuredArray() const;
5330b57cec5SDimitry Andric };
5340b57cec5SDimitry Andric
5359dba64beSDimitry Andric class PythonTuple : public TypedPythonObject<PythonTuple> {
5360b57cec5SDimitry Andric public:
5379dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
5389dba64beSDimitry Andric
5390b57cec5SDimitry Andric explicit PythonTuple(PyInitialValue value);
5400b57cec5SDimitry Andric explicit PythonTuple(int tuple_size);
5410b57cec5SDimitry Andric PythonTuple(std::initializer_list<PythonObject> objects);
5420b57cec5SDimitry Andric PythonTuple(std::initializer_list<PyObject *> objects);
5430b57cec5SDimitry Andric
5440b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
5450b57cec5SDimitry Andric
5460b57cec5SDimitry Andric uint32_t GetSize() const;
5470b57cec5SDimitry Andric
5480b57cec5SDimitry Andric PythonObject GetItemAtIndex(uint32_t index) const;
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric void SetItemAtIndex(uint32_t index, const PythonObject &object);
5510b57cec5SDimitry Andric
5520b57cec5SDimitry Andric StructuredData::ArraySP CreateStructuredArray() const;
5530b57cec5SDimitry Andric };
5540b57cec5SDimitry Andric
5559dba64beSDimitry Andric class PythonDictionary : public TypedPythonObject<PythonDictionary> {
5560b57cec5SDimitry Andric public:
5579dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
5580b57cec5SDimitry Andric
5599dba64beSDimitry Andric PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason
5609dba64beSDimitry Andric
5619dba64beSDimitry Andric explicit PythonDictionary(PyInitialValue value);
5620b57cec5SDimitry Andric
5630b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
5640b57cec5SDimitry Andric
565*c9157d92SDimitry Andric bool HasKey(const llvm::Twine &key) const;
566*c9157d92SDimitry Andric
5670b57cec5SDimitry Andric uint32_t GetSize() const;
5680b57cec5SDimitry Andric
5690b57cec5SDimitry Andric PythonList GetKeys() const;
5700b57cec5SDimitry Andric
5719dba64beSDimitry Andric PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED
5729dba64beSDimitry Andric void SetItemForKey(const PythonObject &key,
5739dba64beSDimitry Andric const PythonObject &value); // DEPRECATED
5749dba64beSDimitry Andric
5759dba64beSDimitry Andric llvm::Expected<PythonObject> GetItem(const PythonObject &key) const;
5769dba64beSDimitry Andric llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const;
5779dba64beSDimitry Andric llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const;
5789dba64beSDimitry Andric llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const;
5790b57cec5SDimitry Andric
5800b57cec5SDimitry Andric StructuredData::DictionarySP CreateStructuredDictionary() const;
5810b57cec5SDimitry Andric };
5820b57cec5SDimitry Andric
5839dba64beSDimitry Andric class PythonModule : public TypedPythonObject<PythonModule> {
5840b57cec5SDimitry Andric public:
5859dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
5860b57cec5SDimitry Andric
5870b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
5880b57cec5SDimitry Andric
5890b57cec5SDimitry Andric static PythonModule BuiltinsModule();
5900b57cec5SDimitry Andric
5910b57cec5SDimitry Andric static PythonModule MainModule();
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andric static PythonModule AddModule(llvm::StringRef module);
5940b57cec5SDimitry Andric
5959dba64beSDimitry Andric // safe, returns invalid on error;
5969dba64beSDimitry Andric static PythonModule ImportModule(llvm::StringRef name) {
5975ffd83dbSDimitry Andric std::string s = std::string(name);
5989dba64beSDimitry Andric auto mod = Import(s.c_str());
5999dba64beSDimitry Andric if (!mod) {
6009dba64beSDimitry Andric llvm::consumeError(mod.takeError());
6019dba64beSDimitry Andric return PythonModule();
6029dba64beSDimitry Andric }
6039dba64beSDimitry Andric return std::move(mod.get());
6049dba64beSDimitry Andric }
6050b57cec5SDimitry Andric
6069dba64beSDimitry Andric static llvm::Expected<PythonModule> Import(const llvm::Twine &name);
6070b57cec5SDimitry Andric
6089dba64beSDimitry Andric llvm::Expected<PythonObject> Get(const llvm::Twine &name);
6090b57cec5SDimitry Andric
6100b57cec5SDimitry Andric PythonDictionary GetDictionary() const;
6110b57cec5SDimitry Andric };
6120b57cec5SDimitry Andric
6139dba64beSDimitry Andric class PythonCallable : public TypedPythonObject<PythonCallable> {
6140b57cec5SDimitry Andric public:
6159dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
6169dba64beSDimitry Andric
6170b57cec5SDimitry Andric struct ArgInfo {
6189dba64beSDimitry Andric /* the largest number of positional arguments this callable
6199dba64beSDimitry Andric * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs
6209dba64beSDimitry Andric * function and can accept an arbitrary number */
6219dba64beSDimitry Andric unsigned max_positional_args;
6229dba64beSDimitry Andric static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline
6230b57cec5SDimitry Andric };
6240b57cec5SDimitry Andric
6250b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
6260b57cec5SDimitry Andric
6279dba64beSDimitry Andric llvm::Expected<ArgInfo> GetArgInfo() const;
6280b57cec5SDimitry Andric
6290b57cec5SDimitry Andric PythonObject operator()();
6300b57cec5SDimitry Andric
6310b57cec5SDimitry Andric PythonObject operator()(std::initializer_list<PyObject *> args);
6320b57cec5SDimitry Andric
6330b57cec5SDimitry Andric PythonObject operator()(std::initializer_list<PythonObject> args);
6340b57cec5SDimitry Andric
6350b57cec5SDimitry Andric template <typename Arg, typename... Args>
6360b57cec5SDimitry Andric PythonObject operator()(const Arg &arg, Args... args) {
6370b57cec5SDimitry Andric return operator()({arg, args...});
6380b57cec5SDimitry Andric }
6390b57cec5SDimitry Andric };
6400b57cec5SDimitry Andric
6419dba64beSDimitry Andric class PythonFile : public TypedPythonObject<PythonFile> {
6420b57cec5SDimitry Andric public:
6439dba64beSDimitry Andric using TypedPythonObject::TypedPythonObject;
6440b57cec5SDimitry Andric
6459dba64beSDimitry Andric PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason
6460b57cec5SDimitry Andric
6470b57cec5SDimitry Andric static bool Check(PyObject *py_obj);
6480b57cec5SDimitry Andric
6499dba64beSDimitry Andric static llvm::Expected<PythonFile> FromFile(File &file,
6509dba64beSDimitry Andric const char *mode = nullptr);
6510b57cec5SDimitry Andric
6529dba64beSDimitry Andric llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false);
6539dba64beSDimitry Andric llvm::Expected<lldb::FileSP>
6549dba64beSDimitry Andric ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false);
6550b57cec5SDimitry Andric };
6560b57cec5SDimitry Andric
6579dba64beSDimitry Andric class PythonException : public llvm::ErrorInfo<PythonException> {
6589dba64beSDimitry Andric private:
6599dba64beSDimitry Andric PyObject *m_exception_type, *m_exception, *m_traceback;
6609dba64beSDimitry Andric PyObject *m_repr_bytes;
6619dba64beSDimitry Andric
6629dba64beSDimitry Andric public:
6639dba64beSDimitry Andric static char ID;
6649dba64beSDimitry Andric const char *toCString() const;
6659dba64beSDimitry Andric PythonException(const char *caller = nullptr);
6669dba64beSDimitry Andric void Restore();
66781ad6265SDimitry Andric ~PythonException() override;
6689dba64beSDimitry Andric void log(llvm::raw_ostream &OS) const override;
6699dba64beSDimitry Andric std::error_code convertToErrorCode() const override;
6709dba64beSDimitry Andric bool Matches(PyObject *exc) const;
6719dba64beSDimitry Andric std::string ReadBacktrace() const;
6729dba64beSDimitry Andric };
6739dba64beSDimitry Andric
6749dba64beSDimitry Andric // This extracts the underlying T out of an Expected<T> and returns it.
6759dba64beSDimitry Andric // If the Expected is an Error instead of a T, that error will be converted
6769dba64beSDimitry Andric // into a python exception, and this will return a default-constructed T.
6779dba64beSDimitry Andric //
6789dba64beSDimitry Andric // This is appropriate for use right at the boundary of python calling into
6799dba64beSDimitry Andric // C++, such as in a SWIG typemap. In such a context you should simply
6809dba64beSDimitry Andric // check if the returned T is valid, and if it is, return a NULL back
6819dba64beSDimitry Andric // to python. This will result in the Error being raised as an exception
6829dba64beSDimitry Andric // from python code's point of view.
6839dba64beSDimitry Andric //
6849dba64beSDimitry Andric // For example:
6859dba64beSDimitry Andric // ```
6869dba64beSDimitry Andric // Expected<Foo *> efoop = some_cpp_function();
6879dba64beSDimitry Andric // Foo *foop = unwrapOrSetPythonException(efoop);
6889dba64beSDimitry Andric // if (!foop)
6899dba64beSDimitry Andric // return NULL;
6909dba64beSDimitry Andric // do_something(*foop);
6919dba64beSDimitry Andric //
6929dba64beSDimitry Andric // If the Error returned was itself created because a python exception was
6939dba64beSDimitry Andric // raised when C++ code called into python, then the original exception
6949dba64beSDimitry Andric // will be restored. Otherwise a simple string exception will be raised.
6959dba64beSDimitry Andric template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) {
6969dba64beSDimitry Andric if (expected)
6979dba64beSDimitry Andric return expected.get();
6989dba64beSDimitry Andric llvm::handleAllErrors(
6999dba64beSDimitry Andric expected.takeError(), [](PythonException &E) { E.Restore(); },
7009dba64beSDimitry Andric [](const llvm::ErrorInfoBase &E) {
7019dba64beSDimitry Andric PyErr_SetString(PyExc_Exception, E.message().c_str());
7029dba64beSDimitry Andric });
7039dba64beSDimitry Andric return T();
7049dba64beSDimitry Andric }
7059dba64beSDimitry Andric
7069dba64beSDimitry Andric // This is only here to help incrementally migrate old, exception-unsafe
7079dba64beSDimitry Andric // code.
7089dba64beSDimitry Andric template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) {
7099dba64beSDimitry Andric if (expected)
7109dba64beSDimitry Andric return std::move(expected.get());
7119dba64beSDimitry Andric llvm::consumeError(expected.takeError());
7129dba64beSDimitry Andric return T();
7139dba64beSDimitry Andric }
7149dba64beSDimitry Andric
7159dba64beSDimitry Andric llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string,
7169dba64beSDimitry Andric const PythonDictionary &globals,
7179dba64beSDimitry Andric const PythonDictionary &locals);
7189dba64beSDimitry Andric
7199dba64beSDimitry Andric llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string,
7209dba64beSDimitry Andric const PythonDictionary &globals,
7219dba64beSDimitry Andric const PythonDictionary &locals);
7229dba64beSDimitry Andric
7239dba64beSDimitry Andric // Sometimes the best way to interact with a python interpreter is
7249dba64beSDimitry Andric // to run some python code. You construct a PythonScript with
7259dba64beSDimitry Andric // script string. The script assigns some function to `_function_`
7269dba64beSDimitry Andric // and you get a C++ callable object that calls the python function.
7279dba64beSDimitry Andric //
7289dba64beSDimitry Andric // Example:
7299dba64beSDimitry Andric //
7309dba64beSDimitry Andric // const char script[] = R"(
7319dba64beSDimitry Andric // def main(x, y):
7329dba64beSDimitry Andric // ....
7339dba64beSDimitry Andric // )";
7349dba64beSDimitry Andric //
7359dba64beSDimitry Andric // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) {
7369dba64beSDimitry Andric // // no need to synchronize access to this global, we already have the GIL
7379dba64beSDimitry Andric // static PythonScript foo(script)
7389dba64beSDimitry Andric // return foo(x, y);
7399dba64beSDimitry Andric // }
7409dba64beSDimitry Andric class PythonScript {
7419dba64beSDimitry Andric const char *script;
7429dba64beSDimitry Andric PythonCallable function;
7439dba64beSDimitry Andric
7449dba64beSDimitry Andric llvm::Error Init();
7459dba64beSDimitry Andric
7469dba64beSDimitry Andric public:
7479dba64beSDimitry Andric PythonScript(const char *script) : script(script), function() {}
7489dba64beSDimitry Andric
7499dba64beSDimitry Andric template <typename... Args>
7509dba64beSDimitry Andric llvm::Expected<PythonObject> operator()(Args &&... args) {
7519dba64beSDimitry Andric if (llvm::Error error = Init())
7529dba64beSDimitry Andric return std::move(error);
7539dba64beSDimitry Andric return function.Call(std::forward<Args>(args)...);
7549dba64beSDimitry Andric }
7559dba64beSDimitry Andric };
7569dba64beSDimitry Andric
75704eeddc0SDimitry Andric class StructuredPythonObject : public StructuredData::Generic {
75804eeddc0SDimitry Andric public:
75904eeddc0SDimitry Andric StructuredPythonObject() : StructuredData::Generic() {}
76004eeddc0SDimitry Andric
76104eeddc0SDimitry Andric // Take ownership of the object we received.
76204eeddc0SDimitry Andric StructuredPythonObject(PythonObject obj)
76304eeddc0SDimitry Andric : StructuredData::Generic(obj.release()) {}
76404eeddc0SDimitry Andric
76504eeddc0SDimitry Andric ~StructuredPythonObject() override {
76604eeddc0SDimitry Andric // Hand ownership back to a (temporary) PythonObject instance and let it
76704eeddc0SDimitry Andric // take care of releasing it.
76804eeddc0SDimitry Andric PythonObject(PyRefType::Owned, static_cast<PyObject *>(GetValue()));
76904eeddc0SDimitry Andric }
77004eeddc0SDimitry Andric
77104eeddc0SDimitry Andric bool IsValid() const override { return GetValue() && GetValue() != Py_None; }
77204eeddc0SDimitry Andric
77304eeddc0SDimitry Andric void Serialize(llvm::json::OStream &s) const override;
77404eeddc0SDimitry Andric
77504eeddc0SDimitry Andric private:
77604eeddc0SDimitry Andric StructuredPythonObject(const StructuredPythonObject &) = delete;
77704eeddc0SDimitry Andric const StructuredPythonObject &
77804eeddc0SDimitry Andric operator=(const StructuredPythonObject &) = delete;
77904eeddc0SDimitry Andric };
78004eeddc0SDimitry Andric
7819dba64beSDimitry Andric } // namespace python
7820b57cec5SDimitry Andric } // namespace lldb_private
7830b57cec5SDimitry Andric
7840b57cec5SDimitry Andric #endif
7850b57cec5SDimitry Andric
7860b57cec5SDimitry Andric #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H
787