class_docstr: Test cron interval timetable can correctly enter a DST boundary.
  
  Zurich (Switzerland) is chosen since it is +1/+2 DST, making it a bit easier
  to get my head around the mental timezone conversion.
  
  In 2023, DST entered on 26th Mar, 2am local clocks (1am UTC) were turned
  forward to 3am. DST exited on 29th Oct, 3am local clocks (1am UTC) were
  turned backward to 2am (making the 2:XX hour fold).
class_docstr_tok: ["Test","cron","interval","timetable","can","correctly","enter","a","DST","boundary",".","Zurich","(","Switzerland",")","is","chosen","since","it","is","+1\/+2","DST",",","making","it","a","bit","easier","to","get","my","head","around","the","mental","timezone","conversion",".","In","2023",",","DST","entered","on","26th","Mar",",","2am","local","clocks","(","1am","UTC",")","were","turned","forward","to","3am",".","DST","exited","on","29th","Oct",",","3am","local","clocks","(","1am","UTC",")","were","turned","backward","to","2am","(","making","the","2",":","XX","hour","fold",")","."]
code: def test_exiting_exact(self) -> None:
      timetable = CronDataIntervalTimetable(
          "0 3 * * *", timezone="Europe/Zurich"
      )
      restriction = TimeRestriction(
          earliest=pendulum.datetime(2023, 10, 27, tz=utc),
          latest=None,
          catchup=True,
      )
  
      # Last run in DST. Interval starts and ends on 1am UTC (local time is +2).
      next_info = timetable.next_dagrun_info(
          last_automated_data_interval=None, restriction=restriction
      )
      assert next_info and next_info.data_interval == DataInterval(
          pendulum.datetime(2023, 10, 27, 1, tz=utc),
          pendulum.datetime(2023, 10, 28, 1, tz=utc),
      )
  
      # Crossing the DST switch. Interval starts on 1am UTC (local time +2)
      # and ends on 2am UTC (local time +1).
      next_info = timetable.next_dagrun_info(
          last_automated_data_interval=next_info.data_interval,
          restriction=restriction,
      )
      assert next_info and next_info.data_interval == DataInterval(
          pendulum.datetime(2023, 10, 28, 1, tz=utc),
          pendulum.datetime(2023, 10, 29, 2, tz=utc),
      )
  
      # Out of DST. Interval starts and ends on 2am UTC (local time is +1).
      next_info = timetable.next_dagrun_info(
          last_automated_data_interval=next_info.data_interval,
          restriction=restriction,
      )
      assert next_info and next_info.data_interval == DataInterval(
          pendulum.datetime(2023, 10, 29, 2, tz=utc),
          pendulum.datetime(2023, 10, 30, 2, tz=utc),
      )
  
imports: from __future__ import annotations
  import datetime
  import dateutil.relativedelta
  import pendulum
  import pytest
  import time_machine
  from airflow.exceptions import AirflowTimetableInvalid
  from airflow.timetables.base import DagRunInfo, DataInterval, TimeRestriction, Timetable
  from airflow.timetables.interval import CronDataIntervalTimetable, DeltaDataIntervalTimetable
  from airflow.utils.timezone import utc
label_desc: Use image node_id 3 for calling the TestCronIntervalDst obj's underlying member method code with example usage: obj.test_exiting_exact() without return types