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