9#include "lldb/Host/Config.h"
23#include "llvm/Support/Casting.h"
24#include "llvm/Support/ConvertUTF.h"
25#include "llvm/Support/Errno.h"
38template <> Expected<bool> python::As<bool>(Expected<PythonObject> &&obj) {
40 return obj.takeError();
41 return obj.get().IsTrue();
45Expected<long long> python::As<long long>(Expected<PythonObject> &&obj) {
47 return obj.takeError();
48 return obj->AsLongLong();
52Expected<unsigned long long>
53python::As<unsigned long long>(Expected<PythonObject> &&obj) {
55 return obj.takeError();
56 return obj->AsUnsignedLongLong();
60Expected<std::string> python::As<std::string>(Expected<PythonObject> &&obj) {
62 return obj.takeError();
63 PyObject *str_obj = PyObject_Str(obj.get().get());
65 return llvm::make_error<PythonException>();
66 auto str = Take<PythonString>(str_obj);
67 auto utf8 = str.AsUTF8();
69 return utf8.takeError();
70 return std::string(utf8.get());
73static bool python_is_finalizing() {
74#if (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 13) || (PY_MAJOR_VERSION > 3)
75 return Py_IsFinalizing();
76#elif PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 7
77 return _Py_Finalizing !=
nullptr;
79 return _Py_IsFinalizing();
83void PythonObject::Reset() {
84 if (m_py_obj && Py_IsInitialized()) {
85 if (python_is_finalizing()) {
89 PyGILState_STATE state = PyGILState_Ensure();
91 PyGILState_Release(state);
97Expected<long long> PythonObject::AsLongLong()
const {
100 assert(!PyErr_Occurred());
101 long long r = PyLong_AsLongLong(m_py_obj);
102 if (PyErr_Occurred())
107Expected<unsigned long long> PythonObject::AsUnsignedLongLong()
const {
110 assert(!PyErr_Occurred());
111 long long r = PyLong_AsUnsignedLongLong(m_py_obj);
112 if (PyErr_Occurred())
118Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong()
const {
121 assert(!PyErr_Occurred());
122 unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj);
124 if (PyErr_Occurred())
129void StructuredPythonObject::Serialize(llvm::json::OStream &s)
const {
130 s.value(llvm::formatv(
"Python Obj: {0:X}", GetValue()).str());
135void PythonObject::Dump(
Stream &strm)
const {
137 FILE *file = llvm::sys::RetryAfterSignal(
nullptr, ::tmpfile);
139 ::PyObject_Print(m_py_obj, file, 0);
140 const long length = ftell(file);
143 std::vector<char> file_contents(length,
'\0');
144 const size_t length_read =
145 ::fread(file_contents.data(), 1, file_contents.size(), file);
147 strm.
Write(file_contents.data(), length_read);
155PyObjectType PythonObject::GetObjectType()
const {
157 return PyObjectType::None;
159 if (PythonModule::Check(m_py_obj))
160 return PyObjectType::Module;
161 if (PythonList::Check(m_py_obj))
162 return PyObjectType::List;
163 if (PythonTuple::Check(m_py_obj))
164 return PyObjectType::Tuple;
165 if (PythonDictionary::Check(m_py_obj))
166 return PyObjectType::Dictionary;
167 if (PythonString::Check(m_py_obj))
168 return PyObjectType::String;
169 if (PythonBytes::Check(m_py_obj))
170 return PyObjectType::Bytes;
171 if (PythonByteArray::Check(m_py_obj))
172 return PyObjectType::ByteArray;
173 if (PythonBoolean::Check(m_py_obj))
174 return PyObjectType::Boolean;
175 if (PythonInteger::Check(m_py_obj))
176 return PyObjectType::Integer;
177 if (PythonFile::Check(m_py_obj))
178 return PyObjectType::File;
179 if (PythonCallable::Check(m_py_obj))
180 return PyObjectType::Callable;
181 return PyObjectType::Unknown;
184PythonString PythonObject::Repr()
const {
186 return PythonString();
187 PyObject *repr = PyObject_Repr(m_py_obj);
189 return PythonString();
190 return PythonString(PyRefType::Owned, repr);
193PythonString PythonObject::Str()
const {
195 return PythonString();
196 PyObject *str = PyObject_Str(m_py_obj);
198 return PythonString();
199 return PythonString(PyRefType::Owned, str);
203PythonObject::ResolveNameWithDictionary(llvm::StringRef name,
204 const PythonDictionary &dict) {
205 size_t dot_pos = name.find(
'.');
206 llvm::StringRef piece = name.substr(0, dot_pos);
207 PythonObject result = dict.GetItemForKey(PythonString(piece));
208 if (dot_pos == llvm::StringRef::npos) {
215 return result.ResolveName(name.substr(dot_pos + 1));
218PythonObject PythonObject::ResolveName(llvm::StringRef name)
const {
229 size_t dot_pos = name.find(
'.');
230 if (dot_pos == llvm::StringRef::npos) {
233 return GetAttributeValue(name);
238 PythonObject parent = ResolveName(name.substr(0, dot_pos));
239 if (!parent.IsAllocated())
240 return PythonObject();
243 return parent.ResolveName(name.substr(dot_pos + 1));
246bool PythonObject::HasAttribute(llvm::StringRef attr)
const {
249 PythonString py_attr(attr);
250 return !!PyObject_HasAttr(m_py_obj, py_attr.get());
253PythonObject PythonObject::GetAttributeValue(llvm::StringRef attr)
const {
255 return PythonObject();
257 PythonString py_attr(attr);
258 if (!PyObject_HasAttr(m_py_obj, py_attr.get()))
259 return PythonObject();
261 return PythonObject(PyRefType::Owned,
262 PyObject_GetAttr(m_py_obj, py_attr.get()));
266 assert(PyGILState_Check());
267 switch (GetObjectType()) {
268 case PyObjectType::Dictionary:
269 return PythonDictionary(PyRefType::Borrowed, m_py_obj)
270 .CreateStructuredDictionary();
271 case PyObjectType::Boolean:
272 return PythonBoolean(PyRefType::Borrowed, m_py_obj)
273 .CreateStructuredBoolean();
274 case PyObjectType::Integer: {
276 PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger();
277 if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp))
278 return std::get<StructuredData::UnsignedIntegerSP>(int_sp);
279 if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp))
280 return std::get<StructuredData::SignedIntegerSP>(int_sp);
283 case PyObjectType::List:
284 return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray();
285 case PyObjectType::String:
286 return PythonString(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
287 case PyObjectType::Bytes:
288 return PythonBytes(PyRefType::Borrowed, m_py_obj).CreateStructuredString();
289 case PyObjectType::ByteArray:
290 return PythonByteArray(PyRefType::Borrowed, m_py_obj)
291 .CreateStructuredString();
292 case PyObjectType::None:
296 PythonObject(PyRefType::Borrowed, m_py_obj)));
302PythonBytes::PythonBytes(llvm::ArrayRef<uint8_t> bytes) { SetBytes(bytes); }
304PythonBytes::PythonBytes(
const uint8_t *bytes,
size_t length) {
305 SetBytes(llvm::ArrayRef<uint8_t>(bytes, length));
308bool PythonBytes::Check(PyObject *py_obj) {
311 return PyBytes_Check(py_obj);
314llvm::ArrayRef<uint8_t> PythonBytes::GetBytes()
const {
316 return llvm::ArrayRef<uint8_t>();
321 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
322 return llvm::ArrayRef<uint8_t>(
reinterpret_cast<uint8_t *
>(c), size);
325size_t PythonBytes::GetSize()
const {
328 return PyBytes_Size(m_py_obj);
331void PythonBytes::SetBytes(llvm::ArrayRef<uint8_t> bytes) {
332 const char *data =
reinterpret_cast<const char *
>(bytes.data());
333 *
this = Take<PythonBytes>(PyBytes_FromStringAndSize(data, bytes.size()));
340 PyBytes_AsStringAndSize(m_py_obj, &c, &size);
341 result->SetValue(std::string(c, size));
345PythonByteArray::PythonByteArray(llvm::ArrayRef<uint8_t> bytes)
346 : PythonByteArray(bytes.data(), bytes.size()) {}
348PythonByteArray::PythonByteArray(
const uint8_t *bytes,
size_t length) {
349 const char *str =
reinterpret_cast<const char *
>(bytes);
350 *
this = Take<PythonByteArray>(PyByteArray_FromStringAndSize(str, length));
353bool PythonByteArray::Check(PyObject *py_obj) {
356 return PyByteArray_Check(py_obj);
359llvm::ArrayRef<uint8_t> PythonByteArray::GetBytes()
const {
361 return llvm::ArrayRef<uint8_t>();
363 char *c = PyByteArray_AsString(m_py_obj);
364 size_t size = GetSize();
365 return llvm::ArrayRef<uint8_t>(
reinterpret_cast<uint8_t *
>(c), size);
368size_t PythonByteArray::GetSize()
const {
372 return PyByteArray_Size(m_py_obj);
377 llvm::ArrayRef<uint8_t> bytes =
GetBytes();
378 const char *str =
reinterpret_cast<const char *
>(bytes.data());
379 result->SetValue(std::string(str, bytes.size()));
385Expected<PythonString> PythonString::FromUTF8(llvm::StringRef
string) {
386 PyObject *str = PyUnicode_FromStringAndSize(
string.data(),
string.size());
388 return llvm::make_error<PythonException>();
389 return Take<PythonString>(str);
392PythonString::PythonString(llvm::StringRef
string) { SetString(
string); }
394bool PythonString::Check(PyObject *py_obj) {
398 if (PyUnicode_Check(py_obj))
403llvm::StringRef PythonString::GetString()
const {
406 llvm::consumeError(s.takeError());
407 return llvm::StringRef(
"");
412Expected<llvm::StringRef> PythonString::AsUTF8()
const {
419 data = PyUnicode_AsUTF8AndSize(m_py_obj, &size);
424 return llvm::StringRef(data, size);
427size_t PythonString::GetSize()
const {
429#if PY_MINOR_VERSION >= 3
430 return PyUnicode_GetLength(m_py_obj);
432 return PyUnicode_GetSize(m_py_obj);
438void PythonString::SetString(llvm::StringRef
string) {
439 auto s = FromUTF8(
string);
441 llvm::consumeError(s.takeError());
444 *
this = std::move(s.get());
450 result->SetValue(GetString());
456PythonInteger::PythonInteger(int64_t value) {
SetInteger(value); }
458bool PythonInteger::Check(PyObject *py_obj) {
464 return PyLong_Check(py_obj);
467void PythonInteger::SetInteger(int64_t value) {
468 *
this = Take<PythonInteger>(PyLong_FromLongLong(value));
474 : CreateStructuredSignedInteger();
478PythonInteger::CreateStructuredUnsignedInteger()
const {
480 llvm::Expected<unsigned long long> value = AsUnsignedLongLong();
482 llvm::consumeError(value.takeError());
484 result = std::make_shared<StructuredData::UnsignedInteger>(value.get());
490PythonInteger::CreateStructuredSignedInteger()
const {
492 llvm::Expected<long long> value = AsLongLong();
494 llvm::consumeError(value.takeError());
496 result = std::make_shared<StructuredData::SignedInteger>(value.get());
503PythonBoolean::PythonBoolean(
bool value) {
507bool PythonBoolean::Check(PyObject *py_obj) {
508 return py_obj ? PyBool_Check(py_obj) : false;
511bool PythonBoolean::GetValue()
const {
512 return m_py_obj ? PyObject_IsTrue(m_py_obj) : false;
515void PythonBoolean::SetValue(
bool value) {
516 *
this = Take<PythonBoolean>(PyBool_FromLong(value));
521 result->SetValue(GetValue());
527PythonList::PythonList(PyInitialValue value) {
528 if (value == PyInitialValue::Empty)
529 *
this = Take<PythonList>(PyList_New(0));
532PythonList::PythonList(
int list_size) {
533 *
this = Take<PythonList>(PyList_New(list_size));
536bool PythonList::Check(PyObject *py_obj) {
539 return PyList_Check(py_obj);
542uint32_t PythonList::GetSize()
const {
544 return PyList_GET_SIZE(m_py_obj);
548PythonObject PythonList::GetItemAtIndex(uint32_t index)
const {
550 return PythonObject(PyRefType::Borrowed, PyList_GetItem(m_py_obj, index));
551 return PythonObject();
554void PythonList::SetItemAtIndex(uint32_t index,
const PythonObject &
object) {
555 if (IsAllocated() &&
object.IsValid()) {
558 Py_INCREF(
object.get());
559 PyList_SetItem(m_py_obj, index,
object.get());
563void PythonList::AppendItem(
const PythonObject &
object) {
564 if (IsAllocated() &&
object.IsValid()) {
567 PyList_Append(m_py_obj,
object.get());
573 uint32_t count = GetSize();
574 for (uint32_t i = 0; i < count; ++i) {
575 PythonObject obj = GetItemAtIndex(i);
576 result->AddItem(obj.CreateStructuredObject());
583PythonTuple::PythonTuple(PyInitialValue value) {
584 if (value == PyInitialValue::Empty)
585 *
this = Take<PythonTuple>(PyTuple_New(0));
588PythonTuple::PythonTuple(
int tuple_size) {
589 *
this = Take<PythonTuple>(PyTuple_New(tuple_size));
592PythonTuple::PythonTuple(std::initializer_list<PythonObject> objects) {
593 m_py_obj = PyTuple_New(objects.size());
596 for (
auto object : objects) {
597 if (
object.IsValid())
598 SetItemAtIndex(idx,
object);
603PythonTuple::PythonTuple(std::initializer_list<PyObject *> objects) {
604 m_py_obj = PyTuple_New(objects.size());
607 for (
auto py_object : objects) {
608 PythonObject object(PyRefType::Borrowed, py_object);
609 if (
object.IsValid())
610 SetItemAtIndex(idx,
object);
615bool PythonTuple::Check(PyObject *py_obj) {
618 return PyTuple_Check(py_obj);
621uint32_t PythonTuple::GetSize()
const {
623 return PyTuple_GET_SIZE(m_py_obj);
627PythonObject PythonTuple::GetItemAtIndex(uint32_t index)
const {
629 return PythonObject(PyRefType::Borrowed, PyTuple_GetItem(m_py_obj, index));
630 return PythonObject();
633void PythonTuple::SetItemAtIndex(uint32_t index,
const PythonObject &
object) {
634 if (IsAllocated() &&
object.IsValid()) {
637 Py_INCREF(
object.get());
638 PyTuple_SetItem(m_py_obj, index,
object.get());
644 uint32_t count = GetSize();
645 for (uint32_t i = 0; i < count; ++i) {
646 PythonObject obj = GetItemAtIndex(i);
647 result->AddItem(obj.CreateStructuredObject());
654PythonDictionary::PythonDictionary(PyInitialValue value) {
655 if (value == PyInitialValue::Empty)
656 *
this = Take<PythonDictionary>(PyDict_New());
659bool PythonDictionary::Check(PyObject *py_obj) {
663 return PyDict_Check(py_obj);
666bool PythonDictionary::HasKey(
const llvm::Twine &key)
const {
670 PythonString key_object(key.isSingleStringRef() ? key.getSingleStringRef()
673 if (
int res = PyDict_Contains(m_py_obj, key_object.get()) > 0)
680uint32_t PythonDictionary::GetSize()
const {
682 return PyDict_Size(m_py_obj);
686PythonList PythonDictionary::GetKeys()
const {
688 return PythonList(PyRefType::Owned, PyDict_Keys(m_py_obj));
689 return PythonList(PyInitialValue::Invalid);
692PythonObject PythonDictionary::GetItemForKey(
const PythonObject &key)
const {
693 auto item = GetItem(key);
695 llvm::consumeError(item.takeError());
696 return PythonObject();
698 return std::move(item.get());
701Expected<PythonObject>
702PythonDictionary::GetItem(
const PythonObject &key)
const {
705 PyObject *o = PyDict_GetItemWithError(m_py_obj, key.get());
706 if (PyErr_Occurred())
710 return Retain<PythonObject>(o);
713Expected<PythonObject> PythonDictionary::GetItem(
const Twine &key)
const {
716 PyObject *o = PyDict_GetItemString(m_py_obj, NullTerminated(key));
717 if (PyErr_Occurred())
721 return Retain<PythonObject>(o);
724Error PythonDictionary::SetItem(
const PythonObject &key,
725 const PythonObject &value)
const {
726 if (!IsValid() || !value.IsValid())
728 int r = PyDict_SetItem(m_py_obj, key.get(), value.get());
731 return Error::success();
734Error PythonDictionary::SetItem(
const Twine &key,
735 const PythonObject &value)
const {
736 if (!IsValid() || !value.IsValid())
738 int r = PyDict_SetItemString(m_py_obj, NullTerminated(key), value.get());
741 return Error::success();
744void PythonDictionary::SetItemForKey(
const PythonObject &key,
745 const PythonObject &value) {
748 llvm::consumeError(std::move(
error));
752PythonDictionary::CreateStructuredDictionary()
const {
754 PythonList keys(GetKeys());
755 uint32_t num_keys = keys.GetSize();
756 for (uint32_t i = 0; i < num_keys; ++i) {
757 PythonObject key = keys.GetItemAtIndex(i);
758 PythonObject value = GetItemForKey(key);
760 result->AddItem(key.Str().GetString(), structured_value);
765PythonModule PythonModule::BuiltinsModule() {
return AddModule(
"builtins"); }
767PythonModule PythonModule::MainModule() {
return AddModule(
"__main__"); }
769PythonModule PythonModule::AddModule(llvm::StringRef module) {
770 std::string str = module.str();
771 return PythonModule(PyRefType::Borrowed, PyImport_AddModule(str.c_str()));
774Expected<PythonModule> PythonModule::Import(
const Twine &name) {
775 PyObject *mod = PyImport_ImportModule(NullTerminated(name));
778 return Take<PythonModule>(mod);
781Expected<PythonObject> PythonModule::Get(
const Twine &name) {
784 PyObject *dict = PyModule_GetDict(m_py_obj);
787 PyObject *item = PyDict_GetItemString(dict, NullTerminated(name));
790 return Retain<PythonObject>(item);
793bool PythonModule::Check(PyObject *py_obj) {
797 return PyModule_Check(py_obj);
800PythonDictionary PythonModule::GetDictionary()
const {
802 return PythonDictionary();
803 return Retain<PythonDictionary>(PyModule_GetDict(m_py_obj));
806bool PythonCallable::Check(PyObject *py_obj) {
810 return PyCallable_Check(py_obj);
813#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
814static const char get_arg_info_script[] = R
"(
815from inspect import signature, Parameter, ismethod
816from collections import namedtuple
817ArgInfo = namedtuple('ArgInfo', ['count', 'has_varargs'])
821 for parameter in signature(f).parameters.values():
822 kind = parameter.kind
823 if kind in (Parameter.POSITIONAL_ONLY,
824 Parameter.POSITIONAL_OR_KEYWORD):
826 elif kind == Parameter.VAR_POSITIONAL:
828 elif kind in (Parameter.KEYWORD_ONLY,
829 Parameter.VAR_KEYWORD):
832 raise Exception(f'unknown parameter kind: {kind}')
833 return ArgInfo(count, varargs)
837Expected<PythonCallable::ArgInfo> PythonCallable::GetArgInfo()
const {
842#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
845 static PythonScript get_arg_info(get_arg_info_script);
846 Expected<PythonObject> pyarginfo = get_arg_info(*
this);
848 return pyarginfo.takeError();
850 cantFail(As<long long>(pyarginfo.get().GetAttribute(
"count")));
852 cantFail(As<bool>(pyarginfo.get().GetAttribute(
"has_varargs")));
853 result.max_positional_args = has_varargs ? ArgInfo::UNBOUNDED : count;
856 PyObject *py_func_obj;
857 bool is_bound_method =
false;
858 bool is_class =
false;
860 if (PyType_Check(m_py_obj) || PyClass_Check(m_py_obj)) {
861 auto init = GetAttribute(
"__init__");
863 return init.takeError();
864 py_func_obj = init.get().get();
867 py_func_obj = m_py_obj;
870 if (PyMethod_Check(py_func_obj)) {
871 py_func_obj = PyMethod_GET_FUNCTION(py_func_obj);
872 PythonObject im_self = GetAttributeValue(
"im_self");
873 if (im_self.IsValid() && !im_self.IsNone())
874 is_bound_method =
true;
877 if (!PyFunction_Check(py_func_obj)) {
878 PythonObject __call__ = GetAttributeValue(
"__call__");
879 if (__call__.IsValid()) {
880 auto __callable__ = __call__.AsType<PythonCallable>();
881 if (__callable__.IsValid()) {
882 py_func_obj = PyMethod_GET_FUNCTION(__callable__.get());
883 PythonObject im_self = __callable__.GetAttributeValue(
"im_self");
884 if (im_self.IsValid() && !im_self.IsNone())
885 is_bound_method =
true;
894 PyCodeObject *code = (PyCodeObject *)PyFunction_GET_CODE(py_func_obj);
898 auto count = code->co_argcount;
899 bool has_varargs = !!(code->co_flags & CO_VARARGS);
900 result.max_positional_args =
901 has_varargs ? ArgInfo::UNBOUNDED
902 : (count - (int)is_bound_method) - (int)is_class;
910 PythonCallable::ArgInfo::UNBOUNDED;
912PythonObject PythonCallable::operator()() {
913 return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj,
nullptr));
916PythonObject PythonCallable::
917operator()(std::initializer_list<PyObject *> args) {
918 PythonTuple arg_tuple(args);
919 return PythonObject(PyRefType::Owned,
920 PyObject_CallObject(m_py_obj, arg_tuple.get()));
923PythonObject PythonCallable::
924operator()(std::initializer_list<PythonObject> args) {
925 PythonTuple arg_tuple(args);
926 return PythonObject(PyRefType::Owned,
927 PyObject_CallObject(m_py_obj, arg_tuple.get()));
930bool PythonFile::Check(PyObject *py_obj) {
938 auto io_module = PythonModule::Import(
"io");
940 llvm::consumeError(io_module.takeError());
943 auto iobase = io_module.get().Get(
"IOBase");
945 llvm::consumeError(iobase.takeError());
948 int r = PyObject_IsInstance(py_obj, iobase.get().get());
950 llvm::consumeError(exception());
956const char *PythonException::toCString()
const {
958 return "unknown exception";
959 return PyBytes_AS_STRING(m_repr_bytes);
962PythonException::PythonException(
const char *caller) {
963 assert(PyErr_Occurred());
964 m_exception_type = m_exception = m_traceback = m_repr_bytes =
nullptr;
965 PyErr_Fetch(&m_exception_type, &m_exception, &m_traceback);
966 PyErr_NormalizeException(&m_exception_type, &m_exception, &m_traceback);
969 PyObject *repr = PyObject_Repr(m_exception);
971 m_repr_bytes = PyUnicode_AsEncodedString(repr,
"utf-8",
nullptr);
982 LLDB_LOGF(log,
"%s failed with exception: %s", caller, toCString());
984 LLDB_LOGF(log,
"python exception: %s", toCString());
986void PythonException::Restore() {
987 if (m_exception_type && m_exception) {
988 PyErr_Restore(m_exception_type, m_exception, m_traceback);
990 PyErr_SetString(PyExc_Exception, toCString());
992 m_exception_type = m_exception = m_traceback =
nullptr;
995PythonException::~PythonException() {
996 Py_XDECREF(m_exception_type);
997 Py_XDECREF(m_exception);
998 Py_XDECREF(m_traceback);
999 Py_XDECREF(m_repr_bytes);
1002void PythonException::log(llvm::raw_ostream &OS)
const {
OS << toCString(); }
1004std::error_code PythonException::convertToErrorCode()
const {
1005 return llvm::inconvertibleErrorCode();
1008bool PythonException::Matches(PyObject *exc)
const {
1009 return PyErr_GivenExceptionMatches(m_exception_type, exc);
1012const char read_exception_script[] = R
"(
1014from traceback import print_exception
1015if sys.version_info.major < 3:
1016 from StringIO import StringIO
1018 from io import StringIO
1019def main(exc_type, exc_value, tb):
1021 print_exception(exc_type, exc_value, tb, file=f)
1025std::string PythonException::ReadBacktrace() const {
1031 static PythonScript read_exception(read_exception_script);
1033 Expected<std::string> backtrace = As<std::string>(
1034 read_exception(m_exception_type, m_exception, m_traceback));
1037 std::string message =
1038 std::string(toCString()) +
"\n" +
1039 "Traceback unavailable, an error occurred while reading it:\n";
1040 return (message + llvm::toString(backtrace.takeError()));
1043 return std::move(backtrace.get());
1046char PythonException::ID = 0;
1048llvm::Expected<File::OpenOptions>
1049GetOptionsForPyObject(
const PythonObject &obj) {
1051 auto readable = As<bool>(obj.CallMethod(
"readable"));
1053 return readable.takeError();
1054 auto writable = As<bool>(obj.CallMethod(
"writable"));
1056 return writable.takeError();
1057 if (readable.get() && writable.get())
1058 options |= File::eOpenOptionReadWrite;
1059 else if (writable.get())
1060 options |= File::eOpenOptionWriteOnly;
1061 else if (readable.get())
1062 options |= File::eOpenOptionReadOnly;
1070template <
typename Base>
class OwnedPythonFile :
public Base {
1072 template <
typename...
Args>
1073 OwnedPythonFile(
const PythonFile &file,
bool borrowed,
Args... args)
1074 :
Base(args...), m_py_obj(file), m_borrowed(borrowed) {
1078 ~OwnedPythonFile()
override {
1087 bool IsPythonSideValid()
const {
1089 auto closed = As<bool>(m_py_obj.GetAttribute(
"closed"));
1091 llvm::consumeError(closed.takeError());
1094 return !closed.get();
1097 bool IsValid()
const override {
1098 return IsPythonSideValid() && Base::IsValid();
1101 Status Close()
override {
1103 Status py_error, base_error;
1106 auto r = m_py_obj.CallMethod(
"close");
1108 py_error =
Status(r.takeError());
1110 base_error = Base::Close();
1111 if (py_error.
Fail())
1116 PyObject *GetPythonObject()
const {
1117 assert(m_py_obj.IsValid());
1118 return m_py_obj.get();
1121 static bool classof(
const File *file) =
delete;
1124 PythonFile m_py_obj;
1132class SimplePythonFile :
public OwnedPythonFile<NativeFile> {
1134 SimplePythonFile(
const PythonFile &file,
bool borrowed,
int fd,
1136 : OwnedPythonFile(file, borrowed, fd, options, false) {}
1139 bool isA(
const void *classID)
const override {
1140 return classID == &
ID || NativeFile::isA(classID);
1142 static bool classof(
const File *file) {
return file->
isA(&
ID); }
1144char SimplePythonFile::ID = 0;
1150 PythonBuffer &operator=(
const PythonBuffer &) =
delete;
1151 PythonBuffer(
const PythonBuffer &) =
delete;
1153 static Expected<PythonBuffer> Create(PythonObject &obj,
1154 int flags = PyBUF_SIMPLE) {
1155 Py_buffer py_buffer = {};
1156 PyObject_GetBuffer(obj.get(), &py_buffer, flags);
1158 return llvm::make_error<PythonException>();
1159 return PythonBuffer(py_buffer);
1162 PythonBuffer(PythonBuffer &&other) {
1163 m_buffer = other.m_buffer;
1164 other.m_buffer.obj =
nullptr;
1169 PyBuffer_Release(&m_buffer);
1172 Py_buffer &get() {
return m_buffer; }
1176 PythonBuffer(
const Py_buffer &py_buffer) : m_buffer(py_buffer) {}
1183class PythonIOFile :
public OwnedPythonFile<File> {
1185 PythonIOFile(
const PythonFile &file,
bool borrowed)
1186 : OwnedPythonFile(file, borrowed) {}
1188 ~PythonIOFile()
override { Close(); }
1190 bool IsValid()
const override {
return IsPythonSideValid(); }
1192 Status Close()
override {
1197 auto r = m_py_obj.CallMethod(
"close");
1199 return Status(r.takeError());
1203 Status Flush()
override {
1205 auto r = m_py_obj.CallMethod(
"flush");
1207 return Status(r.takeError());
1211 Expected<File::OpenOptions> GetOptions()
const override {
1213 return GetOptionsForPyObject(m_py_obj);
1217 bool isA(
const void *classID)
const override {
1218 return classID == &
ID || File::isA(classID);
1220 static bool classof(
const File *file) {
return file->
isA(&
ID); }
1222char PythonIOFile::ID = 0;
1226class BinaryPythonFile :
public PythonIOFile {
1231 BinaryPythonFile(
int fd,
const PythonFile &file,
bool borrowed)
1232 : PythonIOFile(file, borrowed),
1233 m_descriptor(
File::DescriptorIsValid(fd) ? fd
1234 :
File::kInvalidDescriptor) {}
1236 int GetDescriptor()
const override {
return m_descriptor; }
1238 Status Write(
const void *buf,
size_t &num_bytes)
override {
1240 PyObject *pybuffer_p = PyMemoryView_FromMemory(
1241 const_cast<char *
>((
const char *)buf), num_bytes, PyBUF_READ);
1243 return Status(llvm::make_error<PythonException>());
1244 auto pybuffer = Take<PythonObject>(pybuffer_p);
1246 auto bytes_written = As<long long>(m_py_obj.CallMethod(
"write", pybuffer));
1248 return Status(bytes_written.takeError());
1249 if (bytes_written.get() < 0)
1250 return Status(
".write() method returned a negative number!");
1251 static_assert(
sizeof(
long long) >=
sizeof(
size_t),
"overflow");
1252 num_bytes = bytes_written.get();
1256 Status Read(
void *buf,
size_t &num_bytes)
override {
1258 static_assert(
sizeof(
long long) >=
sizeof(
size_t),
"overflow");
1260 m_py_obj.CallMethod(
"read", (
unsigned long long)num_bytes);
1262 return Status(pybuffer_obj.takeError());
1264 if (pybuffer_obj.get().IsNone()) {
1269 auto pybuffer = PythonBuffer::Create(pybuffer_obj.get());
1271 return Status(pybuffer.takeError());
1272 memcpy(buf, pybuffer.get().get().buf, pybuffer.get().get().len);
1273 num_bytes = pybuffer.get().get().len;
1280class TextPythonFile :
public PythonIOFile {
1285 TextPythonFile(
int fd,
const PythonFile &file,
bool borrowed)
1286 : PythonIOFile(file, borrowed),
1287 m_descriptor(
File::DescriptorIsValid(fd) ? fd
1288 :
File::kInvalidDescriptor) {}
1290 int GetDescriptor()
const override {
return m_descriptor; }
1292 Status Write(
const void *buf,
size_t &num_bytes)
override {
1295 PythonString::FromUTF8(llvm::StringRef((
const char *)buf, num_bytes));
1297 return Status(pystring.takeError());
1299 auto bytes_written =
1300 As<long long>(m_py_obj.CallMethod(
"write", pystring.get()));
1302 return Status(bytes_written.takeError());
1303 if (bytes_written.get() < 0)
1304 return Status(
".write() method returned a negative number!");
1305 static_assert(
sizeof(
long long) >=
sizeof(
size_t),
"overflow");
1306 num_bytes = bytes_written.get();
1310 Status Read(
void *buf,
size_t &num_bytes)
override {
1312 size_t num_chars = num_bytes / 6;
1313 size_t orig_num_bytes = num_bytes;
1315 if (orig_num_bytes < 6) {
1316 return Status(
"can't read less than 6 bytes from a utf8 text stream");
1318 auto pystring = As<PythonString>(
1319 m_py_obj.CallMethod(
"read", (
unsigned long long)num_chars));
1321 return Status(pystring.takeError());
1322 if (pystring.get().IsNone()) {
1326 auto stringref = pystring.get().AsUTF8();
1328 return Status(stringref.takeError());
1329 num_bytes = stringref.get().size();
1330 memcpy(buf, stringref.get().begin(), num_bytes);
1336llvm::Expected<FileSP> PythonFile::ConvertToFile(
bool borrowed) {
1338 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1339 "invalid PythonFile");
1341 int fd = PyObject_AsFileDescriptor(m_py_obj);
1344 return ConvertToFileForcingUseOfScriptingIOMethods(borrowed);
1346 auto options = GetOptionsForPyObject(*
this);
1348 return options.takeError();
1351 options.get() & (File::eOpenOptionReadOnly | File::eOpenOptionWriteOnly |
1352 File::eOpenOptionReadWrite);
1353 if (rw == File::eOpenOptionWriteOnly || rw == File::eOpenOptionReadWrite) {
1356 auto r = CallMethod(
"flush");
1358 return r.takeError();
1365 file_sp = std::make_shared<NativeFile>(fd, options.get(),
false);
1367 file_sp = std::static_pointer_cast<File>(
1368 std::make_shared<SimplePythonFile>(*
this, borrowed, fd, options.get()));
1370 if (!file_sp->IsValid())
1371 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1377llvm::Expected<FileSP>
1378PythonFile::ConvertToFileForcingUseOfScriptingIOMethods(
bool borrowed) {
1380 assert(!PyErr_Occurred());
1383 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1384 "invalid PythonFile");
1386 int fd = PyObject_AsFileDescriptor(m_py_obj);
1389 fd = File::kInvalidDescriptor;
1392 auto io_module = PythonModule::Import(
"io");
1394 return io_module.takeError();
1395 auto textIOBase = io_module.get().Get(
"TextIOBase");
1397 return textIOBase.takeError();
1398 auto rawIOBase = io_module.get().Get(
"RawIOBase");
1400 return rawIOBase.takeError();
1401 auto bufferedIOBase = io_module.get().Get(
"BufferedIOBase");
1402 if (!bufferedIOBase)
1403 return bufferedIOBase.takeError();
1407 auto isTextIO = IsInstance(textIOBase.get());
1409 return isTextIO.takeError();
1411 file_sp = std::static_pointer_cast<File>(
1412 std::make_shared<TextPythonFile>(fd, *
this, borrowed));
1414 auto isRawIO = IsInstance(rawIOBase.get());
1416 return isRawIO.takeError();
1417 auto isBufferedIO = IsInstance(bufferedIOBase.get());
1419 return isBufferedIO.takeError();
1421 if (isRawIO.get() || isBufferedIO.get()) {
1422 file_sp = std::static_pointer_cast<File>(
1423 std::make_shared<BinaryPythonFile>(fd, *
this, borrowed));
1427 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1428 "python file is neither text nor binary");
1430 if (!file_sp->IsValid())
1431 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1437Expected<PythonFile> PythonFile::FromFile(
File &file,
const char *mode) {
1439 return llvm::createStringError(llvm::inconvertibleErrorCode(),
1442 if (
auto *simple = llvm::dyn_cast<SimplePythonFile>(&file))
1443 return Retain<PythonFile>(simple->GetPythonObject());
1444 if (
auto *pythonio = llvm::dyn_cast<PythonIOFile>(&file))
1445 return Retain<PythonFile>(pythonio->GetPythonObject());
1450 return m.takeError();
1455 file_obj = PyFile_FromFd(file.
GetDescriptor(),
nullptr, mode, -1,
nullptr,
1456 "ignore",
nullptr, 0);
1461 return Take<PythonFile>(file_obj);
1464Error PythonScript::Init() {
1465 if (function.IsValid())
1466 return Error::success();
1468 PythonDictionary globals(PyInitialValue::Empty);
1469 auto builtins = PythonModule::BuiltinsModule();
1470 if (
Error error = globals.SetItem(
"__builtins__", builtins))
1473 PyRun_String(script, Py_file_input, globals.get(), globals.get());
1476 Take<PythonObject>(o);
1477 auto f = As<PythonCallable>(globals.GetItem(
"main"));
1479 return f.takeError();
1480 function = std::move(f.get());
1482 return Error::success();
1485llvm::Expected<PythonObject>
1486python::runStringOneLine(
const llvm::Twine &
string,
1487 const PythonDictionary &globals,
1488 const PythonDictionary &locals) {
1489 if (!globals.IsValid() || !locals.IsValid())
1493 Py_CompileString(NullTerminated(
string),
"<string>", Py_eval_input);
1497 Py_CompileString(NullTerminated(
string),
"<string>", Py_single_input);
1501 auto code_ref = Take<PythonObject>(code);
1503 PyObject *result = PyEval_EvalCode(code, globals.get(), locals.get());
1508 return Take<PythonObject>(result);
1511llvm::Expected<PythonObject>
1512python::runStringMultiLine(
const llvm::Twine &
string,
1513 const PythonDictionary &globals,
1514 const PythonDictionary &locals) {
1515 if (!globals.IsValid() || !locals.IsValid())
1517 PyObject *result = PyRun_String(NullTerminated(
string), Py_file_input,
1518 globals.get(), locals.get());
1521 return Take<PythonObject>(result);
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)
A command line argument class.
An abstract base class for files.
virtual bool isA(const void *classID) const
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.
bool Fail() const
Test for error condition.
A stream class that can stream formatted output to a file.
size_t Write(const void *src, size_t src_len)
Output character bytes to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
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