From 30e677a7623ff88528ab6be89b7d8acefb1a0fa5 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 12 Sep 2023 14:16:26 +0200 Subject: [PATCH] Python: call the module's run() function --- src/libcalamares/python/PythonJob.cpp | 61 ++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/src/libcalamares/python/PythonJob.cpp b/src/libcalamares/python/PythonJob.cpp index 476fb2ef5..169a46ea4 100644 --- a/src/libcalamares/python/PythonJob.cpp +++ b/src/libcalamares/python/PythonJob.cpp @@ -24,6 +24,12 @@ namespace py = pybind11; namespace { +QString +asQString( const py::object& o ) +{ + return QString::fromUtf8( py::str( o ).cast< std::string >().c_str() ); +} + QString getPrettyNameFromScope( const py::dict& scope ) { @@ -150,7 +156,60 @@ Job::exec() m_d->description = getPrettyNameFromScope( scope ); - return JobResult::ok(); + Q_EMIT progress( 0 ); + static constexpr char key_run[] = "run"; + if ( scope.contains( key_run ) ) + { + const py::object run = scope[ key_run ]; + try + { + py::object r; + try + { + r = run(); + } + catch ( const py::error_already_set& e ) + { + // This is an error in the Python code itself + cError() << e.what(); + return JobResult::internalError( tr( "Bad main script file" ), + tr( "Main script file %1 for python job %2 raised an exception." ) + .arg( scriptFI.absoluteFilePath() ) + .arg( prettyName() ), + JobResult::PythonUncaughtException ); + } + + if ( r.is( py::none() ) ) + { + return JobResult::ok(); + } + const py::tuple items = r; + return JobResult::error( asQString( items[ 0 ] ), asQString( items[ 1 ] ) ); + } + catch ( const py::cast_error& e ) + { + cError() << e.what(); + return JobResult::error( tr( "Bad main script file" ), + tr( "Main script file %1 for python job %2 returned invalid results." ) + .arg( scriptFI.absoluteFilePath() ) + .arg( prettyName() ) ); + } + catch ( const py::error_already_set& e ) + { + cError() << e.what(); + return JobResult::error( tr( "Bad main script file" ), + tr( "Main script file %1 for python job %2 returned invalid results." ) + .arg( scriptFI.absoluteFilePath() ) + .arg( prettyName() ) ); + } + } + else + { + return JobResult::error( tr( "Bad main script file" ), + tr( "Main script file %1 for python job %2 does not contain a run() function." ) + .arg( scriptFI.absoluteFilePath() ) + .arg( prettyName() ) ); + } } /** @brief Sets the pre-run Python code for all PythonJobs