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 74b9c1b51eSKate Stone class StructuredPythonObject : public StructuredData::Generic { 752c1f46dcSZachary Turner public: 76b9c1b51eSKate Stone StructuredPythonObject() : StructuredData::Generic() {} 772c1f46dcSZachary Turner 78b9c1b51eSKate Stone StructuredPythonObject(void *obj) : StructuredData::Generic(obj) { 792c1f46dcSZachary Turner Py_XINCREF(GetValue()); 802c1f46dcSZachary Turner } 812c1f46dcSZachary Turner 82b9c1b51eSKate Stone ~StructuredPythonObject() override { 832c1f46dcSZachary Turner if (Py_IsInitialized()) 842c1f46dcSZachary Turner Py_XDECREF(GetValue()); 852c1f46dcSZachary Turner SetValue(nullptr); 862c1f46dcSZachary Turner } 872c1f46dcSZachary Turner 88b9c1b51eSKate Stone bool IsValid() const override { return GetValue() && GetValue() != Py_None; } 892c1f46dcSZachary Turner 902783d817SJonas Devlieghere void Serialize(llvm::json::OStream &s) const override; 912c1f46dcSZachary Turner 922c1f46dcSZachary Turner private: 93*eaebcbc6SKonrad Kleine StructuredPythonObject(const StructuredPythonObject &) = delete; 94*eaebcbc6SKonrad Kleine const StructuredPythonObject & 95*eaebcbc6SKonrad Kleine operator=(const StructuredPythonObject &) = delete; 962c1f46dcSZachary Turner }; 972c1f46dcSZachary Turner 98b9c1b51eSKate Stone enum class PyObjectType { 992c1f46dcSZachary Turner Unknown, 1002c1f46dcSZachary Turner None, 101b81d715cSTatyana Krasnukha Boolean, 1022c1f46dcSZachary Turner Integer, 1032c1f46dcSZachary Turner Dictionary, 1042c1f46dcSZachary Turner List, 1059c40264fSZachary Turner String, 1065a72c02bSZachary Turner Bytes, 107f9d6d204SZachary Turner ByteArray, 1087841efbbSZachary Turner Module, 109a1405147SZachary Turner Callable, 110a1405147SZachary Turner Tuple, 1119c40264fSZachary Turner File 1122c1f46dcSZachary Turner }; 1132c1f46dcSZachary Turner 114b9c1b51eSKate Stone enum class PyRefType { 115f8b22f8fSZachary Turner Borrowed, // We are not given ownership of the incoming PyObject. 116f8b22f8fSZachary Turner // We cannot safely hold it without calling Py_INCREF. 117f8b22f8fSZachary Turner Owned // We have ownership of the incoming PyObject. We should 118f8b22f8fSZachary Turner // not call Py_INCREF. 119f8b22f8fSZachary Turner }; 120f8b22f8fSZachary Turner 121085328eeSLawrence D'Anna 122085328eeSLawrence D'Anna // Take a reference that you already own, and turn it into 123085328eeSLawrence D'Anna // a PythonObject. 124085328eeSLawrence D'Anna // 125085328eeSLawrence D'Anna // Most python API methods will return a +1 reference 126085328eeSLawrence D'Anna // if they succeed or NULL if and only if 127085328eeSLawrence D'Anna // they set an exception. Use this to collect such return 128085328eeSLawrence D'Anna // values, after checking for NULL. 129085328eeSLawrence D'Anna // 130085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be 131085328eeSLawrence D'Anna // checked to be of the correct type. 132085328eeSLawrence D'Anna template <typename T> T Take(PyObject *obj) { 133085328eeSLawrence D'Anna assert(obj); 134085328eeSLawrence D'Anna assert(!PyErr_Occurred()); 135085328eeSLawrence D'Anna T thing(PyRefType::Owned, obj); 136085328eeSLawrence D'Anna assert(thing.IsValid()); 1371dfb1a85SPavel Labath return thing; 138085328eeSLawrence D'Anna } 139085328eeSLawrence D'Anna 140085328eeSLawrence D'Anna // Retain a reference you have borrowed, and turn it into 141085328eeSLawrence D'Anna // a PythonObject. 142085328eeSLawrence D'Anna // 143085328eeSLawrence D'Anna // A minority of python APIs return a borrowed reference 144085328eeSLawrence D'Anna // instead of a +1. They will also return NULL if and only 145085328eeSLawrence D'Anna // if they set an exception. Use this to collect such return 146085328eeSLawrence D'Anna // values, after checking for NULL. 147085328eeSLawrence D'Anna // 148085328eeSLawrence D'Anna // If T is not just PythonObject, then obj must be already be 149085328eeSLawrence D'Anna // checked to be of the correct type. 150085328eeSLawrence D'Anna template <typename T> T Retain(PyObject *obj) { 151085328eeSLawrence D'Anna assert(obj); 152085328eeSLawrence D'Anna assert(!PyErr_Occurred()); 153085328eeSLawrence D'Anna T thing(PyRefType::Borrowed, obj); 154085328eeSLawrence D'Anna assert(thing.IsValid()); 1551dfb1a85SPavel Labath return thing; 156085328eeSLawrence D'Anna } 157085328eeSLawrence D'Anna 158722b6189SLawrence D'Anna // This class can be used like a utility function to convert from 159722b6189SLawrence D'Anna // a llvm-friendly Twine into a null-terminated const char *, 160722b6189SLawrence D'Anna // which is the form python C APIs want their strings in. 161722b6189SLawrence D'Anna // 162722b6189SLawrence D'Anna // Example: 163722b6189SLawrence D'Anna // const llvm::Twine &some_twine; 164722b6189SLawrence D'Anna // PyFoo_Bar(x, y, z, NullTerminated(some_twine)); 165722b6189SLawrence D'Anna // 166722b6189SLawrence D'Anna // Why a class instead of a function? If the twine isn't already null 167722b6189SLawrence D'Anna // terminated, it will need a temporary buffer to copy the string 168722b6189SLawrence D'Anna // into. We need that buffer to stick around for the lifetime of the 169722b6189SLawrence D'Anna // statement. 170722b6189SLawrence D'Anna class NullTerminated { 171722b6189SLawrence D'Anna const char *str; 172722b6189SLawrence D'Anna llvm::SmallString<32> storage; 173722b6189SLawrence D'Anna 174722b6189SLawrence D'Anna public: 175722b6189SLawrence D'Anna NullTerminated(const llvm::Twine &twine) { 176722b6189SLawrence D'Anna llvm::StringRef ref = twine.toNullTerminatedStringRef(storage); 177722b6189SLawrence D'Anna str = ref.begin(); 178722b6189SLawrence D'Anna } 179722b6189SLawrence D'Anna operator const char *() { return str; } 180722b6189SLawrence D'Anna }; 181722b6189SLawrence D'Anna 18204edd189SLawrence D'Anna inline llvm::Error nullDeref() { 18304edd189SLawrence D'Anna return llvm::createStringError(llvm::inconvertibleErrorCode(), 18404edd189SLawrence D'Anna "A NULL PyObject* was dereferenced"); 18504edd189SLawrence D'Anna } 18604edd189SLawrence D'Anna 18704edd189SLawrence D'Anna inline llvm::Error exception(const char *s = nullptr) { 18804edd189SLawrence D'Anna return llvm::make_error<PythonException>(s); 18904edd189SLawrence D'Anna } 19004edd189SLawrence D'Anna 19104edd189SLawrence D'Anna inline llvm::Error keyError() { 19204edd189SLawrence D'Anna return llvm::createStringError(llvm::inconvertibleErrorCode(), 19304edd189SLawrence D'Anna "key not in dict"); 19404edd189SLawrence D'Anna } 195085328eeSLawrence D'Anna 1966a93a12aSLawrence D'Anna #if PY_MAJOR_VERSION < 3 1976a93a12aSLawrence D'Anna // The python 2 API declares some arguments as char* that should 1986a93a12aSLawrence D'Anna // be const char *, but it doesn't actually modify them. 1996a93a12aSLawrence D'Anna inline char *py2_const_cast(const char *s) { return const_cast<char *>(s); } 2006a93a12aSLawrence D'Anna #else 2016a93a12aSLawrence D'Anna inline const char *py2_const_cast(const char *s) { return s; } 2026a93a12aSLawrence D'Anna #endif 2036a93a12aSLawrence D'Anna 204b9c1b51eSKate Stone enum class PyInitialValue { Invalid, Empty }; 205f8b22f8fSZachary Turner 206085328eeSLawrence D'Anna template <typename T, typename Enable = void> struct PythonFormat; 207085328eeSLawrence D'Anna 208085328eeSLawrence D'Anna template <> struct PythonFormat<unsigned long long> { 209085328eeSLawrence D'Anna static constexpr char format = 'K'; 210085328eeSLawrence D'Anna static auto get(unsigned long long value) { return value; } 211085328eeSLawrence D'Anna }; 212085328eeSLawrence D'Anna 213085328eeSLawrence D'Anna template <> struct PythonFormat<long long> { 214085328eeSLawrence D'Anna static constexpr char format = 'L'; 215085328eeSLawrence D'Anna static auto get(long long value) { return value; } 216085328eeSLawrence D'Anna }; 217085328eeSLawrence D'Anna 21804edd189SLawrence D'Anna template <> struct PythonFormat<PyObject *> { 21904edd189SLawrence D'Anna static constexpr char format = 'O'; 22004edd189SLawrence D'Anna static auto get(PyObject *value) { return value; } 22104edd189SLawrence D'Anna }; 22204edd189SLawrence D'Anna 223085328eeSLawrence D'Anna template <typename T> 224085328eeSLawrence D'Anna struct PythonFormat< 225085328eeSLawrence D'Anna T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> { 226085328eeSLawrence D'Anna static constexpr char format = 'O'; 227085328eeSLawrence D'Anna static auto get(const T &value) { return value.get(); } 228085328eeSLawrence D'Anna }; 229085328eeSLawrence D'Anna 230b9c1b51eSKate Stone class PythonObject { 2312c1f46dcSZachary Turner public: 232b9c1b51eSKate Stone PythonObject() : m_py_obj(nullptr) {} 2332c1f46dcSZachary Turner 23404edd189SLawrence D'Anna PythonObject(PyRefType type, PyObject *py_obj) { 23504edd189SLawrence D'Anna m_py_obj = py_obj; 23604edd189SLawrence D'Anna // If this is a borrowed reference, we need to convert it to 23704edd189SLawrence D'Anna // an owned reference by incrementing it. If it is an owned 23804edd189SLawrence D'Anna // reference (for example the caller allocated it with PyDict_New() 23904edd189SLawrence D'Anna // then we must *not* increment it. 24004edd189SLawrence D'Anna if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed) 24104edd189SLawrence D'Anna Py_XINCREF(m_py_obj); 2422c1f46dcSZachary Turner } 2432c1f46dcSZachary Turner 24403819d1cSLawrence D'Anna PythonObject(const PythonObject &rhs) 24503819d1cSLawrence D'Anna : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {} 2462c1f46dcSZachary Turner 247085328eeSLawrence D'Anna PythonObject(PythonObject &&rhs) { 248085328eeSLawrence D'Anna m_py_obj = rhs.m_py_obj; 249085328eeSLawrence D'Anna rhs.m_py_obj = nullptr; 250085328eeSLawrence D'Anna } 251085328eeSLawrence D'Anna 252d3bd5b3dSLawrence D'Anna ~PythonObject() { Reset(); } 2532c1f46dcSZachary Turner 254b9c1b51eSKate Stone void Reset() { 255085328eeSLawrence D'Anna if (m_py_obj && Py_IsInitialized()) 256085328eeSLawrence D'Anna Py_DECREF(m_py_obj); 257f8b22f8fSZachary Turner m_py_obj = nullptr; 2582c1f46dcSZachary Turner } 259f8b22f8fSZachary Turner 260b9c1b51eSKate Stone void Dump() const { 2612c1f46dcSZachary Turner if (m_py_obj) 2622c1f46dcSZachary Turner _PyObject_Dump(m_py_obj); 2632c1f46dcSZachary Turner else 2642c1f46dcSZachary Turner puts("NULL"); 2652c1f46dcSZachary Turner } 2662c1f46dcSZachary Turner 267b9c1b51eSKate Stone void Dump(Stream &strm) const; 2682c1f46dcSZachary Turner 269b9c1b51eSKate Stone PyObject *get() const { return m_py_obj; } 2702c1f46dcSZachary Turner 271b9c1b51eSKate Stone PyObject *release() { 27260c24f70SZachary Turner PyObject *result = m_py_obj; 27360c24f70SZachary Turner m_py_obj = nullptr; 27460c24f70SZachary Turner return result; 27560c24f70SZachary Turner } 27660c24f70SZachary Turner 27703819d1cSLawrence D'Anna PythonObject &operator=(PythonObject other) { 278085328eeSLawrence D'Anna Reset(); 27903819d1cSLawrence D'Anna m_py_obj = std::exchange(other.m_py_obj, nullptr); 280085328eeSLawrence D'Anna return *this; 281085328eeSLawrence D'Anna } 282085328eeSLawrence D'Anna 283b9c1b51eSKate Stone PyObjectType GetObjectType() const; 2847841efbbSZachary Turner 285b9c1b51eSKate Stone PythonString Repr() const; 2867841efbbSZachary Turner 287b9c1b51eSKate Stone PythonString Str() const; 2887841efbbSZachary Turner 289b9c1b51eSKate Stone static PythonObject ResolveNameWithDictionary(llvm::StringRef name, 290b9c1b51eSKate Stone const PythonDictionary &dict); 2917841efbbSZachary Turner 292b58fb2f4SZachary Turner template <typename T> 293b9c1b51eSKate Stone static T ResolveNameWithDictionary(llvm::StringRef name, 294b9c1b51eSKate Stone const PythonDictionary &dict) { 295b58fb2f4SZachary Turner return ResolveNameWithDictionary(name, dict).AsType<T>(); 296b58fb2f4SZachary Turner } 297b58fb2f4SZachary Turner 298b9c1b51eSKate Stone PythonObject ResolveName(llvm::StringRef name) const; 2997841efbbSZachary Turner 300b9c1b51eSKate Stone template <typename T> T ResolveName(llvm::StringRef name) const { 301b58fb2f4SZachary Turner return ResolveName(name).AsType<T>(); 302b58fb2f4SZachary Turner } 303b58fb2f4SZachary Turner 304b9c1b51eSKate Stone bool HasAttribute(llvm::StringRef attribute) const; 3059c40264fSZachary Turner 306b9c1b51eSKate Stone PythonObject GetAttributeValue(llvm::StringRef attribute) const; 3077d6d218eSZachary Turner 308085328eeSLawrence D'Anna bool IsNone() const { return m_py_obj == Py_None; } 309f8b22f8fSZachary Turner 310085328eeSLawrence D'Anna bool IsValid() const { return m_py_obj != nullptr; } 311f8b22f8fSZachary Turner 312085328eeSLawrence D'Anna bool IsAllocated() const { return IsValid() && !IsNone(); } 313085328eeSLawrence D'Anna 314085328eeSLawrence D'Anna explicit operator bool() const { return IsValid() && !IsNone(); } 3152c1f46dcSZachary Turner 316b9c1b51eSKate Stone template <typename T> T AsType() const { 3177d6d218eSZachary Turner if (!T::Check(m_py_obj)) 3187d6d218eSZachary Turner return T(); 3197d6d218eSZachary Turner return T(PyRefType::Borrowed, m_py_obj); 3207d6d218eSZachary Turner } 3217d6d218eSZachary Turner 322b9c1b51eSKate Stone StructuredData::ObjectSP CreateStructuredObject() const; 3232c1f46dcSZachary Turner 324085328eeSLawrence D'Anna public: 325085328eeSLawrence D'Anna template <typename... T> 326085328eeSLawrence D'Anna llvm::Expected<PythonObject> CallMethod(const char *name, 327085328eeSLawrence D'Anna const T &... t) const { 328085328eeSLawrence D'Anna const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 329085328eeSLawrence D'Anna PyObject *obj = 330c86a6acaSLawrence D'Anna PyObject_CallMethod(m_py_obj, py2_const_cast(name), 331c86a6acaSLawrence D'Anna py2_const_cast(format), PythonFormat<T>::get(t)...); 332c86a6acaSLawrence D'Anna if (!obj) 333c86a6acaSLawrence D'Anna return exception(); 334c86a6acaSLawrence D'Anna return python::Take<PythonObject>(obj); 335c86a6acaSLawrence D'Anna } 336c86a6acaSLawrence D'Anna 337c86a6acaSLawrence D'Anna template <typename... T> 338c86a6acaSLawrence D'Anna llvm::Expected<PythonObject> Call(const T &... t) const { 339c86a6acaSLawrence D'Anna const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 340c86a6acaSLawrence D'Anna PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format), 341c86a6acaSLawrence D'Anna PythonFormat<T>::get(t)...); 342085328eeSLawrence D'Anna if (!obj) 343085328eeSLawrence D'Anna return exception(); 344085328eeSLawrence D'Anna return python::Take<PythonObject>(obj); 345085328eeSLawrence D'Anna } 346085328eeSLawrence D'Anna 347722b6189SLawrence D'Anna llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const { 348085328eeSLawrence D'Anna if (!m_py_obj) 349085328eeSLawrence D'Anna return nullDeref(); 350722b6189SLawrence D'Anna PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name)); 351085328eeSLawrence D'Anna if (!obj) 352085328eeSLawrence D'Anna return exception(); 353085328eeSLawrence D'Anna return python::Take<PythonObject>(obj); 354085328eeSLawrence D'Anna } 355085328eeSLawrence D'Anna 356085328eeSLawrence D'Anna llvm::Expected<bool> IsTrue() { 357085328eeSLawrence D'Anna if (!m_py_obj) 358085328eeSLawrence D'Anna return nullDeref(); 359085328eeSLawrence D'Anna int r = PyObject_IsTrue(m_py_obj); 360085328eeSLawrence D'Anna if (r < 0) 361085328eeSLawrence D'Anna return exception(); 362085328eeSLawrence D'Anna return !!r; 363085328eeSLawrence D'Anna } 364085328eeSLawrence D'Anna 36552712d3fSLawrence D'Anna llvm::Expected<long long> AsLongLong() const; 36652712d3fSLawrence D'Anna 36752712d3fSLawrence D'Anna llvm::Expected<long long> AsUnsignedLongLong() const; 36852712d3fSLawrence D'Anna 36952712d3fSLawrence D'Anna // wraps on overflow, instead of raising an error. 37052712d3fSLawrence D'Anna llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const; 371085328eeSLawrence D'Anna 372085328eeSLawrence D'Anna llvm::Expected<bool> IsInstance(const PythonObject &cls) { 373085328eeSLawrence D'Anna if (!m_py_obj || !cls.IsValid()) 374085328eeSLawrence D'Anna return nullDeref(); 375085328eeSLawrence D'Anna int r = PyObject_IsInstance(m_py_obj, cls.get()); 376085328eeSLawrence D'Anna if (r < 0) 377085328eeSLawrence D'Anna return exception(); 378085328eeSLawrence D'Anna return !!r; 379085328eeSLawrence D'Anna } 380085328eeSLawrence D'Anna 381085328eeSLawrence D'Anna protected: 3822c1f46dcSZachary Turner PyObject *m_py_obj; 3832c1f46dcSZachary Turner }; 3842c1f46dcSZachary Turner 385085328eeSLawrence D'Anna 386085328eeSLawrence D'Anna // This is why C++ needs monads. 387085328eeSLawrence D'Anna template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) { 388085328eeSLawrence D'Anna if (!obj) 389085328eeSLawrence D'Anna return obj.takeError(); 390085328eeSLawrence D'Anna if (!T::Check(obj.get().get())) 391085328eeSLawrence D'Anna return llvm::createStringError(llvm::inconvertibleErrorCode(), 392085328eeSLawrence D'Anna "type error"); 393085328eeSLawrence D'Anna return T(PyRefType::Borrowed, std::move(obj.get().get())); 394085328eeSLawrence D'Anna } 395085328eeSLawrence D'Anna 396085328eeSLawrence D'Anna template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj); 397085328eeSLawrence D'Anna 398085328eeSLawrence D'Anna template <> 399085328eeSLawrence D'Anna llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj); 400085328eeSLawrence D'Anna 401c86a6acaSLawrence D'Anna template <> 40252712d3fSLawrence D'Anna llvm::Expected<unsigned long long> 40352712d3fSLawrence D'Anna As<unsigned long long>(llvm::Expected<PythonObject> &&obj); 40452712d3fSLawrence D'Anna 40552712d3fSLawrence D'Anna template <> 406c86a6acaSLawrence D'Anna llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj); 407c86a6acaSLawrence D'Anna 408085328eeSLawrence D'Anna 409d3bd5b3dSLawrence D'Anna template <class T> class TypedPythonObject : public PythonObject { 4105a72c02bSZachary Turner public: 411d3bd5b3dSLawrence D'Anna // override to perform implicit type conversions on Reset 412d3bd5b3dSLawrence D'Anna // This can be eliminated once we drop python 2 support. 413d3bd5b3dSLawrence D'Anna static void Convert(PyRefType &type, PyObject *&py_obj) {} 414d3bd5b3dSLawrence D'Anna 415722b6189SLawrence D'Anna TypedPythonObject(PyRefType type, PyObject *py_obj) { 416d3bd5b3dSLawrence D'Anna if (!py_obj) 417d3bd5b3dSLawrence D'Anna return; 418d3bd5b3dSLawrence D'Anna T::Convert(type, py_obj); 419d3bd5b3dSLawrence D'Anna if (T::Check(py_obj)) 42004edd189SLawrence D'Anna PythonObject::operator=(PythonObject(type, py_obj)); 421d3bd5b3dSLawrence D'Anna else if (type == PyRefType::Owned) 422d3bd5b3dSLawrence D'Anna Py_DECREF(py_obj); 423d3bd5b3dSLawrence D'Anna } 424d3bd5b3dSLawrence D'Anna 425d3bd5b3dSLawrence D'Anna TypedPythonObject() {} 426d3bd5b3dSLawrence D'Anna }; 427d3bd5b3dSLawrence D'Anna 428d3bd5b3dSLawrence D'Anna class PythonBytes : public TypedPythonObject<PythonBytes> { 429d3bd5b3dSLawrence D'Anna public: 430d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 4315a72c02bSZachary Turner explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 4325a72c02bSZachary Turner PythonBytes(const uint8_t *bytes, size_t length); 4335a72c02bSZachary Turner 434b9c1b51eSKate Stone static bool Check(PyObject *py_obj); 4355a72c02bSZachary Turner 436b9c1b51eSKate Stone llvm::ArrayRef<uint8_t> GetBytes() const; 4375a72c02bSZachary Turner 438b9c1b51eSKate Stone size_t GetSize() const; 4395a72c02bSZachary Turner 440b9c1b51eSKate Stone void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 4415a72c02bSZachary Turner 442b9c1b51eSKate Stone StructuredData::StringSP CreateStructuredString() const; 4435a72c02bSZachary Turner }; 4445a72c02bSZachary Turner 445d3bd5b3dSLawrence D'Anna class PythonByteArray : public TypedPythonObject<PythonByteArray> { 446f9d6d204SZachary Turner public: 447d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 448f9d6d204SZachary Turner explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 449f9d6d204SZachary Turner PythonByteArray(const uint8_t *bytes, size_t length); 450f9d6d204SZachary Turner PythonByteArray(const PythonBytes &object); 451f9d6d204SZachary Turner 452b9c1b51eSKate Stone static bool Check(PyObject *py_obj); 453f9d6d204SZachary Turner 454b9c1b51eSKate Stone llvm::ArrayRef<uint8_t> GetBytes() const; 455f9d6d204SZachary Turner 456b9c1b51eSKate Stone size_t GetSize() const; 457f9d6d204SZachary Turner 458b9c1b51eSKate Stone void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 459f9d6d204SZachary Turner 460b9c1b51eSKate Stone StructuredData::StringSP CreateStructuredString() const; 461f9d6d204SZachary Turner }; 462f9d6d204SZachary Turner 463d3bd5b3dSLawrence D'Anna class PythonString : public TypedPythonObject<PythonString> { 4642c1f46dcSZachary Turner public: 465d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 466085328eeSLawrence D'Anna static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string); 467085328eeSLawrence D'Anna 468d3bd5b3dSLawrence D'Anna PythonString() : TypedPythonObject() {} // MSVC requires this for some reason 469edb35d95SEugene Zelenko 470d3bd5b3dSLawrence D'Anna explicit PythonString(llvm::StringRef string); // safe, null on error 4712c1f46dcSZachary Turner 47222c8efcdSZachary Turner static bool Check(PyObject *py_obj); 473d3bd5b3dSLawrence D'Anna static void Convert(PyRefType &type, PyObject *&py_obj); 4742c1f46dcSZachary Turner 475085328eeSLawrence D'Anna llvm::StringRef GetString() const; // safe, empty string on error 476085328eeSLawrence D'Anna 477085328eeSLawrence D'Anna llvm::Expected<llvm::StringRef> AsUTF8() const; 4782c1f46dcSZachary Turner 479b9c1b51eSKate Stone size_t GetSize() const; 4802c1f46dcSZachary Turner 481085328eeSLawrence D'Anna void SetString(llvm::StringRef string); // safe, null on error 4822c1f46dcSZachary Turner 4832c1f46dcSZachary Turner StructuredData::StringSP CreateStructuredString() const; 4842c1f46dcSZachary Turner }; 4852c1f46dcSZachary Turner 486d3bd5b3dSLawrence D'Anna class PythonInteger : public TypedPythonObject<PythonInteger> { 4872c1f46dcSZachary Turner public: 488d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 489edb35d95SEugene Zelenko 490d3bd5b3dSLawrence D'Anna PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason 491d3bd5b3dSLawrence D'Anna 492d3bd5b3dSLawrence D'Anna explicit PythonInteger(int64_t value); 4932c1f46dcSZachary Turner 49422c8efcdSZachary Turner static bool Check(PyObject *py_obj); 495d3bd5b3dSLawrence D'Anna static void Convert(PyRefType &type, PyObject *&py_obj); 4962c1f46dcSZachary Turner 497b9c1b51eSKate Stone void SetInteger(int64_t value); 4982c1f46dcSZachary Turner 4992c1f46dcSZachary Turner StructuredData::IntegerSP CreateStructuredInteger() const; 5002c1f46dcSZachary Turner }; 5012c1f46dcSZachary Turner 502d3bd5b3dSLawrence D'Anna class PythonBoolean : public TypedPythonObject<PythonBoolean> { 503b81d715cSTatyana Krasnukha public: 504d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 505b81d715cSTatyana Krasnukha 506d3bd5b3dSLawrence D'Anna explicit PythonBoolean(bool value); 507b81d715cSTatyana Krasnukha 508b81d715cSTatyana Krasnukha static bool Check(PyObject *py_obj); 509b81d715cSTatyana Krasnukha 510b81d715cSTatyana Krasnukha bool GetValue() const; 511b81d715cSTatyana Krasnukha 512b81d715cSTatyana Krasnukha void SetValue(bool value); 513b81d715cSTatyana Krasnukha 514b81d715cSTatyana Krasnukha StructuredData::BooleanSP CreateStructuredBoolean() const; 515b81d715cSTatyana Krasnukha }; 516b81d715cSTatyana Krasnukha 517d3bd5b3dSLawrence D'Anna class PythonList : public TypedPythonObject<PythonList> { 5182c1f46dcSZachary Turner public: 519d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 520d3bd5b3dSLawrence D'Anna 521d3bd5b3dSLawrence D'Anna PythonList() : TypedPythonObject() {} // MSVC requires this for some reason 522d3bd5b3dSLawrence D'Anna 52387f47729SZachary Turner explicit PythonList(PyInitialValue value); 52487f47729SZachary Turner explicit PythonList(int list_size); 5252c1f46dcSZachary Turner 52622c8efcdSZachary Turner static bool Check(PyObject *py_obj); 52722c8efcdSZachary Turner 5282c1f46dcSZachary Turner uint32_t GetSize() const; 5292c1f46dcSZachary Turner 5302c1f46dcSZachary Turner PythonObject GetItemAtIndex(uint32_t index) const; 5312c1f46dcSZachary Turner 532f8b22f8fSZachary Turner void SetItemAtIndex(uint32_t index, const PythonObject &object); 5332c1f46dcSZachary Turner 534f8b22f8fSZachary Turner void AppendItem(const PythonObject &object); 5352c1f46dcSZachary Turner 5362c1f46dcSZachary Turner StructuredData::ArraySP CreateStructuredArray() const; 5372c1f46dcSZachary Turner }; 5382c1f46dcSZachary Turner 539d3bd5b3dSLawrence D'Anna class PythonTuple : public TypedPythonObject<PythonTuple> { 540a1405147SZachary Turner public: 541d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 542d3bd5b3dSLawrence D'Anna 543a1405147SZachary Turner explicit PythonTuple(PyInitialValue value); 544a1405147SZachary Turner explicit PythonTuple(int tuple_size); 545a1405147SZachary Turner PythonTuple(std::initializer_list<PythonObject> objects); 546a1405147SZachary Turner PythonTuple(std::initializer_list<PyObject *> objects); 547a1405147SZachary Turner 548a1405147SZachary Turner static bool Check(PyObject *py_obj); 549a1405147SZachary Turner 550a1405147SZachary Turner uint32_t GetSize() const; 551a1405147SZachary Turner 552a1405147SZachary Turner PythonObject GetItemAtIndex(uint32_t index) const; 553a1405147SZachary Turner 554a1405147SZachary Turner void SetItemAtIndex(uint32_t index, const PythonObject &object); 555a1405147SZachary Turner 556a1405147SZachary Turner StructuredData::ArraySP CreateStructuredArray() const; 557a1405147SZachary Turner }; 558a1405147SZachary Turner 559d3bd5b3dSLawrence D'Anna class PythonDictionary : public TypedPythonObject<PythonDictionary> { 5602c1f46dcSZachary Turner public: 561d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 562edb35d95SEugene Zelenko 563d3bd5b3dSLawrence D'Anna PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason 564d3bd5b3dSLawrence D'Anna 565d3bd5b3dSLawrence D'Anna explicit PythonDictionary(PyInitialValue value); 5662c1f46dcSZachary Turner 56722c8efcdSZachary Turner static bool Check(PyObject *py_obj); 56822c8efcdSZachary Turner 5692c1f46dcSZachary Turner uint32_t GetSize() const; 5702c1f46dcSZachary Turner 571f8b22f8fSZachary Turner PythonList GetKeys() const; 5722c1f46dcSZachary Turner 573c86a6acaSLawrence D'Anna PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED 574c86a6acaSLawrence D'Anna void SetItemForKey(const PythonObject &key, 575c86a6acaSLawrence D'Anna const PythonObject &value); // DEPRECATED 576c86a6acaSLawrence D'Anna 577c86a6acaSLawrence D'Anna llvm::Expected<PythonObject> GetItem(const PythonObject &key) const; 578722b6189SLawrence D'Anna llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const; 579c86a6acaSLawrence D'Anna llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const; 580722b6189SLawrence D'Anna llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const; 5812c1f46dcSZachary Turner 5822c1f46dcSZachary Turner StructuredData::DictionarySP CreateStructuredDictionary() const; 5832c1f46dcSZachary Turner }; 58487f47729SZachary Turner 585d3bd5b3dSLawrence D'Anna class PythonModule : public TypedPythonObject<PythonModule> { 5867841efbbSZachary Turner public: 587d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 5887841efbbSZachary Turner 5897841efbbSZachary Turner static bool Check(PyObject *py_obj); 5907841efbbSZachary Turner 591b9c1b51eSKate Stone static PythonModule BuiltinsModule(); 592a1405147SZachary Turner 593b9c1b51eSKate Stone static PythonModule MainModule(); 594a1405147SZachary Turner 595b9c1b51eSKate Stone static PythonModule AddModule(llvm::StringRef module); 5967841efbbSZachary Turner 597085328eeSLawrence D'Anna // safe, returns invalid on error; 598085328eeSLawrence D'Anna static PythonModule ImportModule(llvm::StringRef name) { 599adcd0268SBenjamin Kramer std::string s = std::string(name); 600085328eeSLawrence D'Anna auto mod = Import(s.c_str()); 601085328eeSLawrence D'Anna if (!mod) { 602085328eeSLawrence D'Anna llvm::consumeError(mod.takeError()); 603085328eeSLawrence D'Anna return PythonModule(); 604085328eeSLawrence D'Anna } 605085328eeSLawrence D'Anna return std::move(mod.get()); 606085328eeSLawrence D'Anna } 607085328eeSLawrence D'Anna 608722b6189SLawrence D'Anna static llvm::Expected<PythonModule> Import(const llvm::Twine &name); 609085328eeSLawrence D'Anna 610722b6189SLawrence D'Anna llvm::Expected<PythonObject> Get(const llvm::Twine &name); 6112419f1d5SZachary Turner 6127841efbbSZachary Turner PythonDictionary GetDictionary() const; 6137841efbbSZachary Turner }; 6147841efbbSZachary Turner 615d3bd5b3dSLawrence D'Anna class PythonCallable : public TypedPythonObject<PythonCallable> { 616a1405147SZachary Turner public: 617d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 618d3bd5b3dSLawrence D'Anna 619b58fb2f4SZachary Turner struct ArgInfo { 6202386537cSLawrence D'Anna /* the largest number of positional arguments this callable 6212386537cSLawrence D'Anna * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs 6222386537cSLawrence D'Anna * function and can accept an arbitrary number */ 6232386537cSLawrence D'Anna unsigned max_positional_args; 6242386537cSLawrence D'Anna static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline 625b58fb2f4SZachary Turner }; 626b58fb2f4SZachary Turner 627b9c1b51eSKate Stone static bool Check(PyObject *py_obj); 628a1405147SZachary Turner 629c86a6acaSLawrence D'Anna llvm::Expected<ArgInfo> GetArgInfo() const; 630c86a6acaSLawrence D'Anna 631b9c1b51eSKate Stone PythonObject operator()(); 632a1405147SZachary Turner 633b9c1b51eSKate Stone PythonObject operator()(std::initializer_list<PyObject *> args); 634a1405147SZachary Turner 635b9c1b51eSKate Stone PythonObject operator()(std::initializer_list<PythonObject> args); 636b58fb2f4SZachary Turner 637b58fb2f4SZachary Turner template <typename Arg, typename... Args> 638b9c1b51eSKate Stone PythonObject operator()(const Arg &arg, Args... args) { 639b58fb2f4SZachary Turner return operator()({arg, args...}); 640b58fb2f4SZachary Turner } 641a1405147SZachary Turner }; 642a1405147SZachary Turner 643d3bd5b3dSLawrence D'Anna class PythonFile : public TypedPythonObject<PythonFile> { 6449c40264fSZachary Turner public: 645d3bd5b3dSLawrence D'Anna using TypedPythonObject::TypedPythonObject; 646edb35d95SEugene Zelenko 647d3bd5b3dSLawrence D'Anna PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason 6489c40264fSZachary Turner 6499c40264fSZachary Turner static bool Check(PyObject *py_obj); 6509c40264fSZachary Turner 651d9b553ecSLawrence D'Anna static llvm::Expected<PythonFile> FromFile(File &file, 652d9b553ecSLawrence D'Anna const char *mode = nullptr); 653d9b553ecSLawrence D'Anna 654085328eeSLawrence D'Anna llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false); 655085328eeSLawrence D'Anna llvm::Expected<lldb::FileSP> 656085328eeSLawrence D'Anna ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false); 6579c40264fSZachary Turner }; 6589c40264fSZachary Turner 659085328eeSLawrence D'Anna class PythonException : public llvm::ErrorInfo<PythonException> { 660085328eeSLawrence D'Anna private: 661085328eeSLawrence D'Anna PyObject *m_exception_type, *m_exception, *m_traceback; 662085328eeSLawrence D'Anna PyObject *m_repr_bytes; 663085328eeSLawrence D'Anna 664085328eeSLawrence D'Anna public: 665085328eeSLawrence D'Anna static char ID; 666085328eeSLawrence D'Anna const char *toCString() const; 667085328eeSLawrence D'Anna PythonException(const char *caller = nullptr); 668085328eeSLawrence D'Anna void Restore(); 669085328eeSLawrence D'Anna ~PythonException(); 670085328eeSLawrence D'Anna void log(llvm::raw_ostream &OS) const override; 671085328eeSLawrence D'Anna std::error_code convertToErrorCode() const override; 67204edd189SLawrence D'Anna bool Matches(PyObject *exc) const; 67304edd189SLawrence D'Anna std::string ReadBacktrace() const; 674085328eeSLawrence D'Anna }; 675085328eeSLawrence D'Anna 676085328eeSLawrence D'Anna // This extracts the underlying T out of an Expected<T> and returns it. 677085328eeSLawrence D'Anna // If the Expected is an Error instead of a T, that error will be converted 678085328eeSLawrence D'Anna // into a python exception, and this will return a default-constructed T. 679085328eeSLawrence D'Anna // 680085328eeSLawrence D'Anna // This is appropriate for use right at the boundary of python calling into 681085328eeSLawrence D'Anna // C++, such as in a SWIG typemap. In such a context you should simply 682085328eeSLawrence D'Anna // check if the returned T is valid, and if it is, return a NULL back 683085328eeSLawrence D'Anna // to python. This will result in the Error being raised as an exception 684085328eeSLawrence D'Anna // from python code's point of view. 685085328eeSLawrence D'Anna // 686085328eeSLawrence D'Anna // For example: 687085328eeSLawrence D'Anna // ``` 688085328eeSLawrence D'Anna // Expected<Foo *> efoop = some_cpp_function(); 689085328eeSLawrence D'Anna // Foo *foop = unwrapOrSetPythonException(efoop); 690085328eeSLawrence D'Anna // if (!foop) 691085328eeSLawrence D'Anna // return NULL; 692085328eeSLawrence D'Anna // do_something(*foop); 693085328eeSLawrence D'Anna // 694085328eeSLawrence D'Anna // If the Error returned was itself created because a python exception was 695085328eeSLawrence D'Anna // raised when C++ code called into python, then the original exception 696085328eeSLawrence D'Anna // will be restored. Otherwise a simple string exception will be raised. 697085328eeSLawrence D'Anna template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) { 698085328eeSLawrence D'Anna if (expected) 699085328eeSLawrence D'Anna return expected.get(); 700085328eeSLawrence D'Anna llvm::handleAllErrors( 701085328eeSLawrence D'Anna expected.takeError(), [](PythonException &E) { E.Restore(); }, 702085328eeSLawrence D'Anna [](const llvm::ErrorInfoBase &E) { 703085328eeSLawrence D'Anna PyErr_SetString(PyExc_Exception, E.message().c_str()); 704085328eeSLawrence D'Anna }); 705085328eeSLawrence D'Anna return T(); 706085328eeSLawrence D'Anna } 707085328eeSLawrence D'Anna 708722b6189SLawrence D'Anna // This is only here to help incrementally migrate old, exception-unsafe 709722b6189SLawrence D'Anna // code. 710722b6189SLawrence D'Anna template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) { 711722b6189SLawrence D'Anna if (expected) 712722b6189SLawrence D'Anna return std::move(expected.get()); 713722b6189SLawrence D'Anna llvm::consumeError(expected.takeError()); 714722b6189SLawrence D'Anna return T(); 715722b6189SLawrence D'Anna } 716722b6189SLawrence D'Anna 71704edd189SLawrence D'Anna llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string, 71804edd189SLawrence D'Anna const PythonDictionary &globals, 71904edd189SLawrence D'Anna const PythonDictionary &locals); 72004edd189SLawrence D'Anna 72104edd189SLawrence D'Anna llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string, 72204edd189SLawrence D'Anna const PythonDictionary &globals, 72304edd189SLawrence D'Anna const PythonDictionary &locals); 72404edd189SLawrence D'Anna 72504edd189SLawrence D'Anna // Sometimes the best way to interact with a python interpreter is 72604edd189SLawrence D'Anna // to run some python code. You construct a PythonScript with 72704edd189SLawrence D'Anna // script string. The script assigns some function to `_function_` 72804edd189SLawrence D'Anna // and you get a C++ callable object that calls the python function. 72904edd189SLawrence D'Anna // 73004edd189SLawrence D'Anna // Example: 73104edd189SLawrence D'Anna // 73204edd189SLawrence D'Anna // const char script[] = R"( 73304edd189SLawrence D'Anna // def main(x, y): 73404edd189SLawrence D'Anna // .... 73504edd189SLawrence D'Anna // )"; 73604edd189SLawrence D'Anna // 73704edd189SLawrence D'Anna // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) { 73804edd189SLawrence D'Anna // // no need to synchronize access to this global, we already have the GIL 73904edd189SLawrence D'Anna // static PythonScript foo(script) 74004edd189SLawrence D'Anna // return foo(x, y); 74104edd189SLawrence D'Anna // } 74204edd189SLawrence D'Anna class PythonScript { 74304edd189SLawrence D'Anna const char *script; 74404edd189SLawrence D'Anna PythonCallable function; 74504edd189SLawrence D'Anna 74604edd189SLawrence D'Anna llvm::Error Init(); 74704edd189SLawrence D'Anna 74804edd189SLawrence D'Anna public: 74904edd189SLawrence D'Anna PythonScript(const char *script) : script(script), function() {} 75004edd189SLawrence D'Anna 75104edd189SLawrence D'Anna template <typename... Args> 75204edd189SLawrence D'Anna llvm::Expected<PythonObject> operator()(Args &&... args) { 75304edd189SLawrence D'Anna if (llvm::Error error = Init()) 75404edd189SLawrence D'Anna return std::move(error); 75504edd189SLawrence D'Anna return function.Call(std::forward<Args>(args)...); 75604edd189SLawrence D'Anna } 75704edd189SLawrence D'Anna }; 75804edd189SLawrence D'Anna 75904edd189SLawrence D'Anna } // namespace python 7602c1f46dcSZachary Turner } // namespace lldb_private 7612c1f46dcSZachary Turner 762a281b42bSZachary Turner #endif 763d68983e3SPavel Labath 764d68983e3SPavel Labath #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 765