63 return llvm::createStringError(
"scripted Interface has invalid object");
66 PythonObject(PyRefType::Borrowed,
69 if (!py_obj.IsAllocated())
70 return llvm::createStringError(
71 "scripted Interface has invalid python object");
73 PythonObject py_obj_class = py_obj.GetAttributeValue(
"__class__");
74 if (!py_obj_class.IsValid())
75 return llvm::createStringError(
76 "scripted Interface python object is missing '__class__' attribute");
78 PythonObject py_obj_module = py_obj_class.GetAttributeValue(
"__module__");
79 if (!py_obj_module.IsValid())
80 return llvm::createStringError(
81 "scripted Interface python object '__class__' is missing "
82 "'__module__' attribute");
84 PythonString py_obj_module_str = py_obj_module.Str();
85 if (!py_obj_module_str.IsValid())
86 return llvm::createStringError(
87 "scripted Interface python object '__class__.__module__' attribute "
90 llvm::StringRef py_obj_module_str_ref = py_obj_module_str.GetString();
91 PythonModule py_module = PythonModule::AddModule(py_obj_module_str_ref);
92 if (!py_module.IsValid())
93 return llvm::createStringError(
"failed to import '%s' module",
94 py_obj_module_str_ref.data());
96 PythonObject py_module_file = py_module.GetAttributeValue(
"__file__");
97 if (!py_module_file.IsValid())
98 return llvm::createStringError(
99 "module '%s' is missing '__file__' attribute",
100 py_obj_module_str_ref.data());
102 PythonString py_module_file_str = py_module_file.Str();
103 if (!py_module_file_str.IsValid())
104 return llvm::createStringError(
105 "module '%s.__file__' attribute is not a string",
106 py_obj_module_str_ref.data());
108 return FileSpec(py_module_file_str.GetString());
177 auto create_error = [](llvm::StringLiteral format,
auto &&...ts) {
178 return llvm::createStringError(
179 llvm::formatv(format.data(), std::forward<
decltype(ts)>(ts)...)
183 bool has_class_name = !class_name.empty();
184 bool has_interpreter_dict =
185 !(llvm::StringRef(
m_interpreter.GetDictionaryName()).empty());
186 if (!has_class_name && !has_interpreter_dict && !script_obj) {
188 return create_error(
"Missing script class name.");
189 else if (!has_interpreter_dict)
190 return create_error(
"Invalid script interpreter dictionary.");
192 return create_error(
"Missing scripting object.");
198 PythonObject result = {};
201 result = PythonObject(PyRefType::Borrowed,
202 static_cast<PyObject *
>(script_obj->
GetValue()));
207 if (!dict.IsAllocated())
208 return create_error(
"Could not find interpreter dictionary: {0}",
212 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
214 if (!init.IsAllocated())
215 return create_error(
"Could not find script class: {0}",
218 std::tuple<
Args...> original_args = std::forward_as_tuple(args...);
221 std::string error_string;
222 llvm::Expected<PythonCallable::ArgInfo> arg_info = init.GetArgInfo();
224 llvm::handleAllErrors(
225 arg_info.takeError(),
226 [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
227 [&](
const llvm::ErrorInfoBase &E) {
228 error_string.append(E.message());
230 return llvm::createStringError(llvm::inconvertibleErrorCode(),
234 llvm::Expected<PythonObject> expected_return_object =
235 create_error(
"Resulting object is not initialized.");
249 size_t num_args =
sizeof...(Args);
250 if (arg_info->max_positional_args != PythonCallable::ArgInfo::UNBOUNDED &&
251 num_args != arg_info->max_positional_args) {
252 if (num_args != arg_info->max_positional_args - 1)
253 return create_error(
"Passed arguments ({0}) doesn't match the number "
254 "of expected arguments ({1}).",
255 num_args, arg_info->max_positional_args);
258 [&init, &expected_return_object](
auto &&...args) {
259 llvm::consumeError(expected_return_object.takeError());
260 expected_return_object = init(args...);
262 std::tuple_cat(transformed_args, std::make_tuple(dict)));
265 [&init, &expected_return_object](
auto &&...args) {
266 llvm::consumeError(expected_return_object.takeError());
267 expected_return_object = init(args...);
272 if (!expected_return_object)
273 return expected_return_object.takeError();
274 result = expected_return_object.get();
277 if (!result.IsValid())
278 return create_error(
"Resulting object is not a valid Python Object.");
279 if (!result.HasAttribute(
"__class__"))
280 return create_error(
"Resulting object doesn't have '__class__' member.");
282 PythonObject obj_class = result.GetAttributeValue(
"__class__");
283 if (!obj_class.IsValid())
284 return create_error(
"Resulting class object is not a valid.");
285 if (!obj_class.HasAttribute(
"__name__"))
287 "Resulting object class doesn't have '__name__' member.");
288 PythonString obj_class_name =
289 obj_class.GetAttributeValue(
"__name__").AsType<PythonString>();
291 PythonObject object_class_mapping_proxy =
292 obj_class.GetAttributeValue(
"__dict__");
293 if (!obj_class.HasAttribute(
"__dict__"))
295 "Resulting object class doesn't have '__dict__' member.");
297 PythonCallable dict_converter = PythonModule::BuiltinsModule()
299 .AsType<PythonCallable>();
300 if (!dict_converter.IsAllocated())
302 "Python 'builtins' module doesn't have 'dict' class.");
304 PythonDictionary object_class_dict =
305 dict_converter(object_class_mapping_proxy).AsType<PythonDictionary>();
306 if (!object_class_dict.IsAllocated())
307 return create_error(
"Coudn't create dictionary from resulting object "
308 "class mapping proxy object.");
312 return checker_or_err.takeError();
314 llvm::Error abstract_method_errors = llvm::Error::success();
315 for (
const auto &method_checker : *checker_or_err)
316 switch (method_checker.second.checker_case) {
318 abstract_method_errors = llvm::joinErrors(
319 std::move(abstract_method_errors),
320 std::move(create_error(
"Abstract method {0}.{1} not implemented.",
321 obj_class_name.GetString(),
322 method_checker.first)));
325 abstract_method_errors = llvm::joinErrors(
326 std::move(abstract_method_errors),
327 std::move(create_error(
"Abstract method {0}.{1} not allocated.",
328 obj_class_name.GetString(),
329 method_checker.first)));
332 abstract_method_errors = llvm::joinErrors(
333 std::move(abstract_method_errors),
334 std::move(create_error(
"Abstract method {0}.{1} not callable.",
335 obj_class_name.GetString(),
336 method_checker.first)));
339 abstract_method_errors = llvm::joinErrors(
340 std::move(abstract_method_errors),
341 std::move(create_error(
342 "Abstract method {0}.{1} has unknown argument count.",
343 obj_class_name.GetString(), method_checker.first)));
346 auto &payload_variant = method_checker.second.payload;
347 if (!std::holds_alternative<
350 abstract_method_errors = llvm::joinErrors(
351 std::move(abstract_method_errors),
352 std::move(create_error(
353 "Abstract method {0}.{1} has unexpected argument count.",
354 obj_class_name.GetString(), method_checker.first)));
356 auto payload = std::get<
359 abstract_method_errors = llvm::joinErrors(
360 std::move(abstract_method_errors),
362 create_error(
"Abstract method {0}.{1} has unexpected "
363 "argument count (expected {2} but has {3}).",
364 obj_class_name.GetString(), method_checker.first,
365 payload.required_argument_count,
366 payload.actual_argument_count)));
370 LLDB_LOG(log,
"Abstract method {0}.{1} implemented & valid.",
371 obj_class_name.GetString(), method_checker.first);
375 if (abstract_method_errors) {
377 LLDB_LOG(log,
"Abstract method error in {0}:\n{1}", class_name,
379 return error.ToError();
383 new StructuredPythonObject(std::move(result)));
406 std::string caller_signature =
407 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(
" (") +
408 llvm::Twine(class_name) + llvm::Twine(
".") +
409 llvm::Twine(method_name) + llvm::Twine(
")"))
412 if (class_name.empty())
423 if (!dict.IsAllocated())
426 llvm::formatv(
"could not find interpreter dictionary: {0}",
433 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
435 if (!class_obj.IsAllocated())
438 llvm::formatv(
"could not find script class: {0}", class_name).str(),
442 if (!class_obj.HasAttribute(method_name))
445 llvm::formatv(
"class {0} does not have method {1}", class_name,
450 PythonCallable method =
451 class_obj.GetAttributeValue(method_name).AsType<PythonCallable>();
452 if (!method.IsAllocated())
454 llvm::formatv(
"method {0}.{1} is not callable",
455 class_name, method_name)
460 std::tuple<
Args...> original_args = std::forward_as_tuple(args...);
464 llvm::Expected<PythonObject> expected_return_object =
465 llvm::make_error<llvm::StringError>(
"Not initialized.",
466 llvm::inconvertibleErrorCode());
468 [&method, &expected_return_object](
auto &&...args) {
469 llvm::consumeError(expected_return_object.takeError());
470 expected_return_object = method(args...);
474 if (llvm::Error e = expected_return_object.takeError()) {
477 caller_signature,
"python static method could not be called",
error);
480 PythonObject py_return = std::move(expected_return_object.get());
483 if (
sizeof...(
Args) > 0)
487 "couldn't re-assign reference and pointer arguments",
error);
504 std::string caller_signature =
505 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(
" (") +
506 llvm::Twine(method_name) + llvm::Twine(
")"))
515 PythonObject implementor(PyRefType::Borrowed,
518 if (!implementor.IsAllocated())
521 "python implementor not allocated",
525 std::tuple<
Args...> original_args = std::forward_as_tuple(args...);
528 llvm::Expected<PythonObject> expected_return_object =
529 llvm::make_error<llvm::StringError>(
"Not initialized.",
530 llvm::inconvertibleErrorCode());
532 [&implementor, &method_name, &expected_return_object](
auto &&...args) {
533 llvm::consumeError(expected_return_object.takeError());
534 expected_return_object =
535 implementor.CallMethod(method_name.data(), args...);
539 if (llvm::Error e = expected_return_object.takeError()) {
542 "python method could not be called",
error);
545 PythonObject py_return = std::move(expected_return_object.get());
551 if (
sizeof...(
Args) > 0)
555 "couldn't re-assign reference and pointer arguments",
error);
557 if (!py_return.IsAllocated())