@@ -477,6 +477,7 @@ def __init__( # noqa: DOC503 pylint: disable=too-many-arguments
477477 * ,
478478 auto_start : bool = True ,
479479 start_delay : timedelta = timedelta (0 ),
480+ tick_at_start : bool = False ,
480481 loop : asyncio .AbstractEventLoop | None = None ,
481482 ) -> None :
482483 """Initialize this timer.
@@ -497,6 +498,13 @@ def __init__( # noqa: DOC503 pylint: disable=too-many-arguments
497498 start_delay: The delay before the timer should start. If `auto_start` is
498499 `False`, an exception is raised. This has microseconds resolution,
499500 anything smaller than a microsecond means no delay.
501+ tick_at_start: When `True`, the timer will trigger immediately after
502+ starting, and then wait for the interval before triggering
503+ again. When `False`, the timer will wait the interval before
504+ triggering for the first time. If `auto_start` is `False` and
505+ this is `True`, an exception is raised. If a `start_delay` is
506+ specified and this is `True`, the first trigger will be immediately
507+ after the `start_delay`.
500508 loop: The event loop to use to track time. If `None`,
501509 `asyncio.get_running_loop()` will be used.
502510
@@ -517,6 +525,9 @@ def __init__( # noqa: DOC503 pylint: disable=too-many-arguments
517525 "`auto_start` must be `True` if a `start_delay` is specified"
518526 )
519527
528+ if tick_at_start is True and auto_start is False :
529+ raise ValueError ("`auto_start` must be `True` if `tick_at_start` is `True`" )
530+
520531 self ._interval : int = _to_microseconds (interval )
521532 """The time to between timer ticks."""
522533
@@ -567,7 +578,7 @@ def __init__( # noqa: DOC503 pylint: disable=too-many-arguments
567578 """
568579
569580 if auto_start :
570- self .reset (start_delay = start_delay )
581+ self .reset (start_delay = start_delay , tick_at_start = tick_at_start )
571582
572583 @property
573584 def interval (self ) -> timedelta :
@@ -595,6 +606,7 @@ def reset( # noqa: DOC503
595606 * ,
596607 interval : timedelta | None = None ,
597608 start_delay : timedelta = timedelta (0 ),
609+ tick_at_start : bool = False ,
598610 ) -> None :
599611 """Reset the timer to start timing from now (plus an optional delay).
600612
@@ -608,6 +620,12 @@ def reset( # noqa: DOC503
608620 interval is kept.
609621 start_delay: The delay before the timer should start. This has microseconds
610622 resolution, anything smaller than a microsecond means no delay.
623+ tick_at_start: When `True`, the timer will trigger immediately after
624+ starting, and then wait for the interval before triggering
625+ again. When `False`, the timer will wait the interval before
626+ triggering for the first time. If a `start_delay` is specified
627+ and this is `True`, the first trigger will be immediately after
628+ the `start_delay`.
611629
612630 Raises:
613631 RuntimeError: If it was called without a running loop.
@@ -621,7 +639,10 @@ def reset( # noqa: DOC503
621639 if interval is not None :
622640 self ._interval = _to_microseconds (interval )
623641
624- self ._next_tick_time = self ._now () + start_delay_ms + self ._interval
642+ self ._next_tick_time = self ._now () + start_delay_ms
643+
644+ if not tick_at_start :
645+ self ._next_tick_time += self ._interval
625646
626647 if self .is_running :
627648 self ._reset_event .set ()
0 commit comments