Skip to content

Commit

Permalink
quote escape (#10370)
Browse files Browse the repository at this point in the history
  • Loading branch information
jakekaplan authored Aug 14, 2023
1 parent 94316c5 commit 55be589
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/prefect/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,9 @@ def add_futures_and_states_to_inputs(obj):
elif is_state(obj):
if obj.state_details.task_run_id:
inputs.add(TaskRunResult(id=obj.state_details.task_run_id))
# Expressions inside quotes should not be traversed
elif isinstance(obj, quote):
raise StopVisiting
else:
state = get_state_for_result(obj)
if state and state.state_details.task_run_id:
Expand Down
30 changes: 29 additions & 1 deletion tests/test_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from contextlib import contextmanager
import threading
from typing import List
from unittest.mock import MagicMock
from unittest.mock import MagicMock, patch
from uuid import uuid4

import anyio
Expand All @@ -23,6 +23,7 @@
API_HEALTHCHECKS,
begin_flow_run,
check_api_reachable,
collect_task_run_inputs,
create_and_begin_subflow_run,
create_then_begin_flow_run,
link_state_to_result,
Expand Down Expand Up @@ -2243,3 +2244,30 @@ def parent():
" the same flow."
in caplog.text
)


@patch(
"prefect.utilities.collections.visit_collection",
wraps=prefect.utilities.collections.visit_collection,
)
@patch("prefect.engine.visit_collection", wraps=prefect.engine.visit_collection)
async def test_collect_task_run_inputs_respects_quote(
mock_outer_visit_collection, mock_recursive_visit_collection
):
# Regression test for https://github.com/PrefectHQ/prefect/pull/10370
# This test patches the original `visit_collection` functional call in
# `collect_task_run_inputs` and the recursive call inside `visit_collection`
# separately.

await collect_task_run_inputs([{"a": 1}, {"b": 2}, {"c": 3}])
assert mock_outer_visit_collection.call_count == 1
assert mock_recursive_visit_collection.call_count == 9

mock_outer_visit_collection.reset_mock()
mock_recursive_visit_collection.reset_mock()

# Using `quote` should now keep recursive calls from happening,
# as we no longer introspect the input if annotated.
await collect_task_run_inputs(quote([{"a": 1}, {"b": 2}, {"c": 3}]))
assert mock_outer_visit_collection.call_count == 1
assert mock_recursive_visit_collection.call_count == 0

0 comments on commit 55be589

Please sign in to comment.