Vamsi-klu commented on code in PR #69746:
URL: https://github.com/apache/airflow/pull/69746#discussion_r3949528892
##########
providers/standard/src/airflow/providers/standard/sensors/time.py:
##########
@@ -64,37 +77,68 @@ def __init__(
**kwargs,
) -> None:
super().__init__(**kwargs)
-
- # Create a "date-aware" timestamp that will be used as the
"target_datetime". This is a requirement
- # of the DateTimeTrigger
-
- # Get date considering dag.timezone
- aware_time = timezone.coerce_datetime(
- datetime.datetime.combine(
- datetime.datetime.now(self.dag.timezone), target_time,
self.dag.timezone
- )
- )
-
- # Now that the dag's timezone has made the datetime timezone aware, we
need to convert to UTC
- self.target_datetime = timezone.convert_to_utc(aware_time)
+ # Wall-clock only; tzinfo is stripped so serialized target_time is
deterministic.
+ if isinstance(target_time, datetime.time) and target_time.tzinfo is
not None:
+ self.target_time = target_time.replace(tzinfo=None)
+ else:
+ self.target_time = target_time
self.deferrable = deferrable
self.start_from_trigger = start_from_trigger
self.end_from_trigger = end_from_trigger
+ # Cached for this task attempt so a local-date rollover does not
change the target.
+ self._cached_target_datetime: datetime.datetime | None = None
if self.start_from_trigger:
- # Replaced rather than mutated: ``start_trigger_args`` is a class
attribute, so
- # assigning through it would overwrite the arguments of every
other task built
- # from this operator.
- self.start_trigger_args = dataclasses.replace(
- self.start_trigger_args,
- trigger_kwargs=dict(moment=self.target_datetime,
end_from_trigger=self.end_from_trigger),
+ dag = self._dag
+ if dag is None:
+ raise ValueError(
+ "TimeSensor(start_from_trigger=True) requires the sensor
to be attached to a Dag "
+ "so the timezone is known."
+ )
+ # Parse-stable kwargs only (no datetime.now()); moment is resolved
when the trigger starts.
+ self.start_trigger_args = StartTriggerArgs(
+
trigger_cls="airflow.providers.standard.triggers.temporal.TimeOfDayTrigger",
+ trigger_kwargs={
+ "target_time": self.target_time.isoformat(),
+ "tz": serializable_timezone(dag.timezone),
+ "end_from_trigger": self.end_from_trigger,
+ },
+ next_method="execute_complete",
+ next_kwargs=None,
+ timeout=None,
)
Review Comment:
Agreed. start_trigger_args is a class-level StartTriggerArgs again, same
shape as DateTimeSensor. start_from_trigger=True now uses dataclasses.replace
so we copy the template instead of mutating it or rebuilding the dataclass by
hand. Each task still gets its own object. The class kwargs stay parse-stable
(empty target_time, UTC), so the hash churn does not come back.
---
Drafted-by: Cursor Grok 4.6 (no human review before posting)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]