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 StructuredPythonObject(const StructuredPythonObject &) = delete; 94 const StructuredPythonObject & 95 operator=(const StructuredPythonObject &) = delete; 96 }; 97 98 enum class PyObjectType { 99 Unknown, 100 None, 101 Boolean, 102 Integer, 103 Dictionary, 104 List, 105 String, 106 Bytes, 107 ByteArray, 108 Module, 109 Callable, 110 Tuple, 111 File 112 }; 113 114 enum class PyRefType { 115 Borrowed, // We are not given ownership of the incoming PyObject. 116 // We cannot safely hold it without calling Py_INCREF. 117 Owned // We have ownership of the incoming PyObject. We should 118 // not call Py_INCREF. 119 }; 120 121 122 // Take a reference that you already own, and turn it into 123 // a PythonObject. 124 // 125 // Most python API methods will return a +1 reference 126 // if they succeed or NULL if and only if 127 // they set an exception. Use this to collect such return 128 // values, after checking for NULL. 129 // 130 // If T is not just PythonObject, then obj must be already be 131 // checked to be of the correct type. 132 template <typename T> T Take(PyObject *obj) { 133 assert(obj); 134 assert(!PyErr_Occurred()); 135 T thing(PyRefType::Owned, obj); 136 assert(thing.IsValid()); 137 return thing; 138 } 139 140 // Retain a reference you have borrowed, and turn it into 141 // a PythonObject. 142 // 143 // A minority of python APIs return a borrowed reference 144 // instead of a +1. They will also return NULL if and only 145 // if they set an exception. Use this to collect such return 146 // values, after checking for NULL. 147 // 148 // If T is not just PythonObject, then obj must be already be 149 // checked to be of the correct type. 150 template <typename T> T Retain(PyObject *obj) { 151 assert(obj); 152 assert(!PyErr_Occurred()); 153 T thing(PyRefType::Borrowed, obj); 154 assert(thing.IsValid()); 155 return thing; 156 } 157 158 // This class can be used like a utility function to convert from 159 // a llvm-friendly Twine into a null-terminated const char *, 160 // which is the form python C APIs want their strings in. 161 // 162 // Example: 163 // const llvm::Twine &some_twine; 164 // PyFoo_Bar(x, y, z, NullTerminated(some_twine)); 165 // 166 // Why a class instead of a function? If the twine isn't already null 167 // terminated, it will need a temporary buffer to copy the string 168 // into. We need that buffer to stick around for the lifetime of the 169 // statement. 170 class NullTerminated { 171 const char *str; 172 llvm::SmallString<32> storage; 173 174 public: 175 NullTerminated(const llvm::Twine &twine) { 176 llvm::StringRef ref = twine.toNullTerminatedStringRef(storage); 177 str = ref.begin(); 178 } 179 operator const char *() { return str; } 180 }; 181 182 inline llvm::Error nullDeref() { 183 return llvm::createStringError(llvm::inconvertibleErrorCode(), 184 "A NULL PyObject* was dereferenced"); 185 } 186 187 inline llvm::Error exception(const char *s = nullptr) { 188 return llvm::make_error<PythonException>(s); 189 } 190 191 inline llvm::Error keyError() { 192 return llvm::createStringError(llvm::inconvertibleErrorCode(), 193 "key not in dict"); 194 } 195 196 #if PY_MAJOR_VERSION < 3 197 // The python 2 API declares some arguments as char* that should 198 // be const char *, but it doesn't actually modify them. 199 inline char *py2_const_cast(const char *s) { return const_cast<char *>(s); } 200 #else 201 inline const char *py2_const_cast(const char *s) { return s; } 202 #endif 203 204 enum class PyInitialValue { Invalid, Empty }; 205 206 template <typename T, typename Enable = void> struct PythonFormat; 207 208 template <> struct PythonFormat<unsigned long long> { 209 static constexpr char format = 'K'; 210 static auto get(unsigned long long value) { return value; } 211 }; 212 213 template <> struct PythonFormat<long long> { 214 static constexpr char format = 'L'; 215 static auto get(long long value) { return value; } 216 }; 217 218 template <> struct PythonFormat<PyObject *> { 219 static constexpr char format = 'O'; 220 static auto get(PyObject *value) { return value; } 221 }; 222 223 template <typename T> 224 struct PythonFormat< 225 T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> { 226 static constexpr char format = 'O'; 227 static auto get(const T &value) { return value.get(); } 228 }; 229 230 class PythonObject { 231 public: 232 PythonObject() : m_py_obj(nullptr) {} 233 234 PythonObject(PyRefType type, PyObject *py_obj) { 235 m_py_obj = py_obj; 236 // If this is a borrowed reference, we need to convert it to 237 // an owned reference by incrementing it. If it is an owned 238 // reference (for example the caller allocated it with PyDict_New() 239 // then we must *not* increment it. 240 if (m_py_obj && Py_IsInitialized() && type == PyRefType::Borrowed) 241 Py_XINCREF(m_py_obj); 242 } 243 244 PythonObject(const PythonObject &rhs) 245 : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {} 246 247 PythonObject(PythonObject &&rhs) { 248 m_py_obj = rhs.m_py_obj; 249 rhs.m_py_obj = nullptr; 250 } 251 252 ~PythonObject() { Reset(); } 253 254 void Reset() { 255 if (m_py_obj && Py_IsInitialized()) 256 Py_DECREF(m_py_obj); 257 m_py_obj = nullptr; 258 } 259 260 void Dump() const { 261 if (m_py_obj) 262 _PyObject_Dump(m_py_obj); 263 else 264 puts("NULL"); 265 } 266 267 void Dump(Stream &strm) const; 268 269 PyObject *get() const { return m_py_obj; } 270 271 PyObject *release() { 272 PyObject *result = m_py_obj; 273 m_py_obj = nullptr; 274 return result; 275 } 276 277 PythonObject &operator=(PythonObject other) { 278 Reset(); 279 m_py_obj = std::exchange(other.m_py_obj, nullptr); 280 return *this; 281 } 282 283 PyObjectType GetObjectType() const; 284 285 PythonString Repr() const; 286 287 PythonString Str() const; 288 289 static PythonObject ResolveNameWithDictionary(llvm::StringRef name, 290 const PythonDictionary &dict); 291 292 template <typename T> 293 static T ResolveNameWithDictionary(llvm::StringRef name, 294 const PythonDictionary &dict) { 295 return ResolveNameWithDictionary(name, dict).AsType<T>(); 296 } 297 298 PythonObject ResolveName(llvm::StringRef name) const; 299 300 template <typename T> T ResolveName(llvm::StringRef name) const { 301 return ResolveName(name).AsType<T>(); 302 } 303 304 bool HasAttribute(llvm::StringRef attribute) const; 305 306 PythonObject GetAttributeValue(llvm::StringRef attribute) const; 307 308 bool IsNone() const { return m_py_obj == Py_None; } 309 310 bool IsValid() const { return m_py_obj != nullptr; } 311 312 bool IsAllocated() const { return IsValid() && !IsNone(); } 313 314 explicit operator bool() const { return IsValid() && !IsNone(); } 315 316 template <typename T> T AsType() const { 317 if (!T::Check(m_py_obj)) 318 return T(); 319 return T(PyRefType::Borrowed, m_py_obj); 320 } 321 322 StructuredData::ObjectSP CreateStructuredObject() const; 323 324 public: 325 template <typename... T> 326 llvm::Expected<PythonObject> CallMethod(const char *name, 327 const T &... t) const { 328 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 329 PyObject *obj = 330 PyObject_CallMethod(m_py_obj, py2_const_cast(name), 331 py2_const_cast(format), PythonFormat<T>::get(t)...); 332 if (!obj) 333 return exception(); 334 return python::Take<PythonObject>(obj); 335 } 336 337 template <typename... T> 338 llvm::Expected<PythonObject> Call(const T &... t) const { 339 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 340 PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format), 341 PythonFormat<T>::get(t)...); 342 if (!obj) 343 return exception(); 344 return python::Take<PythonObject>(obj); 345 } 346 347 llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const { 348 if (!m_py_obj) 349 return nullDeref(); 350 PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name)); 351 if (!obj) 352 return exception(); 353 return python::Take<PythonObject>(obj); 354 } 355 356 llvm::Expected<bool> IsTrue() { 357 if (!m_py_obj) 358 return nullDeref(); 359 int r = PyObject_IsTrue(m_py_obj); 360 if (r < 0) 361 return exception(); 362 return !!r; 363 } 364 365 llvm::Expected<long long> AsLongLong() const; 366 367 llvm::Expected<long long> AsUnsignedLongLong() const; 368 369 // wraps on overflow, instead of raising an error. 370 llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const; 371 372 llvm::Expected<bool> IsInstance(const PythonObject &cls) { 373 if (!m_py_obj || !cls.IsValid()) 374 return nullDeref(); 375 int r = PyObject_IsInstance(m_py_obj, cls.get()); 376 if (r < 0) 377 return exception(); 378 return !!r; 379 } 380 381 protected: 382 PyObject *m_py_obj; 383 }; 384 385 386 // This is why C++ needs monads. 387 template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) { 388 if (!obj) 389 return obj.takeError(); 390 if (!T::Check(obj.get().get())) 391 return llvm::createStringError(llvm::inconvertibleErrorCode(), 392 "type error"); 393 return T(PyRefType::Borrowed, std::move(obj.get().get())); 394 } 395 396 template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj); 397 398 template <> 399 llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj); 400 401 template <> 402 llvm::Expected<unsigned long long> 403 As<unsigned long long>(llvm::Expected<PythonObject> &&obj); 404 405 template <> 406 llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj); 407 408 409 template <class T> class TypedPythonObject : public PythonObject { 410 public: 411 // override to perform implicit type conversions on Reset 412 // This can be eliminated once we drop python 2 support. 413 static void Convert(PyRefType &type, PyObject *&py_obj) {} 414 415 TypedPythonObject(PyRefType type, PyObject *py_obj) { 416 if (!py_obj) 417 return; 418 T::Convert(type, py_obj); 419 if (T::Check(py_obj)) 420 PythonObject::operator=(PythonObject(type, py_obj)); 421 else if (type == PyRefType::Owned) 422 Py_DECREF(py_obj); 423 } 424 425 TypedPythonObject() {} 426 }; 427 428 class PythonBytes : public TypedPythonObject<PythonBytes> { 429 public: 430 using TypedPythonObject::TypedPythonObject; 431 explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 432 PythonBytes(const uint8_t *bytes, size_t length); 433 434 static bool Check(PyObject *py_obj); 435 436 llvm::ArrayRef<uint8_t> GetBytes() const; 437 438 size_t GetSize() const; 439 440 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 441 442 StructuredData::StringSP CreateStructuredString() const; 443 }; 444 445 class PythonByteArray : public TypedPythonObject<PythonByteArray> { 446 public: 447 using TypedPythonObject::TypedPythonObject; 448 explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 449 PythonByteArray(const uint8_t *bytes, size_t length); 450 PythonByteArray(const PythonBytes &object); 451 452 static bool Check(PyObject *py_obj); 453 454 llvm::ArrayRef<uint8_t> GetBytes() const; 455 456 size_t GetSize() const; 457 458 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 459 460 StructuredData::StringSP CreateStructuredString() const; 461 }; 462 463 class PythonString : public TypedPythonObject<PythonString> { 464 public: 465 using TypedPythonObject::TypedPythonObject; 466 static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string); 467 468 PythonString() : TypedPythonObject() {} // MSVC requires this for some reason 469 470 explicit PythonString(llvm::StringRef string); // safe, null on error 471 472 static bool Check(PyObject *py_obj); 473 static void Convert(PyRefType &type, PyObject *&py_obj); 474 475 llvm::StringRef GetString() const; // safe, empty string on error 476 477 llvm::Expected<llvm::StringRef> AsUTF8() const; 478 479 size_t GetSize() const; 480 481 void SetString(llvm::StringRef string); // safe, null on error 482 483 StructuredData::StringSP CreateStructuredString() const; 484 }; 485 486 class PythonInteger : public TypedPythonObject<PythonInteger> { 487 public: 488 using TypedPythonObject::TypedPythonObject; 489 490 PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason 491 492 explicit PythonInteger(int64_t value); 493 494 static bool Check(PyObject *py_obj); 495 static void Convert(PyRefType &type, PyObject *&py_obj); 496 497 void SetInteger(int64_t value); 498 499 StructuredData::IntegerSP CreateStructuredInteger() const; 500 }; 501 502 class PythonBoolean : public TypedPythonObject<PythonBoolean> { 503 public: 504 using TypedPythonObject::TypedPythonObject; 505 506 explicit PythonBoolean(bool value); 507 508 static bool Check(PyObject *py_obj); 509 510 bool GetValue() const; 511 512 void SetValue(bool value); 513 514 StructuredData::BooleanSP CreateStructuredBoolean() const; 515 }; 516 517 class PythonList : public TypedPythonObject<PythonList> { 518 public: 519 using TypedPythonObject::TypedPythonObject; 520 521 PythonList() : TypedPythonObject() {} // MSVC requires this for some reason 522 523 explicit PythonList(PyInitialValue value); 524 explicit PythonList(int list_size); 525 526 static bool Check(PyObject *py_obj); 527 528 uint32_t GetSize() const; 529 530 PythonObject GetItemAtIndex(uint32_t index) const; 531 532 void SetItemAtIndex(uint32_t index, const PythonObject &object); 533 534 void AppendItem(const PythonObject &object); 535 536 StructuredData::ArraySP CreateStructuredArray() const; 537 }; 538 539 class PythonTuple : public TypedPythonObject<PythonTuple> { 540 public: 541 using TypedPythonObject::TypedPythonObject; 542 543 explicit PythonTuple(PyInitialValue value); 544 explicit PythonTuple(int tuple_size); 545 PythonTuple(std::initializer_list<PythonObject> objects); 546 PythonTuple(std::initializer_list<PyObject *> objects); 547 548 static bool Check(PyObject *py_obj); 549 550 uint32_t GetSize() const; 551 552 PythonObject GetItemAtIndex(uint32_t index) const; 553 554 void SetItemAtIndex(uint32_t index, const PythonObject &object); 555 556 StructuredData::ArraySP CreateStructuredArray() const; 557 }; 558 559 class PythonDictionary : public TypedPythonObject<PythonDictionary> { 560 public: 561 using TypedPythonObject::TypedPythonObject; 562 563 PythonDictionary() : TypedPythonObject() {} // MSVC requires this for some reason 564 565 explicit PythonDictionary(PyInitialValue value); 566 567 static bool Check(PyObject *py_obj); 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(); 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 } // namespace python 760 } // namespace lldb_private 761 762 #endif 763 764 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 765