Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ class ScriptedInterface {
virtual llvm::SmallVector<AbstractMethodRequirement>
GetAbstractMethodRequirements() const = 0;

virtual llvm::Expected<FileSpec> GetScriptedModulePath() {
return llvm::make_error<UnimplementedError>();
}

llvm::SmallVector<llvm::StringLiteral> const GetAbstractMethods() const {
llvm::SmallVector<llvm::StringLiteral> abstract_methods;
llvm::transform(GetAbstractMethodRequirements(), abstract_methods.begin(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,62 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
std::variant<std::monostate, InvalidArgumentCountPayload> payload;
};

llvm::Expected<FileSpec> GetScriptedModulePath() override {
using namespace python;
using Locker = ScriptInterpreterPythonImpl::Locker;

Locker py_lock(&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
Locker::FreeLock);

if (!m_object_instance_sp)
return llvm::createStringError("scripted Interface has invalid object");

PythonObject py_obj =
PythonObject(PyRefType::Borrowed,
static_cast<PyObject *>(m_object_instance_sp->GetValue()));

if (!py_obj.IsAllocated())
return llvm::createStringError(
"scripted Interface has invalid python object");

PythonObject py_obj_class = py_obj.GetAttributeValue("__class__");
if (!py_obj_class.IsValid())
return llvm::createStringError(
"scripted Interface python object is missing '__class__' attribute");

PythonObject py_obj_module = py_obj_class.GetAttributeValue("__module__");
if (!py_obj_module.IsValid())
return llvm::createStringError(
"scripted Interface python object '__class__' is missing "
"'__module__' attribute");

PythonString py_obj_module_str = py_obj_module.Str();
if (!py_obj_module_str.IsValid())
return llvm::createStringError(
"scripted Interface python object '__class__.__module__' attribute "
"is not a string");

llvm::StringRef py_obj_module_str_ref = py_obj_module_str.GetString();
PythonModule py_module = PythonModule::AddModule(py_obj_module_str_ref);
if (!py_module.IsValid())
return llvm::createStringError("failed to import '%s' module",
py_obj_module_str_ref.data());

PythonObject py_module_file = py_module.GetAttributeValue("__file__");
if (!py_module_file.IsValid())
return llvm::createStringError(
"module '%s' is missing '__file__' attribute",
py_obj_module_str_ref.data());

PythonString py_module_file_str = py_module_file.Str();
if (!py_module_file_str.IsValid())
return llvm::createStringError(
"module '%s.__file__' attribute is not a string",
py_obj_module_str_ref.data());

return FileSpec(py_obj_module_str.GetString());
}

llvm::Expected<std::map<llvm::StringLiteral, AbstractMethodCheckerPayload>>
CheckAbstractMethodImplementation(
const python::PythonDictionary &class_dict) const {
Expand Down
Loading