1061da546Spatrick //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===// 2061da546Spatrick // 3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information. 5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6061da546Spatrick // 7061da546Spatrick //===----------------------------------------------------------------------===// 8061da546Spatrick 9061da546Spatrick // 10061da546Spatrick // !! FIXME FIXME FIXME !! 11061da546Spatrick // 12061da546Spatrick // Python APIs nearly all can return an exception. They do this 13061da546Spatrick // by returning NULL, or -1, or some such value and setting 14061da546Spatrick // the exception state with PyErr_Set*(). Exceptions must be 15061da546Spatrick // handled before further python API functions are called. Failure 16061da546Spatrick // to do so will result in asserts on debug builds of python. 17061da546Spatrick // It will also sometimes, but not usually result in crashes of 18061da546Spatrick // release builds. 19061da546Spatrick // 20061da546Spatrick // Nearly all the code in this header does not handle python exceptions 21061da546Spatrick // correctly. It should all be converted to return Expected<> or 22061da546Spatrick // Error types to capture the exception. 23061da546Spatrick // 24061da546Spatrick // Everything in this file except functions that return Error or 25061da546Spatrick // Expected<> is considered deprecated and should not be 26061da546Spatrick // used in new code. If you need to use it, fix it first. 27061da546Spatrick // 28061da546Spatrick // 29061da546Spatrick // TODOs for this file 30061da546Spatrick // 31061da546Spatrick // * Make all methods safe for exceptions. 32061da546Spatrick // 33061da546Spatrick // * Eliminate method signatures that must translate exceptions into 34061da546Spatrick // empty objects or NULLs. Almost everything here should return 35061da546Spatrick // Expected<>. It should be acceptable for certain operations that 36061da546Spatrick // can never fail to assert instead, such as the creation of 37061da546Spatrick // PythonString from a string literal. 38061da546Spatrick // 39dda28197Spatrick // * Eliminate Reset(), and make all non-default constructors private. 40061da546Spatrick // Python objects should be created with Retain<> or Take<>, and they 41061da546Spatrick // should be assigned with operator= 42061da546Spatrick // 43061da546Spatrick // * Eliminate default constructors, make python objects always 44061da546Spatrick // nonnull, and use optionals where necessary. 45061da546Spatrick // 46061da546Spatrick 47061da546Spatrick 48061da546Spatrick #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 49061da546Spatrick #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 50061da546Spatrick 51061da546Spatrick #include "lldb/Host/Config.h" 52061da546Spatrick 53061da546Spatrick #if LLDB_ENABLE_PYTHON 54061da546Spatrick 55061da546Spatrick // LLDB Python header must be included first 56061da546Spatrick #include "lldb-python.h" 57061da546Spatrick 58061da546Spatrick #include "lldb/Host/File.h" 59061da546Spatrick #include "lldb/Utility/StructuredData.h" 60061da546Spatrick 61061da546Spatrick #include "llvm/ADT/ArrayRef.h" 62061da546Spatrick 63061da546Spatrick namespace lldb_private { 64061da546Spatrick namespace python { 65061da546Spatrick 66061da546Spatrick class PythonObject; 67061da546Spatrick class PythonBytes; 68061da546Spatrick class PythonString; 69061da546Spatrick class PythonList; 70061da546Spatrick class PythonDictionary; 71061da546Spatrick class PythonInteger; 72061da546Spatrick class PythonException; 73061da546Spatrick 74061da546Spatrick class StructuredPythonObject : public StructuredData::Generic { 75061da546Spatrick public: 76061da546Spatrick StructuredPythonObject() : StructuredData::Generic() {} 77061da546Spatrick 78061da546Spatrick StructuredPythonObject(void *obj) : StructuredData::Generic(obj) { 79061da546Spatrick Py_XINCREF(GetValue()); 80061da546Spatrick } 81061da546Spatrick 82061da546Spatrick ~StructuredPythonObject() override { 83061da546Spatrick if (Py_IsInitialized()) 84061da546Spatrick Py_XDECREF(GetValue()); 85061da546Spatrick SetValue(nullptr); 86061da546Spatrick } 87061da546Spatrick 88061da546Spatrick bool IsValid() const override { return GetValue() && GetValue() != Py_None; } 89061da546Spatrick 90061da546Spatrick void Serialize(llvm::json::OStream &s) const override; 91061da546Spatrick 92061da546Spatrick private: 93dda28197Spatrick StructuredPythonObject(const StructuredPythonObject &) = delete; 94dda28197Spatrick const StructuredPythonObject & 95dda28197Spatrick operator=(const StructuredPythonObject &) = delete; 96061da546Spatrick }; 97061da546Spatrick 98061da546Spatrick enum class PyObjectType { 99061da546Spatrick Unknown, 100061da546Spatrick None, 101061da546Spatrick Boolean, 102061da546Spatrick Integer, 103061da546Spatrick Dictionary, 104061da546Spatrick List, 105061da546Spatrick String, 106061da546Spatrick Bytes, 107061da546Spatrick ByteArray, 108061da546Spatrick Module, 109061da546Spatrick Callable, 110061da546Spatrick Tuple, 111061da546Spatrick File 112061da546Spatrick }; 113061da546Spatrick 114061da546Spatrick enum class PyRefType { 115061da546Spatrick Borrowed, // We are not given ownership of the incoming PyObject. 116061da546Spatrick // We cannot safely hold it without calling Py_INCREF. 117061da546Spatrick Owned // We have ownership of the incoming PyObject. We should 118061da546Spatrick // not call Py_INCREF. 119061da546Spatrick }; 120061da546Spatrick 121061da546Spatrick 122061da546Spatrick // Take a reference that you already own, and turn it into 123061da546Spatrick // a PythonObject. 124061da546Spatrick // 125061da546Spatrick // Most python API methods will return a +1 reference 126061da546Spatrick // if they succeed or NULL if and only if 127061da546Spatrick // they set an exception. Use this to collect such return 128061da546Spatrick // values, after checking for NULL. 129061da546Spatrick // 130061da546Spatrick // If T is not just PythonObject, then obj must be already be 131061da546Spatrick // checked to be of the correct type. 132061da546Spatrick template <typename T> T Take(PyObject *obj) { 133061da546Spatrick assert(obj); 134061da546Spatrick assert(!PyErr_Occurred()); 135061da546Spatrick T thing(PyRefType::Owned, obj); 136061da546Spatrick assert(thing.IsValid()); 137061da546Spatrick return thing; 138061da546Spatrick } 139061da546Spatrick 140061da546Spatrick // Retain a reference you have borrowed, and turn it into 141061da546Spatrick // a PythonObject. 142061da546Spatrick // 143061da546Spatrick // A minority of python APIs return a borrowed reference 144061da546Spatrick // instead of a +1. They will also return NULL if and only 145061da546Spatrick // if they set an exception. Use this to collect such return 146061da546Spatrick // values, after checking for NULL. 147061da546Spatrick // 148061da546Spatrick // If T is not just PythonObject, then obj must be already be 149061da546Spatrick // checked to be of the correct type. 150061da546Spatrick template <typename T> T Retain(PyObject *obj) { 151061da546Spatrick assert(obj); 152061da546Spatrick assert(!PyErr_Occurred()); 153061da546Spatrick T thing(PyRefType::Borrowed, obj); 154061da546Spatrick assert(thing.IsValid()); 155061da546Spatrick return thing; 156061da546Spatrick } 157061da546Spatrick 158061da546Spatrick // This class can be used like a utility function to convert from 159061da546Spatrick // a llvm-friendly Twine into a null-terminated const char *, 160061da546Spatrick // which is the form python C APIs want their strings in. 161061da546Spatrick // 162061da546Spatrick // Example: 163061da546Spatrick // const llvm::Twine &some_twine; 164061da546Spatrick // PyFoo_Bar(x, y, z, NullTerminated(some_twine)); 165061da546Spatrick // 166061da546Spatrick // Why a class instead of a function? If the twine isn't already null 167061da546Spatrick // terminated, it will need a temporary buffer to copy the string 168061da546Spatrick // into. We need that buffer to stick around for the lifetime of the 169061da546Spatrick // statement. 170061da546Spatrick class NullTerminated { 171061da546Spatrick const char *str; 172061da546Spatrick llvm::SmallString<32> storage; 173061da546Spatrick 174061da546Spatrick public: 175061da546Spatrick NullTerminated(const llvm::Twine &twine) { 176061da546Spatrick llvm::StringRef ref = twine.toNullTerminatedStringRef(storage); 177061da546Spatrick str = ref.begin(); 178061da546Spatrick } 179061da546Spatrick operator const char *() { return str; } 180061da546Spatrick }; 181061da546Spatrick 182061da546Spatrick inline llvm::Error nullDeref() { 183061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 184061da546Spatrick "A NULL PyObject* was dereferenced"); 185061da546Spatrick } 186061da546Spatrick 187061da546Spatrick inline llvm::Error exception(const char *s = nullptr) { 188061da546Spatrick return llvm::make_error<PythonException>(s); 189061da546Spatrick } 190061da546Spatrick 191061da546Spatrick inline llvm::Error keyError() { 192061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 193061da546Spatrick "key not in dict"); 194061da546Spatrick } 195061da546Spatrick 196061da546Spatrick #if PY_MAJOR_VERSION < 3 197061da546Spatrick // The python 2 API declares some arguments as char* that should 198061da546Spatrick // be const char *, but it doesn't actually modify them. 199061da546Spatrick inline char *py2_const_cast(const char *s) { return const_cast<char *>(s); } 200061da546Spatrick #else 201061da546Spatrick inline const char *py2_const_cast(const char *s) { return s; } 202061da546Spatrick #endif 203061da546Spatrick 204061da546Spatrick enum class PyInitialValue { Invalid, Empty }; 205061da546Spatrick 206061da546Spatrick template <typename T, typename Enable = void> struct PythonFormat; 207061da546Spatrick 208061da546Spatrick template <> struct PythonFormat<unsigned long long> { 209061da546Spatrick static constexpr char format = 'K'; 210061da546Spatrick static auto get(unsigned long long value) { return value; } 211061da546Spatrick }; 212061da546Spatrick 213061da546Spatrick template <> struct PythonFormat<long long> { 214061da546Spatrick static constexpr char format = 'L'; 215061da546Spatrick static auto get(long long value) { return value; } 216061da546Spatrick }; 217061da546Spatrick 218061da546Spatrick template <> struct PythonFormat<PyObject *> { 219061da546Spatrick static constexpr char format = 'O'; 220061da546Spatrick static auto get(PyObject *value) { return value; } 221061da546Spatrick }; 222061da546Spatrick 223061da546Spatrick template <typename T> 224061da546Spatrick struct PythonFormat< 225061da546Spatrick T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> { 226061da546Spatrick static constexpr char format = 'O'; 227061da546Spatrick static auto get(const T &value) { return value.get(); } 228061da546Spatrick }; 229061da546Spatrick 230061da546Spatrick class PythonObject { 231061da546Spatrick public: 232*be691f3bSpatrick PythonObject() = default; 233061da546Spatrick 234061da546Spatrick PythonObject(PyRefType type, PyObject *py_obj) { 235061da546Spatrick m_py_obj = py_obj; 236061da546Spatrick // If this is a borrowed reference, we need to convert it to 237061da546Spatrick // an owned reference by incrementing it. If it is an owned 238061da546Spatrick // reference (for example the caller allocated it with PyDict_New() 239061da546Spatrick // then we must *not* increment it. 240061da546Spatrick if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed) 241061da546Spatrick Py_XINCREF(m_py_obj); 242061da546Spatrick } 243061da546Spatrick 244061da546Spatrick PythonObject(const PythonObject &rhs) 245061da546Spatrick : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {} 246061da546Spatrick 247061da546Spatrick PythonObject(PythonObject &&rhs) { 248061da546Spatrick m_py_obj = rhs.m_py_obj; 249061da546Spatrick rhs.m_py_obj = nullptr; 250061da546Spatrick } 251061da546Spatrick 252061da546Spatrick ~PythonObject() { Reset(); } 253061da546Spatrick 254061da546Spatrick void Reset() { 255061da546Spatrick if (m_py_obj && Py_IsInitialized()) 256061da546Spatrick Py_DECREF(m_py_obj); 257061da546Spatrick m_py_obj = nullptr; 258061da546Spatrick } 259061da546Spatrick 260061da546Spatrick void Dump() const { 261061da546Spatrick if (m_py_obj) 262061da546Spatrick _PyObject_Dump(m_py_obj); 263061da546Spatrick else 264061da546Spatrick puts("NULL"); 265061da546Spatrick } 266061da546Spatrick 267061da546Spatrick void Dump(Stream &strm) const; 268061da546Spatrick 269061da546Spatrick PyObject *get() const { return m_py_obj; } 270061da546Spatrick 271061da546Spatrick PyObject *release() { 272061da546Spatrick PyObject *result = m_py_obj; 273061da546Spatrick m_py_obj = nullptr; 274061da546Spatrick return result; 275061da546Spatrick } 276061da546Spatrick 277061da546Spatrick PythonObject &operator=(PythonObject other) { 278061da546Spatrick Reset(); 279061da546Spatrick m_py_obj = std::exchange(other.m_py_obj, nullptr); 280061da546Spatrick return *this; 281061da546Spatrick } 282061da546Spatrick 283061da546Spatrick PyObjectType GetObjectType() const; 284061da546Spatrick 285061da546Spatrick PythonString Repr() const; 286061da546Spatrick 287061da546Spatrick PythonString Str() const; 288061da546Spatrick 289061da546Spatrick static PythonObject ResolveNameWithDictionary(llvm::StringRef name, 290061da546Spatrick const PythonDictionary &dict); 291061da546Spatrick 292061da546Spatrick template <typename T> 293061da546Spatrick static T ResolveNameWithDictionary(llvm::StringRef name, 294061da546Spatrick const PythonDictionary &dict) { 295061da546Spatrick return ResolveNameWithDictionary(name, dict).AsType<T>(); 296061da546Spatrick } 297061da546Spatrick 298061da546Spatrick PythonObject ResolveName(llvm::StringRef name) const; 299061da546Spatrick 300061da546Spatrick template <typename T> T ResolveName(llvm::StringRef name) const { 301061da546Spatrick return ResolveName(name).AsType<T>(); 302061da546Spatrick } 303061da546Spatrick 304061da546Spatrick bool HasAttribute(llvm::StringRef attribute) const; 305061da546Spatrick 306061da546Spatrick PythonObject GetAttributeValue(llvm::StringRef attribute) const; 307061da546Spatrick 308061da546Spatrick bool IsNone() const { return m_py_obj == Py_None; } 309061da546Spatrick 310061da546Spatrick bool IsValid() const { return m_py_obj != nullptr; } 311061da546Spatrick 312061da546Spatrick bool IsAllocated() const { return IsValid() && !IsNone(); } 313061da546Spatrick 314061da546Spatrick explicit operator bool() const { return IsValid() && !IsNone(); } 315061da546Spatrick 316061da546Spatrick template <typename T> T AsType() const { 317061da546Spatrick if (!T::Check(m_py_obj)) 318061da546Spatrick return T(); 319061da546Spatrick return T(PyRefType::Borrowed, m_py_obj); 320061da546Spatrick } 321061da546Spatrick 322061da546Spatrick StructuredData::ObjectSP CreateStructuredObject() const; 323061da546Spatrick 324061da546Spatrick template <typename... T> 325061da546Spatrick llvm::Expected<PythonObject> CallMethod(const char *name, 326061da546Spatrick const T &... t) const { 327061da546Spatrick const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 328061da546Spatrick PyObject *obj = 329061da546Spatrick PyObject_CallMethod(m_py_obj, py2_const_cast(name), 330061da546Spatrick py2_const_cast(format), PythonFormat<T>::get(t)...); 331061da546Spatrick if (!obj) 332061da546Spatrick return exception(); 333061da546Spatrick return python::Take<PythonObject>(obj); 334061da546Spatrick } 335061da546Spatrick 336061da546Spatrick template <typename... T> 337061da546Spatrick llvm::Expected<PythonObject> Call(const T &... t) const { 338061da546Spatrick const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 339061da546Spatrick PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format), 340061da546Spatrick PythonFormat<T>::get(t)...); 341061da546Spatrick if (!obj) 342061da546Spatrick return exception(); 343061da546Spatrick return python::Take<PythonObject>(obj); 344061da546Spatrick } 345061da546Spatrick 346061da546Spatrick llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const { 347061da546Spatrick if (!m_py_obj) 348061da546Spatrick return nullDeref(); 349061da546Spatrick PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name)); 350061da546Spatrick if (!obj) 351061da546Spatrick return exception(); 352061da546Spatrick return python::Take<PythonObject>(obj); 353061da546Spatrick } 354061da546Spatrick 355061da546Spatrick llvm::Expected<bool> IsTrue() { 356061da546Spatrick if (!m_py_obj) 357061da546Spatrick return nullDeref(); 358061da546Spatrick int r = PyObject_IsTrue(m_py_obj); 359061da546Spatrick if (r < 0) 360061da546Spatrick return exception(); 361061da546Spatrick return !!r; 362061da546Spatrick } 363061da546Spatrick 364dda28197Spatrick llvm::Expected<long long> AsLongLong() const; 365dda28197Spatrick 366dda28197Spatrick llvm::Expected<long long> AsUnsignedLongLong() const; 367dda28197Spatrick 368dda28197Spatrick // wraps on overflow, instead of raising an error. 369dda28197Spatrick llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const; 370061da546Spatrick 371061da546Spatrick llvm::Expected<bool> IsInstance(const PythonObject &cls) { 372061da546Spatrick if (!m_py_obj || !cls.IsValid()) 373061da546Spatrick return nullDeref(); 374061da546Spatrick int r = PyObject_IsInstance(m_py_obj, cls.get()); 375061da546Spatrick if (r < 0) 376061da546Spatrick return exception(); 377061da546Spatrick return !!r; 378061da546Spatrick } 379061da546Spatrick 380061da546Spatrick protected: 381*be691f3bSpatrick PyObject *m_py_obj = nullptr; 382061da546Spatrick }; 383061da546Spatrick 384061da546Spatrick 385061da546Spatrick // This is why C++ needs monads. 386061da546Spatrick template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) { 387061da546Spatrick if (!obj) 388061da546Spatrick return obj.takeError(); 389061da546Spatrick if (!T::Check(obj.get().get())) 390061da546Spatrick return llvm::createStringError(llvm::inconvertibleErrorCode(), 391061da546Spatrick "type error"); 392061da546Spatrick return T(PyRefType::Borrowed, std::move(obj.get().get())); 393061da546Spatrick } 394061da546Spatrick 395061da546Spatrick template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj); 396061da546Spatrick 397061da546Spatrick template <> 398061da546Spatrick llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj); 399061da546Spatrick 400061da546Spatrick template <> 401dda28197Spatrick llvm::Expected<unsigned long long> 402dda28197Spatrick As<unsigned long long>(llvm::Expected<PythonObject> &&obj); 403dda28197Spatrick 404dda28197Spatrick template <> 405061da546Spatrick llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj); 406061da546Spatrick 407061da546Spatrick 408061da546Spatrick template <class T> class TypedPythonObject : public PythonObject { 409061da546Spatrick public: 410061da546Spatrick // override to perform implicit type conversions on Reset 411061da546Spatrick // This can be eliminated once we drop python 2 support. 412061da546Spatrick static void Convert(PyRefType &type, PyObject *&py_obj) {} 413061da546Spatrick 414061da546Spatrick TypedPythonObject(PyRefType type, PyObject *py_obj) { 415061da546Spatrick if (!py_obj) 416061da546Spatrick return; 417061da546Spatrick T::Convert(type, py_obj); 418061da546Spatrick if (T::Check(py_obj)) 419061da546Spatrick PythonObject::operator=(PythonObject(type, py_obj)); 420061da546Spatrick else if (type == PyRefType::Owned) 421061da546Spatrick Py_DECREF(py_obj); 422061da546Spatrick } 423061da546Spatrick 424*be691f3bSpatrick TypedPythonObject() = default; 425061da546Spatrick }; 426061da546Spatrick 427061da546Spatrick class PythonBytes : public TypedPythonObject<PythonBytes> { 428061da546Spatrick public: 429061da546Spatrick using TypedPythonObject::TypedPythonObject; 430061da546Spatrick explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 431061da546Spatrick PythonBytes(const uint8_t *bytes, size_t length); 432061da546Spatrick 433061da546Spatrick static bool Check(PyObject *py_obj); 434061da546Spatrick 435061da546Spatrick llvm::ArrayRef<uint8_t> GetBytes() const; 436061da546Spatrick 437061da546Spatrick size_t GetSize() const; 438061da546Spatrick 439061da546Spatrick void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 440061da546Spatrick 441061da546Spatrick StructuredData::StringSP CreateStructuredString() const; 442061da546Spatrick }; 443061da546Spatrick 444061da546Spatrick class PythonByteArray : public TypedPythonObject<PythonByteArray> { 445061da546Spatrick public: 446061da546Spatrick using TypedPythonObject::TypedPythonObject; 447061da546Spatrick explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 448061da546Spatrick PythonByteArray(const uint8_t *bytes, size_t length); 449061da546Spatrick PythonByteArray(const PythonBytes &object); 450061da546Spatrick 451061da546Spatrick static bool Check(PyObject *py_obj); 452061da546Spatrick 453061da546Spatrick llvm::ArrayRef<uint8_t> GetBytes() const; 454061da546Spatrick 455061da546Spatrick size_t GetSize() const; 456061da546Spatrick 457061da546Spatrick void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 458061da546Spatrick 459061da546Spatrick StructuredData::StringSP CreateStructuredString() const; 460061da546Spatrick }; 461061da546Spatrick 462061da546Spatrick class PythonString : public TypedPythonObject<PythonString> { 463061da546Spatrick public: 464061da546Spatrick using TypedPythonObject::TypedPythonObject; 465061da546Spatrick static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string); 466061da546Spatrick 467061da546Spatrick PythonString() : TypedPythonObject() {} // MSVC requires this for some reason 468061da546Spatrick 469061da546Spatrick explicit PythonString(llvm::StringRef string); // safe, null on error 470061da546Spatrick 471061da546Spatrick static bool Check(PyObject *py_obj); 472061da546Spatrick static void Convert(PyRefType &type, PyObject *&py_obj); 473061da546Spatrick 474061da546Spatrick llvm::StringRef GetString() const; // safe, empty string on error 475061da546Spatrick 476061da546Spatrick llvm::Expected<llvm::StringRef> AsUTF8() const; 477061da546Spatrick 478061da546Spatrick size_t GetSize() const; 479061da546Spatrick 480061da546Spatrick void SetString(llvm::StringRef string); // safe, null on error 481061da546Spatrick 482061da546Spatrick StructuredData::StringSP CreateStructuredString() const; 483061da546Spatrick }; 484061da546Spatrick 485061da546Spatrick class PythonInteger : public TypedPythonObject<PythonInteger> { 486061da546Spatrick public: 487061da546Spatrick using TypedPythonObject::TypedPythonObject; 488061da546Spatrick 489061da546Spatrick PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason 490061da546Spatrick 491061da546Spatrick explicit PythonInteger(int64_t value); 492061da546Spatrick 493061da546Spatrick static bool Check(PyObject *py_obj); 494061da546Spatrick static void Convert(PyRefType &type, PyObject *&py_obj); 495061da546Spatrick 496061da546Spatrick void SetInteger(int64_t value); 497061da546Spatrick 498061da546Spatrick StructuredData::IntegerSP CreateStructuredInteger() const; 499061da546Spatrick }; 500061da546Spatrick 501061da546Spatrick class PythonBoolean : public TypedPythonObject<PythonBoolean> { 502061da546Spatrick public: 503061da546Spatrick using TypedPythonObject::TypedPythonObject; 504061da546Spatrick 505061da546Spatrick explicit PythonBoolean(bool value); 506061da546Spatrick 507061da546Spatrick static bool Check(PyObject *py_obj); 508061da546Spatrick 509061da546Spatrick bool GetValue() const; 510061da546Spatrick 511061da546Spatrick void SetValue(bool value); 512061da546Spatrick 513061da546Spatrick StructuredData::BooleanSP CreateStructuredBoolean() const; 514061da546Spatrick }; 515061da546Spatrick 516061da546Spatrick class PythonList : public TypedPythonObject<PythonList> { 517061da546Spatrick public: 518061da546Spatrick using TypedPythonObject::TypedPythonObject; 519061da546Spatrick 520061da546Spatrick PythonList() : TypedPythonObject() {} // MSVC requires this for some reason 521061da546Spatrick 522061da546Spatrick explicit PythonList(PyInitialValue value); 523061da546Spatrick explicit PythonList(int list_size); 524061da546Spatrick 525061da546Spatrick static bool Check(PyObject *py_obj); 526061da546Spatrick 527061da546Spatrick uint32_t GetSize() const; 528061da546Spatrick 529061da546Spatrick PythonObject GetItemAtIndex(uint32_t index) const; 530061da546Spatrick 531061da546Spatrick void SetItemAtIndex(uint32_t index, const PythonObject &object); 532061da546Spatrick 533061da546Spatrick void AppendItem(const PythonObject &object); 534061da546Spatrick 535061da546Spatrick StructuredData::ArraySP CreateStructuredArray() const; 536061da546Spatrick }; 537061da546Spatrick 538061da546Spatrick class PythonTuple : public TypedPythonObject<PythonTuple> { 539061da546Spatrick public: 540061da546Spatrick using TypedPythonObject::TypedPythonObject; 541061da546Spatrick 542061da546Spatrick explicit PythonTuple(PyInitialValue value); 543061da546Spatrick explicit PythonTuple(int tuple_size); 544061da546Spatrick PythonTuple(std::initializer_list<PythonObject> objects); 545061da546Spatrick PythonTuple(std::initializer_list<PyObject *> objects); 546061da546Spatrick 547061da546Spatrick static bool Check(PyObject *py_obj); 548061da546Spatrick 549061da546Spatrick uint32_t GetSize() const; 550061da546Spatrick 551061da546Spatrick PythonObject GetItemAtIndex(uint32_t index) const; 552061da546Spatrick 553061da546Spatrick void SetItemAtIndex(uint32_t index, const PythonObject &object); 554061da546Spatrick 555061da546Spatrick StructuredData::ArraySP CreateStructuredArray() const; 556061da546Spatrick }; 557061da546Spatrick 558061da546Spatrick class PythonDictionary : public TypedPythonObject<PythonDictionary> { 559061da546Spatrick public: 560061da546Spatrick using TypedPythonObject::TypedPythonObject; 561061da546Spatrick 562061da546Spatrick PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason 563061da546Spatrick 564061da546Spatrick explicit PythonDictionary(PyInitialValue value); 565061da546Spatrick 566061da546Spatrick static bool Check(PyObject *py_obj); 567061da546Spatrick 568061da546Spatrick uint32_t GetSize() const; 569061da546Spatrick 570061da546Spatrick PythonList GetKeys() const; 571061da546Spatrick 572061da546Spatrick PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED 573061da546Spatrick void SetItemForKey(const PythonObject &key, 574061da546Spatrick const PythonObject &value); // DEPRECATED 575061da546Spatrick 576061da546Spatrick llvm::Expected<PythonObject> GetItem(const PythonObject &key) const; 577061da546Spatrick llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const; 578061da546Spatrick llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const; 579061da546Spatrick llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const; 580061da546Spatrick 581061da546Spatrick StructuredData::DictionarySP CreateStructuredDictionary() const; 582061da546Spatrick }; 583061da546Spatrick 584061da546Spatrick class PythonModule : public TypedPythonObject<PythonModule> { 585061da546Spatrick public: 586061da546Spatrick using TypedPythonObject::TypedPythonObject; 587061da546Spatrick 588061da546Spatrick static bool Check(PyObject *py_obj); 589061da546Spatrick 590061da546Spatrick static PythonModule BuiltinsModule(); 591061da546Spatrick 592061da546Spatrick static PythonModule MainModule(); 593061da546Spatrick 594061da546Spatrick static PythonModule AddModule(llvm::StringRef module); 595061da546Spatrick 596061da546Spatrick // safe, returns invalid on error; 597061da546Spatrick static PythonModule ImportModule(llvm::StringRef name) { 598dda28197Spatrick std::string s = std::string(name); 599061da546Spatrick auto mod = Import(s.c_str()); 600061da546Spatrick if (!mod) { 601061da546Spatrick llvm::consumeError(mod.takeError()); 602061da546Spatrick return PythonModule(); 603061da546Spatrick } 604061da546Spatrick return std::move(mod.get()); 605061da546Spatrick } 606061da546Spatrick 607061da546Spatrick static llvm::Expected<PythonModule> Import(const llvm::Twine &name); 608061da546Spatrick 609061da546Spatrick llvm::Expected<PythonObject> Get(const llvm::Twine &name); 610061da546Spatrick 611061da546Spatrick PythonDictionary GetDictionary() const; 612061da546Spatrick }; 613061da546Spatrick 614061da546Spatrick class PythonCallable : public TypedPythonObject<PythonCallable> { 615061da546Spatrick public: 616061da546Spatrick using TypedPythonObject::TypedPythonObject; 617061da546Spatrick 618061da546Spatrick struct ArgInfo { 619061da546Spatrick /* the largest number of positional arguments this callable 620061da546Spatrick * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs 621061da546Spatrick * function and can accept an arbitrary number */ 622061da546Spatrick unsigned max_positional_args; 623061da546Spatrick static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline 624061da546Spatrick }; 625061da546Spatrick 626061da546Spatrick static bool Check(PyObject *py_obj); 627061da546Spatrick 628061da546Spatrick llvm::Expected<ArgInfo> GetArgInfo() const; 629061da546Spatrick 630061da546Spatrick PythonObject operator()(); 631061da546Spatrick 632061da546Spatrick PythonObject operator()(std::initializer_list<PyObject *> args); 633061da546Spatrick 634061da546Spatrick PythonObject operator()(std::initializer_list<PythonObject> args); 635061da546Spatrick 636061da546Spatrick template <typename Arg, typename... Args> 637061da546Spatrick PythonObject operator()(const Arg &arg, Args... args) { 638061da546Spatrick return operator()({arg, args...}); 639061da546Spatrick } 640061da546Spatrick }; 641061da546Spatrick 642061da546Spatrick class PythonFile : public TypedPythonObject<PythonFile> { 643061da546Spatrick public: 644061da546Spatrick using TypedPythonObject::TypedPythonObject; 645061da546Spatrick 646061da546Spatrick PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason 647061da546Spatrick 648061da546Spatrick static bool Check(PyObject *py_obj); 649061da546Spatrick 650061da546Spatrick static llvm::Expected<PythonFile> FromFile(File &file, 651061da546Spatrick const char *mode = nullptr); 652061da546Spatrick 653061da546Spatrick llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false); 654061da546Spatrick llvm::Expected<lldb::FileSP> 655061da546Spatrick ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false); 656061da546Spatrick }; 657061da546Spatrick 658061da546Spatrick class PythonException : public llvm::ErrorInfo<PythonException> { 659061da546Spatrick private: 660061da546Spatrick PyObject *m_exception_type, *m_exception, *m_traceback; 661061da546Spatrick PyObject *m_repr_bytes; 662061da546Spatrick 663061da546Spatrick public: 664061da546Spatrick static char ID; 665061da546Spatrick const char *toCString() const; 666061da546Spatrick PythonException(const char *caller = nullptr); 667061da546Spatrick void Restore(); 668061da546Spatrick ~PythonException(); 669061da546Spatrick void log(llvm::raw_ostream &OS) const override; 670061da546Spatrick std::error_code convertToErrorCode() const override; 671061da546Spatrick bool Matches(PyObject *exc) const; 672061da546Spatrick std::string ReadBacktrace() const; 673061da546Spatrick }; 674061da546Spatrick 675061da546Spatrick // This extracts the underlying T out of an Expected<T> and returns it. 676061da546Spatrick // If the Expected is an Error instead of a T, that error will be converted 677061da546Spatrick // into a python exception, and this will return a default-constructed T. 678061da546Spatrick // 679061da546Spatrick // This is appropriate for use right at the boundary of python calling into 680061da546Spatrick // C++, such as in a SWIG typemap. In such a context you should simply 681061da546Spatrick // check if the returned T is valid, and if it is, return a NULL back 682061da546Spatrick // to python. This will result in the Error being raised as an exception 683061da546Spatrick // from python code's point of view. 684061da546Spatrick // 685061da546Spatrick // For example: 686061da546Spatrick // ``` 687061da546Spatrick // Expected<Foo *> efoop = some_cpp_function(); 688061da546Spatrick // Foo *foop = unwrapOrSetPythonException(efoop); 689061da546Spatrick // if (!foop) 690061da546Spatrick // return NULL; 691061da546Spatrick // do_something(*foop); 692061da546Spatrick // 693061da546Spatrick // If the Error returned was itself created because a python exception was 694061da546Spatrick // raised when C++ code called into python, then the original exception 695061da546Spatrick // will be restored. Otherwise a simple string exception will be raised. 696061da546Spatrick template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) { 697061da546Spatrick if (expected) 698061da546Spatrick return expected.get(); 699061da546Spatrick llvm::handleAllErrors( 700061da546Spatrick expected.takeError(), [](PythonException &E) { E.Restore(); }, 701061da546Spatrick [](const llvm::ErrorInfoBase &E) { 702061da546Spatrick PyErr_SetString(PyExc_Exception, E.message().c_str()); 703061da546Spatrick }); 704061da546Spatrick return T(); 705061da546Spatrick } 706061da546Spatrick 707061da546Spatrick // This is only here to help incrementally migrate old, exception-unsafe 708061da546Spatrick // code. 709061da546Spatrick template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) { 710061da546Spatrick if (expected) 711061da546Spatrick return std::move(expected.get()); 712061da546Spatrick llvm::consumeError(expected.takeError()); 713061da546Spatrick return T(); 714061da546Spatrick } 715061da546Spatrick 716061da546Spatrick llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string, 717061da546Spatrick const PythonDictionary &globals, 718061da546Spatrick const PythonDictionary &locals); 719061da546Spatrick 720061da546Spatrick llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string, 721061da546Spatrick const PythonDictionary &globals, 722061da546Spatrick const PythonDictionary &locals); 723061da546Spatrick 724061da546Spatrick // Sometimes the best way to interact with a python interpreter is 725061da546Spatrick // to run some python code. You construct a PythonScript with 726061da546Spatrick // script string. The script assigns some function to `_function_` 727061da546Spatrick // and you get a C++ callable object that calls the python function. 728061da546Spatrick // 729061da546Spatrick // Example: 730061da546Spatrick // 731061da546Spatrick // const char script[] = R"( 732061da546Spatrick // def main(x, y): 733061da546Spatrick // .... 734061da546Spatrick // )"; 735061da546Spatrick // 736061da546Spatrick // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) { 737061da546Spatrick // // no need to synchronize access to this global, we already have the GIL 738061da546Spatrick // static PythonScript foo(script) 739061da546Spatrick // return foo(x, y); 740061da546Spatrick // } 741061da546Spatrick class PythonScript { 742061da546Spatrick const char *script; 743061da546Spatrick PythonCallable function; 744061da546Spatrick 745061da546Spatrick llvm::Error Init(); 746061da546Spatrick 747061da546Spatrick public: 748061da546Spatrick PythonScript(const char *script) : script(script), function() {} 749061da546Spatrick 750061da546Spatrick template <typename... Args> 751061da546Spatrick llvm::Expected<PythonObject> operator()(Args &&... args) { 752061da546Spatrick if (llvm::Error error = Init()) 753061da546Spatrick return std::move(error); 754061da546Spatrick return function.Call(std::forward<Args>(args)...); 755061da546Spatrick } 756061da546Spatrick }; 757061da546Spatrick 758061da546Spatrick } // namespace python 759061da546Spatrick } // namespace lldb_private 760061da546Spatrick 761061da546Spatrick #endif 762061da546Spatrick 763061da546Spatrick #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 764