From 7f173de361dfd4251c37949d231856b52e02cb0c Mon Sep 17 00:00:00 2001 From: Adriaan de Groot <groot@kde.org> Date: Mon, 30 Dec 2024 23:38:45 +0100 Subject: [PATCH] [libcalamares] Add generic(-ish) variant-to-python code This is code duplicated between the two implementation directories (to be taken out shortly). It isn't generic in a template-sense, but it does use the types and support functions defined in the implementation-specific PythonTypes header. --- src/libcalamares/CMakeLists.txt | 1 + src/libcalamares/python/Variant.cpp | 114 ++++++++++++++++++++++++++++ src/libcalamares/python/Variant.h | 40 ++++++++++ 3 files changed, 155 insertions(+) create mode 100644 src/libcalamares/python/Variant.cpp create mode 100644 src/libcalamares/python/Variant.h diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index f8effad178..55ffaa34f0 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -136,6 +136,7 @@ if(WITH_PYTHON) target_sources(calamares PRIVATE pyboost/PythonHelper.cpp pyboost/PythonJob.cpp pyboost/PythonJobApi.cpp) target_link_libraries(calamares PRIVATE Python::Python Boost::python) endif() + target_sources(calamares PRIVATE python/Variant.cpp) endif() ### OPTIONAL GeoIP XML support diff --git a/src/libcalamares/python/Variant.cpp b/src/libcalamares/python/Variant.cpp new file mode 100644 index 0000000000..22bf51c3cd --- /dev/null +++ b/src/libcalamares/python/Variant.cpp @@ -0,0 +1,114 @@ +/* === This file is part of Calamares - <https://calamares.io> === + * + * SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org> + * SPDX-FileCopyrightText: 2018-2020, 2024 Adriaan de Groot <groot@kde.org> + * SPDX-License-Identifier: GPL-3.0-or-later + * + * Calamares is Free Software: see the License-Identifier above. + * + */ + +#include "Variant.h" + +#include "PythonTypes.h" +#include "compat/Variant.h" + +namespace +{ + +Calamares::Python::List +variantListToPyList( const QVariantList& variantList ) +{ + Calamares::Python::List pyList; + for ( const QVariant& variant : variantList ) + { + pyList.append( Calamares::Python::variantToPyObject( variant ) ); + } + return pyList; +} + +Calamares::Python::Dictionary +variantHashToPyDict( const QVariantHash& variantHash ) +{ + Calamares::Python::Dictionary pyDict; + for ( auto it = variantHash.constBegin(); it != variantHash.constEnd(); ++it ) + { + pyDict[ Calamares::Python::String( it.key().toStdString() ) ] = Calamares::Python::variantToPyObject( it.value() ); + } + return pyDict; +} + +} + +namespace Calamares +{ +namespace Python +{ + +Dictionary +variantMapToPyDict( const QVariantMap& variantMap ) +{ + Calamares::Python::Dictionary pyDict; + for ( auto it = variantMap.constBegin(); it != variantMap.constEnd(); ++it ) + { + pyDict[ Calamares::Python::String( it.key().toStdString() ) ] = Calamares::Python::variantToPyObject( it.value() ); + } + return pyDict; +} + +Object +variantToPyObject( const QVariant& variant ) +{ + QT_WARNING_PUSH + QT_WARNING_DISABLE_CLANG( "-Wswitch-enum" ) + + // 49 enumeration values not handled + switch ( Calamares::typeOf( variant ) ) + { + case Calamares::MapVariantType: + return variantMapToPyDict( variant.toMap() ); + + case Calamares::HashVariantType: + return variantHashToPyDict( variant.toHash() ); + + case Calamares::ListVariantType: + case Calamares::StringListVariantType: + return variantListToPyList( variant.toList() ); + + case Calamares::IntVariantType: + return Python::Integer( variant.toInt() ); + case Calamares::UIntVariantType: + return Python::Integer( variant.toUInt() ); + + case Calamares::LongLongVariantType: + return Python::Integer( variant.toLongLong() ); + case Calamares::ULongLongVariantType: + return Python::Integer( variant.toULongLong() ); + + case Calamares::DoubleVariantType: + return Python::Float( variant.toDouble() ); + + case Calamares::CharVariantType: +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) +#else + // In Qt6, QChar is also available and different from CharVariantType + case QMetaType::Type::QChar: +#endif + case Calamares::StringVariantType: + return Calamares::Python::String( variant.toString().toStdString() ); + + case Calamares::BoolVariantType: + return Python::Boolean( variant.toBool() ); + +#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) + case QVariant::Invalid: +#endif + default: + return Python::None(); + } + QT_WARNING_POP +} + + + } +} diff --git a/src/libcalamares/python/Variant.h b/src/libcalamares/python/Variant.h new file mode 100644 index 0000000000..88a5ea65d3 --- /dev/null +++ b/src/libcalamares/python/Variant.h @@ -0,0 +1,40 @@ +/* === This file is part of Calamares - <https://calamares.io> === + * + * SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org> + * SPDX-FileCopyrightText: 2018-2020, 2024 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_PYTHONVARIANT_H +#define CALAMARES_PYTHONVARIANT_H + +/** + * @file Support for turning QVariant into Python types, and vice-versa + * + * These are helper-functions for converting variants (e.g. values + * in GlobalStorage, or loaded from YAML) into Python. This is not + * public API and is used only inside the Python-job-support code. + */ + +#include "PythonTypes.h" + +#include <QStringList> +#include <QVariant> +#include <QVariantMap> + + +namespace Calamares +{ +namespace Python __attribute__( ( visibility( "hidden" ) ) ) +{ + +Dictionary variantMapToPyDict( const QVariantMap& variantMap ); +Object variantToPyObject( const QVariant& variant ); ///< More generic version of variantMapToPyDict + +} +} + +#endif -- GitLab