Skip to content

Commit

Permalink
Added a decorator (#148)
Browse files Browse the repository at this point in the history
* Added 'repeat' decorator and written a test. Increased the version by 0.0.1.

* Removed the type of the given job for python 2.* compatibility.

* Added some newlines to comply with FLAKE8

* Added import for 'repeat' in the code example

* Added decorator docs and the ability to pass arguments to the job through the decorator

* Fix FLAKE8

* Added rhagenaars to authors

* Apply suggestions from code review
  • Loading branch information
RHagenaars committed Feb 2, 2021
1 parent cc994b3 commit 170b63a
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 3 deletions.
3 changes: 2 additions & 1 deletion AUTHORS.rst
Expand Up @@ -25,4 +25,5 @@ Thanks to all the wonderful folks who have contributed to schedule over the year
- chankeypathak <https://github.com/chankeypathak>
- vubon <https://github.com/vubon>
- gaguirregabiria <https://github.com/gaguirregabiria>
- Skenvy <https://github.com/skenvy>
- rhagenaars <https://github.com/RHagenaars>
- Skenvy <https://github.com/skenvy>
29 changes: 28 additions & 1 deletion docs/examples.rst
Expand Up @@ -43,10 +43,30 @@ Run a job every x minute
schedule.every().minute.at(":17").do(job)
while True:
# run_pending
schedule.run_pending()
time.sleep(1)
Use a decorator to schedule a job
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Use the ``@repeat`` to schedule a function.
Pass it an interval using the same syntax as above while omitting the ``.do()``.

.. code-block:: python
from schedule import every, repeat, run_pending
import time
@repeat(every(10).minutes)
def job():
print("I am a scheduled job")
while True:
run_pending()
time.sleep(1)
The ``@repeat`` decorator does not work on non-static class methods.

Pass arguments to a job
~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -62,6 +82,13 @@ Pass arguments to a job
schedule.every(2).seconds.do(greet, name='Alice')
schedule.every(4).seconds.do(greet, name='Bob')
from schedule import every, repeat
@repeat(every().second, "World")
@repeat(every().day, "Mars")
def hello(planet):
print("Hello", planet)
Cancel a job
~~~~~~~~~~~~
Expand Down
15 changes: 15 additions & 0 deletions schedule/__init__.py
Expand Up @@ -645,3 +645,18 @@ def idle_seconds():
:data:`default scheduler instance <default_scheduler>`.
"""
return default_scheduler.idle_seconds


def repeat(job, *args, **kwargs):
"""
Decorator to schedule a new periodic job.
Any additional arguments are passed on to the decorated function
when the job runs.
:param job: a :class:`Jobs <Job>`
"""
def _schedule_decorator(decorated_function):
job.do(decorated_function, *args, **kwargs)
return decorated_function
return _schedule_decorator
40 changes: 39 additions & 1 deletion test_schedule.py
Expand Up @@ -9,7 +9,8 @@
# pylint: disable-msg=R0201,C0111,E0102,R0904,R0901

import schedule
from schedule import every, ScheduleError, ScheduleValueError, IntervalError
from schedule import every, repeat, \
ScheduleError, ScheduleValueError, IntervalError


def make_mock_job(name=None):
Expand Down Expand Up @@ -357,6 +358,43 @@ def test_run_all(self):
schedule.run_all()
assert mock_job.call_count == 3

def test_run_all_with_decorator(self):
mock_job = make_mock_job()

@repeat(every().minute)
def job1():
mock_job()

@repeat(every().hour)
def job2():
mock_job()

@repeat(every().day.at('11:00'))
def job3():
mock_job()
schedule.run_all()
assert mock_job.call_count == 3

def test_run_all_with_decorator_args(self):
mock_job = make_mock_job()

@repeat(every().minute, 1, 2, 'three', foo=23, bar={})
def job(*args, **kwargs):
mock_job(*args, **kwargs)

schedule.run_all()
mock_job.assert_called_once_with(1, 2, 'three', foo=23, bar={})

def test_run_all_with_decorator_defaultargs(self):
mock_job = make_mock_job()

@repeat(every().minute)
def job(nothing=None):
mock_job(nothing)

schedule.run_all()
mock_job.assert_called_once_with(None)

def test_job_func_args_are_passed_on(self):
mock_job = make_mock_job()
every().second.do(mock_job, 1, 2, 'three', foo=23, bar={})
Expand Down

0 comments on commit 170b63a

Please sign in to comment.