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