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