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