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<const char *> : 198 PassthroughFormat<const char *, 's'> {}; 199 template <> struct PythonFormat<char> : PassthroughFormat<char, 'b'> {}; 200 template <> 201 struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {}; 202 template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {}; 203 template <> 204 struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {}; 205 template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {}; 206 template <> struct PythonFormat<bool> : PassthroughFormat<bool, 'p'> {}; 207 template <> 208 struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {}; 209 template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {}; 210 template <> 211 struct PythonFormat<unsigned long> : PassthroughFormat<unsigned long, 'k'> {}; 212 template <> 213 struct PythonFormat<long long> : PassthroughFormat<long long, 'L'> {}; 214 template <> 215 struct PythonFormat<unsigned long long> 216 : PassthroughFormat<unsigned long long, 'K'> {}; 217 template <> 218 struct PythonFormat<PyObject *> : PassthroughFormat<PyObject *, 'O'> {}; 219 220 template <typename T> 221 struct PythonFormat< 222 T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> { 223 static constexpr char format = 'O'; 224 static auto get(const T &value) { return value.get(); } 225 }; 226 227 class PythonObject { 228 public: 229 PythonObject() = default; 230 231 PythonObject(PyRefType type, PyObject *py_obj) { 232 m_py_obj = py_obj; 233 // If this is a borrowed reference, we need to convert it to 234 // an owned reference by incrementing it. If it is an owned 235 // reference (for example the caller allocated it with PyDict_New() 236 // then we must *not* increment it. 237 if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed) 238 Py_XINCREF(m_py_obj); 239 } 240 241 PythonObject(const PythonObject &rhs) 242 : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {} 243 244 PythonObject(PythonObject &&rhs) { 245 m_py_obj = rhs.m_py_obj; 246 rhs.m_py_obj = nullptr; 247 } 248 249 ~PythonObject() { Reset(); } 250 251 void Reset(); 252 253 void Dump() const { 254 if (m_py_obj) 255 _PyObject_Dump(m_py_obj); 256 else 257 puts("NULL"); 258 } 259 260 void Dump(Stream &strm) const; 261 262 PyObject *get() const { return m_py_obj; } 263 264 PyObject *release() { 265 PyObject *result = m_py_obj; 266 m_py_obj = nullptr; 267 return result; 268 } 269 270 PythonObject &operator=(PythonObject other) { 271 Reset(); 272 m_py_obj = std::exchange(other.m_py_obj, nullptr); 273 return *this; 274 } 275 276 PyObjectType GetObjectType() const; 277 278 PythonString Repr() const; 279 280 PythonString Str() const; 281 282 static PythonObject ResolveNameWithDictionary(llvm::StringRef name, 283 const PythonDictionary &dict); 284 285 template <typename T> 286 static T ResolveNameWithDictionary(llvm::StringRef name, 287 const PythonDictionary &dict) { 288 return ResolveNameWithDictionary(name, dict).AsType<T>(); 289 } 290 291 PythonObject ResolveName(llvm::StringRef name) const; 292 293 template <typename T> T ResolveName(llvm::StringRef name) const { 294 return ResolveName(name).AsType<T>(); 295 } 296 297 bool HasAttribute(llvm::StringRef attribute) const; 298 299 PythonObject GetAttributeValue(llvm::StringRef attribute) const; 300 301 bool IsNone() const { return m_py_obj == Py_None; } 302 303 bool IsValid() const { return m_py_obj != nullptr; } 304 305 bool IsAllocated() const { return IsValid() && !IsNone(); } 306 307 explicit operator bool() const { return IsValid() && !IsNone(); } 308 309 template <typename T> T AsType() const { 310 if (!T::Check(m_py_obj)) 311 return T(); 312 return T(PyRefType::Borrowed, m_py_obj); 313 } 314 315 StructuredData::ObjectSP CreateStructuredObject() const; 316 317 template <typename... T> 318 llvm::Expected<PythonObject> CallMethod(const char *name, 319 const T &... t) const { 320 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 321 PyObject *obj = 322 PyObject_CallMethod(m_py_obj, py2_const_cast(name), 323 py2_const_cast(format), PythonFormat<T>::get(t)...); 324 if (!obj) 325 return exception(); 326 return python::Take<PythonObject>(obj); 327 } 328 329 template <typename... T> 330 llvm::Expected<PythonObject> Call(const T &... t) const { 331 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 332 PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format), 333 PythonFormat<T>::get(t)...); 334 if (!obj) 335 return exception(); 336 return python::Take<PythonObject>(obj); 337 } 338 339 llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const { 340 if (!m_py_obj) 341 return nullDeref(); 342 PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name)); 343 if (!obj) 344 return exception(); 345 return python::Take<PythonObject>(obj); 346 } 347 348 llvm::Expected<PythonObject> GetType() const { 349 if (!m_py_obj) 350 return nullDeref(); 351 PyObject *obj = PyObject_Type(m_py_obj); 352 if (!obj) 353 return exception(); 354 return python::Take<PythonObject>(obj); 355 } 356 357 llvm::Expected<bool> IsTrue() { 358 if (!m_py_obj) 359 return nullDeref(); 360 int r = PyObject_IsTrue(m_py_obj); 361 if (r < 0) 362 return exception(); 363 return !!r; 364 } 365 366 llvm::Expected<long long> AsLongLong() const; 367 368 llvm::Expected<unsigned long long> AsUnsignedLongLong() const; 369 370 // wraps on overflow, instead of raising an error. 371 llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const; 372 373 llvm::Expected<bool> IsInstance(const PythonObject &cls) { 374 if (!m_py_obj || !cls.IsValid()) 375 return nullDeref(); 376 int r = PyObject_IsInstance(m_py_obj, cls.get()); 377 if (r < 0) 378 return exception(); 379 return !!r; 380 } 381 382 protected: 383 PyObject *m_py_obj = nullptr; 384 }; 385 386 387 // This is why C++ needs monads. 388 template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) { 389 if (!obj) 390 return obj.takeError(); 391 if (!T::Check(obj.get().get())) 392 return llvm::createStringError(llvm::inconvertibleErrorCode(), 393 "type error"); 394 return T(PyRefType::Borrowed, std::move(obj.get().get())); 395 } 396 397 template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj); 398 399 template <> 400 llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj); 401 402 template <> 403 llvm::Expected<unsigned long long> 404 As<unsigned long long>(llvm::Expected<PythonObject> &&obj); 405 406 template <> 407 llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj); 408 409 410 template <class T> class TypedPythonObject : public PythonObject { 411 public: 412 TypedPythonObject(PyRefType type, PyObject *py_obj) { 413 if (!py_obj) 414 return; 415 if (T::Check(py_obj)) 416 PythonObject::operator=(PythonObject(type, py_obj)); 417 else if (type == PyRefType::Owned) 418 Py_DECREF(py_obj); 419 } 420 421 TypedPythonObject() = default; 422 }; 423 424 class PythonBytes : public TypedPythonObject<PythonBytes> { 425 public: 426 using TypedPythonObject::TypedPythonObject; 427 explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 428 PythonBytes(const uint8_t *bytes, size_t length); 429 430 static bool Check(PyObject *py_obj); 431 432 llvm::ArrayRef<uint8_t> GetBytes() const; 433 434 size_t GetSize() const; 435 436 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 437 438 StructuredData::StringSP CreateStructuredString() const; 439 }; 440 441 class PythonByteArray : public TypedPythonObject<PythonByteArray> { 442 public: 443 using TypedPythonObject::TypedPythonObject; 444 explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 445 PythonByteArray(const uint8_t *bytes, size_t length); 446 PythonByteArray(const PythonBytes &object); 447 448 static bool Check(PyObject *py_obj); 449 450 llvm::ArrayRef<uint8_t> GetBytes() const; 451 452 size_t GetSize() const; 453 454 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 455 456 StructuredData::StringSP CreateStructuredString() const; 457 }; 458 459 class PythonString : public TypedPythonObject<PythonString> { 460 public: 461 using TypedPythonObject::TypedPythonObject; 462 static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string); 463 464 PythonString() : TypedPythonObject() {} // MSVC requires this for some reason 465 466 explicit PythonString(llvm::StringRef string); // safe, null on error 467 468 static bool Check(PyObject *py_obj); 469 470 llvm::StringRef GetString() const; // safe, empty string on error 471 472 llvm::Expected<llvm::StringRef> AsUTF8() const; 473 474 size_t GetSize() const; 475 476 void SetString(llvm::StringRef string); // safe, null on error 477 478 StructuredData::StringSP CreateStructuredString() const; 479 }; 480 481 class PythonInteger : public TypedPythonObject<PythonInteger> { 482 public: 483 using TypedPythonObject::TypedPythonObject; 484 485 PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason 486 487 explicit PythonInteger(int64_t value); 488 489 static bool Check(PyObject *py_obj); 490 491 void SetInteger(int64_t value); 492 493 StructuredData::IntegerSP CreateStructuredInteger() const; 494 495 StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const; 496 497 StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const; 498 }; 499 500 class PythonBoolean : public TypedPythonObject<PythonBoolean> { 501 public: 502 using TypedPythonObject::TypedPythonObject; 503 504 explicit PythonBoolean(bool value); 505 506 static bool Check(PyObject *py_obj); 507 508 bool GetValue() const; 509 510 void SetValue(bool value); 511 512 StructuredData::BooleanSP CreateStructuredBoolean() const; 513 }; 514 515 class PythonList : public TypedPythonObject<PythonList> { 516 public: 517 using TypedPythonObject::TypedPythonObject; 518 519 PythonList() : TypedPythonObject() {} // MSVC requires this for some reason 520 521 explicit PythonList(PyInitialValue value); 522 explicit PythonList(int list_size); 523 524 static bool Check(PyObject *py_obj); 525 526 uint32_t GetSize() const; 527 528 PythonObject GetItemAtIndex(uint32_t index) const; 529 530 void SetItemAtIndex(uint32_t index, const PythonObject &object); 531 532 void AppendItem(const PythonObject &object); 533 534 StructuredData::ArraySP CreateStructuredArray() const; 535 }; 536 537 class PythonTuple : public TypedPythonObject<PythonTuple> { 538 public: 539 using TypedPythonObject::TypedPythonObject; 540 541 explicit PythonTuple(PyInitialValue value); 542 explicit PythonTuple(int tuple_size); 543 PythonTuple(std::initializer_list<PythonObject> objects); 544 PythonTuple(std::initializer_list<PyObject *> objects); 545 546 static bool Check(PyObject *py_obj); 547 548 uint32_t GetSize() const; 549 550 PythonObject GetItemAtIndex(uint32_t index) const; 551 552 void SetItemAtIndex(uint32_t index, const PythonObject &object); 553 554 StructuredData::ArraySP CreateStructuredArray() const; 555 }; 556 557 class PythonDictionary : public TypedPythonObject<PythonDictionary> { 558 public: 559 using TypedPythonObject::TypedPythonObject; 560 561 PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason 562 563 explicit PythonDictionary(PyInitialValue value); 564 565 static bool Check(PyObject *py_obj); 566 567 bool HasKey(const llvm::Twine &key) const; 568 569 uint32_t GetSize() const; 570 571 PythonList GetKeys() const; 572 573 PythonObject GetItemForKey(const PythonObject &key) const; // DEPRECATED 574 void SetItemForKey(const PythonObject &key, 575 const PythonObject &value); // DEPRECATED 576 577 llvm::Expected<PythonObject> GetItem(const PythonObject &key) const; 578 llvm::Expected<PythonObject> GetItem(const llvm::Twine &key) const; 579 llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const; 580 llvm::Error SetItem(const llvm::Twine &key, const PythonObject &value) const; 581 582 StructuredData::DictionarySP CreateStructuredDictionary() const; 583 }; 584 585 class PythonModule : public TypedPythonObject<PythonModule> { 586 public: 587 using TypedPythonObject::TypedPythonObject; 588 589 static bool Check(PyObject *py_obj); 590 591 static PythonModule BuiltinsModule(); 592 593 static PythonModule MainModule(); 594 595 static PythonModule AddModule(llvm::StringRef module); 596 597 // safe, returns invalid on error; 598 static PythonModule ImportModule(llvm::StringRef name) { 599 std::string s = std::string(name); 600 auto mod = Import(s.c_str()); 601 if (!mod) { 602 llvm::consumeError(mod.takeError()); 603 return PythonModule(); 604 } 605 return std::move(mod.get()); 606 } 607 608 static llvm::Expected<PythonModule> Import(const llvm::Twine &name); 609 610 llvm::Expected<PythonObject> Get(const llvm::Twine &name); 611 612 PythonDictionary GetDictionary() const; 613 }; 614 615 class PythonCallable : public TypedPythonObject<PythonCallable> { 616 public: 617 using TypedPythonObject::TypedPythonObject; 618 619 struct ArgInfo { 620 /* the largest number of positional arguments this callable 621 * can accept, or UNBOUNDED, ie UINT_MAX if it's a varargs 622 * function and can accept an arbitrary number */ 623 unsigned max_positional_args; 624 static constexpr unsigned UNBOUNDED = UINT_MAX; // FIXME c++17 inline 625 }; 626 627 static bool Check(PyObject *py_obj); 628 629 llvm::Expected<ArgInfo> GetArgInfo() const; 630 631 PythonObject operator()(); 632 633 PythonObject operator()(std::initializer_list<PyObject *> args); 634 635 PythonObject operator()(std::initializer_list<PythonObject> args); 636 637 template <typename Arg, typename... Args> 638 PythonObject operator()(const Arg &arg, Args... args) { 639 return operator()({arg, args...}); 640 } 641 }; 642 643 class PythonFile : public TypedPythonObject<PythonFile> { 644 public: 645 using TypedPythonObject::TypedPythonObject; 646 647 PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason 648 649 static bool Check(PyObject *py_obj); 650 651 static llvm::Expected<PythonFile> FromFile(File &file, 652 const char *mode = nullptr); 653 654 llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false); 655 llvm::Expected<lldb::FileSP> 656 ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false); 657 }; 658 659 class PythonException : public llvm::ErrorInfo<PythonException> { 660 private: 661 PyObject *m_exception_type, *m_exception, *m_traceback; 662 PyObject *m_repr_bytes; 663 664 public: 665 static char ID; 666 const char *toCString() const; 667 PythonException(const char *caller = nullptr); 668 void Restore(); 669 ~PythonException() override; 670 void log(llvm::raw_ostream &OS) const override; 671 std::error_code convertToErrorCode() const override; 672 bool Matches(PyObject *exc) const; 673 std::string ReadBacktrace() const; 674 }; 675 676 // This extracts the underlying T out of an Expected<T> and returns it. 677 // If the Expected is an Error instead of a T, that error will be converted 678 // into a python exception, and this will return a default-constructed T. 679 // 680 // This is appropriate for use right at the boundary of python calling into 681 // C++, such as in a SWIG typemap. In such a context you should simply 682 // check if the returned T is valid, and if it is, return a NULL back 683 // to python. This will result in the Error being raised as an exception 684 // from python code's point of view. 685 // 686 // For example: 687 // ``` 688 // Expected<Foo *> efoop = some_cpp_function(); 689 // Foo *foop = unwrapOrSetPythonException(efoop); 690 // if (!foop) 691 // return NULL; 692 // do_something(*foop); 693 // 694 // If the Error returned was itself created because a python exception was 695 // raised when C++ code called into python, then the original exception 696 // will be restored. Otherwise a simple string exception will be raised. 697 template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) { 698 if (expected) 699 return expected.get(); 700 llvm::handleAllErrors( 701 expected.takeError(), [](PythonException &E) { E.Restore(); }, 702 [](const llvm::ErrorInfoBase &E) { 703 PyErr_SetString(PyExc_Exception, E.message().c_str()); 704 }); 705 return T(); 706 } 707 708 // This is only here to help incrementally migrate old, exception-unsafe 709 // code. 710 template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) { 711 if (expected) 712 return std::move(expected.get()); 713 llvm::consumeError(expected.takeError()); 714 return T(); 715 } 716 717 llvm::Expected<PythonObject> runStringOneLine(const llvm::Twine &string, 718 const PythonDictionary &globals, 719 const PythonDictionary &locals); 720 721 llvm::Expected<PythonObject> runStringMultiLine(const llvm::Twine &string, 722 const PythonDictionary &globals, 723 const PythonDictionary &locals); 724 725 // Sometimes the best way to interact with a python interpreter is 726 // to run some python code. You construct a PythonScript with 727 // script string. The script assigns some function to `_function_` 728 // and you get a C++ callable object that calls the python function. 729 // 730 // Example: 731 // 732 // const char script[] = R"( 733 // def main(x, y): 734 // .... 735 // )"; 736 // 737 // Expected<PythonObject> cpp_foo_wrapper(PythonObject x, PythonObject y) { 738 // // no need to synchronize access to this global, we already have the GIL 739 // static PythonScript foo(script) 740 // return foo(x, y); 741 // } 742 class PythonScript { 743 const char *script; 744 PythonCallable function; 745 746 llvm::Error Init(); 747 748 public: 749 PythonScript(const char *script) : script(script), function() {} 750 751 template <typename... Args> 752 llvm::Expected<PythonObject> operator()(Args &&... args) { 753 if (llvm::Error error = Init()) 754 return std::move(error); 755 return function.Call(std::forward<Args>(args)...); 756 } 757 }; 758 759 class StructuredPythonObject : public StructuredData::Generic { 760 public: 761 StructuredPythonObject() : StructuredData::Generic() {} 762 763 // Take ownership of the object we received. 764 StructuredPythonObject(PythonObject obj) 765 : StructuredData::Generic(obj.release()) {} 766 767 ~StructuredPythonObject() override { 768 // Hand ownership back to a (temporary) PythonObject instance and let it 769 // take care of releasing it. 770 PythonObject(PyRefType::Owned, static_cast<PyObject *>(GetValue())); 771 } 772 773 bool IsValid() const override { return GetValue() && GetValue() != Py_None; } 774 775 void Serialize(llvm::json::OStream &s) const override; 776 777 private: 778 StructuredPythonObject(const StructuredPythonObject &) = delete; 779 const StructuredPythonObject & 780 operator=(const StructuredPythonObject &) = delete; 781 }; 782 783 } // namespace python 784 } // namespace lldb_private 785 786 #endif 787 788 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 789