9#include "lldb/Host/Config.h"
23#include "llvm/ADT/ScopeExit.h"
24#include "llvm/Support/Casting.h"
25#include "llvm/Support/ConvertUTF.h"
26#include "llvm/Support/Errno.h"
39template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) {
41 return obj.takeError();
42 return obj.get().IsTrue();
46Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
48 return obj.takeError();
49 return obj->AsLongLong();
53Expected<unsigned long long>
54python::As<unsigned long long>(Expected<PythonObject> &&obj) {
56 return obj.takeError();
57 return obj->AsUnsignedLongLong();
61Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
63 return obj.takeError();
64 PyObject *str_obj = PyObject_Str(obj.get().get());
66 return llvm::make_error<PythonException>();
67 auto str = Take<PythonString>(str_obj);
68 auto utf8 = str.AsUTF8();
70 return utf8.takeError();
71 return std::string(utf8.get());
74void PythonObject::Reset() {
75 if (m_py_obj && Py_IsInitialized()) {
76 PyGILState_STATE state = PyGILState_Ensure();
78 PyGILState_Release(state);
83Expected<long long> PythonObject::AsLongLong()
const {
86 assert(!PyErr_Occurred());
87 long long r = PyLong_AsLongLong(m_py_obj);
93Expected<unsigned long long> PythonObject::AsUnsignedLongLong()
const {
96 assert(!PyErr_Occurred());
97 long long r = PyLong_AsUnsignedLongLong(m_py_obj);
104Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong()
const {
107 assert(!PyErr_Occurred());
108 unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
110 if (PyErr_Occurred())
115void StructuredPythonObject::Serialize(llvm::json::OStream &s)
const {
116 s.value(llvm::formatv(
"Python Obj: {0:X}", GetValue()).str());
121void PythonObject::Dump(
Stream &strm)
const {
127 PyObject *py_str = PyObject_Repr(m_py_obj);
131 auto release_py_str = llvm::make_scope_exit([py_str] { Py_DECREF(py_str); });
133 PyObject *py_bytes = PyUnicode_AsEncodedString(py_str,
"utf-8",
"replace");
137 auto release_py_bytes =
138 llvm::make_scope_exit([py_bytes] { Py_DECREF(py_bytes); });
140 char *buffer =
nullptr;
141 Py_ssize_t length = 0;
142 if (PyBytes_AsStringAndSize(py_bytes, &buffer, &length) == -1)
145 strm << llvm::StringRef(buffer, length);
148PyObjectType PythonObject::GetObjectType()
const {
150 return PyObjectType::None;
152 if (PythonModule::Check(m_py_obj))
153 return PyObjectType::Module;
154 if (PythonList::Check(m_py_obj))
155 return PyObjectType::List;
156 if (PythonTuple::Check(m_py_obj))
157 return PyObjectType::Tuple;
158 if (PythonDictionary::Check(m_py_obj))
159 return PyObjectType::Dictionary;
160 if (PythonString::Check(m_py_obj))
161 return PyObjectType::String;
162 if (PythonBytes::Check(m_py_obj))
163 return PyObjectType::Bytes;
164 if (PythonByteArray::Check(m_py_obj))
165 return PyObjectType::ByteArray;
166 if (PythonBoolean::Check(m_py_obj))
167 return PyObjectType::Boolean;
168 if (PythonInteger::Check(m_py_obj))
169 return PyObjectType::Integer;
170 if (PythonFile::Check(m_py_obj))
171 return PyObjectType::File;
172 if (PythonCallable::Check(m_py_obj))
173 return PyObjectType::Callable;
174 return PyObjectType::Unknown;
177PythonString PythonObject::Repr()
const {
179 return PythonString();
180 PyObject *repr = PyObject_Repr(m_py_obj);
182 return PythonString();
183 return PythonString(PyRefType::Owned, repr);
186PythonString PythonObject::Str()
const {
188 return PythonString();
189 PyObject *str = PyObject_Str(m_py_obj);
191 return PythonString();
192 return PythonString(PyRefType::Owned, str);
196PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
197 const PythonDictionary &dict) {
198 size_t dot_pos = name.find(
'.');
199 llvm::StringRef piece = name.substr(0, dot_pos);
200 PythonObject result = dict.GetItemForKey(PythonString(piece));
201 if (dot_pos == llvm::StringRef::npos) {
208 return result.ResolveName(name.substr(dot_pos + 1));
211PythonObject PythonObject::ResolveName(llvm::StringRef name)
const {
222 size_t dot_pos = name.find(
'.');
223 if (dot_pos == llvm::StringRef::npos) {
226 return GetAttributeValue(name);
231 PythonObject parent = ResolveName(name.substr(0, dot_pos));
232 if (!parent.IsAllocated())
233 return PythonObject();
236 return parent.ResolveName(name.substr(dot_pos + 1));
239bool PythonObject::HasAttribute(llvm::StringRef attr)
const {
242 PythonString py_attr(attr);
243 return !!PyObject_HasAttr(m_py_obj, py_attr.get());
246PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr)
const {
248 return PythonObject();
250 PythonString py_attr(attr);
251 if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
252 return PythonObject();
254 return PythonObject(PyRefType::Owned,
255 PyObject_GetAttr(m_py_obj, py_attr.get()));
259 switch (GetObjectType()) {
260 case PyObjectType::Dictionary:
261 return PythonDictionary(PyRefType::Borrowed, m_py_obj)
262 .CreateStructuredDictionary();
263 case PyObjectType::Boolean:
264 return PythonBoolean(PyRefType::Borrowed, m_py_obj)
265 .CreateStructuredBoolean();
266 case PyObjectType::Integer: {
268 PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger();
269 if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp))
270 return std::get<StructuredData::UnsignedIntegerSP>(int_sp);
271 if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp))
272 return std::get<StructuredData::SignedIntegerSP>(int_sp);
275 case PyObjectType::List:
276 return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
277 case PyObjectType::String:
278 return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
279 case PyObjectType::Bytes:
280 return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
281 case PyObjectType::ByteArray:
282 return PythonByteArray(PyRefType::Borrowed, m_py_obj)
283 .CreateStructuredString();
284 case PyObjectType::None:
288 PythonObject(PyRefType::Borrowed, m_py_obj)));
294PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
296PythonBytes::PythonBytes(
const uint8_t *bytes,
size_t length) {
297 SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
300bool PythonBytes::Check(PyObject *py_obj) {
303 return PyBytes_Check(py_obj);
306llvm::ArrayRef<uint8_t> PythonBytes::GetBytes()
const {
308 return llvm::ArrayRef<uint8_t>();
313 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
314 return llvm::ArrayRef<uint8_t>(
reinterpret_cast<uint8_t *
>(c), size);
317size_t PythonBytes::GetSize()
const {
320 return PyBytes_Size(m_py_obj);
323void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
324 const char *data =
reinterpret_cast<const char *
>(bytes.data());
325 *
this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size()));
332 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
333 result->SetValue(std::string(c, size));
337PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
338 : PythonByteArray(bytes.data(), bytes.size()) {}
340PythonByteArray::PythonByteArray(
const uint8_t *bytes,
size_t length) {
341 const char *str =
reinterpret_cast<const char *
>(bytes);
342 *
this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length));
345bool PythonByteArray::Check(PyObject *py_obj) {
348 return PyByteArray_Check(py_obj);
351llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes()
const {
353 return llvm::ArrayRef<uint8_t>();
355 char *c = PyByteArray_AsString(m_py_obj);
356 size_t size = GetSize();
357 return llvm::ArrayRef<uint8_t>(
reinterpret_cast<uint8_t *
>(c), size);
360size_t PythonByteArray::GetSize()
const {
364 return PyByteArray_Size(m_py_obj);
369 llvm::ArrayRef<uint8_t> bytes =
GetBytes();
370 const char *str =
reinterpret_cast<const char *
>(bytes.data());
371 result->SetValue(std::string(str, bytes.size()));
377Expected<PythonString> PythonString::FromUTF8(llvm::StringRef
string) {
378 PyObject *str = PyUnicode_FromStringAndSize(
string.data(),
string.size());
380 return llvm::make_error<PythonException>();
381 return Take<PythonString>(str);
384PythonString::PythonString(llvm::StringRef
string) { SetString(
string); }
386bool PythonString::Check(PyObject *py_obj) {
390 if (PyUnicode_Check(py_obj))
395llvm::StringRef PythonString::GetString()
const {
398 llvm::consumeError(s.takeError());
399 return llvm::StringRef(
"");
404Expected<llvm::StringRef> PythonString::AsUTF8()
const {
413#if defined(Py_LIMITED_API) && (Py_LIMITED_API < 0x030a0000)
414 PyObject *py_bytes = PyUnicode_AsUTF8String(m_py_obj);
417 auto release_py_str =
418 llvm::make_scope_exit([py_bytes] { Py_DECREF(py_bytes); });
419 Py_ssize_t size = PyBytes_Size(py_bytes);
420 const char *str = PyBytes_AsString(py_bytes);
428 const char *str = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
433 return llvm::StringRef(str, size);
437size_t PythonString::GetSize()
const {
439 return PyUnicode_GetLength(m_py_obj);
443void PythonString::SetString(llvm::StringRef
string) {
444 auto s = FromUTF8(
string);
446 llvm::consumeError(s.takeError());
449 *
this = std::move(s.get());
455 result->SetValue(GetString());
461PythonInteger::PythonInteger(int64_t value) {
SetInteger(value); }
463bool PythonInteger::Check(PyObject *py_obj) {
469 return PyLong_Check(py_obj);
472void PythonInteger::SetInteger(int64_t value) {
473 *
this = Take<PythonInteger>(PyLong_FromLongLong(value));
479 : CreateStructuredSignedInteger();
483PythonInteger::CreateStructuredUnsignedInteger()
const {
485 llvm::Expected<unsigned long long> value = AsUnsignedLongLong();
487 llvm::consumeError(value.takeError());
489 result = std::make_shared<StructuredData::UnsignedInteger>(value.get());
495PythonInteger::CreateStructuredSignedInteger()
const {
497 llvm::Expected<long long> value = AsLongLong();
499 llvm::consumeError(value.takeError());
501 result = std::make_shared<StructuredData::SignedInteger>(value.get());
508PythonBoolean::PythonBoolean(
bool value) { SetValue(value); }
510bool PythonBoolean::Check(PyObject *py_obj) {
511 return py_obj ? PyBool_Check(py_obj) : false;
514bool PythonBoolean::GetValue()
const {
515 return m_py_obj ? PyObject_IsTrue(m_py_obj) : false;
518void PythonBoolean::SetValue(
bool value) {
519 *
this = Take<PythonBoolean>(PyBool_FromLong(value));
524 result->SetValue(GetValue());
530PythonList::PythonList(PyInitialValue value) {
531 if (value == PyInitialValue::Empty)
532 *
this = Take<PythonList>(PyList_New(0));
535PythonList::PythonList(
int list_size) {
536 *
this = Take<PythonList>(PyList_New(list_size));
539bool PythonList::Check(PyObject *py_obj) {
542 return PyList_Check(py_obj);
545uint32_t PythonList::GetSize()
const {
547 return PyList_Size(m_py_obj);
551PythonObject PythonList::GetItemAtIndex(uint32_t index)
const {
553 return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
554 return PythonObject();
557void PythonList::SetItemAtIndex(uint32_t index,
const PythonObject &
object) {
558 if (IsAllocated() &&
object.IsValid()) {
561 Py_INCREF(
object.get());
562 PyList_SetItem(m_py_obj, index,
object.get());
566void PythonList::AppendItem(
const PythonObject &
object) {
567 if (IsAllocated() &&
object.IsValid()) {
570 PyList_Append(m_py_obj,
object.get());
576 uint32_t count = GetSize();
577 for (uint32_t i = 0; i < count; ++i) {
578 PythonObject obj = GetItemAtIndex(i);
579 result->AddItem(obj.CreateStructuredObject());
586PythonTuple::PythonTuple(PyInitialValue value) {
587 if (value == PyInitialValue::Empty)
588 *
this = Take<PythonTuple>(PyTuple_New(0));
591PythonTuple::PythonTuple(
int tuple_size) {
592 *
this = Take<PythonTuple>(PyTuple_New(tuple_size));
595PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
596 m_py_obj = PyTuple_New(objects.size());
599 for (
auto object : objects) {
600 if (
object.IsValid())
601 SetItemAtIndex(idx,
object);
606PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
607 m_py_obj = PyTuple_New(objects.size());
610 for (
auto py_object : objects) {
611 PythonObject object(PyRefType::Borrowed, py_object);
612 if (
object.IsValid())
613 SetItemAtIndex(idx,
object);
618bool PythonTuple::Check(PyObject *py_obj) {
621 return PyTuple_Check(py_obj);
624uint32_t PythonTuple::GetSize()
const {
626 return PyTuple_Size(m_py_obj);
630PythonObject PythonTuple::GetItemAtIndex(uint32_t index)
const {
632 return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
633 return PythonObject();
636void PythonTuple::SetItemAtIndex(uint32_t index,
const PythonObject &
object) {
637 if (IsAllocated() &&
object.IsValid()) {
640 Py_INCREF(
object.get());
641 PyTuple_SetItem(m_py_obj, index,
object.get());
647 uint32_t count = GetSize();
648 for (uint32_t i = 0; i < count; ++i) {
649 PythonObject obj = GetItemAtIndex(i);
650 result->AddItem(obj.CreateStructuredObject());
657PythonDictionary::PythonDictionary(PyInitialValue value) {
658 if (value == PyInitialValue::Empty)
659 *
this = Take<PythonDictionary>(PyDict_New());
662bool PythonDictionary::Check(PyObject *py_obj) {
666 return PyDict_Check(py_obj);
669bool PythonDictionary::HasKey(
const llvm::Twine &key)
const {
673 PythonString key_object(key.isSingleStringRef() ? key.getSingleStringRef()
676 if (
int res = PyDict_Contains(m_py_obj, key_object.get()) > 0)
683uint32_t PythonDictionary::GetSize()
const {
685 return PyDict_Size(m_py_obj);
689PythonList PythonDictionary::GetKeys()
const {
691 return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
692 return PythonList(PyInitialValue::Invalid);
695PythonObject PythonDictionary::GetItemForKey(
const PythonObject &key)
const {
696 auto item = GetItem(key);
698 llvm::consumeError(item.takeError());
699 return PythonObject();
701 return std::move(item.get());
704Expected<PythonObject>
705PythonDictionary::GetItem(
const PythonObject &key)
const {
708 PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
709 if (PyErr_Occurred())
713 return Retain<PythonObject>(o);
716Expected<PythonObject> PythonDictionary::GetItem(
const Twine &key)
const {
719 PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
720 if (PyErr_Occurred())
724 return Retain<PythonObject>(o);
727Error PythonDictionary::SetItem(
const PythonObject &key,
728 const PythonObject &value)
const {
729 if (!IsValid() || !value.IsValid())
731 int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
734 return Error::success();
737Error PythonDictionary::SetItem(
const Twine &key,
738 const PythonObject &value)
const {
739 if (!IsValid() || !value.IsValid())
741 int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
744 return Error::success();
747void PythonDictionary::SetItemForKey(
const PythonObject &key,
748 const PythonObject &value) {
751 llvm::consumeError(std::move(
error));
755PythonDictionary::CreateStructuredDictionary()
const {
757 PythonList keys(GetKeys());
758 uint32_t num_keys = keys.GetSize();
759 for (uint32_t i = 0; i < num_keys; ++i) {
760 PythonObject key = keys.GetItemAtIndex(i);
761 PythonObject value = GetItemForKey(key);
763 result->AddItem(key.Str().GetString(), structured_value);
768PythonModule PythonModule::BuiltinsModule() {
return AddModule(
"builtins"); }
770PythonModule PythonModule::MainModule() {
return AddModule(
"__main__"); }
772PythonModule PythonModule::AddModule(llvm::StringRef module) {
773 std::string str =
module.str();
774 return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
777Expected<PythonModule> PythonModule::Import(
const Twine &name) {
778 PyObject *mod = PyImport_ImportModule(NullTerminated(name));
781 return Take<PythonModule>(mod);
784Expected<PythonObject> PythonModule::Get(
const Twine &name) {
787 PyObject *dict = PyModule_GetDict(m_py_obj);
790 PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
793 return Retain<PythonObject>(item);
796bool PythonModule::Check(PyObject *py_obj) {
800 return PyModule_Check(py_obj);
803PythonDictionary PythonModule::GetDictionary()
const {
805 return PythonDictionary();
806 return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
809bool PythonCallable::Check(PyObject *py_obj) {
813 PythonObject python_obj(PyRefType::Borrowed, py_obj);
817 if (python_obj.HasAttribute(
"__func__")) {
818 PythonObject function_obj = python_obj.GetAttributeValue(
"__func__");
819 if (!function_obj.IsAllocated())
821 return PyCallable_Check(function_obj.release());
824 return PyCallable_Check(py_obj);
827static const char get_arg_info_script[] = R
"(
828from inspect import signature, Parameter, ismethod
829from collections import namedtuple
830ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs'])
834 for parameter in signature(f).parameters.values():
835 kind = parameter.kind
836 if kind in (Parameter.POSITIONAL_ONLY,
837 Parameter.POSITIONAL_OR_KEYWORD):
839 elif kind == Parameter.VAR_POSITIONAL:
841 elif kind in (Parameter.KEYWORD_ONLY,
842 Parameter.VAR_KEYWORD):
845 raise Exception(f'unknown parameter kind: {kind}')
846 return ArgInfo(count, varargs)
849Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
855 static PythonScript get_arg_info(get_arg_info_script);
856 Expected<PythonObject> pyarginfo = get_arg_info(*
this);
858 return pyarginfo.takeError();
860 cantFail(As<long long>(pyarginfo.get().GetAttribute(
"count")));
862 cantFail(As<bool>(pyarginfo.get().GetAttribute(
"has_varargs")));
863 result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count;
869 PythonCallable::ArgInfo::UNBOUNDED;
871PythonObject PythonCallable::operator()() {
872 return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj,
nullptr));
876PythonCallable::operator()(std::initializer_list<PyObject *> args) {
877 PythonTuple arg_tuple(args);
878 return PythonObject(PyRefType::Owned,
879 PyObject_CallObject(m_py_obj, arg_tuple.get()));
883PythonCallable::operator()(std::initializer_list<PythonObject> args) {
884 PythonTuple arg_tuple(args);
885 return PythonObject(PyRefType::Owned,
886 PyObject_CallObject(m_py_obj, arg_tuple.get()));
889bool PythonFile::Check(PyObject *py_obj) {
897 auto io_module = PythonModule::Import(
"io");
899 llvm::consumeError(io_module.takeError());
902 auto iobase = io_module.get().Get(
"IOBase");
904 llvm::consumeError(iobase.takeError());
907 int r = PyObject_IsInstance(py_obj, iobase.get().get());
909 llvm::consumeError(exception());
915const char *PythonException::toCString()
const {
917 return "unknown exception";
918 return PyBytes_AsString(m_repr_bytes);
921PythonException::PythonException(
const char *caller) {
922 assert(PyErr_Occurred());
923 m_exception_type = m_exception = m_traceback = m_repr_bytes =
nullptr;
924 PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
925 PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
928 PyObject *repr = PyObject_Repr(m_exception);
930 m_repr_bytes = PyUnicode_AsEncodedString(repr,
"utf-8",
nullptr);
941 LLDB_LOGF(log,
"%s failed with exception: %s", caller, toCString());
943 LLDB_LOGF(log,
"python exception: %s", toCString());
945void PythonException::Restore() {
946 if (m_exception_type && m_exception) {
947 PyErr_Restore(m_exception_type, m_exception, m_traceback);
949 PyErr_SetString(PyExc_Exception, toCString());
951 m_exception_type = m_exception = m_traceback =
nullptr;
954PythonException::~PythonException() {
955 Py_XDECREF(m_exception_type);
956 Py_XDECREF(m_exception);
957 Py_XDECREF(m_traceback);
958 Py_XDECREF(m_repr_bytes);
961void PythonException::log(llvm::raw_ostream &
OS)
const {
OS << toCString(); }
963std::error_code PythonException::convertToErrorCode()
const {
964 return llvm::inconvertibleErrorCode();
967bool PythonException::Matches(PyObject *exc)
const {
968 return PyErr_GivenExceptionMatches(m_exception_type, exc);
971const char read_exception_script[] = R
"(
973from traceback import print_exception
974if sys.version_info.major < 3:
975 from StringIO import StringIO
977 from io import StringIO
978def main(exc_type, exc_value, tb):
980 print_exception(exc_type, exc_value, tb, file=f)
984std::string PythonException::ReadBacktrace() const {
990 static PythonScript read_exception(read_exception_script);
992 Expected<std::string> backtrace = As<std::string>(
993 read_exception(m_exception_type, m_exception, m_traceback));
996 std::string message =
997 std::string(toCString()) +
"\n" +
998 "Traceback unavailable, an error occurred while reading it:\n";
999 return (message + llvm::toString(backtrace.takeError()));
1002 return std::move(backtrace.get());
1005char PythonException::ID = 0;
1007llvm::Expected<File::OpenOptions>
1008GetOptionsForPyObject(
const PythonObject &obj) {
1010 auto readable = As<bool>(obj.CallMethod(
"readable"));
1012 return readable.takeError();
1013 auto writable = As<bool>(obj.CallMethod(
"writable"));
1015 return writable.takeError();
1016 if (readable.get() && writable.get())
1018 else if (writable.get())
1020 else if (readable.get())
1029template <
typename Base>
class OwnedPythonFile :
public Base {
1031 template <
typename... Args>
1032 OwnedPythonFile(
const PythonFile &file,
bool borrowed, Args... args)
1033 : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1037 ~OwnedPythonFile()
override {
1046 bool IsPythonSideValid()
const {
1048 auto closed = As<bool>(m_py_obj.GetAttribute(
"closed"));
1050 llvm::consumeError(closed.takeError());
1053 return !closed.get();
1056 bool IsValid()
const override {
1057 return IsPythonSideValid() && Base::IsValid();
1060 Status Close()
override {
1062 Status py_error, base_error;
1065 auto r = m_py_obj.CallMethod(
"close");
1067 py_error = Status::FromError(r.takeError());
1069 base_error = Base::Close();
1071 if (py_error.Fail())
1072 return py_error.Clone();
1073 return base_error.Clone();
1076 PyObject *GetPythonObject()
const {
1077 assert(m_py_obj.IsValid());
1078 return m_py_obj.get();
1081 static bool classof(
const File *file) =
delete;
1084 PythonFile m_py_obj;
1092class SimplePythonFile :
public OwnedPythonFile<NativeFile> {
1094 SimplePythonFile(
const PythonFile &file,
bool borrowed,
int fd,
1095 File::OpenOptions options)
1096 : OwnedPythonFile(file, borrowed, fd, options, false) {}
1099 bool isA(
const void *classID)
const override {
1100 return classID == &
ID || NativeFile::isA(classID);
1102 static bool classof(
const File *file) {
return file->
isA(&
ID); }
1104char SimplePythonFile::ID = 0;
1109class PythonIOFile :
public OwnedPythonFile<File> {
1111 PythonIOFile(
const PythonFile &file,
bool borrowed)
1112 : OwnedPythonFile(file, borrowed) {}
1114 ~PythonIOFile()
override { Close(); }
1116 bool IsValid()
const override {
return IsPythonSideValid(); }
1118 Status Close()
override {
1123 auto r = m_py_obj.CallMethod(
"close");
1126 return Status::FromError(r.takeError()).Clone();
1130 Status Flush()
override {
1132 auto r = m_py_obj.CallMethod(
"flush");
1135 return Status::FromError(r.takeError()).Clone();
1139 Expected<File::OpenOptions> GetOptions()
const override {
1141 return GetOptionsForPyObject(m_py_obj);
1145 bool isA(
const void *classID)
const override {
1146 return classID == &
ID || File::isA(classID);
1148 static bool classof(
const File *file) {
return file->
isA(&
ID); }
1150char PythonIOFile::ID = 0;
1154class BinaryPythonFile :
public PythonIOFile {
1159 BinaryPythonFile(
int fd,
const PythonFile &file,
bool borrowed)
1160 : PythonIOFile(file, borrowed),
1161 m_descriptor(File::DescriptorIsValid(fd) ? fd
1162 : File::kInvalidDescriptor) {}
1164 int GetDescriptor()
const override {
return m_descriptor; }
1166 Status Write(
const void *buf,
size_t &num_bytes)
override {
1168 PyObject *pybuffer_p = PyMemoryView_FromMemory(
1169 const_cast<char *
>((
const char *)buf), num_bytes, PyBUF_READ);
1172 return Status::FromError(llvm::make_error<PythonException>()).Clone();
1173 auto pybuffer = Take<PythonObject>(pybuffer_p);
1175 auto bytes_written = As<long long>(m_py_obj.CallMethod(
"write", pybuffer));
1177 return Status::FromError(bytes_written.takeError());
1178 if (bytes_written.get() < 0)
1179 return Status::FromErrorString(
1180 ".write() method returned a negative number!");
1181 static_assert(
sizeof(
long long) >=
sizeof(size_t),
"overflow");
1182 num_bytes = bytes_written.get();
1186 Status Read(
void *buf,
size_t &num_bytes)
override {
1188 static_assert(
sizeof(
long long) >=
sizeof(size_t),
"overflow");
1190 m_py_obj.CallMethod(
"read", (
unsigned long long)num_bytes);
1193 return Status::FromError(pybuffer_obj.takeError()).Clone();
1195 if (pybuffer_obj.get().IsNone()) {
1200 PythonBytes pybytes(PyRefType::Borrowed, pybuffer_obj->get());
1202 return Status::FromError(llvm::make_error<PythonException>());
1203 llvm::ArrayRef<uint8_t> bytes = pybytes.GetBytes();
1204 memcpy(buf, bytes.begin(), bytes.size());
1205 num_bytes = bytes.size();
1212class TextPythonFile :
public PythonIOFile {
1217 TextPythonFile(
int fd,
const PythonFile &file,
bool borrowed)
1218 : PythonIOFile(file, borrowed),
1219 m_descriptor(File::DescriptorIsValid(fd) ? fd
1220 : File::kInvalidDescriptor) {}
1222 int GetDescriptor()
const override {
return m_descriptor; }
1224 Status Write(
const void *buf,
size_t &num_bytes)
override {
1227 PythonString::FromUTF8(llvm::StringRef((
const char *)buf, num_bytes));
1229 return Status::FromError(pystring.takeError());
1231 auto bytes_written =
1232 As<long long>(m_py_obj.CallMethod(
"write", pystring.get()));
1235 return Status::FromError(bytes_written.takeError()).Clone();
1236 if (bytes_written.get() < 0)
1237 return Status::FromErrorString(
1238 ".write() method returned a negative number!");
1239 static_assert(
sizeof(
long long) >=
sizeof(size_t),
"overflow");
1240 num_bytes = bytes_written.get();
1244 Status Read(
void *buf,
size_t &num_bytes)
override {
1246 size_t num_chars = num_bytes / 6;
1247 size_t orig_num_bytes = num_bytes;
1249 if (orig_num_bytes < 6) {
1250 return Status::FromErrorString(
1251 "can't read less than 6 bytes from a utf8 text stream");
1253 auto pystring = As<PythonString>(
1254 m_py_obj.CallMethod(
"read", (
unsigned long long)num_chars));
1257 return Status::FromError(pystring.takeError()).Clone();
1258 if (pystring.get().IsNone()) {
1262 auto stringref = pystring.get().AsUTF8();
1265 return Status::FromError(stringref.takeError()).Clone();
1266 num_bytes = stringref.get().size();
1267 memcpy(buf, stringref.get().begin(), num_bytes);
1273llvm::Expected<FileSP> PythonFile::ConvertToFile(
bool borrowed) {
1275 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1276 "invalid PythonFile");
1278 int fd = PyObject_AsFileDescriptor(m_py_obj);
1281 return ConvertToFileForcingUseOfScriptingIOMethods(borrowed);
1283 auto options = GetOptionsForPyObject(*
this);
1285 return options.takeError();
1293 auto r = CallMethod(
"flush");
1295 return r.takeError();
1302 file_sp = std::make_shared<NativeFile>(fd, options.get(),
false);
1304 file_sp = std::static_pointer_cast<File>(
1305 std::make_shared<SimplePythonFile>(*
this, borrowed, fd, options.get()));
1307 if (!file_sp->IsValid())
1308 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1314llvm::Expected<FileSP>
1315PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(
bool borrowed) {
1317 assert(!PyErr_Occurred());
1320 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1321 "invalid PythonFile");
1323 int fd = PyObject_AsFileDescriptor(m_py_obj);
1329 auto io_module = PythonModule::Import(
"io");
1331 return io_module.takeError();
1332 auto textIOBase = io_module.get().Get(
"TextIOBase");
1334 return textIOBase.takeError();
1335 auto rawIOBase = io_module.get().Get(
"RawIOBase");
1337 return rawIOBase.takeError();
1338 auto bufferedIOBase = io_module.get().Get(
"BufferedIOBase");
1339 if (!bufferedIOBase)
1340 return bufferedIOBase.takeError();
1344 auto isTextIO = IsInstance(textIOBase.get());
1346 return isTextIO.takeError();
1348 file_sp = std::static_pointer_cast<File>(
1349 std::make_shared<TextPythonFile>(fd, *
this, borrowed));
1351 auto isRawIO = IsInstance(rawIOBase.get());
1353 return isRawIO.takeError();
1354 auto isBufferedIO = IsInstance(bufferedIOBase.get());
1356 return isBufferedIO.takeError();
1358 if (isRawIO.get() || isBufferedIO.get()) {
1359 file_sp = std::static_pointer_cast<File>(
1360 std::make_shared<BinaryPythonFile>(fd, *
this, borrowed));
1364 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1365 "python file is neither text nor binary");
1367 if (!file_sp->IsValid())
1368 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1374Expected<PythonFile> PythonFile::FromFile(File &file,
const char *mode) {
1376 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1379 if (
auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
1380 return Retain<PythonFile>(simple->GetPythonObject());
1381 if (
auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
1382 return Retain<PythonFile>(pythonio->GetPythonObject());
1387 return m.takeError();
1392 file_obj = PyFile_FromFd(file.
GetDescriptor(),
nullptr, mode, -1,
nullptr,
1393 "ignore",
nullptr, 0);
1398 return Take<PythonFile>(file_obj);
1401Error PythonScript::Init() {
1402 if (function.IsValid())
1403 return Error::success();
1405 PythonDictionary globals(PyInitialValue::Empty);
1406 auto builtins = PythonModule::BuiltinsModule();
1407 if (
Error error = globals.SetItem(
"__builtins__", builtins))
1409 PyObject *o = RunString(script, Py_file_input, globals.get(), globals.get());
1412 Take<PythonObject>(o);
1413 auto f = As<PythonCallable>(globals.GetItem(
"main"));
1415 return f.takeError();
1416 function = std::move(f.get());
1418 return Error::success();
1421llvm::Expected<PythonObject>
1422python::runStringOneLine(
const llvm::Twine &
string,
1423 const PythonDictionary &globals,
1424 const PythonDictionary &locals) {
1425 if (!globals.IsValid() || !locals.IsValid())
1429 Py_CompileString(NullTerminated(
string),
"<string>", Py_eval_input);
1433 Py_CompileString(NullTerminated(
string),
"<string>", Py_single_input);
1437 auto code_ref = Take<PythonObject>(code);
1439 PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
1444 return Take<PythonObject>(result);
1447llvm::Expected<PythonObject>
1448python::runStringMultiLine(
const llvm::Twine &
string,
1449 const PythonDictionary &globals,
1450 const PythonDictionary &locals) {
1451 if (!globals.IsValid() || !locals.IsValid())
1453 PyObject *result = RunString(NullTerminated(
string), Py_file_input,
1454 globals.get(), locals.get());
1457 return Take<PythonObject>(result);
1460PyObject *lldb_private::python::RunString(
const char *str,
int start,
1461 PyObject *globals, PyObject *locals) {
1462 const char *filename =
"<string>";
1465 PyObject *code = Py_CompileString(str, filename, start);
1470 PyObject *result = PyEval_EvalCode(code, globals, locals);
1478int lldb_private::python::RunSimpleString(
const char *str) {
1479 PyObject *main_module = PyImport_AddModule(
"__main__");
1483 PyObject *globals = PyModule_GetDict(main_module);
1487 PyObject *result = RunString(str, Py_file_input, globals, globals);
static void SetInteger(Scalar &scalar, uint64_t raw_value, bool is_signed)
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
static uint32_t GetBytes(uint32_t bits)
virtual bool isA(const void *classID) const
static int kInvalidDescriptor
virtual int GetDescriptor() const
Get underlying OS file descriptor for this file, or kInvalidDescriptor.
llvm::Expected< const char * > GetOpenMode() const
bool IsValid() const override
IsValid.
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
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.
std::shared_ptr< lldb_private::File > FileSP