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)...)
184 llvm::StringRef class_name = scripted_metadata.
GetClassName();
185 bool has_class_name = !class_name.empty();
186 bool has_interpreter_dict =
187 !(llvm::StringRef(
m_interpreter.GetDictionaryName()).empty());
188 if (!has_class_name && !has_interpreter_dict && !script_obj) {
190 return create_error(
"Missing script class name.");
191 else if (!has_interpreter_dict)
192 return create_error(
"Invalid script interpreter dictionary.");
194 return create_error(
"Missing scripting object.");
200 PythonObject result = {};
203 result = PythonObject(PyRefType::Borrowed,
204 static_cast<PyObject *
>(script_obj->
GetValue()));
209 if (!dict.IsAllocated())
210 return create_error(
"Could not find interpreter dictionary: {0}",
214 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
216 if (!init.IsAllocated())
217 return create_error(
"Could not find script class: {0}",
220 std::tuple<
Args...> original_args = std::forward_as_tuple(args...);
223 std::string error_string;
224 llvm::Expected<PythonCallable::ArgInfo> arg_info = init.GetArgInfo();
226 llvm::handleAllErrors(
227 arg_info.takeError(),
228 [&](PythonException &E) { error_string.append(E.ReadBacktrace()); },
229 [&](
const llvm::ErrorInfoBase &E) {
230 error_string.append(E.message());
232 return llvm::createStringError(llvm::inconvertibleErrorCode(),
236 llvm::Expected<PythonObject> expected_return_object =
237 create_error(
"Resulting object is not initialized.");
251 size_t num_args =
sizeof...(Args);
252 if (arg_info->max_positional_args != PythonCallable::ArgInfo::UNBOUNDED &&
253 num_args != arg_info->max_positional_args) {
254 if (num_args != arg_info->max_positional_args - 1)
255 return create_error(
"Passed arguments ({0}) doesn't match the number "
256 "of expected arguments ({1}).",
257 num_args, arg_info->max_positional_args);
260 [&init, &expected_return_object](
auto &&...args) {
261 llvm::consumeError(expected_return_object.takeError());
262 expected_return_object = init(args...);
264 std::tuple_cat(transformed_args, std::make_tuple(dict)));
267 [&init, &expected_return_object](
auto &&...args) {
268 llvm::consumeError(expected_return_object.takeError());
269 expected_return_object = init(args...);
274 if (!expected_return_object)
275 return expected_return_object.takeError();
276 result = expected_return_object.get();
279 if (!result.IsValid())
280 return create_error(
"Resulting object is not a valid Python Object.");
281 if (!result.HasAttribute(
"__class__"))
282 return create_error(
"Resulting object doesn't have '__class__' member.");
284 PythonObject obj_class = result.GetAttributeValue(
"__class__");
285 if (!obj_class.IsValid())
286 return create_error(
"Resulting class object is not a valid.");
287 if (!obj_class.HasAttribute(
"__name__"))
289 "Resulting object class doesn't have '__name__' member.");
290 PythonString obj_class_name =
291 obj_class.GetAttributeValue(
"__name__").AsType<PythonString>();
293 PythonObject object_class_mapping_proxy =
294 obj_class.GetAttributeValue(
"__dict__");
295 if (!obj_class.HasAttribute(
"__dict__"))
297 "Resulting object class doesn't have '__dict__' member.");
299 PythonCallable dict_converter = PythonModule::BuiltinsModule()
301 .AsType<PythonCallable>();
302 if (!dict_converter.IsAllocated())
304 "Python 'builtins' module doesn't have 'dict' class.");
306 PythonDictionary object_class_dict =
307 dict_converter(object_class_mapping_proxy).AsType<PythonDictionary>();
308 if (!object_class_dict.IsAllocated())
309 return create_error(
"Coudn't create dictionary from resulting object "
310 "class mapping proxy object.");
314 return checker_or_err.takeError();
316 llvm::Error abstract_method_errors = llvm::Error::success();
317 for (
const auto &method_checker : *checker_or_err)
318 switch (method_checker.second.checker_case) {
320 abstract_method_errors = llvm::joinErrors(
321 std::move(abstract_method_errors),
322 std::move(create_error(
"Abstract method {0}.{1} not implemented.",
323 obj_class_name.GetString(),
324 method_checker.first)));
327 abstract_method_errors = llvm::joinErrors(
328 std::move(abstract_method_errors),
329 std::move(create_error(
"Abstract method {0}.{1} not allocated.",
330 obj_class_name.GetString(),
331 method_checker.first)));
334 abstract_method_errors = llvm::joinErrors(
335 std::move(abstract_method_errors),
336 std::move(create_error(
"Abstract method {0}.{1} not callable.",
337 obj_class_name.GetString(),
338 method_checker.first)));
341 abstract_method_errors = llvm::joinErrors(
342 std::move(abstract_method_errors),
343 std::move(create_error(
344 "Abstract method {0}.{1} has unknown argument count.",
345 obj_class_name.GetString(), method_checker.first)));
348 auto &payload_variant = method_checker.second.payload;
349 if (!std::holds_alternative<
352 abstract_method_errors = llvm::joinErrors(
353 std::move(abstract_method_errors),
354 std::move(create_error(
355 "Abstract method {0}.{1} has unexpected argument count.",
356 obj_class_name.GetString(), method_checker.first)));
358 auto payload = std::get<
361 abstract_method_errors = llvm::joinErrors(
362 std::move(abstract_method_errors),
364 create_error(
"Abstract method {0}.{1} has unexpected "
365 "argument count (expected {2} but has {3}).",
366 obj_class_name.GetString(), method_checker.first,
367 payload.required_argument_count,
368 payload.actual_argument_count)));
372 LLDB_LOG(log,
"Abstract method {0}.{1} implemented & valid.",
373 obj_class_name.GetString(), method_checker.first);
377 if (abstract_method_errors) {
379 LLDB_LOG(log,
"Abstract method error in {0}:\n{1}", class_name,
381 return error.ToError();
385 new StructuredPythonObject(std::move(result)));
408 std::string caller_signature =
409 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(
" (") +
410 llvm::Twine(class_name) + llvm::Twine(
".") +
411 llvm::Twine(method_name) + llvm::Twine(
")"))
414 if (class_name.empty())
425 if (!dict.IsAllocated())
428 llvm::formatv(
"could not find interpreter dictionary: {0}",
435 PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
437 if (!class_obj.IsAllocated())
440 llvm::formatv(
"could not find script class: {0}", class_name).str(),
444 if (!class_obj.HasAttribute(method_name))
447 llvm::formatv(
"class {0} does not have method {1}", class_name,
452 PythonCallable method =
453 class_obj.GetAttributeValue(method_name).AsType<PythonCallable>();
454 if (!method.IsAllocated())
456 llvm::formatv(
"method {0}.{1} is not callable",
457 class_name, method_name)
462 std::tuple<
Args...> original_args = std::forward_as_tuple(args...);
466 llvm::Expected<PythonObject> expected_return_object =
467 llvm::createStringError(
"not initialized");
469 [&method, &expected_return_object](
auto &&...args) {
470 llvm::consumeError(expected_return_object.takeError());
471 expected_return_object = method(args...);
475 if (llvm::Error e = expected_return_object.takeError()) {
478 caller_signature,
"python static method could not be called",
error);
481 PythonObject py_return = std::move(expected_return_object.get());
484 if (
sizeof...(
Args) > 0)
488 "couldn't re-assign reference and pointer arguments",
error);
505 std::string caller_signature =
506 llvm::Twine(LLVM_PRETTY_FUNCTION + llvm::Twine(
" (") +
507 llvm::Twine(method_name) + llvm::Twine(
")"))
516 PythonObject implementor(PyRefType::Borrowed,
519 if (!implementor.IsAllocated())
522 "python implementor not allocated",
526 std::tuple<
Args...> original_args = std::forward_as_tuple(args...);
529 llvm::Expected<PythonObject> expected_return_object =
530 llvm::createStringError(
"not initialized");
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())