Replies: 2 comments 5 replies
-
Hey @mjpieters! Working towards type completeness is very important to Prefect, so we're thrilled you opened this discussion! As you noted, we run For concrete next steps, we can add a step to our CI pipeline to run and publish a type completeness report on How does that sound to you? Is there anything else you would recommend? |
Beta Was this translation helpful? Give feedback.
-
Pyright 1.1.391 fixed the bug that produced the confusing output. |
Beta Was this translation helpful? Give feedback.
-
Hi!
I wanted to kick of a discussion about improving Prefect's type completeness; how important type completeness is to Prefect and if it is considered important, how to reach and maintain type completeness.
I'm in the process of evaluating workflow orchestration frameworks for a company I currently consult for, and Prefect is one of our front-runners. One of prefect's strong points is that the project makes use of type annotations, where those annotations actively help you validate your code. In other words, the annotations are not just there to help the framework serialise and deserialise input and output data.
However, the SDK type annotations are not type complete, meaning that if you want to rely on the provided annotations to validate projects using prefect, then the type annotations fall short in several ways:
Where the codebase uses generic types such as
TaskRunner
,ResultSerializer
,State
orTask
, the annotations fail to provide type arguments.E.g. the
Flow.on_completion
decorator is annotated to take an argumentfn
, annotated asCallable[["Flow", FlowRun, State]
. Both theFlow
andState
types are generic types but no arguments are provided. A complete type annotation would beCallable[["Flow[P, R]", FlowRun, State[R]]
, because the function will be passed the current flow and aState
that, if the flow produced a return value of typeR
, would reference that return value.Some public methods lack annotations altogether; pyright reports 48 cases where public types reachable from
prefect.main
, lack a type annotation for a function argument, and 103 cases where a return type annotation is missing.Some aspects of the
prefect
public API are not as straightforward to express using might be desired, e.g. the fact thatprefect.Flow.from_source
is copied over to thefrom_source
attribute of theprefect.flow()
function is not reflected in the type annotations. Unless this is fixed, my developers would have to either useprefect.Flow.from_source()
or silence the type checker for perfectly normal and documented code patterns.See below for the
pyright --verifytypes
report for more details.I also note that there is very little in the way of type annotation testing. The only validation is running mypy via the pre-commit hook, where mypy is configured to run in almost the default configuration with additional overrides to ignore missing imports. There are no type annotation-specific tests, e.g. tests that cover how generic type variables are propagated. This is, unfortunately, too weak a check, as the default configuration ignores unannotated code and doesn't enforce type annotation rules important for type completeness.
Now, if we do go with Prefect, I can budget some of my time in helping improve the annotations in this project. I really want developers working with Prefect to be able to rely on the type annotations, both when writing workflow code in their IDE and when linting the code in the CI. But I really want to know first if this is something this project actually wants to support!
So:
How important is type completeness for Prefect?
and if the answer is 'it is very important', then the follow-up questions are:
pytest --verifytypes prefect.main --ignoreexternal report
Type completeness report
This report focuses on just
prefect.main
, which defines the public API used by workflow developers. Running the same check on all ofprefect
is much more verbose, because this then also covers code from outside the SDK and even the alembic migration steps for the server.To reproduce this report, first set up a virtualenv with both
pyright
andprefect
installed; e.g. when in a checkout of this Github project:uv venv uv pip install --upgrade pyright -e .
and then run pyright to produce the report:
I removed a confusing series of
Could not resolve module: "prefect.main.NAME"
errors from the start of the report that are most likely due to a pyright bug connected to running this report against theprefect.main
package instead ofprefect
; these errors did not seem to affect the accuracy of the report.I also removed the full path of the virtualenv on my local machine for privacy reasons.
Additional resources
Beta Was this translation helpful? Give feedback.
All reactions