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