diff --git a/crontab/_crontab.py b/crontab/_crontab.py index 0ab64bb..6da5af6 100644 --- a/crontab/_crontab.py +++ b/crontab/_crontab.py @@ -125,20 +125,32 @@ def _assert(condition, message, *args): raise ValueError(message%args) class _Matcher(object): - __slots__ = 'allowed', 'end', 'any', 'input', 'which' + __slots__ = 'allowed', 'end', 'any', 'input', 'which', 'split' def __init__(self, which, entry): _assert(0 <= which <= 5, "improper number of cron entries specified") self.input = entry.lower() + self.split = self.input.split(',') self.which = which - self.allowed, self.end = self._parse_crontab(which, entry.lower()) - self.any = self.allowed is None + self.allowed = set() + self.end = None + self.any = '*' in self.split or '?' in self.split + for it in self.split: + al, en = self._parse_crontab(which, it) + if al is not None: + self.allowed.update(al) + self.end = en + _assert(self.end is not None, + "improper item specification: %r", entry.lower() + ) def __call__(self, v, dt): - if self.input == 'l': - return v == _end_of_month(dt).day - elif self.input.startswith('l'): + if 'l' in self.split: + if v == _end_of_month(dt).day: + return True + elif any(x.startswith('l') for x in self.split): okay = dt.month != (dt + WEEK).month - return okay and (self.any or v in self.allowed) + if okay and (self.any or v in self.allowed): + return True return self.any or v in self.allowed def __lt__(self, other): if self.any: diff --git a/setup.py b/setup.py index 51758b0..d6d8de0 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ with open('README') as f: setup( name='crontab', - version='.13', + version='.14', description='Parse and use crontab schedules in Python', author='Josiah Carlson', author_email='josiah.carlson@gmail.com', diff --git a/tests/test_crontab.py b/tests/test_crontab.py index 01a3e97..887e2aa 100644 --- a/tests/test_crontab.py +++ b/tests/test_crontab.py @@ -38,7 +38,7 @@ class TestCrontab(unittest.TestCase): self._run_test('0 0 ? * 0-6', 86400) self._run_test('0 0 31 * *', 62*86400, datetime.datetime(2011, 1, 31)) self._run_test('0,1/2 * * * *', 60, datetime.datetime(2011, 1, 1, 1, 0)) - self._run_test('0,1/2 * * * *', 60, datetime.datetime(2011, 1, 1, 1, 1)) + self._run_test('0,1/2 * * * *', 120, datetime.datetime(2011, 1, 1, 1, 1)) self._run_test('0,1/2 * * * *', 60, datetime.datetime(2011, 1, 1, 1, 2)) self._run_test('0-6,50-59/2 * * * *', 60, datetime.datetime(2011, 1, 1, 1, 1)) self._run_test('0-6,50-59/2 * * * *', 120, datetime.datetime(2011, 1, 1, 1, 2)) @@ -63,6 +63,8 @@ class TestCrontab(unittest.TestCase): def test_last_day(self): self._run_test('0 0 L 2 ?', 28*86400, datetime.datetime(2011, 1, 31)) + self._run_test('0 0 1,L 2 ?', 86400, datetime.datetime(2011, 1, 31)) + self._run_test('0 0 2,L 2 ?', 2*86400, datetime.datetime(2011, 1, 31)) self._run_test('0 0 L 2 ?', 58*86400, datetime.datetime(2011, 1, 1)) self._run_test('0 0 ? 2 L1', 58*86400, datetime.datetime(2011, 1, 31)) self._run_test('0 0 ? 7 L1', 1*86400, datetime.datetime(2011, 7, 24)) @@ -105,6 +107,7 @@ class TestCrontab(unittest.TestCase): self.assertRaises(ValueError, lambda: CronTab('* * * L *')) self.assertRaises(ValueError, lambda: CronTab('* L * * *')) self.assertRaises(ValueError, lambda: CronTab('L * * * *')) + self.assertRaises(ValueError, lambda: CronTab('* 1, * * *')) def test(): suite = unittest.TestLoader().loadTestsFromTestCase(TestCrontab)