class_docstr: Timetable that triggers DAG runs according to a cron expression.
  
  This is different from ``CronDataIntervalTimetable``, where the cron
  expression specifies the *data interval* of a DAG run. With this timetable,
  the data intervals are specified independently from the cron expression.
  Also for the same reason, this timetable kicks off a DAG run immediately at
  the start of the period (similar to POSIX cron), instead of needing to wait
  for one data interval to pass.
  
  Don't pass ``@once`` in here; use ``OnceTimetable`` instead.
code: def next_dagrun_info(
      self,
      *,
      last_automated_data_interval: DataInterval | None,
      restriction: TimeRestriction,
  ) -> DagRunInfo | None:
      if restriction.catchup:
          if last_automated_data_interval is not None:
              next_start_time = self._get_next(
                  last_automated_data_interval.end
              )
          elif restriction.earliest is None:
              return None  # Don't know where to catch up from, give up.
          else:
              next_start_time = self._align_to_next(
                  restriction.earliest
              )
      else:
          start_time_candidates = [
              self._align_to_prev(DateTime.utcnow())
          ]
          if last_automated_data_interval is not None:
              start_time_candidates.append(
                  self._get_next(last_automated_data_interval.end)
              )
          if restriction.earliest is not None:
              start_time_candidates.append(
                  self._align_to_next(restriction.earliest)
              )
          next_start_time = max(start_time_candidates)
      if (
          restriction.latest is not None
          and restriction.latest < next_start_time
      ):
          return None
      return DagRunInfo.interval(
          # pendulum.Datetime ± timedelta should return pendulum.Datetime
          # however mypy decide that output would be datetime.datetime
          next_start_time - self._interval,  # type: ignore[arg-type]
          next_start_time,
      )
  
file_path: airflow/airflow/timetables/trigger.py
imports: from __future__ import annotations
  import datetime
  from typing import TYPE_CHECKING, Any
  from pendulum import DateTime
  from airflow.timetables._cron import CronMixin
  from airflow.timetables.base import DagRunInfo, DataInterval, Timetable
label_desc: Use image node_id 5 for calling the CronTriggerTimetable obj's underlying member method code with example usage: obj.next_dagrun_info() and returns: DagRunInfo, None, None