fix: preserve context schema for reserved aliases
This commit is contained in:
@@ -14,6 +14,7 @@ from wf_core.context_contracts import (
|
|||||||
FOREACH_CONTEXT_KEY,
|
FOREACH_CONTEXT_KEY,
|
||||||
LOOP_INDEX_CONTEXT_KEY,
|
LOOP_INDEX_CONTEXT_KEY,
|
||||||
LOOP_ITEM_CONTEXT_KEY,
|
LOOP_ITEM_CONTEXT_KEY,
|
||||||
|
RESERVED_CONTEXT_KEYS,
|
||||||
STANDARD_CONTEXT_FIELDS,
|
STANDARD_CONTEXT_FIELDS,
|
||||||
ContextFieldContract,
|
ContextFieldContract,
|
||||||
ContextSchema,
|
ContextSchema,
|
||||||
@@ -319,7 +320,11 @@ def _context_schema_for_stack(
|
|||||||
required.extend([LOOP_ITEM_CONTEXT_KEY, LOOP_INDEX_CONTEXT_KEY])
|
required.extend([LOOP_ITEM_CONTEXT_KEY, LOOP_INDEX_CONTEXT_KEY])
|
||||||
for owner_id in stack:
|
for owner_id in stack:
|
||||||
foreach = foreach_nodes.get(owner_id)
|
foreach = foreach_nodes.get(owner_id)
|
||||||
if foreach is not None and foreach.as_:
|
if (
|
||||||
|
foreach is not None
|
||||||
|
and foreach.as_
|
||||||
|
and foreach.as_ not in RESERVED_CONTEXT_KEYS
|
||||||
|
):
|
||||||
properties[foreach.as_] = deepcopy(
|
properties[foreach.as_] = deepcopy(
|
||||||
_foreach_item_schema(
|
_foreach_item_schema(
|
||||||
workflow, foreach, foreach_nodes, owner_stack_by_node
|
workflow, foreach, foreach_nodes, owner_stack_by_node
|
||||||
|
|||||||
@@ -156,6 +156,31 @@ def test_all_standard_context_names_are_reserved_from_foreach_aliases() -> None:
|
|||||||
frame_context_view(_run_with(frame), frame)
|
frame_context_view(_run_with(frame), frame)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("alias", ["prior_outcome", "foreach"])
|
||||||
|
def test_reserved_alias_does_not_overwrite_generated_context_schema(alias: str) -> None:
|
||||||
|
"""Invalid aliases still leave secondary context diagnostics coherent."""
|
||||||
|
from wf_core.analysis.context_scopes import context_schema_for_node
|
||||||
|
|
||||||
|
workflow = _workflow(
|
||||||
|
start="each",
|
||||||
|
nodes=[_foreach("each", alias=alias), _node("body")],
|
||||||
|
edges=[
|
||||||
|
{"from": "each", "outcome": "loop", "to": "body"},
|
||||||
|
{"from": "body", "outcome": "ok", "to": "each"},
|
||||||
|
{"from": "each", "outcome": "done", "to": END},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
generated = context_schema_for_node(workflow, "body")["properties"][alias]
|
||||||
|
analyzed = _field_map(workflow, "body")[alias].schema
|
||||||
|
|
||||||
|
assert generated == analyzed
|
||||||
|
if alias == "prior_outcome":
|
||||||
|
assert generated == {"type": ["string", "null"]}
|
||||||
|
else:
|
||||||
|
assert generated["type"] == "object"
|
||||||
|
assert set(generated["properties"]) == {"each"}
|
||||||
|
|
||||||
|
|
||||||
def test_serial_and_concurrent_foreach_expose_the_same_scoped_context() -> None:
|
def test_serial_and_concurrent_foreach_expose_the_same_scoped_context() -> None:
|
||||||
for mode in ("serial", "concurrent"):
|
for mode in ("serial", "concurrent"):
|
||||||
workflow = _workflow(
|
workflow = _workflow(
|
||||||
|
|||||||
Reference in New Issue
Block a user