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 // * Elimintate 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 #ifndef LLDB_DISABLE_PYTHON 52 53 // LLDB Python header must be included first 54 #include "lldb-python.h" 55 56 #include "lldb/Host/File.h" 57 #include "lldb/Utility/StructuredData.h" 58 59 #include "llvm/ADT/ArrayRef.h" 60 61 namespace lldb_private { 62 63 class PythonObject; 64 class PythonBytes; 65 class PythonString; 66 class PythonList; 67 class PythonDictionary; 68 class PythonInteger; 69 class PythonException; 70 71 class StructuredPythonObject : public StructuredData::Generic { 72 public: 73 StructuredPythonObject() : StructuredData::Generic() {} 74 75 StructuredPythonObject(void *obj) : StructuredData::Generic(obj) { 76 Py_XINCREF(GetValue()); 77 } 78 79 ~StructuredPythonObject() override { 80 if (Py_IsInitialized()) 81 Py_XDECREF(GetValue()); 82 SetValue(nullptr); 83 } 84 85 bool IsValid() const override { return GetValue() && GetValue() != Py_None; } 86 87 void Serialize(llvm::json::OStream &s) const override; 88 89 private: 90 DISALLOW_COPY_AND_ASSIGN(StructuredPythonObject); 91 }; 92 93 enum class PyObjectType { 94 Unknown, 95 None, 96 Boolean, 97 Integer, 98 Dictionary, 99 List, 100 String, 101 Bytes, 102 ByteArray, 103 Module, 104 Callable, 105 Tuple, 106 File 107 }; 108 109 enum class PyRefType { 110 Borrowed, // We are not given ownership of the incoming PyObject. 111 // We cannot safely hold it without calling Py_INCREF. 112 Owned // We have ownership of the incoming PyObject. We should 113 // not call Py_INCREF. 114 }; 115 116 namespace python { 117 118 // Take a reference that you already own, and turn it into 119 // a PythonObject. 120 // 121 // Most python API methods will return a +1 reference 122 // if they succeed or NULL if and only if 123 // they set an exception. Use this to collect such return 124 // values, after checking for NULL. 125 // 126 // If T is not just PythonObject, then obj must be already be 127 // checked to be of the correct type. 128 template <typename T> T Take(PyObject *obj) { 129 assert(obj); 130 assert(!PyErr_Occurred()); 131 T thing(PyRefType::Owned, obj); 132 assert(thing.IsValid()); 133 return std::move(thing); 134 } 135 136 // Retain a reference you have borrowed, and turn it into 137 // a PythonObject. 138 // 139 // A minority of python APIs return a borrowed reference 140 // instead of a +1. They will also return NULL if and only 141 // if they set an exception. Use this to collect such return 142 // values, after checking for NULL. 143 // 144 // If T is not just PythonObject, then obj must be already be 145 // checked to be of the correct type. 146 template <typename T> T Retain(PyObject *obj) { 147 assert(obj); 148 assert(!PyErr_Occurred()); 149 T thing(PyRefType::Borrowed, obj); 150 assert(thing.IsValid()); 151 return std::move(thing); 152 } 153 154 // This class can be used like a utility function to convert from 155 // a llvm-friendly Twine into a null-terminated const char *, 156 // which is the form python C APIs want their strings in. 157 // 158 // Example: 159 // const llvm::Twine &some_twine; 160 // PyFoo_Bar(x, y, z, NullTerminated(some_twine)); 161 // 162 // Why a class instead of a function? If the twine isn't already null 163 // terminated, it will need a temporary buffer to copy the string 164 // into. We need that buffer to stick around for the lifetime of the 165 // statement. 166 class NullTerminated { 167 const char *str; 168 llvm::SmallString<32> storage; 169 170 public: 171 NullTerminated(const llvm::Twine &twine) { 172 llvm::StringRef ref = twine.toNullTerminatedStringRef(storage); 173 str = ref.begin(); 174 } 175 operator const char *() { return str; } 176 }; 177 178 } // namespace python 179 180 enum class PyInitialValue { Invalid, Empty }; 181 182 template <typename T, typename Enable = void> struct PythonFormat; 183 184 template <> struct PythonFormat<unsigned long long> { 185 static constexpr char format = 'K'; 186 static auto get(unsigned long long value) { return value; } 187 }; 188 189 template <> struct PythonFormat<long long> { 190 static constexpr char format = 'L'; 191 static auto get(long long value) { return value; } 192 }; 193 194 template <typename T> 195 struct PythonFormat< 196 T, typename std::enable_if<std::is_base_of<PythonObject, T>::value>::type> { 197 static constexpr char format = 'O'; 198 static auto get(const T &value) { return value.get(); } 199 }; 200 201 class PythonObject { 202 public: 203 PythonObject() : m_py_obj(nullptr) {} 204 205 PythonObject(PyRefType type, PyObject *py_obj) : m_py_obj(nullptr) { 206 Reset(type, py_obj); 207 } 208 209 PythonObject(const PythonObject &rhs) 210 : PythonObject(PyRefType::Borrowed, rhs.m_py_obj) {} 211 212 PythonObject(PythonObject &&rhs) { 213 m_py_obj = rhs.m_py_obj; 214 rhs.m_py_obj = nullptr; 215 } 216 217 ~PythonObject() { Reset(); } 218 219 void Reset() { 220 if (m_py_obj && Py_IsInitialized()) 221 Py_DECREF(m_py_obj); 222 m_py_obj = nullptr; 223 } 224 225 void Reset(PyRefType type, PyObject *py_obj) { 226 if (py_obj == m_py_obj) 227 return; 228 229 if (Py_IsInitialized()) 230 Py_XDECREF(m_py_obj); 231 232 m_py_obj = py_obj; 233 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 void Dump() const { 243 if (m_py_obj) 244 _PyObject_Dump(m_py_obj); 245 else 246 puts("NULL"); 247 } 248 249 void Dump(Stream &strm) const; 250 251 PyObject *get() const { return m_py_obj; } 252 253 PyObject *release() { 254 PyObject *result = m_py_obj; 255 m_py_obj = nullptr; 256 return result; 257 } 258 259 PythonObject &operator=(PythonObject other) { 260 Reset(); 261 m_py_obj = std::exchange(other.m_py_obj, nullptr); 262 return *this; 263 } 264 265 PyObjectType GetObjectType() const; 266 267 PythonString Repr() const; 268 269 PythonString Str() const; 270 271 static PythonObject ResolveNameWithDictionary(llvm::StringRef name, 272 const PythonDictionary &dict); 273 274 template <typename T> 275 static T ResolveNameWithDictionary(llvm::StringRef name, 276 const PythonDictionary &dict) { 277 return ResolveNameWithDictionary(name, dict).AsType<T>(); 278 } 279 280 PythonObject ResolveName(llvm::StringRef name) const; 281 282 template <typename T> T ResolveName(llvm::StringRef name) const { 283 return ResolveName(name).AsType<T>(); 284 } 285 286 bool HasAttribute(llvm::StringRef attribute) const; 287 288 PythonObject GetAttributeValue(llvm::StringRef attribute) const; 289 290 bool IsNone() const { return m_py_obj == Py_None; } 291 292 bool IsValid() const { return m_py_obj != nullptr; } 293 294 bool IsAllocated() const { return IsValid() && !IsNone(); } 295 296 explicit operator bool() const { return IsValid() && !IsNone(); } 297 298 template <typename T> T AsType() const { 299 if (!T::Check(m_py_obj)) 300 return T(); 301 return T(PyRefType::Borrowed, m_py_obj); 302 } 303 304 StructuredData::ObjectSP CreateStructuredObject() const; 305 306 protected: 307 static llvm::Error nullDeref() { 308 return llvm::createStringError(llvm::inconvertibleErrorCode(), 309 "A NULL PyObject* was dereferenced"); 310 } 311 static llvm::Error exception(const char *s = nullptr) { 312 return llvm::make_error<PythonException>(s); 313 } 314 static llvm::Error keyError() { 315 return llvm::createStringError(llvm::inconvertibleErrorCode(), 316 "key not in dict"); 317 } 318 319 #if PY_MAJOR_VERSION < 3 320 // The python 2 API declares some arguments as char* that should 321 // be const char *, but it doesn't actually modify them. 322 static char *py2_const_cast(const char *s) { return const_cast<char *>(s); } 323 #else 324 static const char *py2_const_cast(const char *s) { return s; } 325 #endif 326 327 public: 328 template <typename... T> 329 llvm::Expected<PythonObject> CallMethod(const char *name, 330 const T &... t) const { 331 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 332 PyObject *obj = 333 PyObject_CallMethod(m_py_obj, py2_const_cast(name), 334 py2_const_cast(format), PythonFormat<T>::get(t)...); 335 if (!obj) 336 return exception(); 337 return python::Take<PythonObject>(obj); 338 } 339 340 template <typename... T> 341 llvm::Expected<PythonObject> Call(const T &... t) const { 342 const char format[] = {'(', PythonFormat<T>::format..., ')', 0}; 343 PyObject *obj = PyObject_CallFunction(m_py_obj, py2_const_cast(format), 344 PythonFormat<T>::get(t)...); 345 if (!obj) 346 return exception(); 347 return python::Take<PythonObject>(obj); 348 } 349 350 llvm::Expected<PythonObject> GetAttribute(const llvm::Twine &name) const { 351 using namespace python; 352 if (!m_py_obj) 353 return nullDeref(); 354 PyObject *obj = PyObject_GetAttrString(m_py_obj, NullTerminated(name)); 355 if (!obj) 356 return exception(); 357 return python::Take<PythonObject>(obj); 358 } 359 360 llvm::Expected<bool> IsTrue() { 361 if (!m_py_obj) 362 return nullDeref(); 363 int r = PyObject_IsTrue(m_py_obj); 364 if (r < 0) 365 return exception(); 366 return !!r; 367 } 368 369 llvm::Expected<long long> AsLongLong() { 370 if (!m_py_obj) 371 return nullDeref(); 372 assert(!PyErr_Occurred()); 373 long long r = PyLong_AsLongLong(m_py_obj); 374 if (PyErr_Occurred()) 375 return exception(); 376 return r; 377 } 378 379 llvm::Expected<bool> IsInstance(const PythonObject &cls) { 380 if (!m_py_obj || !cls.IsValid()) 381 return nullDeref(); 382 int r = PyObject_IsInstance(m_py_obj, cls.get()); 383 if (r < 0) 384 return exception(); 385 return !!r; 386 } 387 388 protected: 389 PyObject *m_py_obj; 390 }; 391 392 namespace python { 393 394 // This is why C++ needs monads. 395 template <typename T> llvm::Expected<T> As(llvm::Expected<PythonObject> &&obj) { 396 if (!obj) 397 return obj.takeError(); 398 if (!T::Check(obj.get().get())) 399 return llvm::createStringError(llvm::inconvertibleErrorCode(), 400 "type error"); 401 return T(PyRefType::Borrowed, std::move(obj.get().get())); 402 } 403 404 template <> llvm::Expected<bool> As<bool>(llvm::Expected<PythonObject> &&obj); 405 406 template <> 407 llvm::Expected<long long> As<long long>(llvm::Expected<PythonObject> &&obj); 408 409 template <> 410 llvm::Expected<std::string> As<std::string>(llvm::Expected<PythonObject> &&obj); 411 412 } // namespace python 413 414 template <class T> class TypedPythonObject : public PythonObject { 415 public: 416 // override to perform implicit type conversions on Reset 417 // This can be eliminated once we drop python 2 support. 418 static void Convert(PyRefType &type, PyObject *&py_obj) {} 419 420 void Reset() { PythonObject::Reset(); } 421 422 void Reset(PyRefType type, PyObject *py_obj) = delete; 423 424 TypedPythonObject(PyRefType type, PyObject *py_obj) { 425 if (!py_obj) 426 return; 427 T::Convert(type, py_obj); 428 if (T::Check(py_obj)) 429 PythonObject::Reset(type, py_obj); 430 else if (type == PyRefType::Owned) 431 Py_DECREF(py_obj); 432 } 433 434 TypedPythonObject() {} 435 }; 436 437 class PythonBytes : public TypedPythonObject<PythonBytes> { 438 public: 439 using TypedPythonObject::TypedPythonObject; 440 explicit PythonBytes(llvm::ArrayRef<uint8_t> bytes); 441 PythonBytes(const uint8_t *bytes, size_t length); 442 443 static bool Check(PyObject *py_obj); 444 445 llvm::ArrayRef<uint8_t> GetBytes() const; 446 447 size_t GetSize() const; 448 449 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 450 451 StructuredData::StringSP CreateStructuredString() const; 452 }; 453 454 class PythonByteArray : public TypedPythonObject<PythonByteArray> { 455 public: 456 using TypedPythonObject::TypedPythonObject; 457 explicit PythonByteArray(llvm::ArrayRef<uint8_t> bytes); 458 PythonByteArray(const uint8_t *bytes, size_t length); 459 PythonByteArray(const PythonBytes &object); 460 461 static bool Check(PyObject *py_obj); 462 463 llvm::ArrayRef<uint8_t> GetBytes() const; 464 465 size_t GetSize() const; 466 467 void SetBytes(llvm::ArrayRef<uint8_t> stringbytes); 468 469 StructuredData::StringSP CreateStructuredString() const; 470 }; 471 472 class PythonString : public TypedPythonObject<PythonString> { 473 public: 474 using TypedPythonObject::TypedPythonObject; 475 static llvm::Expected<PythonString> FromUTF8(llvm::StringRef string); 476 477 PythonString() : TypedPythonObject() {} // MSVC requires this for some reason 478 479 explicit PythonString(llvm::StringRef string); // safe, null on error 480 481 static bool Check(PyObject *py_obj); 482 static void Convert(PyRefType &type, PyObject *&py_obj); 483 484 llvm::StringRef GetString() const; // safe, empty string on error 485 486 llvm::Expected<llvm::StringRef> AsUTF8() const; 487 488 size_t GetSize() const; 489 490 void SetString(llvm::StringRef string); // safe, null on error 491 492 StructuredData::StringSP CreateStructuredString() const; 493 }; 494 495 class PythonInteger : public TypedPythonObject<PythonInteger> { 496 public: 497 using TypedPythonObject::TypedPythonObject; 498 499 PythonInteger() : TypedPythonObject() {} // MSVC requires this for some reason 500 501 explicit PythonInteger(int64_t value); 502 503 static bool Check(PyObject *py_obj); 504 static void Convert(PyRefType &type, PyObject *&py_obj); 505 506 int64_t GetInteger() const; 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 = 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 /* the number of positional arguments, including optional ones, 637 * and excluding varargs. If this is a bound method, then the 638 * count will still include a +1 for self. 639 * 640 * FIXME. That's crazy. This should be replaced with 641 * an accurate min and max for positional args. 642 */ 643 int count; 644 /* does the callable have positional varargs? */ 645 bool has_varargs : 1; // FIXME delete this 646 }; 647 648 static bool Check(PyObject *py_obj); 649 650 llvm::Expected<ArgInfo> GetArgInfo() const; 651 652 llvm::Expected<ArgInfo> GetInitArgInfo() const; 653 654 ArgInfo GetNumArguments() const; // DEPRECATED 655 656 // If the callable is a Py_Class, then find the number of arguments 657 // of the __init__ method. 658 ArgInfo GetNumInitArguments() const; // DEPRECATED 659 660 PythonObject operator()(); 661 662 PythonObject operator()(std::initializer_list<PyObject *> args); 663 664 PythonObject operator()(std::initializer_list<PythonObject> args); 665 666 template <typename Arg, typename... Args> 667 PythonObject operator()(const Arg &arg, Args... args) { 668 return operator()({arg, args...}); 669 } 670 }; 671 672 class PythonFile : public TypedPythonObject<PythonFile> { 673 public: 674 using TypedPythonObject::TypedPythonObject; 675 676 PythonFile() : TypedPythonObject() {} // MSVC requires this for some reason 677 678 static bool Check(PyObject *py_obj); 679 680 static llvm::Expected<PythonFile> FromFile(File &file, 681 const char *mode = nullptr); 682 683 llvm::Expected<lldb::FileSP> ConvertToFile(bool borrowed = false); 684 llvm::Expected<lldb::FileSP> 685 ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed = false); 686 }; 687 688 class PythonException : public llvm::ErrorInfo<PythonException> { 689 private: 690 PyObject *m_exception_type, *m_exception, *m_traceback; 691 PyObject *m_repr_bytes; 692 693 public: 694 static char ID; 695 const char *toCString() const; 696 PythonException(const char *caller = nullptr); 697 void Restore(); 698 ~PythonException(); 699 void log(llvm::raw_ostream &OS) const override; 700 std::error_code convertToErrorCode() const override; 701 }; 702 703 // This extracts the underlying T out of an Expected<T> and returns it. 704 // If the Expected is an Error instead of a T, that error will be converted 705 // into a python exception, and this will return a default-constructed T. 706 // 707 // This is appropriate for use right at the boundary of python calling into 708 // C++, such as in a SWIG typemap. In such a context you should simply 709 // check if the returned T is valid, and if it is, return a NULL back 710 // to python. This will result in the Error being raised as an exception 711 // from python code's point of view. 712 // 713 // For example: 714 // ``` 715 // Expected<Foo *> efoop = some_cpp_function(); 716 // Foo *foop = unwrapOrSetPythonException(efoop); 717 // if (!foop) 718 // return NULL; 719 // do_something(*foop); 720 // 721 // If the Error returned was itself created because a python exception was 722 // raised when C++ code called into python, then the original exception 723 // will be restored. Otherwise a simple string exception will be raised. 724 template <typename T> T unwrapOrSetPythonException(llvm::Expected<T> expected) { 725 if (expected) 726 return expected.get(); 727 llvm::handleAllErrors( 728 expected.takeError(), [](PythonException &E) { E.Restore(); }, 729 [](const llvm::ErrorInfoBase &E) { 730 PyErr_SetString(PyExc_Exception, E.message().c_str()); 731 }); 732 return T(); 733 } 734 735 namespace python { 736 // This is only here to help incrementally migrate old, exception-unsafe 737 // code. 738 template <typename T> T unwrapIgnoringErrors(llvm::Expected<T> expected) { 739 if (expected) 740 return std::move(expected.get()); 741 llvm::consumeError(expected.takeError()); 742 return T(); 743 } 744 } // namespace python 745 746 } // namespace lldb_private 747 748 #endif 749 750 #endif // LLDB_PLUGINS_SCRIPTINTERPRETER_PYTHON_PYTHONDATAOBJECTS_H 751