Feature/support prior return value in when clause - #3990
Conversation
|
Thanks for the contribution! It looks like @davidmreed is an internal user so signing the CLA is not required. However, we need to confirm this. |
jstvz
left a comment
There was a problem hiding this comment.
Useful feature, but the substitution as written has correctness gaps that surface for any return value other than the literal strings "True" and "False".
Blocking (inline):
result.return_values.get(name)returnsNonewhen the key is missing, andstr.replace(needle, None)raises TypeError. Non-string return values hit the same path.- Raw
str.replaceinto a Jinja2 expression has no quoting contract. The tests pass only because "True"/"False" are Jinja boolean literals; a string return like "Good to Go!" produces invalid Jinja and fails to compile. Pick a contract (repr-quote, or bind values into the Jinja context).
Non-blocking (inline):
- Regex
\^\^\S+swallows trailing punctuation; tighten to[\w.]+. - Mutating
step.whencorrupts the skip-log output.
Other notes (no inline):
if prior_return_values is not None:is dead defensive code;re.findallalways returns a list. Theforhandles empty.- The new
^^syntax inwhen:is user-facing and undocumented. Please add to the cookbook / when-clause docs. - The new logic duplicates
resolve_return_value_options(line 751). A shared helper would prevent these two paths from drifting. - CLA check is missing on this PR; needs to be signed before merge.
- Test coverage for the path-not-found NameError is good; please extend with a string return value, a missing key on an existing path, and a parenthesized expression.
| prior_return_values = RETURN_VALUE_SUBS_RE.findall(step.when) | ||
| if prior_return_values is not None: | ||
| for value in prior_return_values: | ||
| path, name = value[len(RETURN_VALUE_OPTION_PREFIX) :].rsplit(".", 1) |
There was a problem hiding this comment.
result.return_values.get(name) returns None when the key is missing, and str.replace(needle, None) raises TypeError. Non-string return values (bool, int) hit the same path. Either default to "", raise a clear error, or build a Jinja context dict instead of string-replacing.
| prior_return_values = RETURN_VALUE_SUBS_RE.findall(step.when) | ||
| if prior_return_values is not None: | ||
| for value in prior_return_values: | ||
| path, name = value[len(RETURN_VALUE_OPTION_PREFIX) :].rsplit(".", 1) |
There was a problem hiding this comment.
Raw textual .replace() into a Jinja2 expression has no quoting contract. The current tests only pass because "True" and "False" happen to be Jinja boolean literals. A return value like "Good to Go!" (the exact case from issue #3663) substitutes into when: Good to Go! and fails to compile. A string with whitespace or operators is a syntax error. Pick a contract: either repr()-quote the substituted value, or bind the values into the Jinja2 context as e.g. tasks['some.task'].return_value and document the syntax.
|
|
||
|
|
||
| RETURN_VALUE_OPTION_PREFIX = "^^" | ||
| RETURN_VALUE_SUBS_RE = re.compile(r"\^\^\S+") |
There was a problem hiding this comment.
r"\^\^\S+" greedily captures trailing punctuation. Expressions like ^^task.flag=='ok' match the entire token, then rsplit(".", 1) splits on the wrong dot. Tighten to r"\^\^[\w.]+" to stop at non-word boundaries.
| prior_return_values = RETURN_VALUE_SUBS_RE.findall(step.when) | ||
| if prior_return_values is not None: | ||
| for value in prior_return_values: | ||
| path, name = value[len(RETURN_VALUE_OPTION_PREFIX) :].rsplit(".", 1) |
There was a problem hiding this comment.
step.when = step.when.replace(...) mutates the StepSpec. Subsequent skip-log output prints the post-substitution text instead of the author's ^^… reference. Assign to a local expr_str before evaluation.
Adds the ability to reference output of tasks to determine if subsequent tasks should be run or not.
This pull request enhances the flow runner to support dynamic substitution of prior step return values within a step's
whenclause, allowing for more flexible and data-driven conditional execution of steps. It also introduces comprehensive tests to validate this new behavior.Enhancements to flow runner conditional logic:
whenclause using the^^path.keysyntax. The flow runner now parses and substitutes these references with the actual return values from previous steps before evaluating the condition. [1] [2] [3]Testing and validation:
_TaskReturnsBoolStrin the test suite to facilitate testing of return value substitution.return_booltest task in the test project configuration.whenclause.