Nash Taylor
05/20/2022, 10:55 PMpy.typed
on my own. I see that there is a py.typed
on the master branch; was there a conscious decision made not to include this marker file in 2.0? If so, why?
Without the marker file, I get:
from prefect.flows import flow
reveal_type(flow) # Unknown
With the marker file, I get:
from prefect.flows import flow
reveal_type(flow) # Overload[(__fn: (**P@flow) -> R@flow, /) -> Flow[P@flow, R@flow], (*, name: str = None, version: str = None, task_runner: BaseTaskRunner = ConcurrentTaskRunner, description: str = None, timeout_seconds: int | float = None, validate_parameters: bool = True) -> (((**P@flow) -> R@flow) -> Flow[P@flow, R@flow]), (__fn: Unknown | None = None, *, name: str = None, version: str = None, task_runner: BaseTaskRunner = ConcurrentTaskRunner, description: str = None, timeout_seconds: int | float = None, validate_parameters: bool = True) -> (Flow[P, R] | (((**P) -> R) -> Flow[P, R]))]
which is much better.
For example, now when I decorate a function with @task
and use it in an @flow
, the return type of the task is known to have a .result()
method. When it was just an Unknown, pyright would complain that I'm accessing a method that doesn't exist. For someone who enforces fully passing mypy (now pyright) checks on every pull request, this is kind of a necessity.Zanie
05/21/2022, 1:07 AMNash Taylor
05/21/2022, 1:13 AMtouch py.typed
Alvaro Durán Tovar
05/21/2022, 9:17 AMNash Taylor
05/21/2022, 3:15 PMTask.__call__
(i.e. type your function you’ve decorated with @task
), it always chooses the [first overload](https://github.com/PrefectHQ/prefect/blob/orion/src/prefect/tasks.py#L231-L255), Task[P, NoReturn]
, whose return type is PrefectFuture[None, Sync]
. Basically, it assumes that every single user function decorated with @task
has a return type of None
, which causes .result()
to always be None@task
def my_task(a: str, b: int) -> float:
return len(a) + b + 0.5
it picks up the third overload Task[P, T]
and returns a PrefectFuture[T, Sync]
, which here is a PrefectFuture[float, Sync]
. And therefore my_task("a", 0).result()
is a float