From 074f8e6c461aa5a9aa1a6191559f678f3e3749cd Mon Sep 17 00:00:00 2001 From: Mathieu Pellerin Date: Tue, 21 Jan 2025 15:54:58 +0700 Subject: [PATCH 1/2] [processing] Fix feature iteration against a model (fixes #60131) --- .../processing/qgsprocessingcontext.sip.in | 7 +++++++ .../processing/qgsprocessingcontext.sip.in | 7 +++++++ .../plugins/processing/gui/AlgorithmExecutor.py | 3 +++ .../models/qgsprocessingmodelalgorithm.cpp | 4 ++++ src/core/processing/qgsprocessingcontext.cpp | 5 +++++ src/core/processing/qgsprocessingcontext.h | 7 +++++++ tests/src/analysis/testqgsprocessing.cpp | 15 +++++++++++++++ 7 files changed, 48 insertions(+) diff --git a/python/PyQt6/core/auto_generated/processing/qgsprocessingcontext.sip.in b/python/PyQt6/core/auto_generated/processing/qgsprocessingcontext.sip.in index 99c99c858917..3058f23c53cf 100644 --- a/python/PyQt6/core/auto_generated/processing/qgsprocessingcontext.sip.in +++ b/python/PyQt6/core/auto_generated/processing/qgsprocessingcontext.sip.in @@ -662,6 +662,13 @@ Returns the model results, populated when the context is used to run a model alg %End + void clearModelResult(); +%Docstring +Clears model results previously populated when the context was used to run a model algorithm. + +.. versionadded:: 3.42 +%End + private: QgsProcessingContext( const QgsProcessingContext &other ); }; diff --git a/python/core/auto_generated/processing/qgsprocessingcontext.sip.in b/python/core/auto_generated/processing/qgsprocessingcontext.sip.in index b35acb194587..f049c6216b8e 100644 --- a/python/core/auto_generated/processing/qgsprocessingcontext.sip.in +++ b/python/core/auto_generated/processing/qgsprocessingcontext.sip.in @@ -662,6 +662,13 @@ Returns the model results, populated when the context is used to run a model alg %End + void clearModelResult(); +%Docstring +Clears model results previously populated when the context was used to run a model algorithm. + +.. versionadded:: 3.42 +%End + private: QgsProcessingContext( const QgsProcessingContext &other ); }; diff --git a/python/plugins/processing/gui/AlgorithmExecutor.py b/python/plugins/processing/gui/AlgorithmExecutor.py index c1ef9432d449..8c7fadc022d3 100644 --- a/python/plugins/processing/gui/AlgorithmExecutor.py +++ b/python/plugins/processing/gui/AlgorithmExecutor.py @@ -465,6 +465,9 @@ def executeIterating(alg, parameters, paramToIter, context, feedback): if feedback.isCanceled(): return False + # clear any model result stored in the last iteration + context.clearModelResult() + parameters[paramToIter] = f for out in alg.destinationParameterDefinitions(): if out.name() not in outputs: diff --git a/src/core/processing/models/qgsprocessingmodelalgorithm.cpp b/src/core/processing/models/qgsprocessingmodelalgorithm.cpp index 17825726dc88..3e9fe7da2e93 100644 --- a/src/core/processing/models/qgsprocessingmodelalgorithm.cpp +++ b/src/core/processing/models/qgsprocessingmodelalgorithm.cpp @@ -373,7 +373,9 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa break; if ( executed.contains( childId ) ) + { continue; + } bool canExecute = true; const QSet< QString > dependencies = dependsOnChildAlgorithms( childId ); @@ -387,7 +389,9 @@ QVariantMap QgsProcessingModelAlgorithm::processAlgorithm( const QVariantMap &pa } if ( !canExecute ) + { continue; + } executedAlg = true; diff --git a/src/core/processing/qgsprocessingcontext.cpp b/src/core/processing/qgsprocessingcontext.cpp index 3feb9876fced..f22bde0030a1 100644 --- a/src/core/processing/qgsprocessingcontext.cpp +++ b/src/core/processing/qgsprocessingcontext.cpp @@ -325,3 +325,8 @@ std::unique_ptr< QgsProcessingModelInitialRunConfig > QgsProcessingContext::take { return std::move( mModelConfig ); } + +void QgsProcessingContext::clearModelResult() +{ + mModelResult.clear(); +} diff --git a/src/core/processing/qgsprocessingcontext.h b/src/core/processing/qgsprocessingcontext.h index 33beda889663..2cc3c7cd3554 100644 --- a/src/core/processing/qgsprocessingcontext.h +++ b/src/core/processing/qgsprocessingcontext.h @@ -794,6 +794,13 @@ class CORE_EXPORT QgsProcessingContext */ QgsProcessingModelResult &modelResult() SIP_SKIP { return mModelResult; } + /** + * Clears model results previously populated when the context was used to run a model algorithm. + * + * \since QGIS 3.42 + */ + void clearModelResult(); + private: QgsProcessingContext::Flags mFlags = QgsProcessingContext::Flags(); diff --git a/tests/src/analysis/testqgsprocessing.cpp b/tests/src/analysis/testqgsprocessing.cpp index 4d72b1f2d96f..b391c4cdf1b1 100644 --- a/tests/src/analysis/testqgsprocessing.cpp +++ b/tests/src/analysis/testqgsprocessing.cpp @@ -1412,6 +1412,21 @@ void TestQgsProcessing::context() QCOMPARE( context3.modelResult().childResults().value( QStringLiteral( "CHILD1" ) ).outputs().value( QStringLiteral( "RESULT1" ) ).toInt(), 1 ); QCOMPARE( context3.modelResult().childResults().value( QStringLiteral( "CHILD2" ) ).outputs().value( QStringLiteral( "RESULT2" ) ).toInt(), 2 ); + QgsProcessingContext context4; + context4.takeResultsFrom( context ); + context4.modelResult().rawChildInputs().insert( QStringLiteral( "test_input" ), 1 ); + context4.modelResult().rawChildOutputs().insert( QStringLiteral( "test_output" ), 1 ); + context4.modelResult().executedChildIds() << "alg:test"; + QCOMPARE( context4.modelResult().childResults().count(), 2 ); + QCOMPARE( context4.modelResult().rawChildInputs().count(), 1 ); + QCOMPARE( context4.modelResult().rawChildOutputs().count(), 1 ); + QCOMPARE( context4.modelResult().executedChildIds().count(), 1 ); + context4.clearModelResult(); + QCOMPARE( context4.modelResult().childResults().count(), 0 ); + QCOMPARE( context4.modelResult().rawChildInputs().count(), 0 ); + QCOMPARE( context4.modelResult().rawChildOutputs().count(), 0 ); + QCOMPARE( context4.modelResult().executedChildIds().count(), 0 ); + // make sure postprocessor is correctly deleted ppDeleted = false; pp = new TestPostProcessor( &ppDeleted ); From 826ccf62b031890d62d0405bfca8116181983477 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 21 Jan 2025 09:46:53 +0000 Subject: [PATCH 2/2] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/src/analysis/testqgsprocessing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/src/analysis/testqgsprocessing.cpp b/tests/src/analysis/testqgsprocessing.cpp index b391c4cdf1b1..39839d721f92 100644 --- a/tests/src/analysis/testqgsprocessing.cpp +++ b/tests/src/analysis/testqgsprocessing.cpp @@ -1426,7 +1426,7 @@ void TestQgsProcessing::context() QCOMPARE( context4.modelResult().rawChildInputs().count(), 0 ); QCOMPARE( context4.modelResult().rawChildOutputs().count(), 0 ); QCOMPARE( context4.modelResult().executedChildIds().count(), 0 ); - + // make sure postprocessor is correctly deleted ppDeleted = false; pp = new TestPostProcessor( &ppDeleted );