Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 23 additions & 22 deletions cylc/flow/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2394,28 +2394,29 @@ def load_graph(self):

self.set_required_outputs(task_output_opt)

# Print inferred output optionality, for debugging graph parser.
# Note this excludes tasks that just default to success-required.
optionals = [
f" \u2022 {name}:{output}"
for (name, output), (optional, _, _) in task_output_opt.items()
if optional
]
requireds = [
f" \u2022 {name}:{output}"
for (name, output), (optional, _, _) in task_output_opt.items()
if not optional
]
if optionals:
LOG.debug(
"Optional outputs inferred from the graph:\n"
f"{'\n'.join(optionals)}"
)
if requireds:
LOG.debug(
"Required outputs inferred from the graph:\n"
f"{'\n'.join(requireds)}"
)
if cylc.flow.flags.verbosity > 1:
# Print inferred output optionality for debugging the graph parser.
# (This does not includes tasks that default to success-required.)
optionals = [
f" \u2022 {name}:{output}"
for (name, output), (optional, _, _) in task_output_opt.items()
if optional
]
requireds = [
f" \u2022 {name}:{output}"
for (name, output), (optional, _, _) in task_output_opt.items()
if not optional
]
if optionals:
LOG.debug(
"Optional outputs inferred from the graph:\n"
f"{'\n'.join(optionals)}"
)
if requireds:
LOG.debug(
"Required outputs inferred from the graph:\n"
f"{'\n'.join(requireds)}"
)

# Detect use of xtrigger names with '@' prefix (creates a task).
overlap = set(self.taskdefs.keys()).intersection(
Expand Down
14 changes: 9 additions & 5 deletions tests/integration/test_optional_outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ async def test_optional_outputs_consistency(flow, validate, graph, err):
{
("a", "succeeded"): True, # inferred
("m1", "succeeded"): True, # default
("m2", "succeeded"): False, # inferred (override default)
("m2", "succeeded"): False, # explicit "?"
},
),
pytest.param(
Expand Down Expand Up @@ -802,7 +802,7 @@ async def test_optional_outputs_consistency(flow, validate, graph, err):
""",
{
("a", "succeeded"): True, # inferred
("b", "succeeded"): False, # inferred
("b", "succeeded"): False, # explicit "?"
("c", "succeeded"): True, # default
},
),
Expand All @@ -813,7 +813,7 @@ async def test_optional_outputs_consistency(flow, validate, graph, err):
{
("a", "succeeded"): True, # inferred
("c", "succeeded"): True, # default
("c", "x"): True, # inferred
("c", "x"): True, # explicit ":x"
},
),
pytest.param(
Expand All @@ -823,7 +823,7 @@ async def test_optional_outputs_consistency(flow, validate, graph, err):
{
("a", "succeeded"): True, # inferred
("c", "succeeded"): True, # default
("c", "x"): False, # inferred
("c", "x"): False, # explicit ":x?"
},
),
pytest.param(
Expand Down Expand Up @@ -880,14 +880,15 @@ async def test_optional_outputs_inference(
},
}
)

config = validate(id)
for (task, output), exp in expected.items():
tdef = config.get_taskdef(task)
(_, required) = tdef.outputs[output]
assert required == exp


async def test_log_outputs(flow, validate, caplog):
async def test_log_outputs(flow, validate, caplog, monkeypatch):
"""Test logging of optional and required outputs inferred from the graph.

This probes output optionality inferred by the graph parser, so it does
Expand Down Expand Up @@ -921,6 +922,9 @@ async def test_log_outputs(flow, validate, caplog):
}
}
)

monkeypatch.setattr('cylc.flow.flags.verbosity', 2)

caplog.set_level(logging.DEBUG)
validate(id)

Expand Down
Loading