Add type-checking guards to DeadlineAlert init - #73294
Conversation
SameerMesiah97
left a comment
There was a problem hiding this comment.
I had just one thing to point out.
potiuk
left a comment
There was a problem hiding this comment.
Approving — the guards are a real improvement, and I checked that the reasoning behind the strict callback check holds: _decode_deadline_callback allow-lists AsyncCallback and SyncCallback by qualified class name, so a Callback subclass that passed the old isinstance check only blew up later, at deserialization. Moving that to Dag-parse time is the right call, and the comment recording why isinstance is too loose earns its place.
I'm not gating the merge on the points below, but I would like them fixed — the first two are decisions rather than polish:
deadline.py:157— a bareintinterval round-trips end to end today (the decoder has a back-compat branch for numbers); this guard rejects it, and the PR carriesbackport-to-v3-3-test. Normalise it, or drop the backport label and add a newsfragment.deadline.py:162— the comment's own argument applies to the interval check too:pendulum.duration(...)subclassestimedelta, passes the guard, then dies in serde with aTypeError. Normalising subclasses would make it work instead of failing late.deadline.py:154— narrowcallback: CallbacktoAsyncCallback | SyncCallback, so mypy catches the subclass case statically.deadline.py:163— the permitted-callback tuple now duplicates the decoder's allow-list; tie both to one constant.test_deadline.py:237— the interval test never asserts the reported type name, unlike its callback sibling.
Details inline.
Smaller observations
- The PR body says "Adds a couple unit tests…", but the diff also changes two production validation paths in a backport-labelled PR. Worth a line in the description — backport reviewers read it.
test_serialize_deserialize_deadline_alert: switching the third case toSerializedDeadlineAlertis the right resolution of@SameerMesiah97's point, and gives better coverage of the core-side round trip. The param idserialized_variable_intervalnow describes a different case though — something likecore_serialized_alertwould read truer.- No newsfragment is correct as the PR stands, since the subclass and loose-type cases already failed at (de)serialization. That answer changes if the
intrejection above is kept as-is.
This review was drafted by an AI-assisted tool and
confirmed by an Airflow maintainer. The maintainer
approving this PR has read the findings and signed off. If
something feels off, please reply on the PR and a maintainer
will follow up.More on how Airflow handles maintainer review:
contributing-docs/05_pull_requests.rst.
f084e40 to
a325e2b
Compare
Backport successfully created: v3-3-testNote: As of Merging PRs targeted for Airflow 3.X In matter of doubt please ask in #release-management Slack channel.
|
## Must land after #72651(merged)#72651 made the scheduler decode deadline intervals and callbacks by exact class name. This adds the matching validation on the write side, so a Dag author is refused at parse time instead of the scheduler failing later on a row it cannot read.
DeadlineAlert.__init__now refuses acallbackthat is not exactlyAsyncCallbackorSyncCallback, since the decoder allow-lists those by class name and a subclass could be written but never read back.DeadlineAlert.__init__validatesinterval. Numbers are deprecated, not rejected: accepted as seconds with aRemovedInAirflow4Warning, becauseinterval=3600parses today.timedeltasubclasses such aspendulum.duration(...)are normalized to a plaintimedeltainstead of failing later in serde.interval=Trueis refused.serialization/decoders.pybuilds its allow-list from a sharedDEADLINE_CALLBACK_TYPESinstead of keeping a second copy of the pair.Added a
significantnewsfragment for the deprecation and the callback tightening, and unit testing for the above