LLDB mainline
PythonDataObjects.cpp
Go to the documentation of this file.
1//===-- PythonDataObjects.cpp ---------------------------------------------===//
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#include "PythonDataObjects.h"
11
12#include "lldb/Host/File.h"
16#include "lldb/Utility/Log.h"
17#include "lldb/Utility/Stream.h"
18
19#include "llvm/ADT/ScopeExit.h"
20#include "llvm/Support/Casting.h"
21#include "llvm/Support/ConvertUTF.h"
22#include "llvm/Support/Errno.h"
23
24#ifdef _WIN32
26#endif
27
28#include <cstdio>
29#include <variant>
30
31using namespace lldb_private;
32using namespace lldb;
33using namespace lldb_private::python;
34using llvm::cantFail;
35using llvm::Error;
36using llvm::Expected;
37using llvm::Twine;
38
39template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) {
40 if (!obj)
41 return obj.takeError();
42 return obj.get().IsTrue();
43}
44
45template <>
46Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
47 if (!obj)
48 return obj.takeError();
49 return obj->AsLongLong();
50}
51
52template <>
53Expected<unsigned long long>
54python::As<unsigned long long>(Expected<PythonObject> &&obj) {
55 if (!obj)
56 return obj.takeError();
57 return obj->AsUnsignedLongLong();
58}
59
60template <>
61Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
62 if (!obj)
63 return obj.takeError();
64 PyObject *str_obj = PyObject_Str(obj.get().get());
65 if (!str_obj)
66 return llvm::make_error<PythonException>();
67 auto str = Take<PythonString>(str_obj);
68 auto utf8 = str.AsUTF8();
69 if (!utf8)
70 return utf8.takeError();
71 return std::string(utf8.get());
72}
73
75 if (m_py_obj && Py_IsInitialized()) {
76 PyGILState_STATE state = PyGILState_Ensure();
77 Py_DECREF(m_py_obj);
78 PyGILState_Release(state);
79 }
80 m_py_obj = nullptr;
81}
82
83Expected<long long> PythonObject::AsLongLong() const {
84 if (!m_py_obj)
85 return nullDeref();
86 assert(!PyErr_Occurred());
87 long long r = PyLong_AsLongLong(m_py_obj);
88 if (PyErr_Occurred())
89 return exception();
90 return r;
91}
92
93Expected<unsigned long long> PythonObject::AsUnsignedLongLong() const {
94 if (!m_py_obj)
95 return nullDeref();
96 assert(!PyErr_Occurred());
97 long long r = PyLong_AsUnsignedLongLong(m_py_obj);
98 if (PyErr_Occurred())
99 return exception();
100 return r;
101}
102
103// wraps on overflow, instead of raising an error.
104Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const {
105 if (!m_py_obj)
106 return nullDeref();
107 assert(!PyErr_Occurred());
108 unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
109 // FIXME: We should fetch the exception message and hoist it.
110 if (PyErr_Occurred())
111 return exception();
112 return r;
113}
114
115void StructuredPythonObject::Serialize(llvm::json::OStream &s) const {
116 s.value(llvm::formatv("Python Obj: {0:X}", GetValue()).str());
117}
118
119// PythonObject
120
121void PythonObject::Dump(Stream &strm) const {
122 if (!m_py_obj) {
123 strm << "NULL";
124 return;
125 }
126
127 PyObject *py_str = PyObject_Repr(m_py_obj);
128 if (!py_str)
129 return;
130
131 llvm::scope_exit release_py_str([py_str] { Py_DECREF(py_str); });
132
133 PyObject *py_bytes = PyUnicode_AsEncodedString(py_str, "utf-8", "replace");
134 if (!py_bytes)
135 return;
136
137 llvm::scope_exit release_py_bytes([py_bytes] { Py_DECREF(py_bytes); });
138
139 char *buffer = nullptr;
140 Py_ssize_t length = 0;
141 if (PyBytes_AsStringAndSize(py_bytes, &buffer, &length) == -1)
142 return;
143
144 strm << llvm::StringRef(buffer, length);
145}
146
175
177 if (!m_py_obj)
178 return PythonString();
179 PyObject *repr = PyObject_Repr(m_py_obj);
180 if (!repr)
181 return PythonString();
182 return PythonString(PyRefType::Owned, repr);
183}
184
186 if (!m_py_obj)
187 return PythonString();
188 PyObject *str = PyObject_Str(m_py_obj);
189 if (!str)
190 return PythonString();
191 return PythonString(PyRefType::Owned, str);
192}
193
196 const PythonDictionary &dict) {
197 size_t dot_pos = name.find('.');
198 llvm::StringRef piece = name.substr(0, dot_pos);
199 PythonObject result = dict.GetItemForKey(PythonString(piece));
200 if (dot_pos == llvm::StringRef::npos) {
201 // There was no dot, we're done.
202 return result;
203 }
204
205 // There was a dot. The remaining portion of the name should be looked up in
206 // the context of the object that was found in the dictionary.
207 return result.ResolveName(name.substr(dot_pos + 1));
208}
209
210PythonObject PythonObject::ResolveName(llvm::StringRef name) const {
211 // Resolve the name in the context of the specified object. If, for example,
212 // `this` refers to a PyModule, then this will look for `name` in this
213 // module. If `this` refers to a PyType, then it will resolve `name` as an
214 // attribute of that type. If `this` refers to an instance of an object,
215 // then it will resolve `name` as the value of the specified field.
216 //
217 // This function handles dotted names so that, for example, if `m_py_obj`
218 // refers to the `sys` module, and `name` == "path.append", then it will find
219 // the function `sys.path.append`.
220
221 size_t dot_pos = name.find('.');
222 if (dot_pos == llvm::StringRef::npos) {
223 // No dots in the name, we should be able to find the value immediately as
224 // an attribute of `m_py_obj`.
225 return GetAttributeValue(name);
226 }
227
228 // Look up the first piece of the name, and resolve the rest as a child of
229 // that.
230 PythonObject parent = ResolveName(name.substr(0, dot_pos));
231 if (!parent.IsAllocated())
232 return PythonObject();
233
234 // Tail recursion.. should be optimized by the compiler
235 return parent.ResolveName(name.substr(dot_pos + 1));
236}
237
238bool PythonObject::HasAttribute(llvm::StringRef attr) const {
239 if (!IsValid())
240 return false;
241 PythonString py_attr(attr);
242 return !!PyObject_HasAttr(m_py_obj, py_attr.get());
243}
244
246 if (!IsValid())
247 return PythonObject();
248
249 PythonString py_attr(attr);
250 if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
251 return PythonObject();
252
254 PyObject_GetAttr(m_py_obj, py_attr.get()));
255}
256
258 switch (GetObjectType()) {
268 if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp))
269 return std::get<StructuredData::UnsignedIntegerSP>(int_sp);
270 if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp))
271 return std::get<StructuredData::SignedIntegerSP>(int_sp);
272 return nullptr;
273 };
285 default:
288 }
289}
290
291// PythonString
292
293PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
294
295PythonBytes::PythonBytes(const uint8_t *bytes, size_t length) {
296 SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
297}
298
299bool PythonBytes::Check(PyObject *py_obj) {
300 if (!py_obj)
301 return false;
302 return PyBytes_Check(py_obj);
303}
304
305llvm::ArrayRef<uint8_t> PythonBytes::GetBytes() const {
306 if (!IsValid())
307 return llvm::ArrayRef<uint8_t>();
308
309 Py_ssize_t size;
310 char *c;
311
312 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
313 return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
314}
315
316size_t PythonBytes::GetSize() const {
317 if (!IsValid())
318 return 0;
319 return PyBytes_Size(m_py_obj);
320}
321
322void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
323 const char *data = reinterpret_cast<const char *>(bytes.data());
324 *this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size()));
325}
326
329 Py_ssize_t size;
330 char *c;
331 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
332 result->SetValue(std::string(c, size));
333 return result;
334}
335
336PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
337 : PythonByteArray(bytes.data(), bytes.size()) {}
338
339PythonByteArray::PythonByteArray(const uint8_t *bytes, size_t length) {
340 const char *str = reinterpret_cast<const char *>(bytes);
341 *this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length));
342}
343
344bool PythonByteArray::Check(PyObject *py_obj) {
345 if (!py_obj)
346 return false;
347 return PyByteArray_Check(py_obj);
348}
349
350llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes() const {
351 if (!IsValid())
352 return llvm::ArrayRef<uint8_t>();
353
354 char *c = PyByteArray_AsString(m_py_obj);
355 size_t size = GetSize();
356 return llvm::ArrayRef<uint8_t>(reinterpret_cast<uint8_t *>(c), size);
357}
358
360 if (!IsValid())
361 return 0;
362
363 return PyByteArray_Size(m_py_obj);
364}
365
368 llvm::ArrayRef<uint8_t> bytes = GetBytes();
369 const char *str = reinterpret_cast<const char *>(bytes.data());
370 result->SetValue(std::string(str, bytes.size()));
371 return result;
372}
373
374// PythonString
375
376Expected<PythonString> PythonString::FromUTF8(llvm::StringRef string) {
377 PyObject *str = PyUnicode_FromStringAndSize(string.data(), string.size());
378 if (!str)
379 return llvm::make_error<PythonException>();
380 return Take<PythonString>(str);
381}
382
383PythonString::PythonString(llvm::StringRef string) { SetString(string); }
384
385bool PythonString::Check(PyObject *py_obj) {
386 if (!py_obj)
387 return false;
388
389 if (PyUnicode_Check(py_obj))
390 return true;
391 return false;
392}
393
394llvm::StringRef PythonString::GetString() const {
395 auto s = AsUTF8();
396 if (!s) {
397 llvm::consumeError(s.takeError());
398 return llvm::StringRef("");
399 }
400 return s.get();
401}
402
403Expected<llvm::StringRef> PythonString::AsUTF8() const {
404 if (!IsValid())
405 return nullDeref();
406
407 // PyUnicode_AsUTF8AndSize caches the UTF-8 representation of the string in
408 // the Unicode object, which makes it more efficient and ties the lifetime of
409 // the data to the Python string. However, it was only added to the Stable API
410 // in Python 3.10. Older versions that want to use the Stable API must use
411 // PyUnicode_AsUTF8String in combination with ConstString.
412#if defined(Py_LIMITED_API) && (Py_LIMITED_API < 0x030a0000)
413 PyObject *py_bytes = PyUnicode_AsUTF8String(m_py_obj);
414 if (!py_bytes)
415 return exception();
416 llvm::scope_exit release_py_str([py_bytes] { Py_DECREF(py_bytes); });
417 Py_ssize_t size = PyBytes_Size(py_bytes);
418 const char *str = PyBytes_AsString(py_bytes);
419
420 if (!str)
421 return exception();
422
423 return ConstString(str, size).GetStringRef();
424#else
425 Py_ssize_t size;
426 const char *str = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
427
428 if (!str)
429 return exception();
430
431 return llvm::StringRef(str, size);
432#endif
433}
434
435size_t PythonString::GetSize() const {
436 if (IsValid())
437 return PyUnicode_GetLength(m_py_obj);
438 return 0;
439}
440
441void PythonString::SetString(llvm::StringRef string) {
442 auto s = FromUTF8(string);
443 if (!s) {
444 llvm::consumeError(s.takeError());
445 Reset();
446 } else {
447 *this = std::move(s.get());
448 }
449}
450
453 result->SetValue(GetString());
454 return result;
455}
456
457// PythonInteger
458
459PythonInteger::PythonInteger(int64_t value) { SetInteger(value); }
460
461bool PythonInteger::Check(PyObject *py_obj) {
462 if (!py_obj)
463 return false;
464
465 // Python 3 does not have PyInt_Check. There is only one type of integral
466 // value, long.
467 return PyLong_Check(py_obj);
468}
469
470void PythonInteger::SetInteger(int64_t value) {
471 *this = Take<PythonInteger>(PyLong_FromLongLong(value));
472}
473
479
482 StructuredData::UnsignedIntegerSP result = nullptr;
483 llvm::Expected<unsigned long long> value = AsUnsignedLongLong();
484 if (!value)
485 llvm::consumeError(value.takeError());
486 else
487 result = std::make_shared<StructuredData::UnsignedInteger>(value.get());
488
489 return result;
490}
491
494 StructuredData::SignedIntegerSP result = nullptr;
495 llvm::Expected<long long> value = AsLongLong();
496 if (!value)
497 llvm::consumeError(value.takeError());
498 else
499 result = std::make_shared<StructuredData::SignedInteger>(value.get());
500
501 return result;
502}
503
504// PythonBoolean
505
507
508bool PythonBoolean::Check(PyObject *py_obj) {
509 return py_obj ? PyBool_Check(py_obj) : false;
510}
511
513 return m_py_obj ? PyObject_IsTrue(m_py_obj) : false;
514}
515
516void PythonBoolean::SetValue(bool value) {
517 *this = Take<PythonBoolean>(PyBool_FromLong(value));
518}
519
525
526// PythonList
527
529 if (value == PyInitialValue::Empty)
530 *this = Take<PythonList>(PyList_New(0));
531}
532
534 *this = Take<PythonList>(PyList_New(list_size));
535}
536
537bool PythonList::Check(PyObject *py_obj) {
538 if (!py_obj)
539 return false;
540 return PyList_Check(py_obj);
541}
542
543uint32_t PythonList::GetSize() const {
544 if (IsValid())
545 return PyList_Size(m_py_obj);
546 return 0;
547}
548
550 if (IsValid())
551 return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
552 return PythonObject();
553}
554
555void PythonList::SetItemAtIndex(uint32_t index, const PythonObject &object) {
556 if (IsAllocated() && object.IsValid()) {
557 // PyList_SetItem is documented to "steal" a reference, so we need to
558 // convert it to an owned reference by incrementing it.
559 Py_INCREF(object.get());
560 PyList_SetItem(m_py_obj, index, object.get());
561 }
562}
563
565 if (IsAllocated() && object.IsValid()) {
566 // `PyList_Append` does *not* steal a reference, so do not call `Py_INCREF`
567 // here like we do with `PyList_SetItem`.
568 PyList_Append(m_py_obj, object.get());
569 }
570}
571
574 uint32_t count = GetSize();
575 for (uint32_t i = 0; i < count; ++i) {
577 result->AddItem(obj.CreateStructuredObject());
578 }
579 return result;
580}
581
582// PythonTuple
583
585 if (value == PyInitialValue::Empty)
586 *this = Take<PythonTuple>(PyTuple_New(0));
587}
588
590 *this = Take<PythonTuple>(PyTuple_New(tuple_size));
591}
592
593PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
594 m_py_obj = PyTuple_New(objects.size());
595
596 uint32_t idx = 0;
597 for (auto object : objects) {
598 if (object.IsValid())
599 SetItemAtIndex(idx, object);
600 idx++;
601 }
602}
603
604PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
605 m_py_obj = PyTuple_New(objects.size());
606
607 uint32_t idx = 0;
608 for (auto py_object : objects) {
609 PythonObject object(PyRefType::Borrowed, py_object);
610 if (object.IsValid())
611 SetItemAtIndex(idx, object);
612 idx++;
613 }
614}
615
616bool PythonTuple::Check(PyObject *py_obj) {
617 if (!py_obj)
618 return false;
619 return PyTuple_Check(py_obj);
620}
621
622uint32_t PythonTuple::GetSize() const {
623 if (IsValid())
624 return PyTuple_Size(m_py_obj);
625 return 0;
626}
627
629 if (IsValid())
630 return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
631 return PythonObject();
632}
633
634void PythonTuple::SetItemAtIndex(uint32_t index, const PythonObject &object) {
635 if (IsAllocated() && object.IsValid()) {
636 // PyTuple_SetItem is documented to "steal" a reference, so we need to
637 // convert it to an owned reference by incrementing it.
638 Py_INCREF(object.get());
639 PyTuple_SetItem(m_py_obj, index, object.get());
640 }
641}
642
645 uint32_t count = GetSize();
646 for (uint32_t i = 0; i < count; ++i) {
648 result->AddItem(obj.CreateStructuredObject());
649 }
650 return result;
651}
652
653// PythonDictionary
654
659
660bool PythonDictionary::Check(PyObject *py_obj) {
661 if (!py_obj)
662 return false;
663
664 return PyDict_Check(py_obj);
665}
666
667bool PythonDictionary::HasKey(const llvm::Twine &key) const {
668 if (!IsValid())
669 return false;
670
671 PythonString key_object(key.isSingleStringRef() ? key.getSingleStringRef()
672 : key.str());
673
674 if (int res = PyDict_Contains(m_py_obj, key_object.get()) > 0)
675 return res;
676
677 PyErr_Print();
678 return false;
679}
680
682 if (IsValid())
683 return PyDict_Size(m_py_obj);
684 return 0;
685}
686
692
694 auto item = GetItem(key);
695 if (!item) {
696 llvm::consumeError(item.takeError());
697 return PythonObject();
698 }
699 return std::move(item.get());
700}
701
702Expected<PythonObject>
704 if (!IsValid() || !key.IsValid())
705 return nullDeref();
706 PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
707 if (PyErr_Occurred())
708 return exception();
709 if (!o)
710 return keyError();
711 return Retain<PythonObject>(o);
712}
713
714Expected<PythonObject> PythonDictionary::GetItem(const Twine &key) const {
715 if (!IsValid())
716 return nullDeref();
717 PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
718 if (PyErr_Occurred())
719 return exception();
720 if (!o)
721 return keyError();
722 return Retain<PythonObject>(o);
723}
724
726 const PythonObject &value) const {
727 if (!IsValid() || !value.IsValid())
728 return nullDeref();
729 int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
730 if (r < 0)
731 return exception();
732 return Error::success();
733}
734
735Error PythonDictionary::SetItem(const Twine &key,
736 const PythonObject &value) const {
737 if (!IsValid() || !value.IsValid())
738 return nullDeref();
739 int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
740 if (r < 0)
741 return exception();
742 return Error::success();
743}
744
746 const PythonObject &value) {
747 Error error = SetItem(key, value);
748 if (error)
749 llvm::consumeError(std::move(error));
750}
751
755 PythonList keys(GetKeys());
756 uint32_t num_keys = keys.GetSize();
757 for (uint32_t i = 0; i < num_keys; ++i) {
758 PythonObject key = keys.GetItemAtIndex(i);
759 PythonObject value = GetItemForKey(key);
760 StructuredData::ObjectSP structured_value = value.CreateStructuredObject();
761 result->AddItem(key.Str().GetString(), structured_value);
762 }
763 return result;
764}
765
767
769
770PythonModule PythonModule::AddModule(llvm::StringRef module) {
771 std::string str = module.str();
772 return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
773}
774
775Expected<PythonModule> PythonModule::Import(const Twine &name) {
776 PyObject *mod = PyImport_ImportModule(NullTerminated(name));
777 if (!mod)
778 return exception();
779 return Take<PythonModule>(mod);
780}
781
782Expected<PythonObject> PythonModule::Get(const Twine &name) {
783 if (!IsValid())
784 return nullDeref();
785 PyObject *dict = PyModule_GetDict(m_py_obj);
786 if (!dict)
787 return exception();
788 PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
789 if (!item)
790 return exception();
791 return Retain<PythonObject>(item);
792}
793
794bool PythonModule::Check(PyObject *py_obj) {
795 if (!py_obj)
796 return false;
797
798 return PyModule_Check(py_obj);
799}
800
802 if (!IsValid())
803 return PythonDictionary();
804 return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
805}
806
807bool PythonCallable::Check(PyObject *py_obj) {
808 if (!py_obj)
809 return false;
810
811 PythonObject python_obj(PyRefType::Borrowed, py_obj);
812
813 // Handle staticmethod/classmethod descriptors by extracting the
814 // `__func__` attribute.
815 if (python_obj.HasAttribute("__func__")) {
816 PythonObject function_obj = python_obj.GetAttributeValue("__func__");
817 if (!function_obj.IsAllocated())
818 return false;
819 return PyCallable_Check(function_obj.release());
820 }
821
822 return PyCallable_Check(py_obj);
823}
824
825static const char get_arg_info_script[] = R"(
826from inspect import signature, Parameter, ismethod
827from collections import namedtuple
828ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs'])
829def main(f):
830 count = 0
831 varargs = False
832 for parameter in signature(f).parameters.values():
833 kind = parameter.kind
834 if kind in (Parameter.POSITIONAL_ONLY,
835 Parameter.POSITIONAL_OR_KEYWORD):
836 count += 1
837 elif kind == Parameter.VAR_POSITIONAL:
838 varargs = True
839 elif kind in (Parameter.KEYWORD_ONLY,
840 Parameter.VAR_KEYWORD):
841 pass
842 else:
843 raise Exception(f'unknown parameter kind: {kind}')
844 return ArgInfo(count, varargs)
845)";
846
847// inspect.signature() is deeply recursive and expensive in C-stack terms;
848// reentrant scripted callbacks dispatched through GetArgInfo() can turn
849// that into a fatal stack overflow instead of a catchable Python
850// RecursionError. GetArgInfo() never calls this itself; callers fall back
851// to it explicitly when they need to handle callables its cheaper,
852// attribute-only approach can't (e.g. builtins).
853Expected<PythonCallable::ArgInfo>
855 PythonCallable::ArgInfo result = {};
856 // no need to synchronize access to this global, we already have the GIL
857 static PythonScript get_arg_info(get_arg_info_script);
858 Expected<PythonObject> pyarginfo = get_arg_info(callable);
859 if (!pyarginfo)
860 return pyarginfo.takeError();
861 long long count =
862 cantFail(As<long long>(pyarginfo.get().GetAttribute("count")));
863 bool has_varargs =
864 cantFail(As<bool>(pyarginfo.get().GetAttribute("has_varargs")));
865 result.max_positional_args =
866 has_varargs ? PythonCallable::ArgInfo::UNBOUNDED : count;
867 return result;
868}
869
870// GetArgInfo()'s branches, top to bottom (`func` is what each branch ends up
871// introspecting; the final step is always func.__code__.co_argcount/co_flags):
872//
873// callable
874// |-- has __self__ -> func = __func__ (bound method;
875// | fails for slot wrappers, e.g. (1).__add__)
876// |-- has __code__ already -> func = callable (plain function)
877// `-- neither
878// |-- is a class
879// | |-- __init__ has __code__ -> func = __init__
880// | `-- else: check __new__ too (object.__init__ is lenient about
881// | extra args once __new__ is overridden)
882// | |-- __new__ has __code__ -> func = __new__
883// | `-- else -> ArgInfo{0} (object's defaults)
884// `-- is an instance
885// `-- func = __call__ (unwrap __func__ if bound)
886// `-- no __code__ -> error (e.g. a builtin)
887Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
888 if (!IsValid())
889 return nullDeref();
890
891 PythonObject func = *this;
892 bool implicit_first_arg = false;
893 if (HasAttribute("__self__")) {
894 implicit_first_arg = true;
895 Expected<PythonObject> func_or_err = GetAttribute("__func__");
896 if (!func_or_err)
897 return func_or_err.takeError();
898 func = *func_or_err;
899 } else if (!HasAttribute("__code__")) {
900 implicit_first_arg = true;
901 if (PyType_Check(m_py_obj)) {
902 Expected<PythonObject> init_or_err = GetAttribute("__init__");
903 if (!init_or_err)
904 return init_or_err.takeError();
905 func = *init_or_err;
906 if (!func.HasAttribute("__code__")) {
907 // __init__ is still object.__init__. A class may customize
908 // __new__ instead and leave __init__ untouched, which makes
909 // object.__init__ lenient about extra arguments -- so check
910 // __new__ too before concluding there are none.
911 Expected<PythonObject> new_or_err = GetAttribute("__new__");
912 if (!new_or_err)
913 return new_or_err.takeError();
914 func = *new_or_err;
915 if (!func.HasAttribute("__code__"))
916 return ArgInfo{0};
917 }
918 } else {
919 Expected<PythonObject> call_or_err = GetAttribute("__call__");
920 if (!call_or_err)
921 return call_or_err.takeError();
922 func = *call_or_err;
923 if (func.HasAttribute("__self__")) {
924 Expected<PythonObject> inner_or_err = func.GetAttribute("__func__");
925 if (!inner_or_err)
926 return inner_or_err.takeError();
927 func = *inner_or_err;
928 }
929 if (!func.HasAttribute("__code__"))
930 return llvm::createStringError("__call__ has no __code__");
931 }
932 }
933
934 Expected<PythonObject> code_or_err = func.GetAttribute("__code__");
935 if (!code_or_err)
936 return code_or_err.takeError();
937 PythonObject code = *code_or_err;
938
939 Expected<long long> argcount =
940 As<long long>(code.GetAttribute("co_argcount"));
941 if (!argcount)
942 return argcount.takeError();
943 Expected<long long> flags = As<long long>(code.GetAttribute("co_flags"));
944 if (!flags)
945 return flags.takeError();
946
947 ArgInfo result = {};
948 // Mirrors CPython's CO_VARARGS from <code.h>, which isn't reliably
949 // visible across the Python versions/platforms this file builds against.
950 constexpr long long kCoFlagVarArgs = 0x04;
951 if (*flags & kCoFlagVarArgs) {
953 } else {
954 long long count = *argcount - (implicit_first_arg ? 1 : 0);
955 result.max_positional_args = count > 0 ? static_cast<unsigned>(count) : 0;
956 }
957 return result;
958}
959
960constexpr unsigned
961 PythonCallable::ArgInfo::UNBOUNDED; // FIXME delete after c++17
962
964 return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
965}
966
968PythonCallable::operator()(std::initializer_list<PyObject *> args) {
969 PythonTuple arg_tuple(args);
971 PyObject_CallObject(m_py_obj, arg_tuple.get()));
972}
973
975PythonCallable::operator()(std::initializer_list<PythonObject> args) {
976 PythonTuple arg_tuple(args);
978 PyObject_CallObject(m_py_obj, arg_tuple.get()));
979}
980
981bool PythonFile::Check(PyObject *py_obj) {
982 if (!py_obj)
983 return false;
984 // In Python 3, there is no `PyFile_Check`, and in fact PyFile is not even a
985 // first-class object type anymore. `PyFile_FromFd` is just a thin wrapper
986 // over `io.open()`, which returns some object derived from `io.IOBase`. As a
987 // result, the only way to detect a file in Python 3 is to check whether it
988 // inherits from `io.IOBase`.
989 auto io_module = PythonModule::Import("io");
990 if (!io_module) {
991 llvm::consumeError(io_module.takeError());
992 return false;
993 }
994 auto iobase = io_module.get().Get("IOBase");
995 if (!iobase) {
996 llvm::consumeError(iobase.takeError());
997 return false;
998 }
999 int r = PyObject_IsInstance(py_obj, iobase.get().get());
1000 if (r < 0) {
1001 llvm::consumeError(exception()); // clear the exception and log it.
1002 return false;
1003 }
1004 return !!r;
1005}
1006
1007#if defined(_WIN32) && !defined(_DLL)
1008// When LLVM is built with a different CRT allocator, it's built against the
1009// static C runtime. The official Python builds link to the dynamic C runtime.
1010// Since the file descriptors are managed per CRT instance, liblldb and Python
1011// have different fd mappings. This translates between the two using the msvcrt
1012// module.
1013int PythonFile::TranslateFdToPython(int our_fd) {
1014 intptr_t handle = _get_osfhandle(our_fd);
1015 if (handle == 0 || (HANDLE)handle == INVALID_HANDLE_VALUE)
1016 return -1;
1017
1018 PyObject *msvcrt = PyImport_ImportModule("msvcrt");
1019 if (!msvcrt)
1020 return -1;
1021 PyObject *open_osf = PyObject_GetAttrString(msvcrt, "open_osfhandle");
1022 Py_XDECREF(msvcrt);
1023 if (!open_osf)
1024 return -1;
1025 PyObject *fd_obj =
1026 PyObject_CallFunction(open_osf, "Li", (long long)handle, 0);
1027 Py_XDECREF(open_osf);
1028 if (!fd_obj)
1029 return -1;
1030 if (!PyLong_Check(fd_obj)) {
1031 Py_XDECREF(fd_obj);
1032 return -1;
1033 }
1034 long theirs = PyLong_AsLong(fd_obj);
1035 Py_XDECREF(fd_obj);
1036 return (int)theirs;
1037}
1038
1039int PythonFile::TranslateFdFromPython(int their_fd) {
1040 PyObject *msvcrt = PyImport_ImportModule("msvcrt");
1041 if (!msvcrt)
1042 return -1;
1043 PyObject *get_handle = PyObject_GetAttrString(msvcrt, "get_osfhandle");
1044 Py_XDECREF(msvcrt);
1045 if (!get_handle)
1046 return -1;
1047 PyObject *handle_obj = PyObject_CallFunction(get_handle, "i", their_fd);
1048 Py_XDECREF(get_handle);
1049 if (!handle_obj)
1050 return -1;
1051 if (!PyLong_Check(handle_obj)) {
1052 Py_XDECREF(handle_obj);
1053 return -1;
1054 }
1055 size_t handle = PyLong_AsSize_t(handle_obj);
1056 Py_XDECREF(handle_obj);
1057 return _open_osfhandle((intptr_t)handle, 0);
1058}
1059#else
1060int PythonFile::TranslateFdToPython(int our_fd) { return our_fd; }
1061int PythonFile::TranslateFdFromPython(int their_fd) { return their_fd; }
1062#endif
1063
1064const char *PythonException::toCString() const {
1065 if (!m_repr_bytes)
1066 return "unknown exception";
1067 return PyBytes_AsString(m_repr_bytes);
1068}
1069
1071 assert(PyErr_Occurred());
1073 PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
1074 PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
1075 PyErr_Clear();
1076 if (m_exception) {
1077 PyObject *repr = PyObject_Repr(m_exception);
1078 if (repr) {
1079 m_repr_bytes = PyUnicode_AsEncodedString(repr, "utf-8", nullptr);
1080 if (!m_repr_bytes) {
1081 PyErr_Clear();
1082 }
1083 Py_XDECREF(repr);
1084 } else {
1085 PyErr_Clear();
1086 }
1087 }
1089 if (caller)
1090 LLDB_LOGF(log, "%s failed with exception: %s", caller, toCString());
1091 else
1092 LLDB_LOGF(log, "python exception: %s", toCString());
1093}
1096 PyErr_Restore(m_exception_type, m_exception, m_traceback);
1097 } else {
1098 PyErr_SetString(PyExc_Exception, toCString());
1099 }
1101}
1102
1104 Py_XDECREF(m_exception_type);
1105 Py_XDECREF(m_exception);
1106 Py_XDECREF(m_traceback);
1107 Py_XDECREF(m_repr_bytes);
1108}
1109
1110void PythonException::log(llvm::raw_ostream &OS) const { OS << toCString(); }
1111
1113 return llvm::inconvertibleErrorCode();
1114}
1115
1116bool PythonException::Matches(PyObject *exc) const {
1117 return PyErr_GivenExceptionMatches(m_exception_type, exc);
1118}
1119
1120const char read_exception_script[] = R"(
1121import sys
1122from traceback import print_exception
1123from io import StringIO
1124def main(exc_type, exc_value, tb):
1125 f = StringIO()
1126 print_exception(exc_type, exc_value, tb, file=f)
1127 return f.getvalue()
1128)";
1129
1131
1132 if (!m_traceback)
1133 return toCString();
1134
1135 // no need to synchronize access to this global, we already have the GIL
1136 static PythonScript read_exception(read_exception_script);
1137
1138 Expected<std::string> backtrace = As<std::string>(
1139 read_exception(m_exception_type, m_exception, m_traceback));
1140
1141 if (!backtrace) {
1142 std::string message =
1143 std::string(toCString()) + "\n" +
1144 "Traceback unavailable, an error occurred while reading it:\n";
1145 return (message + llvm::toString(backtrace.takeError()));
1146 }
1147
1148 return std::move(backtrace.get());
1149}
1150
1151char PythonException::ID = 0;
1152
1153llvm::Expected<File::OpenOptions>
1155 auto options = File::OpenOptions(0);
1156 auto readable = As<bool>(obj.CallMethod("readable"));
1157 if (!readable)
1158 return readable.takeError();
1159 auto writable = As<bool>(obj.CallMethod("writable"));
1160 if (!writable)
1161 return writable.takeError();
1162 if (readable.get() && writable.get())
1163 options |= File::eOpenOptionReadWrite;
1164 else if (writable.get())
1165 options |= File::eOpenOptionWriteOnly;
1166 else if (readable.get())
1167 options |= File::eOpenOptionReadOnly;
1168 return options;
1169}
1170
1171// Base class template for python files. All it knows how to do
1172// is hold a reference to the python object and close or flush it
1173// when the File is closed.
1174namespace {
1175template <typename Base> class OwnedPythonFile : public Base {
1176public:
1177 template <typename... Args>
1178 OwnedPythonFile(const PythonFile &file, bool borrowed, Args... args)
1179 : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1180 assert(m_py_obj);
1181 }
1182
1183 ~OwnedPythonFile() override {
1184 assert(m_py_obj);
1185 GIL takeGIL;
1186 Close();
1187 // we need to ensure the python object is released while we still
1188 // hold the GIL
1189 m_py_obj.Reset();
1190 }
1191
1192 bool IsPythonSideValid() const {
1193 GIL takeGIL;
1194 auto closed = As<bool>(m_py_obj.GetAttribute("closed"));
1195 if (!closed) {
1196 llvm::consumeError(closed.takeError());
1197 return false;
1198 }
1199 return !closed.get();
1200 }
1201
1202 bool IsValid() const override {
1203 return IsPythonSideValid() && Base::IsValid();
1204 }
1205
1206 Status Close() override {
1207 assert(m_py_obj);
1208 Status py_error, base_error;
1209 GIL takeGIL;
1210 if (!m_borrowed) {
1211 auto r = m_py_obj.CallMethod("close");
1212 if (!r)
1213 py_error = Status::FromError(r.takeError());
1214 }
1215 base_error = Base::Close();
1216 // Cloning since the wrapped exception may still reference the PyThread.
1217 if (py_error.Fail())
1218 return py_error.Clone();
1219 return base_error.Clone();
1220 };
1221
1222 PyObject *GetPythonObject() const {
1223 assert(m_py_obj.IsValid());
1224 return m_py_obj.get();
1225 }
1226
1227 static bool classof(const File *file) = delete;
1228
1229protected:
1230 PythonFile m_py_obj;
1231 bool m_borrowed;
1232};
1233} // namespace
1234
1235// A SimplePythonFile is a OwnedPythonFile that just does all I/O as
1236// a NativeFile
1237namespace {
1238class SimplePythonFile : public OwnedPythonFile<NativeFile> {
1239public:
1240 SimplePythonFile(const PythonFile &file, bool borrowed, int fd,
1241 File::OpenOptions options)
1242 : OwnedPythonFile(file, borrowed, fd, options, false) {}
1243
1244 static char ID;
1245 bool isA(const void *classID) const override {
1246 return classID == &ID || NativeFile::isA(classID);
1247 }
1248 static bool classof(const File *file) { return file->isA(&ID); }
1249};
1250char SimplePythonFile::ID = 0;
1251} // namespace
1252
1253// Shared methods between TextPythonFile and BinaryPythonFile
1254namespace {
1255class PythonIOFile : public OwnedPythonFile<File> {
1256public:
1257 PythonIOFile(const PythonFile &file, bool borrowed)
1258 : OwnedPythonFile(file, borrowed) {}
1259
1260 ~PythonIOFile() override { Close(); }
1261
1262 bool IsValid() const override { return IsPythonSideValid(); }
1263
1264 Status Close() override {
1265 assert(m_py_obj);
1266 GIL takeGIL;
1267 if (m_borrowed)
1268 return Flush();
1269 auto r = m_py_obj.CallMethod("close");
1270 if (!r)
1271 // Cloning since the wrapped exception may still reference the PyThread.
1272 return Status::FromError(r.takeError()).Clone();
1273 return Status();
1274 }
1275
1276 Status Flush() override {
1277 GIL takeGIL;
1278 auto r = m_py_obj.CallMethod("flush");
1279 if (!r)
1280 // Cloning since the wrapped exception may still reference the PyThread.
1281 return Status::FromError(r.takeError()).Clone();
1282 return Status();
1283 }
1284
1285 Expected<File::OpenOptions> GetOptions() const override {
1286 GIL takeGIL;
1287 return GetOptionsForPyObject(m_py_obj);
1288 }
1289
1290 static char ID;
1291 bool isA(const void *classID) const override {
1292 return classID == &ID || File::isA(classID);
1293 }
1294 static bool classof(const File *file) { return file->isA(&ID); }
1295};
1296char PythonIOFile::ID = 0;
1297} // namespace
1298
1299namespace {
1300class BinaryPythonFile : public PythonIOFile {
1301protected:
1302 int m_descriptor;
1303
1304public:
1305 BinaryPythonFile(int fd, const PythonFile &file, bool borrowed)
1306 : PythonIOFile(file, borrowed),
1307 m_descriptor(File::DescriptorIsValid(fd) ? fd
1308 : File::kInvalidDescriptor) {}
1309
1310 int GetDescriptor() const override { return m_descriptor; }
1311
1312 Status Write(const void *buf, size_t &num_bytes) override {
1313 GIL takeGIL;
1314 PyObject *pybuffer_p = PyMemoryView_FromMemory(
1315 const_cast<char *>((const char *)buf), num_bytes, PyBUF_READ);
1316 if (!pybuffer_p)
1317 // Cloning since the wrapped exception may still reference the PyThread.
1318 return Status::FromError(llvm::make_error<PythonException>()).Clone();
1319 auto pybuffer = Take<PythonObject>(pybuffer_p);
1320 num_bytes = 0;
1321 auto bytes_written = As<long long>(m_py_obj.CallMethod("write", pybuffer));
1322 if (!bytes_written)
1323 return Status::FromError(bytes_written.takeError());
1324 if (bytes_written.get() < 0)
1325 return Status::FromErrorString(
1326 ".write() method returned a negative number!");
1327 static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1328 num_bytes = bytes_written.get();
1329 return Status();
1330 }
1331
1332 Status Read(void *buf, size_t &num_bytes) override {
1333 GIL takeGIL;
1334 static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1335 auto pybuffer_obj =
1336 m_py_obj.CallMethod("read", (unsigned long long)num_bytes);
1337 if (!pybuffer_obj)
1338 // Cloning since the wrapped exception may still reference the PyThread.
1339 return Status::FromError(pybuffer_obj.takeError()).Clone();
1340 num_bytes = 0;
1341 if (pybuffer_obj.get().IsNone()) {
1342 // EOF
1343 num_bytes = 0;
1344 return Status();
1345 }
1346 PythonBytes pybytes(PyRefType::Borrowed, pybuffer_obj->get());
1347 if (!pybytes)
1348 return Status::FromError(llvm::make_error<PythonException>());
1349 llvm::ArrayRef<uint8_t> bytes = pybytes.GetBytes();
1350 memcpy(buf, bytes.begin(), bytes.size());
1351 num_bytes = bytes.size();
1352 return Status();
1353 }
1354};
1355} // namespace
1356
1357namespace {
1358class TextPythonFile : public PythonIOFile {
1359protected:
1360 int m_descriptor;
1361
1362public:
1363 TextPythonFile(int fd, const PythonFile &file, bool borrowed)
1364 : PythonIOFile(file, borrowed),
1365 m_descriptor(File::DescriptorIsValid(fd) ? fd
1366 : File::kInvalidDescriptor) {}
1367
1368 int GetDescriptor() const override { return m_descriptor; }
1369
1370 Status Write(const void *buf, size_t &num_bytes) override {
1371 GIL takeGIL;
1372 auto pystring =
1373 PythonString::FromUTF8(llvm::StringRef((const char *)buf, num_bytes));
1374 if (!pystring)
1375 return Status::FromError(pystring.takeError());
1376 num_bytes = 0;
1377 auto bytes_written =
1378 As<long long>(m_py_obj.CallMethod("write", pystring.get()));
1379 if (!bytes_written)
1380 // Cloning since the wrapped exception may still reference the PyThread.
1381 return Status::FromError(bytes_written.takeError()).Clone();
1382 if (bytes_written.get() < 0)
1383 return Status::FromErrorString(
1384 ".write() method returned a negative number!");
1385 static_assert(sizeof(long long) >= sizeof(size_t), "overflow");
1386 num_bytes = bytes_written.get();
1387 return Status();
1388 }
1389
1390 Status Read(void *buf, size_t &num_bytes) override {
1391 GIL takeGIL;
1392 size_t num_chars = num_bytes / 6;
1393 size_t orig_num_bytes = num_bytes;
1394 num_bytes = 0;
1395 if (orig_num_bytes < 6) {
1396 return Status::FromErrorString(
1397 "can't read less than 6 bytes from a utf8 text stream");
1398 }
1399 auto pystring = As<PythonString>(
1400 m_py_obj.CallMethod("read", (unsigned long long)num_chars));
1401 if (!pystring)
1402 // Cloning since the wrapped exception may still reference the PyThread.
1403 return Status::FromError(pystring.takeError()).Clone();
1404 if (pystring.get().IsNone()) {
1405 // EOF
1406 return Status();
1407 }
1408 auto stringref = pystring.get().AsUTF8();
1409 if (!stringref)
1410 // Cloning since the wrapped exception may still reference the PyThread.
1411 return Status::FromError(stringref.takeError()).Clone();
1412 num_bytes = stringref.get().size();
1413 memcpy(buf, stringref.get().begin(), num_bytes);
1414 return Status();
1415 }
1416};
1417} // namespace
1418
1419llvm::Expected<FileSP> PythonFile::ConvertToFile(bool borrowed) {
1420 if (!IsValid())
1421 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1422 "invalid PythonFile");
1423
1424 int fd = PyObject_AsFileDescriptor(m_py_obj);
1425 if (fd < 0) {
1426 PyErr_Clear();
1428 }
1429 fd = TranslateFdFromPython(fd);
1430 if (fd < 0) {
1431 PyErr_Clear();
1432 return llvm::createStringError("failed to translate Python fd to our fd");
1433 }
1434
1435 auto options = GetOptionsForPyObject(*this);
1436 if (!options)
1437 return options.takeError();
1438
1443 // LLDB and python will not share I/O buffers. We should probably
1444 // flush the python buffers now.
1445 auto r = CallMethod("flush");
1446 if (!r)
1447 return r.takeError();
1448 }
1449
1450 FileSP file_sp;
1451 if (borrowed) {
1452 // In this case we don't need to retain the python
1453 // object at all.
1454 file_sp = std::make_shared<NativeFile>(fd, options.get(), false);
1455 } else {
1456 file_sp = std::static_pointer_cast<File>(
1457 std::make_shared<SimplePythonFile>(*this, borrowed, fd, options.get()));
1458 }
1459 if (!file_sp->IsValid())
1460 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1461 "invalid File");
1462
1463 return file_sp;
1464}
1465
1466llvm::Expected<FileSP>
1468
1469 assert(!PyErr_Occurred());
1470
1471 if (!IsValid())
1472 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1473 "invalid PythonFile");
1474
1475 int fd = PyObject_AsFileDescriptor(m_py_obj);
1476 if (fd < 0) {
1477 PyErr_Clear();
1479 } else {
1480 fd = TranslateFdFromPython(fd);
1481 if (fd < 0) {
1482 PyErr_Clear();
1483 return llvm::createStringError("failed to translate Python fd to our fd");
1484 }
1485 }
1486
1487 auto io_module = PythonModule::Import("io");
1488 if (!io_module)
1489 return io_module.takeError();
1490 auto textIOBase = io_module.get().Get("TextIOBase");
1491 if (!textIOBase)
1492 return textIOBase.takeError();
1493 auto rawIOBase = io_module.get().Get("RawIOBase");
1494 if (!rawIOBase)
1495 return rawIOBase.takeError();
1496 auto bufferedIOBase = io_module.get().Get("BufferedIOBase");
1497 if (!bufferedIOBase)
1498 return bufferedIOBase.takeError();
1499
1500 FileSP file_sp;
1501
1502 auto isTextIO = IsInstance(textIOBase.get());
1503 if (!isTextIO)
1504 return isTextIO.takeError();
1505 if (isTextIO.get())
1506 file_sp = std::static_pointer_cast<File>(
1507 std::make_shared<TextPythonFile>(fd, *this, borrowed));
1508
1509 auto isRawIO = IsInstance(rawIOBase.get());
1510 if (!isRawIO)
1511 return isRawIO.takeError();
1512 auto isBufferedIO = IsInstance(bufferedIOBase.get());
1513 if (!isBufferedIO)
1514 return isBufferedIO.takeError();
1515
1516 if (isRawIO.get() || isBufferedIO.get()) {
1517 file_sp = std::static_pointer_cast<File>(
1518 std::make_shared<BinaryPythonFile>(fd, *this, borrowed));
1519 }
1520
1521 if (!file_sp)
1522 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1523 "python file is neither text nor binary");
1524
1525 if (!file_sp->IsValid())
1526 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1527 "invalid File");
1528
1529 return file_sp;
1530}
1531
1532Expected<PythonFile> PythonFile::FromFile(File &file, const char *mode) {
1533 if (!file.IsValid())
1534 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1535 "invalid file");
1536
1537 if (auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
1538 return Retain<PythonFile>(simple->GetPythonObject());
1539 if (auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
1540 return Retain<PythonFile>(pythonio->GetPythonObject());
1541
1542 if (!mode) {
1543 auto m = file.GetOpenMode();
1544 if (!m)
1545 return m.takeError();
1546 mode = m.get();
1547 }
1548
1549 PyObject *file_obj;
1550 file_obj = PyFile_FromFd(TranslateFdToPython(file.GetDescriptor()), nullptr,
1551 mode, -1, nullptr, "ignore", nullptr, /*closefd=*/0);
1552
1553 if (!file_obj)
1554 return exception();
1555
1556 return Take<PythonFile>(file_obj);
1557}
1558
1560 if (function.IsValid())
1561 return Error::success();
1562
1564 auto builtins = PythonModule::BuiltinsModule();
1565 if (Error error = globals.SetItem("__builtins__", builtins))
1566 return error;
1567 PyObject *o = RunString(script, Py_file_input, globals.get(), globals.get());
1568 if (!o)
1569 return exception();
1571 auto f = As<PythonCallable>(globals.GetItem("main"));
1572 if (!f)
1573 return f.takeError();
1574 function = std::move(f.get());
1575
1576 return Error::success();
1577}
1578
1579llvm::Expected<PythonObject>
1580python::runStringOneLine(const llvm::Twine &string,
1581 const PythonDictionary &globals,
1582 const PythonDictionary &locals) {
1583 if (!globals.IsValid() || !locals.IsValid())
1584 return nullDeref();
1585
1586 PyObject *code =
1587 Py_CompileString(NullTerminated(string), "<string>", Py_eval_input);
1588 if (!code) {
1589 PyErr_Clear();
1590 code =
1591 Py_CompileString(NullTerminated(string), "<string>", Py_single_input);
1592 }
1593 if (!code)
1594 return exception();
1595 auto code_ref = Take<PythonObject>(code);
1596
1597 PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
1598
1599 if (!result)
1600 return exception();
1601
1602 return Take<PythonObject>(result);
1603}
1604
1605llvm::Expected<PythonObject>
1606python::runStringMultiLine(const llvm::Twine &string,
1607 const PythonDictionary &globals,
1608 const PythonDictionary &locals) {
1609 if (!globals.IsValid() || !locals.IsValid())
1610 return nullDeref();
1611 PyObject *result = RunString(NullTerminated(string), Py_file_input,
1612 globals.get(), locals.get());
1613 if (!result)
1614 return exception();
1615 return Take<PythonObject>(result);
1616}
1617
1618PyObject *lldb_private::python::RunString(const char *str, int start,
1619 PyObject *globals, PyObject *locals) {
1620 const char *filename = "<string>";
1621
1622 // Compile the string into a code object.
1623 PyObject *code = Py_CompileString(str, filename, start);
1624 if (!code)
1625 return nullptr;
1626
1627 // Execute the code object.
1628 PyObject *result = PyEval_EvalCode(code, globals, locals);
1629
1630 // Clean up the code object.
1631 Py_DECREF(code);
1632
1633 return result;
1634}
1635
1637 PyObject *main_module = PyImport_AddModule("__main__");
1638 if (!main_module)
1639 return -1;
1640
1641 PyObject *globals = PyModule_GetDict(main_module);
1642 if (!globals)
1643 return -1;
1644
1645 PyObject *result = RunString(str, Py_file_input, globals, globals);
1646 if (!result)
1647 return -1;
1648
1649 return 0;
1650}
static llvm::raw_ostream & error(Stream &strm)
static char ID
#define LLDB_LOGF(log,...)
Definition Log.h:389
void * HANDLE
static const char get_arg_info_script[]
llvm::Expected< File::OpenOptions > GetOptionsForPyObject(const PythonObject &obj)
const char read_exception_script[]
A uniqued constant string class.
Definition ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
virtual bool isA(const void *classID) const
Definition FileBase.h:363
static int kInvalidDescriptor
Definition FileBase.h:36
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
Definition File.cpp:119
llvm::Expected< const char * > GetOpenMode() const
Definition FileBase.h:321
bool IsValid() const override
IsValid.
Definition File.cpp:106
bool isA(const void *classID) const override
Definition FilePosix.h:38
Status Clone() const
Don't call this function in new code.
Definition Status.h:174
bool Fail() const
Test for error condition.
Definition Status.cpp:293
A stream class that can stream formatted output to a file.
Definition Stream.h:28
std::shared_ptr< UnsignedInteger > UnsignedIntegerSP
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
std::shared_ptr< String > StringSP
std::shared_ptr< Array > ArraySP
std::shared_ptr< Boolean > BooleanSP
std::shared_ptr< SignedInteger > SignedIntegerSP
std::variant< UnsignedIntegerSP, SignedIntegerSP > IntegerSP
StructuredData::BooleanSP CreateStructuredBoolean() const
static bool Check(PyObject *py_obj)
StructuredData::StringSP CreateStructuredString() const
llvm::ArrayRef< uint8_t > GetBytes() const
static bool Check(PyObject *py_obj)
PythonByteArray(llvm::ArrayRef< uint8_t > bytes)
static bool Check(PyObject *py_obj)
StructuredData::StringSP CreateStructuredString() const
void SetBytes(llvm::ArrayRef< uint8_t > stringbytes)
PythonBytes(llvm::ArrayRef< uint8_t > bytes)
llvm::ArrayRef< uint8_t > GetBytes() const
static llvm::Expected< ArgInfo > GetArgInfoFromInspectSignature(const PythonCallable &callable)
llvm::Expected< ArgInfo > GetArgInfo() const
static bool Check(PyObject *py_obj)
StructuredData::DictionarySP CreateStructuredDictionary() const
llvm::Expected< PythonObject > GetItem(const PythonObject &key) const
bool HasKey(const llvm::Twine &key) const
PythonObject GetItemForKey(const PythonObject &key) const
llvm::Error SetItem(const PythonObject &key, const PythonObject &value) const
void SetItemForKey(const PythonObject &key, const PythonObject &value)
std::error_code convertToErrorCode() const override
void log(llvm::raw_ostream &OS) const override
PythonException(const char *caller=nullptr)
llvm::Expected< lldb::FileSP > ConvertToFileForcingUseOfScriptingIOMethods(bool borrowed=false)
static int TranslateFdFromPython(int their_fd)
llvm::Expected< lldb::FileSP > ConvertToFile(bool borrowed=false)
static bool Check(PyObject *py_obj)
static int TranslateFdToPython(int our_fd)
static llvm::Expected< PythonFile > FromFile(File &file, const char *mode=nullptr)
StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const
static bool Check(PyObject *py_obj)
StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const
StructuredData::IntegerSP CreateStructuredInteger() const
PythonObject GetItemAtIndex(uint32_t index) const
void AppendItem(const PythonObject &object)
static bool Check(PyObject *py_obj)
void SetItemAtIndex(uint32_t index, const PythonObject &object)
StructuredData::ArraySP CreateStructuredArray() const
static PythonModule AddModule(llvm::StringRef module)
llvm::Expected< PythonObject > Get(const llvm::Twine &name)
static bool Check(PyObject *py_obj)
static llvm::Expected< PythonModule > Import(const llvm::Twine &name)
PythonObject ResolveName(llvm::StringRef name) const
llvm::Expected< long long > AsLongLong() const
StructuredData::ObjectSP CreateStructuredObject() const
llvm::Expected< unsigned long long > AsModuloUnsignedLongLong() const
PythonObject GetAttributeValue(llvm::StringRef attribute) const
static PythonObject ResolveNameWithDictionary(llvm::StringRef name, const PythonDictionary &dict)
llvm::Expected< unsigned long long > AsUnsignedLongLong() const
llvm::Expected< bool > IsInstance(const PythonObject &cls)
llvm::Expected< PythonObject > GetAttribute(const llvm::Twine &name) const
bool HasAttribute(llvm::StringRef attribute) const
llvm::Expected< PythonObject > CallMethod(const char *name, const T &... t) const
llvm::Expected< llvm::StringRef > AsUTF8() const
void SetString(llvm::StringRef string)
StructuredData::StringSP CreateStructuredString() const
static bool Check(PyObject *py_obj)
static llvm::Expected< PythonString > FromUTF8(llvm::StringRef string)
StructuredData::ArraySP CreateStructuredArray() const
void SetItemAtIndex(uint32_t index, const PythonObject &object)
PythonObject GetItemAtIndex(uint32_t index) const
static bool Check(PyObject *py_obj)
void Serialize(llvm::json::OStream &s) const override
#define PyBUF_READ
Definition lldb-python.h:59
llvm::Expected< unsigned long long > As< unsigned long long >(llvm::Expected< PythonObject > &&obj)
llvm::Error exception(const char *s=nullptr)
llvm::Expected< std::string > As< std::string >(llvm::Expected< PythonObject > &&obj)
PyObject * RunString(const char *str, int start, PyObject *globals, PyObject *locals)
T Retain(PyObject *obj)
llvm::Expected< T > As(llvm::Expected< PythonObject > &&obj)
llvm::Expected< PythonObject > runStringMultiLine(const llvm::Twine &string, const PythonDictionary &globals, const PythonDictionary &locals)
int RunSimpleString(const char *str)
llvm::Expected< long long > As< long long >(llvm::Expected< PythonObject > &&obj)
llvm::Expected< bool > As< bool >(llvm::Expected< PythonObject > &&obj)
llvm::Expected< PythonObject > runStringOneLine(const llvm::Twine &string, const PythonDictionary &globals, const PythonDictionary &locals)
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:338
std::shared_ptr< lldb_private::File > FileSP