Fix for specifiers like 1,L

This commit is contained in:
Josiah Carlson 2012-04-18 13:30:19 -07:00
parent 3cb7a6ad57
commit 7ddf9cd2e1
3 changed files with 24 additions and 9 deletions

View file

@ -125,20 +125,32 @@ def _assert(condition, message, *args):
raise ValueError(message%args) raise ValueError(message%args)
class _Matcher(object): class _Matcher(object):
__slots__ = 'allowed', 'end', 'any', 'input', 'which' __slots__ = 'allowed', 'end', 'any', 'input', 'which', 'split'
def __init__(self, which, entry): def __init__(self, which, entry):
_assert(0 <= which <= 5, _assert(0 <= which <= 5,
"improper number of cron entries specified") "improper number of cron entries specified")
self.input = entry.lower() self.input = entry.lower()
self.split = self.input.split(',')
self.which = which self.which = which
self.allowed, self.end = self._parse_crontab(which, entry.lower()) self.allowed = set()
self.any = self.allowed is None 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): def __call__(self, v, dt):
if self.input == 'l': if 'l' in self.split:
return v == _end_of_month(dt).day if v == _end_of_month(dt).day:
elif self.input.startswith('l'): return True
elif any(x.startswith('l') for x in self.split):
okay = dt.month != (dt + WEEK).month 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 return self.any or v in self.allowed
def __lt__(self, other): def __lt__(self, other):
if self.any: if self.any:

View file

@ -7,7 +7,7 @@ with open('README') as f:
setup( setup(
name='crontab', name='crontab',
version='.13', version='.14',
description='Parse and use crontab schedules in Python', description='Parse and use crontab schedules in Python',
author='Josiah Carlson', author='Josiah Carlson',
author_email='josiah.carlson@gmail.com', author_email='josiah.carlson@gmail.com',

View file

@ -38,7 +38,7 @@ class TestCrontab(unittest.TestCase):
self._run_test('0 0 ? * 0-6', 86400) 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 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, 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,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 * * * *', 60, datetime.datetime(2011, 1, 1, 1, 1))
self._run_test('0-6,50-59/2 * * * *', 120, datetime.datetime(2011, 1, 1, 1, 2)) 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): def test_last_day(self):
self._run_test('0 0 L 2 ?', 28*86400, datetime.datetime(2011, 1, 31)) 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 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 ? 2 L1', 58*86400, datetime.datetime(2011, 1, 31))
self._run_test('0 0 ? 7 L1', 1*86400, datetime.datetime(2011, 7, 24)) 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('* L * * *'))
self.assertRaises(ValueError, lambda: CronTab('L * * * *')) self.assertRaises(ValueError, lambda: CronTab('L * * * *'))
self.assertRaises(ValueError, lambda: CronTab('* 1, * * *'))
def test(): def test():
suite = unittest.TestLoader().loadTestsFromTestCase(TestCrontab) suite = unittest.TestLoader().loadTestsFromTestCase(TestCrontab)