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..39839d721f92 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 );