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 llvm::scope_exit release_py_str([py_str] { Py_DECREF(py_str); });
133 PyObject *py_bytes = PyUnicode_AsEncodedString(py_str,
"utf-8",
"replace");
137 llvm::scope_exit release_py_bytes([py_bytes] { Py_DECREF(py_bytes); });
139 char *buffer =
nullptr;
140 Py_ssize_t length = 0;
141 if (PyBytes_AsStringAndSize(py_bytes, &buffer, &length) == -1)
144 strm << llvm::StringRef(buffer, length);
147PyObjectType PythonObject::GetObjectType()
const {
149 return PyObjectType::None;
151 if (PythonModule::Check(m_py_obj))
152 return PyObjectType::Module;
153 if (PythonList::Check(m_py_obj))
154 return PyObjectType::List;
155 if (PythonTuple::Check(m_py_obj))
156 return PyObjectType::Tuple;
157 if (PythonDictionary::Check(m_py_obj))
158 return PyObjectType::Dictionary;
159 if (PythonString::Check(m_py_obj))
160 return PyObjectType::String;
161 if (PythonBytes::Check(m_py_obj))
162 return PyObjectType::Bytes;
163 if (PythonByteArray::Check(m_py_obj))
164 return PyObjectType::ByteArray;
165 if (PythonBoolean::Check(m_py_obj))
166 return PyObjectType::Boolean;
167 if (PythonInteger::Check(m_py_obj))
168 return PyObjectType::Integer;
169 if (PythonFile::Check(m_py_obj))
170 return PyObjectType::File;
171 if (PythonCallable::Check(m_py_obj))
172 return PyObjectType::Callable;
173 return PyObjectType::Unknown;
176PythonString PythonObject::Repr()
const {
178 return PythonString();
179 PyObject *repr = PyObject_Repr(m_py_obj);
181 return PythonString();
182 return PythonString(PyRefType::Owned, repr);
185PythonString PythonObject::Str()
const {
187 return PythonString();
188 PyObject *str = PyObject_Str(m_py_obj);
190 return PythonString();
191 return PythonString(PyRefType::Owned, str);
195PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
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) {
207 return result.ResolveName(name.substr(dot_pos + 1));
210PythonObject PythonObject::ResolveName(llvm::StringRef name)
const {
221 size_t dot_pos = name.find(
'.');
222 if (dot_pos == llvm::StringRef::npos) {
225 return GetAttributeValue(name);
230 PythonObject parent = ResolveName(name.substr(0, dot_pos));
231 if (!parent.IsAllocated())
232 return PythonObject();
235 return parent.ResolveName(name.substr(dot_pos + 1));
238bool PythonObject::HasAttribute(llvm::StringRef attr)
const {
241 PythonString py_attr(attr);
242 return !!PyObject_HasAttr(m_py_obj, py_attr.get());
245PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr)
const {
247 return PythonObject();
249 PythonString py_attr(attr);
250 if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
251 return PythonObject();
253 return PythonObject(PyRefType::Owned,
254 PyObject_GetAttr(m_py_obj, py_attr.get()));
258 switch (GetObjectType()) {
259 case PyObjectType::Dictionary:
260 return PythonDictionary(PyRefType::Borrowed, m_py_obj)
261 .CreateStructuredDictionary();
262 case PyObjectType::Boolean:
263 return PythonBoolean(PyRefType::Borrowed, m_py_obj)
264 .CreateStructuredBoolean();
265 case PyObjectType::Integer: {
267 PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger();
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);
274 case PyObjectType::List:
275 return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
276 case PyObjectType::String:
277 return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
278 case PyObjectType::Bytes:
279 return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
280 case PyObjectType::ByteArray:
281 return PythonByteArray(PyRefType::Borrowed, m_py_obj)
282 .CreateStructuredString();
283 case PyObjectType::None:
287 PythonObject(PyRefType::Borrowed, m_py_obj)));
293PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
295PythonBytes::PythonBytes(
const uint8_t *bytes,
size_t length) {
296 SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
299bool PythonBytes::Check(PyObject *py_obj) {
302 return PyBytes_Check(py_obj);
305llvm::ArrayRef<uint8_t> PythonBytes::GetBytes()
const {
307 return llvm::ArrayRef<uint8_t>();
312 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
313 return llvm::ArrayRef<uint8_t>(
reinterpret_cast<uint8_t *
>(c), size);
316size_t PythonBytes::GetSize()
const {
319 return PyBytes_Size(m_py_obj);
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()));
331 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
332 result->SetValue(std::string(c, size));
336PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
337 : PythonByteArray(bytes.data(), bytes.size()) {}
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));
344bool PythonByteArray::Check(PyObject *py_obj) {
347 return PyByteArray_Check(py_obj);
350llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes()
const {
352 return llvm::ArrayRef<uint8_t>();
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);
359size_t PythonByteArray::GetSize()
const {
363 return PyByteArray_Size(m_py_obj);
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()));
376Expected<PythonString> PythonString::FromUTF8(llvm::StringRef
string) {
377 PyObject *str = PyUnicode_FromStringAndSize(
string.data(),
string.size());
379 return llvm::make_error<PythonException>();
380 return Take<PythonString>(str);
383PythonString::PythonString(llvm::StringRef
string) { SetString(
string); }
385bool PythonString::Check(PyObject *py_obj) {
389 if (PyUnicode_Check(py_obj))
394llvm::StringRef PythonString::GetString()
const {
397 llvm::consumeError(s.takeError());
398 return llvm::StringRef(
"");
403Expected<llvm::StringRef> PythonString::AsUTF8()
const {
412#if defined(Py_LIMITED_API) && (Py_LIMITED_API < 0x030a0000)
413 PyObject *py_bytes = PyUnicode_AsUTF8String(m_py_obj);
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);
426 const char *str = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
431 return llvm::StringRef(str, size);
435size_t PythonString::GetSize()
const {
437 return PyUnicode_GetLength(m_py_obj);
441void PythonString::SetString(llvm::StringRef
string) {
442 auto s = FromUTF8(
string);
444 llvm::consumeError(s.takeError());
447 *
this = std::move(s.get());
453 result->SetValue(GetString());
459PythonInteger::PythonInteger(int64_t value) {
SetInteger(value); }
461bool PythonInteger::Check(PyObject *py_obj) {
467 return PyLong_Check(py_obj);
470void PythonInteger::SetInteger(int64_t value) {
471 *
this = Take<PythonInteger>(PyLong_FromLongLong(value));
477 : CreateStructuredSignedInteger();
481PythonInteger::CreateStructuredUnsignedInteger()
const {
483 llvm::Expected<unsigned long long> value = AsUnsignedLongLong();
485 llvm::consumeError(value.takeError());
487 result = std::make_shared<StructuredData::UnsignedInteger>(value.get());
493PythonInteger::CreateStructuredSignedInteger()
const {
495 llvm::Expected<long long> value = AsLongLong();
497 llvm::consumeError(value.takeError());
499 result = std::make_shared<StructuredData::SignedInteger>(value.get());
506PythonBoolean::PythonBoolean(
bool value) { SetValue(value); }
508bool PythonBoolean::Check(PyObject *py_obj) {
509 return py_obj ? PyBool_Check(py_obj) : false;
512bool PythonBoolean::GetValue()
const {
513 return m_py_obj ? PyObject_IsTrue(m_py_obj) : false;
516void PythonBoolean::SetValue(
bool value) {
517 *
this = Take<PythonBoolean>(PyBool_FromLong(value));
522 result->SetValue(GetValue());
528PythonList::PythonList(PyInitialValue value) {
529 if (value == PyInitialValue::Empty)
530 *
this = Take<PythonList>(PyList_New(0));
533PythonList::PythonList(
int list_size) {
534 *
this = Take<PythonList>(PyList_New(list_size));
537bool PythonList::Check(PyObject *py_obj) {
540 return PyList_Check(py_obj);
543uint32_t PythonList::GetSize()
const {
545 return PyList_Size(m_py_obj);
549PythonObject PythonList::GetItemAtIndex(uint32_t index)
const {
551 return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
552 return PythonObject();
555void PythonList::SetItemAtIndex(uint32_t index,
const PythonObject &
object) {
556 if (IsAllocated() &&
object.IsValid()) {
559 Py_INCREF(
object.get());
560 PyList_SetItem(m_py_obj, index,
object.get());
564void PythonList::AppendItem(
const PythonObject &
object) {
565 if (IsAllocated() &&
object.IsValid()) {
568 PyList_Append(m_py_obj,
object.get());
574 uint32_t count = GetSize();
575 for (uint32_t i = 0; i < count; ++i) {
576 PythonObject obj = GetItemAtIndex(i);
577 result->AddItem(obj.CreateStructuredObject());
584PythonTuple::PythonTuple(PyInitialValue value) {
585 if (value == PyInitialValue::Empty)
586 *
this = Take<PythonTuple>(PyTuple_New(0));
589PythonTuple::PythonTuple(
int tuple_size) {
590 *
this = Take<PythonTuple>(PyTuple_New(tuple_size));
593PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
594 m_py_obj = PyTuple_New(objects.size());
597 for (
auto object : objects) {
598 if (
object.IsValid())
599 SetItemAtIndex(idx,
object);
604PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
605 m_py_obj = PyTuple_New(objects.size());
608 for (
auto py_object : objects) {
609 PythonObject object(PyRefType::Borrowed, py_object);
610 if (
object.IsValid())
611 SetItemAtIndex(idx,
object);
616bool PythonTuple::Check(PyObject *py_obj) {
619 return PyTuple_Check(py_obj);
622uint32_t PythonTuple::GetSize()
const {
624 return PyTuple_Size(m_py_obj);
628PythonObject PythonTuple::GetItemAtIndex(uint32_t index)
const {
630 return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
631 return PythonObject();
634void PythonTuple::SetItemAtIndex(uint32_t index,
const PythonObject &
object) {
635 if (IsAllocated() &&
object.IsValid()) {
638 Py_INCREF(
object.get());
639 PyTuple_SetItem(m_py_obj, index,
object.get());
645 uint32_t count = GetSize();
646 for (uint32_t i = 0; i < count; ++i) {
647 PythonObject obj = GetItemAtIndex(i);
648 result->AddItem(obj.CreateStructuredObject());
655PythonDictionary::PythonDictionary(PyInitialValue value) {
656 if (value == PyInitialValue::Empty)
657 *
this = Take<PythonDictionary>(PyDict_New());
660bool PythonDictionary::Check(PyObject *py_obj) {
664 return PyDict_Check(py_obj);
667bool PythonDictionary::HasKey(
const llvm::Twine &key)
const {
671 PythonString key_object(key.isSingleStringRef() ? key.getSingleStringRef()
674 if (
int res = PyDict_Contains(m_py_obj, key_object.get()) > 0)
681uint32_t PythonDictionary::GetSize()
const {
683 return PyDict_Size(m_py_obj);
687PythonList PythonDictionary::GetKeys()
const {
689 return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
690 return PythonList(PyInitialValue::Invalid);
693PythonObject PythonDictionary::GetItemForKey(
const PythonObject &key)
const {
694 auto item = GetItem(key);
696 llvm::consumeError(item.takeError());
697 return PythonObject();
699 return std::move(item.get());
702Expected<PythonObject>
703PythonDictionary::GetItem(
const PythonObject &key)
const {
706 PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
707 if (PyErr_Occurred())
711 return Retain<PythonObject>(o);
714Expected<PythonObject> PythonDictionary::GetItem(
const Twine &key)
const {
717 PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
718 if (PyErr_Occurred())
722 return Retain<PythonObject>(o);
725Error PythonDictionary::SetItem(
const PythonObject &key,
726 const PythonObject &value)
const {
727 if (!IsValid() || !value.IsValid())
729 int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
732 return Error::success();
735Error PythonDictionary::SetItem(
const Twine &key,
736 const PythonObject &value)
const {
737 if (!IsValid() || !value.IsValid())
739 int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
742 return Error::success();
745void PythonDictionary::SetItemForKey(
const PythonObject &key,
746 const PythonObject &value) {
749 llvm::consumeError(std::move(
error));
753PythonDictionary::CreateStructuredDictionary()
const {
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);
761 result->AddItem(key.Str().GetString(), structured_value);
766PythonModule PythonModule::BuiltinsModule() {
return AddModule(
"builtins"); }
768PythonModule PythonModule::MainModule() {
return AddModule(
"__main__"); }
770PythonModule PythonModule::AddModule(llvm::StringRef module) {
771 std::string str =
module.str();
772 return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
775Expected<PythonModule> PythonModule::Import(
const Twine &name) {
776 PyObject *mod = PyImport_ImportModule(NullTerminated(name));
779 return Take<PythonModule>(mod);
782Expected<PythonObject> PythonModule::Get(
const Twine &name) {
785 PyObject *dict = PyModule_GetDict(m_py_obj);
788 PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
791 return Retain<PythonObject>(item);
794bool PythonModule::Check(PyObject *py_obj) {
798 return PyModule_Check(py_obj);
801PythonDictionary PythonModule::GetDictionary()
const {
803 return PythonDictionary();
804 return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
807bool PythonCallable::Check(PyObject *py_obj) {
811 PythonObject python_obj(PyRefType::Borrowed, py_obj);
815 if (python_obj.HasAttribute(
"__func__")) {
816 PythonObject function_obj = python_obj.GetAttributeValue(
"__func__");
817 if (!function_obj.IsAllocated())
819 return PyCallable_Check(function_obj.release());
822 return PyCallable_Check(py_obj);
825static const char get_arg_info_script[] = R
"(
826from inspect import signature, Parameter, ismethod
827from collections import namedtuple
828ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs'])
832 for parameter in signature(f).parameters.values():
833 kind = parameter.kind
834 if kind in (Parameter.POSITIONAL_ONLY,
835 Parameter.POSITIONAL_OR_KEYWORD):
837 elif kind == Parameter.VAR_POSITIONAL:
839 elif kind in (Parameter.KEYWORD_ONLY,
840 Parameter.VAR_KEYWORD):
843 raise Exception(f'unknown parameter kind: {kind}')
844 return ArgInfo(count, varargs)
847Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo() const {
853 static PythonScript get_arg_info(get_arg_info_script);
854 Expected<PythonObject> pyarginfo = get_arg_info(*
this);
856 return pyarginfo.takeError();
858 cantFail(As<long long>(pyarginfo.get().GetAttribute(
"count")));
860 cantFail(As<bool>(pyarginfo.get().GetAttribute(
"has_varargs")));
861 result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count;
867 PythonCallable::ArgInfo::UNBOUNDED;
869PythonObject PythonCallable::operator()() {
870 return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj,
nullptr));
874PythonCallable::operator()(std::initializer_list<PyObject *> args) {
875 PythonTuple arg_tuple(args);
876 return PythonObject(PyRefType::Owned,
877 PyObject_CallObject(m_py_obj, arg_tuple.get()));
881PythonCallable::operator()(std::initializer_list<PythonObject> args) {
882 PythonTuple arg_tuple(args);
883 return PythonObject(PyRefType::Owned,
884 PyObject_CallObject(m_py_obj, arg_tuple.get()));
887bool PythonFile::Check(PyObject *py_obj) {
895 auto io_module = PythonModule::Import(
"io");
897 llvm::consumeError(io_module.takeError());
900 auto iobase = io_module.get().Get(
"IOBase");
902 llvm::consumeError(iobase.takeError());
905 int r = PyObject_IsInstance(py_obj, iobase.get().get());
907 llvm::consumeError(exception());
913const char *PythonException::toCString()
const {
915 return "unknown exception";
916 return PyBytes_AsString(m_repr_bytes);
919PythonException::PythonException(
const char *caller) {
920 assert(PyErr_Occurred());
921 m_exception_type = m_exception = m_traceback = m_repr_bytes =
nullptr;
922 PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
923 PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
926 PyObject *repr = PyObject_Repr(m_exception);
928 m_repr_bytes = PyUnicode_AsEncodedString(repr,
"utf-8",
nullptr);
939 LLDB_LOGF(log,
"%s failed with exception: %s", caller, toCString());
941 LLDB_LOGF(log,
"python exception: %s", toCString());
943void PythonException::Restore() {
944 if (m_exception_type && m_exception) {
945 PyErr_Restore(m_exception_type, m_exception, m_traceback);
947 PyErr_SetString(PyExc_Exception, toCString());
949 m_exception_type = m_exception = m_traceback =
nullptr;
952PythonException::~PythonException() {
953 Py_XDECREF(m_exception_type);
954 Py_XDECREF(m_exception);
955 Py_XDECREF(m_traceback);
956 Py_XDECREF(m_repr_bytes);
959void PythonException::log(llvm::raw_ostream &
OS)
const {
OS << toCString(); }
961std::error_code PythonException::convertToErrorCode()
const {
962 return llvm::inconvertibleErrorCode();
965bool PythonException::Matches(PyObject *exc)
const {
966 return PyErr_GivenExceptionMatches(m_exception_type, exc);
969const char read_exception_script[] = R
"(
971from traceback import print_exception
972if sys.version_info.major < 3:
973 from StringIO import StringIO
975 from io import StringIO
976def main(exc_type, exc_value, tb):
978 print_exception(exc_type, exc_value, tb, file=f)
982std::string PythonException::ReadBacktrace() const {
988 static PythonScript read_exception(read_exception_script);
990 Expected<std::string> backtrace = As<std::string>(
991 read_exception(m_exception_type, m_exception, m_traceback));
994 std::string message =
995 std::string(toCString()) +
"\n" +
996 "Traceback unavailable, an error occurred while reading it:\n";
997 return (message + llvm::toString(backtrace.takeError()));
1000 return std::move(backtrace.get());
1003char PythonException::ID = 0;
1005llvm::Expected<File::OpenOptions>
1006GetOptionsForPyObject(
const PythonObject &obj) {
1008 auto readable = As<bool>(obj.CallMethod(
"readable"));
1010 return readable.takeError();
1011 auto writable = As<bool>(obj.CallMethod(
"writable"));
1013 return writable.takeError();
1014 if (readable.get() && writable.get())
1016 else if (writable.get())
1018 else if (readable.get())
1027template <
typename Base>
class OwnedPythonFile :
public Base {
1029 template <
typename... Args>
1030 OwnedPythonFile(
const PythonFile &file,
bool borrowed, Args... args)
1031 : Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1035 ~OwnedPythonFile()
override {
1044 bool IsPythonSideValid()
const {
1046 auto closed = As<bool>(m_py_obj.GetAttribute(
"closed"));
1048 llvm::consumeError(closed.takeError());
1051 return !closed.get();
1054 bool IsValid()
const override {
1055 return IsPythonSideValid() && Base::IsValid();
1058 Status Close()
override {
1060 Status py_error, base_error;
1063 auto r = m_py_obj.CallMethod(
"close");
1065 py_error = Status::FromError(r.takeError());
1067 base_error = Base::Close();
1069 if (py_error.Fail())
1070 return py_error.Clone();
1071 return base_error.Clone();
1074 PyObject *GetPythonObject()
const {
1075 assert(m_py_obj.IsValid());
1076 return m_py_obj.get();
1079 static bool classof(
const File *file) =
delete;
1082 PythonFile m_py_obj;
1090class SimplePythonFile :
public OwnedPythonFile<NativeFile> {
1092 SimplePythonFile(
const PythonFile &file,
bool borrowed,
int fd,
1093 File::OpenOptions options)
1094 : OwnedPythonFile(file, borrowed, fd, options, false) {}
1097 bool isA(
const void *classID)
const override {
1098 return classID == &
ID || NativeFile::isA(classID);
1100 static bool classof(
const File *file) {
return file->
isA(&
ID); }
1102char SimplePythonFile::ID = 0;
1107class PythonIOFile :
public OwnedPythonFile<File> {
1109 PythonIOFile(
const PythonFile &file,
bool borrowed)
1110 : OwnedPythonFile(file, borrowed) {}
1112 ~PythonIOFile()
override { Close(); }
1114 bool IsValid()
const override {
return IsPythonSideValid(); }
1116 Status Close()
override {
1121 auto r = m_py_obj.CallMethod(
"close");
1124 return Status::FromError(r.takeError()).Clone();
1128 Status Flush()
override {
1130 auto r = m_py_obj.CallMethod(
"flush");
1133 return Status::FromError(r.takeError()).Clone();
1137 Expected<File::OpenOptions> GetOptions()
const override {
1139 return GetOptionsForPyObject(m_py_obj);
1143 bool isA(
const void *classID)
const override {
1144 return classID == &
ID || File::isA(classID);
1146 static bool classof(
const File *file) {
return file->
isA(&
ID); }
1148char PythonIOFile::ID = 0;
1152class BinaryPythonFile :
public PythonIOFile {
1157 BinaryPythonFile(
int fd,
const PythonFile &file,
bool borrowed)
1158 : PythonIOFile(file, borrowed),
1159 m_descriptor(File::DescriptorIsValid(fd) ? fd
1160 : File::kInvalidDescriptor) {}
1162 int GetDescriptor()
const override {
return m_descriptor; }
1164 Status Write(
const void *buf,
size_t &num_bytes)
override {
1166 PyObject *pybuffer_p = PyMemoryView_FromMemory(
1167 const_cast<char *
>((
const char *)buf), num_bytes, PyBUF_READ);
1170 return Status::FromError(llvm::make_error<PythonException>()).Clone();
1171 auto pybuffer = Take<PythonObject>(pybuffer_p);
1173 auto bytes_written = As<long long>(m_py_obj.CallMethod(
"write", pybuffer));
1175 return Status::FromError(bytes_written.takeError());
1176 if (bytes_written.get() < 0)
1177 return Status::FromErrorString(
1178 ".write() method returned a negative number!");
1179 static_assert(
sizeof(
long long) >=
sizeof(size_t),
"overflow");
1180 num_bytes = bytes_written.get();
1184 Status Read(
void *buf,
size_t &num_bytes)
override {
1186 static_assert(
sizeof(
long long) >=
sizeof(size_t),
"overflow");
1188 m_py_obj.CallMethod(
"read", (
unsigned long long)num_bytes);
1191 return Status::FromError(pybuffer_obj.takeError()).Clone();
1193 if (pybuffer_obj.get().IsNone()) {
1198 PythonBytes pybytes(PyRefType::Borrowed, pybuffer_obj->get());
1200 return Status::FromError(llvm::make_error<PythonException>());
1201 llvm::ArrayRef<uint8_t> bytes = pybytes.GetBytes();
1202 memcpy(buf, bytes.begin(), bytes.size());
1203 num_bytes = bytes.size();
1210class TextPythonFile :
public PythonIOFile {
1215 TextPythonFile(
int fd,
const PythonFile &file,
bool borrowed)
1216 : PythonIOFile(file, borrowed),
1217 m_descriptor(File::DescriptorIsValid(fd) ? fd
1218 : File::kInvalidDescriptor) {}
1220 int GetDescriptor()
const override {
return m_descriptor; }
1222 Status Write(
const void *buf,
size_t &num_bytes)
override {
1225 PythonString::FromUTF8(llvm::StringRef((
const char *)buf, num_bytes));
1227 return Status::FromError(pystring.takeError());
1229 auto bytes_written =
1230 As<long long>(m_py_obj.CallMethod(
"write", pystring.get()));
1233 return Status::FromError(bytes_written.takeError()).Clone();
1234 if (bytes_written.get() < 0)
1235 return Status::FromErrorString(
1236 ".write() method returned a negative number!");
1237 static_assert(
sizeof(
long long) >=
sizeof(size_t),
"overflow");
1238 num_bytes = bytes_written.get();
1242 Status Read(
void *buf,
size_t &num_bytes)
override {
1244 size_t num_chars = num_bytes / 6;
1245 size_t orig_num_bytes = num_bytes;
1247 if (orig_num_bytes < 6) {
1248 return Status::FromErrorString(
1249 "can't read less than 6 bytes from a utf8 text stream");
1251 auto pystring = As<PythonString>(
1252 m_py_obj.CallMethod(
"read", (
unsigned long long)num_chars));
1255 return Status::FromError(pystring.takeError()).Clone();
1256 if (pystring.get().IsNone()) {
1260 auto stringref = pystring.get().AsUTF8();
1263 return Status::FromError(stringref.takeError()).Clone();
1264 num_bytes = stringref.get().size();
1265 memcpy(buf, stringref.get().begin(), num_bytes);
1271llvm::Expected<FileSP> PythonFile::ConvertToFile(
bool borrowed) {
1273 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1274 "invalid PythonFile");
1276 int fd = PyObject_AsFileDescriptor(m_py_obj);
1279 return ConvertToFileForcingUseOfScriptingIOMethods(borrowed);
1281 auto options = GetOptionsForPyObject(*
this);
1283 return options.takeError();
1291 auto r = CallMethod(
"flush");
1293 return r.takeError();
1300 file_sp = std::make_shared<NativeFile>(fd, options.get(),
false);
1302 file_sp = std::static_pointer_cast<File>(
1303 std::make_shared<SimplePythonFile>(*
this, borrowed, fd, options.get()));
1305 if (!file_sp->IsValid())
1306 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1312llvm::Expected<FileSP>
1313PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(
bool borrowed) {
1315 assert(!PyErr_Occurred());
1318 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1319 "invalid PythonFile");
1321 int fd = PyObject_AsFileDescriptor(m_py_obj);
1327 auto io_module = PythonModule::Import(
"io");
1329 return io_module.takeError();
1330 auto textIOBase = io_module.get().Get(
"TextIOBase");
1332 return textIOBase.takeError();
1333 auto rawIOBase = io_module.get().Get(
"RawIOBase");
1335 return rawIOBase.takeError();
1336 auto bufferedIOBase = io_module.get().Get(
"BufferedIOBase");
1337 if (!bufferedIOBase)
1338 return bufferedIOBase.takeError();
1342 auto isTextIO = IsInstance(textIOBase.get());
1344 return isTextIO.takeError();
1346 file_sp = std::static_pointer_cast<File>(
1347 std::make_shared<TextPythonFile>(fd, *
this, borrowed));
1349 auto isRawIO = IsInstance(rawIOBase.get());
1351 return isRawIO.takeError();
1352 auto isBufferedIO = IsInstance(bufferedIOBase.get());
1354 return isBufferedIO.takeError();
1356 if (isRawIO.get() || isBufferedIO.get()) {
1357 file_sp = std::static_pointer_cast<File>(
1358 std::make_shared<BinaryPythonFile>(fd, *
this, borrowed));
1362 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1363 "python file is neither text nor binary");
1365 if (!file_sp->IsValid())
1366 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1372Expected<PythonFile> PythonFile::FromFile(File &file,
const char *mode) {
1374 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1377 if (
auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
1378 return Retain<PythonFile>(simple->GetPythonObject());
1379 if (
auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
1380 return Retain<PythonFile>(pythonio->GetPythonObject());
1385 return m.takeError();
1390 file_obj = PyFile_FromFd(file.
GetDescriptor(),
nullptr, mode, -1,
nullptr,
1391 "ignore",
nullptr, 0);
1396 return Take<PythonFile>(file_obj);
1399Error PythonScript::Init() {
1400 if (function.IsValid())
1401 return Error::success();
1403 PythonDictionary globals(PyInitialValue::Empty);
1404 auto builtins = PythonModule::BuiltinsModule();
1405 if (
Error error = globals.SetItem(
"__builtins__", builtins))
1407 PyObject *o = RunString(script, Py_file_input, globals.get(), globals.get());
1410 Take<PythonObject>(o);
1411 auto f = As<PythonCallable>(globals.GetItem(
"main"));
1413 return f.takeError();
1414 function = std::move(f.get());
1416 return Error::success();
1419llvm::Expected<PythonObject>
1420python::runStringOneLine(
const llvm::Twine &
string,
1421 const PythonDictionary &globals,
1422 const PythonDictionary &locals) {
1423 if (!globals.IsValid() || !locals.IsValid())
1427 Py_CompileString(NullTerminated(
string),
"<string>", Py_eval_input);
1431 Py_CompileString(NullTerminated(
string),
"<string>", Py_single_input);
1435 auto code_ref = Take<PythonObject>(code);
1437 PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
1442 return Take<PythonObject>(result);
1445llvm::Expected<PythonObject>
1446python::runStringMultiLine(
const llvm::Twine &
string,
1447 const PythonDictionary &globals,
1448 const PythonDictionary &locals) {
1449 if (!globals.IsValid() || !locals.IsValid())
1451 PyObject *result = RunString(NullTerminated(
string), Py_file_input,
1452 globals.get(), locals.get());
1455 return Take<PythonObject>(result);
1458PyObject *lldb_private::python::RunString(
const char *str,
int start,
1459 PyObject *globals, PyObject *locals) {
1460 const char *filename =
"<string>";
1463 PyObject *code = Py_CompileString(str, filename, start);
1468 PyObject *result = PyEval_EvalCode(code, globals, locals);
1476int lldb_private::python::RunSimpleString(
const char *str) {
1477 PyObject *main_module = PyImport_AddModule(
"__main__");
1481 PyObject *globals = PyModule_GetDict(main_module);
1485 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