Stop exposing flat nested inputs in workflow when expressions

This commit is contained in:
John Chilton
2026-08-29 10:37:51 -04:00
parent 10c38ffae8
commit 73caef00c1
4 changed files with 72 additions and 18 deletions
+9
View File
@@ -4,3 +4,12 @@
===========================================================
26.2 Galaxy Release
===========================================================
Workflow expression compatibility
=================================
Workflow ``when`` expressions no longer expose connected nested tool inputs
through Galaxy's internal pipe-prefixed connection names (for example,
``inputs["cond|param"]``). Use the nested tool-state form instead, such as
``inputs.cond.param`` or ``inputs["cond"]["param"]``. Ordinary top-level inputs
and extra expression inputs such as ``inputs.when`` remain unchanged.
+16 -18
View File
@@ -3117,25 +3117,23 @@ class ToolModule(WorkflowModule):
extra_step_state = {}
for step_input in step.inputs:
step_input_name = step_input.name
input_in_execution_state = step_input_name not in execution_state.inputs
if input_in_execution_state:
if step_input_name in all_inputs_by_name:
if iteration_elements and step_input_name in iteration_elements: # noqa: B023
value = iteration_elements[step_input_name] # noqa: B023
else:
value = progress.replacement_for_input(trans, step, all_inputs_by_name[step_input_name])
# TODO: only do this for values... is everything with a default
# this way a field parameter? I guess not?
extra_step_state[step_input_name] = value
# Might be needed someday...
# elif step_input.default_value_set:
# extra_step_state[step_input_name] = step_input.default_value
if step_input_name in execution_state.inputs:
continue
if step_input_name in all_inputs_by_name:
if step_input_name and "|" in step_input_name:
# Nested tool inputs have flat connection names but are already represented
# by their nested shape in the execution state.
continue
if iteration_elements and step_input_name in iteration_elements: # noqa: B023
value = iteration_elements[step_input_name] # noqa: B023
else:
if iteration_elements and step_input_name in iteration_elements: # noqa: B023
value = iteration_elements[step_input_name] # noqa: B023
else:
value = progress.replacement_for_connection(step_input.connections[0], is_data=True)
extra_step_state[step_input_name] = value
value = progress.replacement_for_input(trans, step, all_inputs_by_name[step_input_name])
else:
if iteration_elements and step_input_name in iteration_elements: # noqa: B023
value = iteration_elements[step_input_name] # noqa: B023
else:
value = progress.replacement_for_connection(step_input.connections[0], is_data=True)
extra_step_state[step_input_name] = value
if when_value is not False:
when_value = evaluate_value_from_expressions(
@@ -0,0 +1,16 @@
- doc: Nested dot and bracket access work when an optional input is omitted.
job: {}
outputs:
out:
asserts:
has_line:
line: okay
- doc: Nested dot and bracket access work when an optional input is supplied.
job:
optional_text: supplied
expected: supplied
outputs:
out:
asserts:
has_line:
line: okay
@@ -0,0 +1,31 @@
class: GalaxyWorkflow
doc: |
Ensure workflow when expressions expose connected tool parameters only in
their tool-state shape while preserving genuine extra expression inputs.
inputs:
optional_text:
type: text
optional: true
gate:
type: boolean
default: true
expected:
type: text
default: fdefault
outputs:
out:
outputSource: inputs_as_json/out_file1
steps:
inputs_as_json:
tool_id: inputs_as_json
state:
test_case: 0
cond:
cond_test: first
in:
cond|more_text: optional_text
booltest: gate
when: gate
probe: gate
expected: expected
when: $(inputs.when && inputs.probe && inputs.booltest === inputs["booltest"] && inputs.cond.more_text === inputs["cond"]["more_text"] && inputs.cond.more_text === inputs.expected && !("cond|more_text" in inputs))