<@ULVA73B9P>, does a function decorated with `@tas...
# ask-marvin
p
@Marvin, does a function decorated with
@task
change the type from
Callable
to something else?
m
thought for 211.4 seconds
Short answer: yes. In Prefect 3.x, decorating a function with
@task
turns it into an instance of
prefect.tasks.Task[P, R]
(not a plain
Callable
). It remains callable, but its type is
Task
with: - P = ParamSpec capturing the function’s full parameter signature - R = the original return type Key points: -
isinstance(my_task, Task)
→ True - Direct call returns the original return type
R
-
.submit(...)
returns
PrefectFuture[R]
-
return_state=True
returns
State[R]
- If you specifically need a
Callable[...]
, use the underlying function at
my_task.fn
Example:
Copy code
from typing import Callable
from prefect import task, Task

@task
def add(x: int, y: int) -> float:
    return x + y

# It's a Task, not a Callable
assert isinstance(add, Task)

# Still callable
result: float = add(1, 2)

# Future-typed call
fut = add.submit(1, 2)  # PrefectFuture[float]

# If you need a Callable, use the underlying function
fn: Callable[[int, int], float] = add.fn
Typing compatibility: - Prefect’s
Task
uses PEP 612 (ParamSpec) to preserve the exact signature through the decorator. - Pyright/Pylance: fully supported and recommended. - Mypy: partial support; you may see degraded inference or need to use
add.fn
when a
Callable
is required.
p
@Marvin, does this apply to Prefect 2.x as well?
m
thought for 119.6 seconds
Yes—Prefect 2.x behaves the same in this regard. -
@task
returns a Task[P, R] instance (not a plain Callable). It’s a callable object with your function stored at
.fn
. - Direct call returns the original return type `R`; calling with
return_state=True
returns
State[R]
. -
.submit(...)
returns
PrefectFuture[R]
. Typing notes: - Prefect 2.x also uses ParamSpec (PEP 612) and TypeVar to preserve the function’s signature. - Pyright/Pylance handle this well; mypy’s ParamSpec support is incomplete, so you may need to reference the underlying function via
my_task.fn
when something requires a
Callable[...]
. So in both Prefect 2.x and 3.x: - Decorated functions are Tasks, not Callables. - They remain callable and provide task-specific methods/overloads.