1 //===-- PythonDataObjects.h--------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 // 10 // !! FIXME FIXME FIXME !! 11 // 12 // Python APIs nearly all can return an exception. They do this 13 // by returning NULL, or -1, or some such value and setting 14 // the exception state with PyErr_Set*(). Exceptions must be 15 // handled before further python API functions are called. Failure 16 // to do so will result in asserts on debug builds of python. 17 // It will also sometimes, but not usually result in crashes of 18 // release builds. 19 // 20 // Nearly all the code in this header does not handle python exceptions 21 // correctly. It should all be converted to return Expected<> or 22 // Error types to capture the exception. 23 // 24 // Everything in this file except functions that return Error or 25 // Expected<> is considered deprecated and should not be 26 // used in new code. If you need to use it, fix it first. 27 // 28 // 29 // TODOs for this file 30 // 31 // * Make all methods safe for exceptions. 32 // 33 // * Eliminate method signatures that must translate exceptions into 34 // empty objects or NULLs. Almost everything here should return 35 // Expected<>. It should be acceptable for certain operations that 36 // can never fail to assert instead, such as the creation of 37 // PythonString from a string literal. 38 // 39 // * Eliminate Reset(), and make all non-default constructors private. 40 // Python objects should be created with Retain<> or Take<>, and they 41 // should be assigned with operator= 42 // 43 // * Eliminate default constructors, make python objects always 44 // nonnull, and use optionals where necessary. 45 // 46 47 48 #ifndef LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 49 #define LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 50 51 #include "lldb/Host/Config.h" 52 53 #if LLDB_ENABLE_PYTHON 54 55 // LLDB Python header must be included first 56 #include "lldb-python.h" 57 58 #include "lldb/Host/File.h" 59 #include "lldb/Utility/StructuredData.h" 60 61 #include "llvm/ADT/ArrayRef.h" 62 63 namespace lldb_private { 64 namespace python { 65 66 class PythonObject; 67 class PythonBytes; 68 class PythonString; 69 class PythonList; 70 class PythonDictionary; 71 class PythonInteger; 72 class PythonException; 73 74 class GIL { 75 public: 76 GIL() { 77 m_state = PyGILState_Ensure(); 78 assert(!PyErr_Occurred()); 79 } 80 ~GIL() { PyGILState_Release(m_state); } 81 82 protected: 83 PyGILState_STATE m_state; 84 }; 85 86 enum class PyObjectType { 87 Unknown, 88 None, 89 Boolean, 90 Integer, 91 Dictionary, 92 List, 93 String, 94 Bytes, 95 ByteArray, 96 Module, 97 Callable, 98 Tuple, 99 File 100 }; 101 102 enum class PyRefType { 103 Borrowed, // We are not given ownership of the incoming PyObject. 104 // We cannot safely hold it without calling Py_INCREF. 105 Owned // We have ownership of the incoming PyObject. We should 106 // not call Py_INCREF. 107 }; 108 109 110 // Take a reference that you already own, and turn it into 111 // a PythonObject. 112 // 113 // Most python API methods will return a +1 reference 114 // if they succeed or NULL if and only if 115 // they set an exception. Use this to collect such return 116 // values, after checking for NULL. 117 // 118 // If T is not just PythonObject, then obj must be already be 119 // checked to be of the correct type. 120 template <typename T> T Take(PyObject *obj) { 121 assert(obj); 122 assert(!PyErr_Occurred()); 123 T thing(PyRefType::Owned, obj); 124 assert(thing.IsValid()); 125 return thing; 126 } 127 128 // Retain a reference you have borrowed, and turn it into 129 // a PythonObject. 130 // 131 // A minority of python APIs return a borrowed reference 132 // instead of a +1. They will also return NULL if and only 133 // if they set an exception. Use this to collect such return 134 // values, after checking for NULL. 135 // 136 // If T is not just PythonObject, then obj must be already be 137 // checked to be of the correct type. 138 template <typename T> T Retain(PyObject *obj) { 139 assert(obj); 140 assert(!PyErr_Occurred()); 141 T thing(PyRefType::Borrowed, obj); 142 assert(thing.IsValid()); 143 return thing; 144 } 145 146 // This class can be used like a utility function to convert from 147 // a llvm-friendly Twine into a null-terminated const char *, 148 // which is the form python C APIs want their strings in. 149 // 150 // Example: 151 // const llvm::Twine &some_twine; 152 // PyFoo_Bar(x, y, z, NullTerminated(some_twine)); 153 // 154 // Why a class instead of a function? If the twine isn't already null 155 // terminated, it will need a temporary buffer to copy the string 156 // into. We need that buffer to stick around for the lifetime of the 157 // statement. 158 class NullTerminated { 159 const char *str; 160 llvm::SmallString<32> storage; 161 162 public: 163 NullTerminated(const llvm::Twine &twine) { 164 llvm::StringRef ref = twine.toNullTerminatedStringRef(storage); 165 str = ref.begin(); 166 } 167 operator const char *() { return str; } 168 }; 169 170 inline llvm::Error nullDeref() { 171 return llvm::createStringError(llvm::inconvertibleErrorCode(), 172 "A NULL PyObject* was dereferenced"); 173 } 174 175 inline llvm::Error exception(const char *s = nullptr) { 176 return llvm::make_error<PythonException>(s); 177 } 178 179 inline llvm::Error keyError() { 180 return llvm::createStringError(llvm::inconvertibleErrorCode(), 181 "key not in dict"); 182 } 183 184 inline const char *py2_const_cast(const char *s) { return s; } 185 186 enum class PyInitialValue { Invalid, Empty }; 187 188 // DOC: https://docs.python.org/3/c-api/arg.html#building-values 189 template <typename T, typename Enable = void> struct PythonFormat; 190 191 template <typename T, char F> struct PassthroughFormat { 192 static constexpr char format = F; 193 static constexpr T get(T t) { return t; } 194 }; 195 196 template <> struct PythonFormat<char *> : PassthroughFormat<char *, 's'> {}; 197 template <> struct PythonFormat<char> : PassthroughFormat<char, 'b'> {}; 198 template <> 199 struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {}; 200 template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {}; 201 template <> 202 struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {}; 203 template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {}; 204 template <> 205 struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {}; 206 template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {}; 207 template <> 208 struct PythonFormat<unsigned long> : PassthroughFormat<unsigned long, 'k'> {}; 209 template <> 210 struct PythonFormat<long long> : PassthroughFormat<long long, 'L'> {}; 211 template <> 212 struct PythonFormat<unsigned long long> 213 : PassthroughFormat<unsigned long long, 'K'> {}; 214 template <> 215 struct PythonFormat<PyObject *> : PassthroughFormat<PyObject *, 'O'> {}; 216 217 template <typename T> 218 struct PythonFormat< 219 T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> { 220 static constexpr char format = 'O'; 221 static auto get(const T &value) { return value.get(); } 222 }; 223 224 class PythonObject { 225 public: 226 PythonObject() = default; 227 228 PythonObject(PyRefType type, PyObject *py_obj) { 229 m_py_obj = py_obj; 230 // If this is a borrowed reference, we need to convert it to 231 // an owned reference by incrementing it. If it is an owned 232 // reference (for example the caller allocated it with PyDict_New() 233 // then we must *not* increment it. 234 if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed) 235 Py_XINCREF(m_py_obj); 236 } 237 238 PythonObject(const PythonObject &rhs) 239 : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {} 240 241 PythonObject(PythonObject &&rhs) { 242 m_py_obj = rhs.m_py_obj; 243 rhs.m_py_obj = nullptr; 244 } 245 246 ~PythonObject() { Reset(); } 247 248 void Reset(); 249 250 void Dump() const { 251 if (m_py_obj) 252 _PyObject_Dump(m_py_obj); 253 else 254 puts("NULL"); 255 } 256 257 void Dump(Stream &strm) const; 258 259 PyObject *get() const { return m_py_obj; } 260 261 PyObject *release() { 262 PyObject *result = m_py_obj; 263 m_py_obj = nullptr; 264 return result; 265 } 266 267 PythonObject &operator=(PythonObject other) { 268 Reset(); 269 m_py_obj = std::exchange(other.m_py_obj, nullptr); 270 return *this; 271 } 272 273 PyObjectType GetObjectType() const; 274 275 PythonString Repr() const; 276 277 PythonString Str() const; 278 279 static PythonObject ResolveNameWithDictionary(llvm::StringRef name, 280 const PythonDictionary &dict); 281 282 template <typename T> 283 static T ResolveNameWithDictionary(llvm::StringRef name, 284 const PythonDictionary &dict) { 285 return ResolveNameWithDictionary(name, dict).AsType<T>(); 286 } 287 288 PythonObject ResolveName(llvm::StringRef name) const; 289 290 template <typename T> T ResolveName(llvm::StringRef name) const { 291 return ResolveName(name).AsType<T>(); 292 } 293 294 bool HasAttribute(llvm::StringRef attribute) const; 295 296 PythonObject GetAttributeValue(llvm::StringRef attribute) const; 297 298 bool IsNone() const { return m_py_obj == Py_None; } 299 300 bool IsValid() const { return m_py_obj != nullptr; } 301 302 bool IsAllocated() const { return IsValid() && !IsNone(); } 303 304 explicit operator bool() const { return IsValid() && !IsNone(); } 305 306 template <typename T> T AsType() const { 307 if (!T::Check(m_py_obj)) 308 return T(); 309 return T(PyRefType::Borrowed, m_py_obj); 310 } 311 312 StructuredData::ObjectSP CreateStructuredObject() const; 313 314 template <typename... T> 315 llvm::Expected<PythonObject> CallMethod(const char *name, 316 const T &... t) const { 317 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 318 PyObject *obj = 319 PyObject_CallMethod(m_py_obj, py2_const_cast(name), 320 py2_const_cast(format), PythonFormat<T>::get(t)...); 321 if (!obj) 322 return exception(); 323 return python::Take<PythonObject>(obj); 324 } 325 326 template <typename... T> 327 llvm::Expected<PythonObject> Call(const T &... t) const { 328 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 329 PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format), 330 PythonFormat<T>::get(t)...); 331 if (!obj) 332 return exception(); 333 return python::Take<PythonObject>(obj); 334 } 335 336 llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const { 337 if (!m_py_obj) 338 return nullDeref(); 339 PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name)); 340 if (!obj) 341 return exception(); 342 return python::Take<PythonObject>(obj); 343 } 344 345 llvm::Expected<bool> IsTrue() { 346 if (!m_py_obj) 347 return nullDeref(); 348 int r = PyObject_IsTrue(m_py_obj); 349 if (r < 0) 350 return exception(); 351 return !!r; 352 } 353 354 llvm::Expected<long long> AsLongLong() const; 355 356 llvm::Expected<long long> AsUnsignedLongLong() const; 357 358 // wraps on overflow, instead of raising an error. 359 llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const; 360 361 llvm::Expected<bool> IsInstance(const PythonObject &cls) { 362 if (!m_py_obj || !cls.IsValid()) 363 return nullDeref(); 364 int r = PyObject_IsInstance(m_py_obj, cls.get()); 365 if (r < 0) 366 return exception(); 367 return !!r; 368 } 369 370 protected: 371 PyObject *m_py_obj = nullptr; 372 }; 373 374 375 // This is why C++ needs monads. 376 template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) { 377 if (!obj) 378 return obj.takeError(); 379 if (!T::Check(obj.get().get())) 380 return llvm::createStringError(llvm::inconvertibleErrorCode(), 381 "type error"); 382 return T(PyRefType::Borrowed, std::move(obj.get().get())); 383 } 384 385 template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj); 386 387 template <> 388 llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj); 389 390 template <> 391 llvm::Expected<unsigned long long> 392 As<unsigned long long>(llvm::Expected<PythonObject> &&obj); 393 394 template <> 395 llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj); 396 397 398 template <class T> class TypedPythonObject : public PythonObject { 399 public: 400 TypedPythonObject(PyRefType type, PyObject *py_obj) { 401 if (!py_obj) 402 return; 403 if (T::Check(py_obj)) 404 PythonObject::operator=(PythonObject(type, py_obj)); 405 else if (type == PyRefType::Owned) 406 Py_DECREF(py_obj); 407 } 408 409 TypedPythonObject() = default; 410 }; 411 412 class PythonBytes : public TypedPythonObject<PythonBytes> { 413 public: 414 using TypedPythonObject::TypedPythonObject; 415 explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 416 PythonBytes(const uint8_t *bytes, size_t length); 417 418 static bool Check(PyObject *py_obj); 419 420 llvm::ArrayRef<uint8_t> GetBytes() const; 421 422 size_t GetSize() const; 423 424 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 425 426 StructuredData::StringSP CreateStructuredString() const; 427 }; 428 429 class PythonByteArray : public TypedPythonObject<PythonByteArray> { 430 public: 431 using TypedPythonObject::TypedPythonObject; 432 explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 433 PythonByteArray(const uint8_t *bytes, size_t length); 434 PythonByteArray(const PythonBytes &object); 435 436 static bool Check(PyObject *py_obj); 437 438 llvm::ArrayRef<uint8_t> GetBytes() const; 439 440 size_t GetSize() const; 441 442 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 443 444 StructuredData::StringSP CreateStructuredString() const; 445 }; 446 447 class PythonString : public TypedPythonObject<PythonString> { 448 public: 449 using TypedPythonObject::TypedPythonObject; 450 static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string); 451 452 PythonString() : TypedPythonObject() {} // MSVC requires this for some reason 453 454 explicit PythonString(llvm::StringRef string); // safe, null on error 455 456 static bool Check(PyObject *py_obj); 457 458 llvm::StringRef GetString() const; // safe, empty string on error 459 460 llvm::Expected<llvm::StringRef> AsUTF8() const; 461 462 size_t GetSize() const; 463 464 void SetString(llvm::StringRef string); // safe, null on error 465 466 StructuredData::StringSP CreateStructuredString() const; 467 }; 468 469 class PythonInteger : public TypedPythonObject<PythonInteger> { 470 public: 471 using TypedPythonObject::TypedPythonObject; 472 473 PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason 474 475 explicit PythonInteger(int64_t value); 476 477 static bool Check(PyObject *py_obj); 478 479 void SetInteger(int64_t value); 480 481 StructuredData::IntegerSP CreateStructuredInteger() const; 482 }; 483 484 class PythonBoolean : public TypedPythonObject<PythonBoolean> { 485 public: 486 using TypedPythonObject::TypedPythonObject; 487 488 explicit PythonBoolean(bool value); 489 490 static bool Check(PyObject *py_obj); 491 492 bool GetValue() const; 493 494 void SetValue(bool value); 495 496 StructuredData::BooleanSP CreateStructuredBoolean() const; 497 }; 498 499 class PythonList : public TypedPythonObject<PythonList> { 500 public: 501 using TypedPythonObject::TypedPythonObject; 502 503 PythonList() : TypedPythonObject() {} // MSVC requires this for some reason 504 505 explicit PythonList(PyInitialValue value); 506 explicit PythonList(int list_size); 507 508 static bool Check(PyObject *py_obj); 509 510 uint32_t GetSize() const; 511 512 PythonObject GetItemAtIndex(uint32_t index) const; 513 514 void SetItemAtIndex(uint32_t index, const PythonObject &object); 515 516 void AppendItem(const PythonObject &object); 517 518 StructuredData::ArraySP CreateStructuredArray() const; 519 }; 520 521 class PythonTuple : public TypedPythonObject<PythonTuple> { 522 public: 523 using TypedPythonObject::TypedPythonObject; 524 525 explicit PythonTuple(PyInitialValue value); 526 explicit PythonTuple(int tuple_size); 527 PythonTuple(std::initializer_list<PythonObject> objects); 528 PythonTuple(std::initializer_list<PyObject *> objects); 529 530 static bool Check(PyObject *py_obj); 531 532 uint32_t GetSize() const; 533 534 PythonObject GetItemAtIndex(uint32_t index) const; 535 536 void SetItemAtIndex(uint32_t index, const PythonObject &object); 537 538 StructuredData::ArraySP CreateStructuredArray() const; 539 }; 540 541 class PythonDictionary : public TypedPythonObject<PythonDictionary> { 542 public: 543 using TypedPythonObject::TypedPythonObject; 544 545 PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason 546 547 explicit PythonDictionary(PyInitialValue value); 548 549 static bool Check(PyObject *py_obj); 550 551 uint32_t GetSize() const; 552 553 PythonList GetKeys() const; 554 555 PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED 556 void SetItemForKey(const PythonObject &key, 557 const PythonObject &value); // DEPRECATED 558 559 llvm::Expected<PythonObject> GetItem(const PythonObject &key) const; 560 llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const; 561 llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const; 562 llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const; 563 564 StructuredData::DictionarySP CreateStructuredDictionary() const; 565 }; 566 567 class PythonModule : public TypedPythonObject<PythonModule> { 568 public: 569 using TypedPythonObject::TypedPythonObject; 570 571 static bool Check(PyObject *py_obj); 572 573 static PythonModule BuiltinsModule(); 574 575 static PythonModule MainModule(); 576 577 static PythonModule AddModule(llvm::StringRef module); 578 579 // safe, returns invalid on error; 580 static PythonModule ImportModule(llvm::StringRef name) { 581 std::string s = std::string(name); 582 auto mod = Import(s.c_str()); 583 if (!mod) { 584 llvm::consumeError(mod.takeError()); 585 return PythonModule(); 586 } 587 return std::move(mod.get()); 588 } 589 590 static llvm::Expected<PythonModule> Import(const llvm::Twine &name); 591 592 llvm::Expected<PythonObject> Get(const llvm::Twine &name); 593 594 PythonDictionary GetDictionary() const; 595 }; 596 597 class PythonCallable : public TypedPythonObject<PythonCallable> { 598 public: 599 using TypedPythonObject::TypedPythonObject; 600 601 struct ArgInfo { 602 /* the largest number of positional arguments this callable 603 * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs 604 * function and can accept an arbitrary number */ 605 unsigned max_positional_args; 606 static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline 607 }; 608 609 static bool Check(PyObject *py_obj); 610 611 llvm::Expected<ArgInfo> GetArgInfo() const; 612 613 PythonObject operator()(); 614 615 PythonObject operator()(std::initializer_list<PyObject *> args); 616 617 PythonObject operator()(std::initializer_list<PythonObject> args); 618 619 template <typename Arg, typename... Args> 620 PythonObject operator()(const Arg &arg, Args... args) { 621 return operator()({arg, args...}); 622 } 623 }; 624 625 class PythonFile : public TypedPythonObject<PythonFile> { 626 public: 627 using TypedPythonObject::TypedPythonObject; 628 629 PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason 630 631 static bool Check(PyObject *py_obj); 632 633 static llvm::Expected<PythonFile> FromFile(File &file, 634 const char *mode = nullptr); 635 636 llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false); 637 llvm::Expected<lldb::FileSP> 638 ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false); 639 }; 640 641 class PythonException : public llvm::ErrorInfo<PythonException> { 642 private: 643 PyObject *m_exception_type, *m_exception, *m_traceback; 644 PyObject *m_repr_bytes; 645 646 public: 647 static char ID; 648 const char *toCString() const; 649 PythonException(const char *caller = nullptr); 650 void Restore(); 651 ~PythonException() override; 652 void log(llvm::raw_ostream &OS) const override; 653 std::error_code convertToErrorCode() const override; 654 bool Matches(PyObject *exc) const; 655 std::string ReadBacktrace() const; 656 }; 657 658 // This extracts the underlying T out of an Expected<T> and returns it. 659 // If the Expected is an Error instead of a T, that error will be converted 660 // into a python exception, and this will return a default-constructed T. 661 // 662 // This is appropriate for use right at the boundary of python calling into 663 // C++, such as in a SWIG typemap. In such a context you should simply 664 // check if the returned T is valid, and if it is, return a NULL back 665 // to python. This will result in the Error being raised as an exception 666 // from python code's point of view. 667 // 668 // For example: 669 // ``` 670 // Expected<Foo *> efoop = some_cpp_function(); 671 // Foo *foop = unwrapOrSetPythonException(efoop); 672 // if (!foop) 673 // return NULL; 674 // do_something(*foop); 675 // 676 // If the Error returned was itself created because a python exception was 677 // raised when C++ code called into python, then the original exception 678 // will be restored. Otherwise a simple string exception will be raised. 679 template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) { 680 if (expected) 681 return expected.get(); 682 llvm::handleAllErrors( 683 expected.takeError(), [](PythonException &E) { E.Restore(); }, 684 [](const llvm::ErrorInfoBase &E) { 685 PyErr_SetString(PyExc_Exception, E.message().c_str()); 686 }); 687 return T(); 688 } 689 690 // This is only here to help incrementally migrate old, exception-unsafe 691 // code. 692 template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) { 693 if (expected) 694 return std::move(expected.get()); 695 llvm::consumeError(expected.takeError()); 696 return T(); 697 } 698 699 llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string, 700 const PythonDictionary &globals, 701 const PythonDictionary &locals); 702 703 llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string, 704 const PythonDictionary &globals, 705 const PythonDictionary &locals); 706 707 // Sometimes the best way to interact with a python interpreter is 708 // to run some python code. You construct a PythonScript with 709 // script string. The script assigns some function to `_function_` 710 // and you get a C++ callable object that calls the python function. 711 // 712 // Example: 713 // 714 // const char script[] = R"( 715 // def main(x, y): 716 // .... 717 // )"; 718 // 719 // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) { 720 // // no need to synchronize access to this global, we already have the GIL 721 // static PythonScript foo(script) 722 // return foo(x, y); 723 // } 724 class PythonScript { 725 const char *script; 726 PythonCallable function; 727 728 llvm::Error Init(); 729 730 public: 731 PythonScript(const char *script) : script(script), function() {} 732 733 template <typename... Args> 734 llvm::Expected<PythonObject> operator()(Args &&... args) { 735 if (llvm::Error error = Init()) 736 return std::move(error); 737 return function.Call(std::forward<Args>(args)...); 738 } 739 }; 740 741 class StructuredPythonObject : public StructuredData::Generic { 742 public: 743 StructuredPythonObject() : StructuredData::Generic() {} 744 745 // Take ownership of the object we received. 746 StructuredPythonObject(PythonObject obj) 747 : StructuredData::Generic(obj.release()) {} 748 749 ~StructuredPythonObject() override { 750 // Hand ownership back to a (temporary) PythonObject instance and let it 751 // take care of releasing it. 752 PythonObject(PyRefType::Owned, static_cast<PyObject *>(GetValue())); 753 } 754 755 bool IsValid() const override { return GetValue() && GetValue() != Py_None; } 756 757 void Serialize(llvm::json::OStream &s) const override; 758 759 private: 760 StructuredPythonObject(const StructuredPythonObject &) = delete; 761 const StructuredPythonObject & 762 operator=(const StructuredPythonObject &) = delete; 763 }; 764 765 } // namespace python 766 } // namespace lldb_private 767 768 #endif 769 770 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 771