Python: get pretty_name from Python module

Add a convenience method for logging pybind11 objects.
This commit is contained in:
Adriaan de Groot 2023-09-12 13:35:21 +02:00
parent dd2da734ba
commit bfb23b3b84
3 changed files with 105 additions and 7 deletions

View File

@ -191,9 +191,10 @@ load_yaml( const std::string& path )
return variantMapToPyDict( map ); return variantMapToPyDict( map );
} }
static Calamares::GlobalStorage * _global_storage() static Calamares::GlobalStorage*
_global_storage()
{ {
static Calamares::GlobalStorage * p = new Calamares::GlobalStorage; static Calamares::GlobalStorage* p = new Calamares::GlobalStorage;
return p; return p;
} }
@ -209,8 +210,7 @@ _gettext_languages()
// own GlobalStoragePythonWrapper, which then holds a // own GlobalStoragePythonWrapper, which then holds a
// GlobalStorage object for all of Python. // GlobalStorage object for all of Python.
Calamares::JobQueue* jq = Calamares::JobQueue::instance(); Calamares::JobQueue* jq = Calamares::JobQueue::instance();
Calamares::GlobalStorage* gs Calamares::GlobalStorage* gs = jq ? jq->globalStorage() : _global_storage();
= jq ? jq->globalStorage() : _global_storage();
QString lang = Calamares::Locale::readGS( *gs, QStringLiteral( "LANG" ) ); QString lang = Calamares::Locale::readGS( *gs, QStringLiteral( "LANG" ) );
if ( !lang.isEmpty() ) if ( !lang.isEmpty() )

View File

@ -0,0 +1,32 @@
/* === This file is part of Calamares - <https://calamares.io> ===
*
* SPDX-FileCopyrightText: 2023 Adriaan de Groot <groot@kde.org>
* SPDX-License-Identifier: GPL-3.0-or-later
*
* Calamares is Free Software: see the License-Identifier above.
*
*
*/
#ifndef CALAMARES_PYTHON_LOGGER_H
#define CALAMARES_PYTHON_LOGGER_H
/** @file
*
* Additional logging helpers for pybind11 types.
*/
#include "utils/Logger.h"
#undef slots
#include <pybind11/pybind11.h>
#include <string>
inline QDebug&
operator<<( QDebug& s, const pybind11::handle & h )
{
return s << pybind11::str(h).cast<std::string>();
}
#endif

View File

@ -8,6 +8,9 @@
*/ */
#include "python/PythonJob.h" #include "python/PythonJob.h"
#include "python/Logger.h"
#include "utils/Logger.h"
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QString> #include <QString>
@ -18,6 +21,56 @@
namespace py = pybind11; namespace py = pybind11;
namespace
{
QString
getPrettyNameFromScope( const py::dict& scope )
{
static constexpr char key_name[] = "pretty_name";
if ( scope.contains( key_name ) )
{
const py::object func = scope[ key_name ];
try
{
const auto s = func().cast< std::string >();
return QString::fromUtf8( s.c_str() );
}
catch ( const py::cast_error& e )
{
// Ignore, we will try __doc__ next
}
}
static constexpr char key_doc[] = "__doc__";
if ( scope.contains( key_doc ) )
{
const py::object doc = scope[ key_doc ];
try
{
const auto s = doc.cast< std::string >();
auto string = QString::fromUtf8( s.c_str() ).trimmed();
const auto newline_index = string.indexOf( '\n' );
if ( newline_index >= 0 )
{
string.truncate( newline_index );
return string;
}
// __doc__ is apparently empty, try next fallback
}
catch ( const py::cast_error& e )
{
// Ignore, try next fallback
}
}
// No more fallbacks
return QString();
}
} // namespace
namespace Calamares namespace Calamares
{ {
namespace Python namespace Python
@ -31,9 +84,12 @@ struct Job::Private
, configurationMap( configuration ) , configurationMap( configuration )
{ {
} }
QString scriptFile; QString scriptFile; // From the module descriptor
QString workingPath; QString workingPath;
QVariantMap configurationMap;
QVariantMap configurationMap; // The module configuration
QString description; // Obtained from the Python code
}; };
Job::Job( const QString& scriptFile, Job::Job( const QString& scriptFile,
@ -55,7 +111,15 @@ Job::prettyName() const
QString QString
Job::prettyStatusMessage() const Job::prettyStatusMessage() const
{ {
return QStringLiteral( "Python Status" ); // The description is updated when progress is reported, see emitProgress()
if ( m_d->description.isEmpty() )
{
return tr( "Running %1 operation." ).arg( prettyName() );
}
else
{
return m_d->description;
}
} }
JobResult JobResult
@ -84,6 +148,8 @@ Job::exec()
auto scope = py::module_::import( "__main__" ).attr( "__dict__" ); auto scope = py::module_::import( "__main__" ).attr( "__dict__" );
py::eval_file( scriptFI.absoluteFilePath().toUtf8().constData(), scope ); py::eval_file( scriptFI.absoluteFilePath().toUtf8().constData(), scope );
m_d->description = getPrettyNameFromScope( scope );
return JobResult::ok(); return JobResult::ok();
} }