diff options
-rw-r--r-- | apscheduler/job.py | 12 | ||||
-rw-r--r-- | apscheduler/schedulers/base.py | 3 | ||||
-rw-r--r-- | apscheduler/util.py | 2 | ||||
-rw-r--r-- | tests/conftest.py | 4 | ||||
-rw-r--r-- | tests/test_executors.py | 5 | ||||
-rw-r--r-- | tests/test_job.py | 2 | ||||
-rw-r--r-- | tests/test_schedulers.py | 18 | ||||
-rw-r--r-- | tests/test_util.py | 4 |
8 files changed, 26 insertions, 24 deletions
diff --git a/apscheduler/job.py b/apscheduler/job.py index bb9f86f..7c2b3a4 100644 --- a/apscheduler/job.py +++ b/apscheduler/job.py @@ -1,11 +1,11 @@ from collections import Iterable, Mapping -from datetime import datetime from uuid import uuid4 import six from apscheduler.triggers.base import BaseTrigger -from apscheduler.util import ref_to_obj, obj_to_ref, datetime_repr, repr_escape, get_callable_name, check_callable_args +from apscheduler.util import ref_to_obj, obj_to_ref, datetime_repr, repr_escape, get_callable_name, check_callable_args, \ + convert_to_datetime class Job(object): @@ -95,8 +95,8 @@ class Job(object): """ Computes the scheduled run times between ``next_run_time`` and ``now`` (inclusive). - :type now: datetime - :rtype: list[datetime] + :type now: datetime.datetime + :rtype: list[datetime.datetime] """ run_times = [] @@ -189,9 +189,7 @@ class Job(object): if 'next_run_time' in changes: value = changes.pop('next_run_time') - if value and not isinstance(value, datetime): - raise TypeError('next_run_time must be either None or a datetime instance') - approved['next_run_time'] = value + approved['next_run_time'] = convert_to_datetime(value, self._scheduler.timezone, 'next_run_time') if changes: raise AttributeError('The following are not modifiable attributes of Job: %s' % ', '.join(changes)) diff --git a/apscheduler/schedulers/base.py b/apscheduler/schedulers/base.py index dbb22b6..fba9dee 100644 --- a/apscheduler/schedulers/base.py +++ b/apscheduler/schedulers/base.py @@ -17,7 +17,7 @@ from apscheduler.jobstores.base import ConflictingIdError, JobLookupError, BaseJ from apscheduler.jobstores.memory import MemoryJobStore from apscheduler.job import Job from apscheduler.triggers.base import BaseTrigger -from apscheduler.util import maybe_ref, asbool, astimezone, timedelta_seconds, undefined, asint +from apscheduler.util import asbool, asint, astimezone, maybe_ref, timedelta_seconds, undefined from apscheduler.events import ( SchedulerEvent, JobEvent, EVENT_SCHEDULER_START, EVENT_SCHEDULER_SHUTDOWN, EVENT_JOBSTORE_ADDED, EVENT_JOBSTORE_REMOVED, EVENT_ALL, EVENT_JOB_MODIFIED, EVENT_JOB_REMOVED, EVENT_JOB_ADDED, EVENT_EXECUTOR_ADDED, @@ -378,7 +378,6 @@ class BaseScheduler(six.with_metaclass(ABCMeta)): :param str|unicode job_id: the identifier of the job :param str|unicode jobstore: alias of the job store that contains the job """ - with self._jobstores_lock: job, jobstore = self._lookup_job(job_id, jobstore) job._modify(**changes) diff --git a/apscheduler/util.py b/apscheduler/util.py index 1ef8646..8504ac0 100644 --- a/apscheduler/util.py +++ b/apscheduler/util.py @@ -118,7 +118,7 @@ def convert_to_datetime(input, tz, arg_name): values = dict(values) datetime_ = datetime(**values) else: - raise TypeError('Unsupported input type: %s' % input.__class__.__name__) + raise TypeError('Unsupported type for %s: %s' % (arg_name, input.__class__.__name__)) if datetime_.tzinfo is not None: return datetime_ diff --git a/tests/conftest.py b/tests/conftest.py index 669ddc7..1b10421 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -79,9 +79,9 @@ def job_defaults(timezone): @pytest.fixture(scope='session') -def create_job(job_defaults): +def create_job(job_defaults, timezone): def create(**kwargs): - kwargs.setdefault('scheduler', Mock(BaseScheduler)) + kwargs.setdefault('scheduler', Mock(BaseScheduler, timezone=timezone)) job_kwargs = job_defaults.copy() job_kwargs.update(kwargs) job_kwargs['trigger'] = BlockingScheduler()._create_trigger(job_kwargs.pop('trigger'), diff --git a/tests/test_executors.py b/tests/test_executors.py index cd686f6..b1daaf9 100644 --- a/tests/test_executors.py +++ b/tests/test_executors.py @@ -4,6 +4,7 @@ import pytest from apscheduler.events import EVENT_JOB_ERROR from apscheduler.executors.base import MaxInstancesReachedError +from apscheduler.schedulers.base import BaseScheduler try: @@ -13,8 +14,8 @@ except ImportError: @pytest.fixture -def mock_scheduler(): - scheduler_ = Mock([]) +def mock_scheduler(timezone): + scheduler_ = Mock(BaseScheduler, timezone=timezone) scheduler_._create_lock = MagicMock() return scheduler_ diff --git a/tests/test_job.py b/tests/test_job.py index 62b615f..dac4509 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -192,7 +192,7 @@ def test_private_modify_bad_next_run_time(job): """Tests that passing a next_run_time of the wrong type raises a TypeError.""" exc = pytest.raises(TypeError, job._modify, next_run_time=1) - assert str(exc.value) == 'next_run_time must be either None or a datetime instance' + assert str(exc.value) == 'Unsupported type for next_run_time: int' def test_private_modify_bad_argument(job): diff --git a/tests/test_schedulers.py b/tests/test_schedulers.py index 2149606..0013231 100644 --- a/tests/test_schedulers.py +++ b/tests/test_schedulers.py @@ -1,5 +1,5 @@ from logging import StreamHandler, getLogger, INFO -from datetime import timedelta +from datetime import datetime, timedelta from threading import Thread from pytz import utc @@ -105,7 +105,8 @@ class DummyJobStore(BaseJobStore): @pytest.fixture -def scheduler(): +def scheduler(monkeypatch, timezone): + monkeypatch.setattr('apscheduler.schedulers.base.get_localzone', MagicMock(return_value=timezone)) return DummyScheduler() @@ -340,17 +341,20 @@ class TestBaseScheduler(object): assert scheduler._listeners == [(func2, EVENT_JOBSTORE_ADDED)] @pytest.mark.parametrize('stopped', [True, False], ids=['stopped=True', 'stopped=False']) - def test_add_job(self, scheduler, stopped): + def test_add_job(self, scheduler, stopped, timezone): func = lambda x, y: None scheduler._stopped = stopped scheduler._real_add_job = MagicMock() - job = scheduler.add_job(func, 'date', [1], {'y': 2}, 'my-id', 'dummy', run_date='2014-06-01 08:41:00') + job = scheduler.add_job(func, 'date', [1], {'y': 2}, 'my-id', 'dummy', + next_run_time=datetime(2014, 5, 23, 10), + run_date='2014-06-01 08:41:00') assert isinstance(job, Job) assert job.id == 'my-id' assert not hasattr(job, 'misfire_grace_time') assert not hasattr(job, 'coalesce') assert not hasattr(job, 'max_instances') + assert job.next_run_time.tzinfo.zone == timezone.zone assert len(scheduler._pending_jobs) == (1 if stopped else 0) assert scheduler._real_add_job.call_count == (0 if stopped else 1) @@ -365,16 +369,16 @@ class TestBaseScheduler(object): run_date='2014-06-01 08:41:00') @pytest.mark.parametrize('pending', [True, False], ids=['pending job', 'scheduled job']) - def test_modify_job(self, scheduler, pending): + def test_modify_job(self, scheduler, pending, timezone): job = MagicMock() scheduler._dispatch_event = MagicMock() scheduler._lookup_job = MagicMock(return_value=(job, None if pending else 'default')) if not pending: jobstore = MagicMock() scheduler._lookup_jobstore = lambda alias: jobstore if alias == 'default' else None - scheduler.modify_job('blah', misfire_grace_time=5, max_instances=2) + scheduler.modify_job('blah', misfire_grace_time=5, max_instances=2, next_run_time=datetime(2014, 10, 17)) - job._modify.assert_called_once_with(misfire_grace_time=5, max_instances=2) + job._modify.assert_called_once_with(misfire_grace_time=5, max_instances=2, next_run_time=datetime(2014, 10, 17)) if not pending: jobstore.update_job.assert_called_once(job) diff --git a/tests/test_util.py b/tests/test_util.py index 5232a5d..bf13476 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -101,8 +101,8 @@ class TestConvertToDatetime(object): assert returned == expected def test_invalid_input_type(self, timezone): - exc = pytest.raises(TypeError, convert_to_datetime, 92123, timezone, None) - assert str(exc.value) == 'Unsupported input type: int' + exc = pytest.raises(TypeError, convert_to_datetime, 92123, timezone, 'foo') + assert str(exc.value) == 'Unsupported type for foo: int' def test_invalid_input_value(self, timezone): exc = pytest.raises(ValueError, convert_to_datetime, '19700-12-1', timezone, None) |