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 StructuredPythonObject : public StructuredData::Generic { 75 public: 76 StructuredPythonObject() : StructuredData::Generic() {} 77 78 StructuredPythonObject(void *obj) : StructuredData::Generic(obj) { 79 Py_XINCREF(GetValue()); 80 } 81 82 ~StructuredPythonObject() override { 83 if (Py_IsInitialized()) 84 Py_XDECREF(GetValue()); 85 SetValue(nullptr); 86 } 87 88 bool IsValid() const override { return GetValue() && GetValue() != Py_None; } 89 90 void Serialize(llvm::json::OStream &s) const override; 91 92 private: 93 DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); 94 }; 95 96 enum class PyObjectType { 97 Unknown, 98 None, 99 Boolean, 100 Integer, 101 Dictionary, 102 List, 103 String, 104 Bytes, 105 ByteArray, 106 Module, 107 Callable, 108 Tuple, 109 File 110 }; 111 112 enum class PyRefType { 113 Borrowed, // We are not given ownership of the incoming PyObject. 114 // We cannot safely hold it without calling Py_INCREF. 115 Owned // We have ownership of the incoming PyObject. We should 116 // not call Py_INCREF. 117 }; 118 119 120 // Take a reference that you already own, and turn it into 121 // a PythonObject. 122 // 123 // Most python API methods will return a +1 reference 124 // if they succeed or NULL if and only if 125 // they set an exception. Use this to collect such return 126 // values, after checking for NULL. 127 // 128 // If T is not just PythonObject, then obj must be already be 129 // checked to be of the correct type. 130 template <typename T> T Take(PyObject *obj) { 131 assert(obj); 132 assert(!PyErr_Occurred()); 133 T thing(PyRefType::Owned, obj); 134 assert(thing.IsValid()); 135 return thing; 136 } 137 138 // Retain a reference you have borrowed, and turn it into 139 // a PythonObject. 140 // 141 // A minority of python APIs return a borrowed reference 142 // instead of a +1. They will also return NULL if and only 143 // if they set an exception. Use this to collect such return 144 // values, after checking for NULL. 145 // 146 // If T is not just PythonObject, then obj must be already be 147 // checked to be of the correct type. 148 template <typename T> T Retain(PyObject *obj) { 149 assert(obj); 150 assert(!PyErr_Occurred()); 151 T thing(PyRefType::Borrowed, obj); 152 assert(thing.IsValid()); 153 return thing; 154 } 155 156 // This class can be used like a utility function to convert from 157 // a llvm-friendly Twine into a null-terminated const char *, 158 // which is the form python C APIs want their strings in. 159 // 160 // Example: 161 // const llvm::Twine &some_twine; 162 // PyFoo_Bar(x, y, z, NullTerminated(some_twine)); 163 // 164 // Why a class instead of a function? If the twine isn't already null 165 // terminated, it will need a temporary buffer to copy the string 166 // into. We need that buffer to stick around for the lifetime of the 167 // statement. 168 class NullTerminated { 169 const char *str; 170 llvm::SmallString<32> storage; 171 172 public: 173 NullTerminated(const llvm::Twine &twine) { 174 llvm::StringRef ref = twine.toNullTerminatedStringRef(storage); 175 str = ref.begin(); 176 } 177 operator const char *() { return str; } 178 }; 179 180 inline llvm::Error nullDeref() { 181 return llvm::createStringError(llvm::inconvertibleErrorCode(), 182 "A NULL PyObject* was dereferenced"); 183 } 184 185 inline llvm::Error exception(const char *s = nullptr) { 186 return llvm::make_error<PythonException>(s); 187 } 188 189 inline llvm::Error keyError() { 190 return llvm::createStringError(llvm::inconvertibleErrorCode(), 191 "key not in dict"); 192 } 193 194 #if PY_MAJOR_VERSION < 3 195 // The python 2 API declares some arguments as char* that should 196 // be const char *, but it doesn't actually modify them. 197 inline char *py2_const_cast(const char *s) { return const_cast<char *>(s); } 198 #else 199 inline const char *py2_const_cast(const char *s) { return s; } 200 #endif 201 202 enum class PyInitialValue { Invalid, Empty }; 203 204 template <typename T, typename Enable = void> struct PythonFormat; 205 206 template <> struct PythonFormat<unsigned long long> { 207 static constexpr char format = 'K'; 208 static auto get(unsigned long long value) { return value; } 209 }; 210 211 template <> struct PythonFormat<long long> { 212 static constexpr char format = 'L'; 213 static auto get(long long value) { return value; } 214 }; 215 216 template <> struct PythonFormat<PyObject *> { 217 static constexpr char format = 'O'; 218 static auto get(PyObject *value) { return value; } 219 }; 220 221 template <typename T> 222 struct PythonFormat< 223 T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> { 224 static constexpr char format = 'O'; 225 static auto get(const T &value) { return value.get(); } 226 }; 227 228 class PythonObject { 229 public: 230 PythonObject() : m_py_obj(nullptr) {} 231 232 PythonObject(PyRefType type, PyObject *py_obj) { 233 m_py_obj = py_obj; 234 // If this is a borrowed reference, we need to convert it to 235 // an owned reference by incrementing it. If it is an owned 236 // reference (for example the caller allocated it with PyDict_New() 237 // then we must *not* increment it. 238 if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed) 239 Py_XINCREF(m_py_obj); 240 } 241 242 PythonObject(const PythonObject &rhs) 243 : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {} 244 245 PythonObject(PythonObject &&rhs) { 246 m_py_obj = rhs.m_py_obj; 247 rhs.m_py_obj = nullptr; 248 } 249 250 ~PythonObject() { Reset(); } 251 252 void Reset() { 253 if (m_py_obj && Py_IsInitialized()) 254 Py_DECREF(m_py_obj); 255 m_py_obj = nullptr; 256 } 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 public: 323 template <typename... T> 324 llvm::Expected<PythonObject> CallMethod(const char *name, 325 const T &... t) const { 326 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 327 PyObject *obj = 328 PyObject_CallMethod(m_py_obj, py2_const_cast(name), 329 py2_const_cast(format), PythonFormat<T>::get(t)...); 330 if (!obj) 331 return exception(); 332 return python::Take<PythonObject>(obj); 333 } 334 335 template <typename... T> 336 llvm::Expected<PythonObject> Call(const T &... t) const { 337 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 338 PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format), 339 PythonFormat<T>::get(t)...); 340 if (!obj) 341 return exception(); 342 return python::Take<PythonObject>(obj); 343 } 344 345 llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const { 346 if (!m_py_obj) 347 return nullDeref(); 348 PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name)); 349 if (!obj) 350 return exception(); 351 return python::Take<PythonObject>(obj); 352 } 353 354 llvm::Expected<bool> IsTrue() { 355 if (!m_py_obj) 356 return nullDeref(); 357 int r = PyObject_IsTrue(m_py_obj); 358 if (r < 0) 359 return exception(); 360 return !!r; 361 } 362 363 llvm::Expected<long long> AsLongLong() const; 364 365 llvm::Expected<long long> AsUnsignedLongLong() const; 366 367 // wraps on overflow, instead of raising an error. 368 llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const; 369 370 llvm::Expected<bool> IsInstance(const PythonObject &cls) { 371 if (!m_py_obj || !cls.IsValid()) 372 return nullDeref(); 373 int r = PyObject_IsInstance(m_py_obj, cls.get()); 374 if (r < 0) 375 return exception(); 376 return !!r; 377 } 378 379 protected: 380 PyObject *m_py_obj; 381 }; 382 383 384 // This is why C++ needs monads. 385 template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) { 386 if (!obj) 387 return obj.takeError(); 388 if (!T::Check(obj.get().get())) 389 return llvm::createStringError(llvm::inconvertibleErrorCode(), 390 "type error"); 391 return T(PyRefType::Borrowed, std::move(obj.get().get())); 392 } 393 394 template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj); 395 396 template <> 397 llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj); 398 399 template <> 400 llvm::Expected<unsigned long long> 401 As<unsigned long long>(llvm::Expected<PythonObject> &&obj); 402 403 template <> 404 llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj); 405 406 407 template <class T> class TypedPythonObject : public PythonObject { 408 public: 409 // override to perform implicit type conversions on Reset 410 // This can be eliminated once we drop python 2 support. 411 static void Convert(PyRefType &type, PyObject *&py_obj) {} 412 413 TypedPythonObject(PyRefType type, PyObject *py_obj) { 414 if (!py_obj) 415 return; 416 T::Convert(type, py_obj); 417 if (T::Check(py_obj)) 418 PythonObject::operator=(PythonObject(type, py_obj)); 419 else if (type == PyRefType::Owned) 420 Py_DECREF(py_obj); 421 } 422 423 TypedPythonObject() {} 424 }; 425 426 class PythonBytes : public TypedPythonObject<PythonBytes> { 427 public: 428 using TypedPythonObject::TypedPythonObject; 429 explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 430 PythonBytes(const uint8_t *bytes, size_t length); 431 432 static bool Check(PyObject *py_obj); 433 434 llvm::ArrayRef<uint8_t> GetBytes() const; 435 436 size_t GetSize() const; 437 438 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 439 440 StructuredData::StringSP CreateStructuredString() const; 441 }; 442 443 class PythonByteArray : public TypedPythonObject<PythonByteArray> { 444 public: 445 using TypedPythonObject::TypedPythonObject; 446 explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 447 PythonByteArray(const uint8_t *bytes, size_t length); 448 PythonByteArray(const PythonBytes &object); 449 450 static bool Check(PyObject *py_obj); 451 452 llvm::ArrayRef<uint8_t> GetBytes() const; 453 454 size_t GetSize() const; 455 456 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 457 458 StructuredData::StringSP CreateStructuredString() const; 459 }; 460 461 class PythonString : public TypedPythonObject<PythonString> { 462 public: 463 using TypedPythonObject::TypedPythonObject; 464 static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string); 465 466 PythonString() : TypedPythonObject() {} // MSVC requires this for some reason 467 468 explicit PythonString(llvm::StringRef string); // safe, null on error 469 470 static bool Check(PyObject *py_obj); 471 static void Convert(PyRefType &type, PyObject *&py_obj); 472 473 llvm::StringRef GetString() const; // safe, empty string on error 474 475 llvm::Expected<llvm::StringRef> AsUTF8() const; 476 477 size_t GetSize() const; 478 479 void SetString(llvm::StringRef string); // safe, null on error 480 481 StructuredData::StringSP CreateStructuredString() const; 482 }; 483 484 class PythonInteger : public TypedPythonObject<PythonInteger> { 485 public: 486 using TypedPythonObject::TypedPythonObject; 487 488 PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason 489 490 explicit PythonInteger(int64_t value); 491 492 static bool Check(PyObject *py_obj); 493 static void Convert(PyRefType &type, PyObject *&py_obj); 494 495 void SetInteger(int64_t value); 496 497 StructuredData::IntegerSP CreateStructuredInteger() 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 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(); 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 } // namespace python 758 } // namespace lldb_private 759 760 #endif 761 762 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 763