Update tempora-4.1.2

This commit is contained in:
JonnyWong16 2021-10-14 21:13:30 -07:00
parent edd2f21ce1
commit a94edb4644
No known key found for this signature in database
GPG key ID: B1F1F9807184697A
6 changed files with 982 additions and 695 deletions

View file

@ -1,10 +1,17 @@
# -*- coding: utf-8 -*-
"""
Classes for calling functions a schedule.
"""
Classes for calling functions a schedule. Has time zone support.
from __future__ import absolute_import
For example, to run a job at 08:00 every morning in 'Asia/Calcutta':
>>> job = lambda: print("time is now", datetime.datetime())
>>> time = datetime.time(8, tzinfo=pytz.timezone('Asia/Calcutta'))
>>> cmd = PeriodicCommandFixedDelay.daily_at(time, job)
>>> sched = InvokeScheduler()
>>> sched.add(cmd)
>>> while True: # doctest: +SKIP
... sched.run_pending()
... time.sleep(.1)
"""
import datetime
import numbers
@ -13,8 +20,6 @@ import bisect
import pytz
__metaclass__ = type
def now():
"""
@ -44,8 +49,13 @@ class DelayedCommand(datetime.datetime):
@classmethod
def from_datetime(cls, other):
return cls(
other.year, other.month, other.day, other.hour,
other.minute, other.second, other.microsecond,
other.year,
other.month,
other.day,
other.hour,
other.minute,
other.second,
other.microsecond,
other.tzinfo,
)
@ -91,6 +101,7 @@ class PeriodicCommand(DelayedCommand):
Like a delayed command, but expect this command to run every delay
seconds.
"""
def _next_time(self):
"""
Add delay to self, localized
@ -117,8 +128,7 @@ class PeriodicCommand(DelayedCommand):
def __setattr__(self, key, value):
if key == 'delay' and not value > datetime.timedelta():
raise ValueError(
"A PeriodicCommand must have a positive, "
"non-zero delay."
"A PeriodicCommand must have a positive, " "non-zero delay."
)
super(PeriodicCommand, self).__setattr__(key, value)
@ -132,6 +142,11 @@ class PeriodicCommandFixedDelay(PeriodicCommand):
@classmethod
def at_time(cls, at, delay, target):
"""
>>> cmd = PeriodicCommandFixedDelay.at_time(0, 30, None)
>>> cmd.delay.total_seconds()
30.0
"""
at = cls._from_timestamp(at)
cmd = cls.from_datetime(at)
if isinstance(delay, numbers.Number):
@ -144,11 +159,18 @@ class PeriodicCommandFixedDelay(PeriodicCommand):
def daily_at(cls, at, target):
"""
Schedule a command to run at a specific time each day.
>>> from tempora import utc
>>> noon = utc.time(12, 0)
>>> cmd = PeriodicCommandFixedDelay.daily_at(noon, None)
>>> cmd.delay.total_seconds()
86400.0
"""
daily = datetime.timedelta(days=1)
# convert when to the next datetime matching this time
when = datetime.datetime.combine(datetime.date.today(), at)
if when < now():
when -= daily
while when < now():
when += daily
return cls.at_time(cls._localize(when), daily, target)
@ -158,6 +180,7 @@ class Scheduler:
A rudimentary abstract scheduler accepting DelayedCommands
and dispatching them on schedule.
"""
def __init__(self):
self.queue = []
@ -186,6 +209,7 @@ class InvokeScheduler(Scheduler):
"""
Command targets are functions to be invoked on schedule.
"""
def run(self, command):
command.target()
@ -194,8 +218,9 @@ class CallbackScheduler(Scheduler):
"""
Command targets are passed to a dispatch callable on schedule.
"""
def __init__(self, dispatch):
super(CallbackScheduler, self).__init__()
super().__init__()
self.dispatch = dispatch
def run(self, command):