Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-APScheduler for 
openSUSE:Factory checked in at 2021-02-02 14:25:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-APScheduler (Old)
 and      /work/SRC/openSUSE:Factory/.python-APScheduler.new.28504 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-APScheduler"

Tue Feb  2 14:25:28 2021 rev:13 rq:868433 version:3.7.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-APScheduler/python-APScheduler.changes    
2021-01-22 21:52:58.581904591 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-APScheduler.new.28504/python-APScheduler.changes
 2021-02-02 14:25:42.815395725 +0100
@@ -1,0 +2,30 @@
+Mon Feb  1 17:38:33 UTC 2021 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 3.7.0:
+  * Dropped support for Python 3.4
+  * Added PySide2 support (PR by Abdulla Ibrahim)
+  * Pinned ``tzlocal`` to a version compatible with pytz
+  * Ensured that jitter is always non-negative to prevent triggers from firing
+    more often than intended
+  * Changed ``AsyncIOScheduler`` to obtain the event loop in ``start()``
+    instead of ``__init__()``,
+    to prevent situations where the scheduler won't run because it's using a
+    different event loop than then one currently running
+  * Made it possible to create weak references to ``Job`` instances
+  * Made the schedulers explicitly raise a descriptive ``TypeError`` when 
serialization is attempted
+  * Fixed Zookeeper job store using backslashes instead of forward slashes for 
paths
+    on Windows
+  * Fixed deprecation warnings on the MongoDB job store and increased the 
minimum PyMongo
+  * Fixed ``BlockingScheduler`` and ``BackgroundScheduler`` shutdown hanging 
after the user has
+    erroneously tried to start it twice
+  * Fixed memory leak when coroutine jobs raise exceptions
+  * Fixed inability to schedule wrapped functions with extra arguments when 
the wrapped function
+    cannot accept them but the wrapper can (original PR by Egor Malykh)
+  * Fixed potential ``where`` clause error in the SQLAlchemy job store when a 
subclass uses more than
+    one search condition
+  * Fixed a problem where bound methods added as jobs via textual references 
were called with an
+    unwanted extra ``self`` argument (PR by Pengjie Song)
+  * Fixed ``BrokenPoolError`` in ``ProcessPoolExecutor`` so that it will 
automatically replace the
+    broken pool with a fresh instance
+
+-------------------------------------------------------------------

Old:
----
  APScheduler-3.6.3.tar.gz

New:
----
  APScheduler-3.7.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-APScheduler.spec ++++++
--- /var/tmp/diff_new_pack.KoocFM/_old  2021-02-02 14:25:43.531396839 +0100
+++ /var/tmp/diff_new_pack.KoocFM/_new  2021-02-02 14:25:43.531396839 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-APScheduler
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %bcond_without python2
 Name:           python-APScheduler
-Version:        3.6.3
+Version:        3.7.0
 Release:        0
 Summary:        In-process task scheduler with Cron-like capabilities
 License:        MIT
@@ -28,27 +28,27 @@
 BuildRequires:  %{python_module SQLAlchemy >= 0.8}
 BuildRequires:  %{python_module Twisted}
 BuildRequires:  %{python_module gevent}
+BuildRequires:  %{python_module pytest < 6}
 BuildRequires:  %{python_module pytest-asyncio}
 BuildRequires:  %{python_module pytest-cov}
 BuildRequires:  %{python_module pytest-tornado}
-BuildRequires:  %{python_module pytest}
 BuildRequires:  %{python_module pytz}
 BuildRequires:  %{python_module setuptools >= 36.2.7}
 BuildRequires:  %{python_module setuptools_scm >= 1.7.0}
 BuildRequires:  %{python_module six >= 1.4.0}
 BuildRequires:  %{python_module tornado}
-BuildRequires:  %{python_module tzlocal >= 1.2}
+BuildRequires:  %{python_module tzlocal >= 2.0}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
 BuildRequires:  python3-pytest-asyncio
 Requires:       python-pytz
 Requires:       python-six >= 1.4.0
-Requires:       python-tzlocal >= 1.2
+Requires:       python-tzlocal >= 2.0
 Recommends:     python-SQLAlchemy >= 0.8
 Recommends:     python-Twisted
 Recommends:     python-gevent
 Suggests:       python-kazoo
-Suggests:       python-pymongo >= 2.8
+Suggests:       python-pymongo >= 3.0
 Suggests:       python-redis
 Suggests:       python-tornado >= 4.3
 BuildArch:      noarch

++++++ APScheduler-3.6.3.tar.gz -> APScheduler-3.7.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/.travis.yml 
new/APScheduler-3.7.0/.travis.yml
--- old/APScheduler-3.6.3/.travis.yml   2019-11-05 08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/.travis.yml   2021-01-19 15:34:44.000000000 +0100
@@ -17,7 +17,7 @@
     - &test
       stage: test
       env: TOXENV=pypy
-      python: pypy2.7-6.0
+      python: pypy
       before_install: docker-compose up -d
       after_success:
         - pip install coveralls
@@ -25,17 +25,13 @@
 
     - <<: *test
       env: TOXENV=pypy3
-      python: pypy3.5-6.0
+      python: pypy3
 
     - <<: *test
       env: TOXENV=py27
       python: "2.7"
 
     - <<: *test
-      env: TOXENV=py34
-      python: "3.4"
-
-    - <<: *test
       env: TOXENV=py35
       python: "3.5"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/APScheduler.egg-info/PKG-INFO 
new/APScheduler-3.7.0/APScheduler.egg-info/PKG-INFO
--- old/APScheduler-3.6.3/APScheduler.egg-info/PKG-INFO 2019-11-05 
08:51:47.000000000 +0100
+++ new/APScheduler-3.7.0/APScheduler.egg-info/PKG-INFO 2021-01-19 
15:35:14.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: APScheduler
-Version: 3.6.3
+Version: 3.7.0
 Summary: In-process task scheduler with Cron-like capabilities
 Home-page: https://github.com/agronholm/apscheduler
 Author: Alex Gr??nholm
@@ -49,9 +49,16 @@
         * `Tornado <http://www.tornadoweb.org/>`_
         * `Twisted <http://twistedmatrix.com/>`_
         * `Qt <http://qt-project.org/>`_ (using either
-          `PyQt <http://www.riverbankcomputing.com/software/pyqt/intro>`_ or
+          `PyQt <http://www.riverbankcomputing.com/software/pyqt/intro>`_ ,
+          `PySide2 <https://wiki.qt.io/Qt_for_Python>`_ or
           `PySide <http://qt-project.org/wiki/PySide>`_)
         
+        There are third party solutions for integrating APScheduler with other 
frameworks:
+        
+        * `Django <https://github.com/jarekwg/django-apscheduler>`_
+        * `Flask <https://github.com/viniciuschiele/flask-apscheduler>`_
+        
+        
         .. [#f1] The cutoff period for this is also configurable.
         
         
@@ -91,10 +98,10 @@
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4
 Provides-Extra: asyncio
 Provides-Extra: gevent
 Provides-Extra: mongodb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/APScheduler.egg-info/requires.txt 
new/APScheduler-3.7.0/APScheduler.egg-info/requires.txt
--- old/APScheduler-3.6.3/APScheduler.egg-info/requires.txt     2019-11-05 
08:51:47.000000000 +0100
+++ new/APScheduler-3.7.0/APScheduler.egg-info/requires.txt     2021-01-19 
15:35:14.000000000 +0100
@@ -1,11 +1,13 @@
 setuptools>=0.7
 six>=1.4.0
 pytz
-tzlocal>=1.2
+tzlocal~=2.0
+
+[:python_version < "3.5"]
+funcsigs
 
 [:python_version == "2.7"]
 futures
-funcsigs
 
 [asyncio:python_version == "2.7"]
 trollius
@@ -18,7 +20,7 @@
 gevent
 
 [mongodb]
-pymongo>=2.8
+pymongo>=3.0
 
 [redis]
 redis>=3.0
@@ -30,7 +32,7 @@
 sqlalchemy>=0.8
 
 [testing]
-pytest
+pytest<6
 pytest-cov
 pytest-tornado5
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/PKG-INFO 
new/APScheduler-3.7.0/PKG-INFO
--- old/APScheduler-3.6.3/PKG-INFO      2019-11-05 08:51:47.000000000 +0100
+++ new/APScheduler-3.7.0/PKG-INFO      2021-01-19 15:35:15.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: APScheduler
-Version: 3.6.3
+Version: 3.7.0
 Summary: In-process task scheduler with Cron-like capabilities
 Home-page: https://github.com/agronholm/apscheduler
 Author: Alex Gr??nholm
@@ -49,9 +49,16 @@
         * `Tornado <http://www.tornadoweb.org/>`_
         * `Twisted <http://twistedmatrix.com/>`_
         * `Qt <http://qt-project.org/>`_ (using either
-          `PyQt <http://www.riverbankcomputing.com/software/pyqt/intro>`_ or
+          `PyQt <http://www.riverbankcomputing.com/software/pyqt/intro>`_ ,
+          `PySide2 <https://wiki.qt.io/Qt_for_Python>`_ or
           `PySide <http://qt-project.org/wiki/PySide>`_)
         
+        There are third party solutions for integrating APScheduler with other 
frameworks:
+        
+        * `Django <https://github.com/jarekwg/django-apscheduler>`_
+        * `Flask <https://github.com/viniciuschiele/flask-apscheduler>`_
+        
+        
         .. [#f1] The cutoff period for this is also configurable.
         
         
@@ -91,10 +98,10 @@
 Classifier: Programming Language :: Python
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
 Classifier: Programming Language :: Python :: 3.7
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4
 Provides-Extra: asyncio
 Provides-Extra: gevent
 Provides-Extra: mongodb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/README.rst 
new/APScheduler-3.7.0/README.rst
--- old/APScheduler-3.6.3/README.rst    2019-11-05 08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/README.rst    2021-01-19 15:34:44.000000000 +0100
@@ -41,9 +41,16 @@
 * `Tornado <http://www.tornadoweb.org/>`_
 * `Twisted <http://twistedmatrix.com/>`_
 * `Qt <http://qt-project.org/>`_ (using either
-  `PyQt <http://www.riverbankcomputing.com/software/pyqt/intro>`_ or
+  `PyQt <http://www.riverbankcomputing.com/software/pyqt/intro>`_ ,
+  `PySide2 <https://wiki.qt.io/Qt_for_Python>`_ or
   `PySide <http://qt-project.org/wiki/PySide>`_)
 
+There are third party solutions for integrating APScheduler with other 
frameworks:
+
+* `Django <https://github.com/jarekwg/django-apscheduler>`_
+* `Flask <https://github.com/viniciuschiele/flask-apscheduler>`_
+
+
 .. [#f1] The cutoff period for this is also configurable.
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/executors/base_py3.py 
new/APScheduler-3.7.0/apscheduler/executors/base_py3.py
--- old/APScheduler-3.6.3/apscheduler/executors/base_py3.py     2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/executors/base_py3.py     2021-01-19 
15:34:44.000000000 +0100
@@ -1,5 +1,6 @@
 import logging
 import sys
+import traceback
 from datetime import datetime, timedelta
 from traceback import format_tb
 
@@ -33,6 +34,7 @@
             events.append(JobExecutionEvent(EVENT_JOB_ERROR, job.id, 
jobstore_alias, run_time,
                                             exception=exc, 
traceback=formatted_tb))
             logger.exception('Job "%s" raised an exception', job)
+            traceback.clear_frames(tb)
         else:
             events.append(JobExecutionEvent(EVENT_JOB_EXECUTED, job.id, 
jobstore_alias, run_time,
                                             retval=retval))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/executors/pool.py 
new/APScheduler-3.7.0/apscheduler/executors/pool.py
--- old/APScheduler-3.6.3/apscheduler/executors/pool.py 2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/executors/pool.py 2021-01-19 
15:34:44.000000000 +0100
@@ -3,6 +3,11 @@
 
 from apscheduler.executors.base import BaseExecutor, run_job
 
+try:
+    from concurrent.futures.process import BrokenProcessPool
+except ImportError:
+    BrokenProcessPool = None
+
 
 class BasePoolExecutor(BaseExecutor):
     @abstractmethod
@@ -19,7 +24,13 @@
             else:
                 self._run_job_success(job.id, f.result())
 
-        f = self._pool.submit(run_job, job, job._jobstore_alias, run_times, 
self._logger.name)
+        try:
+            f = self._pool.submit(run_job, job, job._jobstore_alias, 
run_times, self._logger.name)
+        except BrokenProcessPool:
+            self._logger.warning('Process pool is broken; replacing pool with 
a fresh instance')
+            self._pool = self._pool.__class__(self._pool._max_workers)
+            f = self._pool.submit(run_job, job, job._jobstore_alias, 
run_times, self._logger.name)
+
         f.add_done_callback(callback)
 
     def shutdown(self, wait=True):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/job.py 
new/APScheduler-3.7.0/apscheduler/job.py
--- old/APScheduler-3.6.3/apscheduler/job.py    2019-11-05 08:51:24.000000000 
+0100
+++ new/APScheduler-3.7.0/apscheduler/job.py    2021-01-19 15:34:44.000000000 
+0100
@@ -28,7 +28,7 @@
     :var trigger: the trigger object that controls the schedule of this job
     :var str executor: the name of the executor that will run this job
     :var int misfire_grace_time: the time (in seconds) how much this job's 
execution is allowed to
-        be late
+        be late (``None`` means "allow the job to run no matter how late it 
is")
     :var int max_instances: the maximum number of concurrently executing 
instances allowed for this
         job
     :var datetime.datetime next_run_time: the next scheduled run time of this 
job
@@ -40,7 +40,7 @@
 
     __slots__ = ('_scheduler', '_jobstore_alias', 'id', 'trigger', 'executor', 
'func', 'func_ref',
                  'args', 'kwargs', 'name', 'misfire_grace_time', 'coalesce', 
'max_instances',
-                 'next_run_time')
+                 'next_run_time', '__weakref__')
 
     def __init__(self, scheduler, id=None, **kwargs):
         super(Job, self).__init__()
@@ -242,8 +242,9 @@
 
         # Instance methods cannot survive serialization as-is, so store the 
"self" argument
         # explicitly
-        if ismethod(self.func) and not isclass(self.func.__self__):
-            args = (self.func.__self__,) + tuple(self.args)
+        func = self.func
+        if ismethod(func) and not isclass(func.__self__) and obj_to_ref(func) 
== self.func_ref:
+            args = (func.__self__,) + tuple(self.args)
         else:
             args = self.args
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/jobstores/mongodb.py 
new/APScheduler-3.7.0/apscheduler/jobstores/mongodb.py
--- old/APScheduler-3.6.3/apscheduler/jobstores/mongodb.py      2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/jobstores/mongodb.py      2021-01-19 
15:34:44.000000000 +0100
@@ -54,7 +54,7 @@
 
     def start(self, scheduler, alias):
         super(MongoDBJobStore, self).start(scheduler, alias)
-        self.collection.ensure_index('next_run_time', sparse=True)
+        self.collection.create_index('next_run_time', sparse=True)
 
     @property
     def connection(self):
@@ -83,7 +83,7 @@
 
     def add_job(self, job):
         try:
-            self.collection.insert({
+            self.collection.insert_one({
                 '_id': job.id,
                 'next_run_time': datetime_to_utc_timestamp(job.next_run_time),
                 'job_state': Binary(pickle.dumps(job.__getstate__(), 
self.pickle_protocol))
@@ -96,13 +96,13 @@
             'next_run_time': datetime_to_utc_timestamp(job.next_run_time),
             'job_state': Binary(pickle.dumps(job.__getstate__(), 
self.pickle_protocol))
         }
-        result = self.collection.update({'_id': job.id}, {'$set': changes})
-        if result and result['n'] == 0:
+        result = self.collection.update_one({'_id': job.id}, {'$set': changes})
+        if result and result.matched_count == 0:
             raise JobLookupError(job.id)
 
     def remove_job(self, job_id):
-        result = self.collection.remove(job_id)
-        if result and result['n'] == 0:
+        result = self.collection.delete_one({'_id': job_id})
+        if result and result.deleted_count == 0:
             raise JobLookupError(job_id)
 
     def remove_all_jobs(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/APScheduler-3.6.3/apscheduler/jobstores/sqlalchemy.py 
new/APScheduler-3.7.0/apscheduler/jobstores/sqlalchemy.py
--- old/APScheduler-3.6.3/apscheduler/jobstores/sqlalchemy.py   2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/jobstores/sqlalchemy.py   2021-01-19 
15:34:44.000000000 +0100
@@ -11,7 +11,7 @@
 
 try:
     from sqlalchemy import (
-        create_engine, Table, Column, MetaData, Unicode, Float, LargeBinary, 
select)
+        create_engine, Table, Column, MetaData, Unicode, Float, LargeBinary, 
select, and_)
     from sqlalchemy.exc import IntegrityError
     from sqlalchemy.sql.expression import null
 except ImportError:  # pragma: nocover
@@ -134,7 +134,7 @@
         jobs = []
         selectable = select([self.jobs_t.c.id, self.jobs_t.c.job_state]).\
             order_by(self.jobs_t.c.next_run_time)
-        selectable = selectable.where(*conditions) if conditions else 
selectable
+        selectable = selectable.where(and_(*conditions)) if conditions else 
selectable
         failed_job_ids = set()
         for row in self.engine.execute(selectable):
             try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/jobstores/zookeeper.py 
new/APScheduler-3.7.0/apscheduler/jobstores/zookeeper.py
--- old/APScheduler-3.6.3/apscheduler/jobstores/zookeeper.py    2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/jobstores/zookeeper.py    2021-01-19 
15:34:44.000000000 +0100
@@ -1,6 +1,5 @@
 from __future__ import absolute_import
 
-import os
 from datetime import datetime
 
 from pytz import utc
@@ -65,7 +64,7 @@
 
     def lookup_job(self, job_id):
         self._ensure_paths()
-        node_path = os.path.join(self.path, job_id)
+        node_path = self.path + "/" + str(job_id)
         try:
             content, _ = self.client.get(node_path)
             doc = pickle.loads(content)
@@ -92,7 +91,7 @@
 
     def add_job(self, job):
         self._ensure_paths()
-        node_path = os.path.join(self.path,  str(job.id))
+        node_path = self.path + "/" + str(job.id)
         value = {
             'next_run_time': datetime_to_utc_timestamp(job.next_run_time),
             'job_state': job.__getstate__()
@@ -105,7 +104,7 @@
 
     def update_job(self, job):
         self._ensure_paths()
-        node_path = os.path.join(self.path,  str(job.id))
+        node_path = self.path + "/" + str(job.id)
         changes = {
             'next_run_time': datetime_to_utc_timestamp(job.next_run_time),
             'job_state': job.__getstate__()
@@ -118,7 +117,7 @@
 
     def remove_job(self, job_id):
         self._ensure_paths()
-        node_path = os.path.join(self.path,  str(job_id))
+        node_path = self.path + "/" + str(job_id)
         try:
             self.client.delete(node_path)
         except NoNodeError:
@@ -151,7 +150,7 @@
         all_ids = self.client.get_children(self.path)
         for node_name in all_ids:
             try:
-                node_path = os.path.join(self.path, node_name)
+                node_path = self.path + "/" + node_name
                 content, _ = self.client.get(node_path)
                 doc = pickle.loads(content)
                 job_def = {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/schedulers/asyncio.py 
new/APScheduler-3.7.0/apscheduler/schedulers/asyncio.py
--- old/APScheduler-3.6.3/apscheduler/schedulers/asyncio.py     2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/schedulers/asyncio.py     2021-01-19 
15:34:44.000000000 +0100
@@ -38,13 +38,19 @@
     _eventloop = None
     _timeout = None
 
+    def start(self, paused=False):
+        if not self._eventloop:
+            self._eventloop = asyncio.get_event_loop()
+
+        super(AsyncIOScheduler, self).start(paused)
+
     @run_in_event_loop
     def shutdown(self, wait=True):
         super(AsyncIOScheduler, self).shutdown(wait)
         self._stop_timer()
 
     def _configure(self, config):
-        self._eventloop = maybe_ref(config.pop('event_loop', None)) or 
asyncio.get_event_loop()
+        self._eventloop = maybe_ref(config.pop('event_loop', None))
         super(AsyncIOScheduler, self)._configure(config)
 
     def _start_timer(self, wait_seconds):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/APScheduler-3.6.3/apscheduler/schedulers/background.py 
new/APScheduler-3.7.0/apscheduler/schedulers/background.py
--- old/APScheduler-3.6.3/apscheduler/schedulers/background.py  2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/schedulers/background.py  2021-01-19 
15:34:44.000000000 +0100
@@ -29,7 +29,9 @@
         super(BackgroundScheduler, self)._configure(config)
 
     def start(self, *args, **kwargs):
-        self._event = Event()
+        if self._event is None or self._event.is_set():
+            self._event = Event()
+
         BaseScheduler.start(self, *args, **kwargs)
         self._thread = Thread(target=self._main_loop, name='APScheduler')
         self._thread.daemon = self._daemon
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/schedulers/base.py 
new/APScheduler-3.7.0/apscheduler/schedulers/base.py
--- old/APScheduler-3.6.3/apscheduler/schedulers/base.py        2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/schedulers/base.py        2021-01-19 
15:34:44.000000000 +0100
@@ -86,6 +86,11 @@
         self.state = STATE_STOPPED
         self.configure(gconfig, **options)
 
+    def __getstate__(self):
+        raise TypeError("Schedulers cannot be serialized. Ensure that you are 
not passing a "
+                        "scheduler instance as an argument to a job, or 
scheduling an instance "
+                        "method where the instance contains a scheduler as an 
attribute.")
+
     def configure(self, gconfig={}, prefix='apscheduler.', **options):
         """
         Reconfigures the scheduler with the given options.
@@ -402,7 +407,7 @@
         :param str|unicode id: explicit identifier for the job (for modifying 
it later)
         :param str|unicode name: textual description of the job
         :param int misfire_grace_time: seconds after the designated runtime 
that the job is still
-            allowed to be run
+            allowed to be run (or ``None`` to allow the job to run no matter 
how late it is)
         :param bool coalesce: run once instead of many times if the scheduler 
determines that the
             job should be run more than once in succession
         :param int max_instances: maximum number of concurrently running 
instances allowed for this
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/schedulers/blocking.py 
new/APScheduler-3.7.0/apscheduler/schedulers/blocking.py
--- old/APScheduler-3.6.3/apscheduler/schedulers/blocking.py    2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/schedulers/blocking.py    2021-01-19 
15:34:44.000000000 +0100
@@ -14,7 +14,9 @@
     _event = None
 
     def start(self, *args, **kwargs):
-        self._event = Event()
+        if self._event is None or self._event.is_set():
+            self._event = Event()
+
         super(BlockingScheduler, self).start(*args, **kwargs)
         self._main_loop()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/schedulers/qt.py 
new/APScheduler-3.7.0/apscheduler/schedulers/qt.py
--- old/APScheduler-3.6.3/apscheduler/schedulers/qt.py  2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/schedulers/qt.py  2021-01-19 
15:34:44.000000000 +0100
@@ -9,9 +9,13 @@
         from PyQt4.QtCore import QObject, QTimer
     except ImportError:
         try:
-            from PySide.QtCore import QObject, QTimer  # noqa
+            from PySide2.QtCore import QObject, QTimer  # noqa
         except ImportError:
-            raise ImportError('QtScheduler requires either PyQt5, PyQt4 or 
PySide installed')
+            try:
+                from PySide.QtCore import QObject, QTimer  # noqa
+            except ImportError:
+                raise ImportError('QtScheduler requires either PyQt5, PyQt4, 
PySide2 '
+                                  'or PySide installed')
 
 
 class QtScheduler(BaseScheduler):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/triggers/base.py 
new/APScheduler-3.7.0/apscheduler/triggers/base.py
--- old/APScheduler-3.6.3/apscheduler/triggers/base.py  2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/triggers/base.py  2021-01-19 
15:34:44.000000000 +0100
@@ -22,27 +22,16 @@
 
     def _apply_jitter(self, next_fire_time, jitter, now):
         """
-        Randomize ``next_fire_time`` by adding or subtracting a random value 
(the jitter). If the
-        resulting datetime is in the past, returns the initial 
``next_fire_time`` without jitter.
-
-        ``next_fire_time - jitter <= result <= next_fire_time + jitter``
+        Randomize ``next_fire_time`` by adding a random value (the jitter).
 
         :param datetime.datetime|None next_fire_time: next fire time without 
jitter applied. If
             ``None``, returns ``None``.
-        :param int|None jitter: maximum number of seconds to add or subtract to
-            ``next_fire_time``. If ``None`` or ``0``, returns 
``next_fire_time``
+        :param int|None jitter: maximum number of seconds to add to 
``next_fire_time``
+            (if ``None`` or ``0``, returns ``next_fire_time``)
         :param datetime.datetime now: current datetime
         :return datetime.datetime|None: next fire time with a jitter.
         """
         if next_fire_time is None or not jitter:
             return next_fire_time
 
-        next_fire_time_with_jitter = next_fire_time + timedelta(
-                seconds=random.uniform(-jitter, jitter))
-
-        if next_fire_time_with_jitter < now:
-            # Next fire time with jitter is in the past.
-            # Ignore jitter to avoid false misfire.
-            return next_fire_time
-
-        return next_fire_time_with_jitter
+        return next_fire_time + timedelta(seconds=random.uniform(0, jitter))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/triggers/combining.py 
new/APScheduler-3.7.0/apscheduler/triggers/combining.py
--- old/APScheduler-3.6.3/apscheduler/triggers/combining.py     2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/triggers/combining.py     2021-01-19 
15:34:44.000000000 +0100
@@ -45,7 +45,7 @@
     Trigger alias: ``and``
 
     :param list triggers: triggers to combine
-    :param int|None jitter: advance or delay the job execution by ``jitter`` 
seconds at most.
+    :param int|None jitter: delay the job execution by ``jitter`` seconds at 
most
     """
 
     __slots__ = ()
@@ -73,7 +73,7 @@
     Trigger alias: ``or``
 
     :param list triggers: triggers to combine
-    :param int|None jitter: advance or delay the job execution by ``jitter`` 
seconds at most.
+    :param int|None jitter: delay the job execution by ``jitter`` seconds at 
most
 
     .. note:: Triggers that depends on the previous fire time, such as the 
interval trigger, may
         seem to behave strangely since they are always passed the previous 
fire time produced by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/APScheduler-3.6.3/apscheduler/triggers/cron/__init__.py 
new/APScheduler-3.7.0/apscheduler/triggers/cron/__init__.py
--- old/APScheduler-3.6.3/apscheduler/triggers/cron/__init__.py 2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/triggers/cron/__init__.py 2021-01-19 
15:34:44.000000000 +0100
@@ -16,7 +16,7 @@
 
     :param int|str year: 4-digit year
     :param int|str month: month (1-12)
-    :param int|str day: day of the (1-31)
+    :param int|str day: day of month (1-31)
     :param int|str week: ISO week (1-53)
     :param int|str day_of_week: number or name of weekday (0-6 or 
mon,tue,wed,thu,fri,sat,sun)
     :param int|str hour: hour (0-23)
@@ -26,7 +26,7 @@
     :param datetime|str end_date: latest possible date/time to trigger on 
(inclusive)
     :param datetime.tzinfo|str timezone: time zone to use for the date/time 
calculations (defaults
         to scheduler timezone)
-    :param int|None jitter: advance or delay the job execution by ``jitter`` 
seconds at most.
+    :param int|None jitter: delay the job execution by ``jitter`` seconds at 
most
 
     .. note:: The first weekday is always **monday**.
     """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/triggers/interval.py 
new/APScheduler-3.7.0/apscheduler/triggers/interval.py
--- old/APScheduler-3.6.3/apscheduler/triggers/interval.py      2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/apscheduler/triggers/interval.py      2021-01-19 
15:34:44.000000000 +0100
@@ -20,7 +20,7 @@
     :param datetime|str start_date: starting point for the interval calculation
     :param datetime|str end_date: latest possible date/time to trigger on
     :param datetime.tzinfo|str timezone: time zone to use for the date/time 
calculations
-    :param int|None jitter: advance or delay the job execution by ``jitter`` 
seconds at most.
+    :param int|None jitter: delay the job execution by ``jitter`` seconds at 
most
     """
 
     __slots__ = 'timezone', 'start_date', 'end_date', 'interval', 
'interval_length', 'jitter'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/apscheduler/util.py 
new/APScheduler-3.7.0/apscheduler/util.py
--- old/APScheduler-3.6.3/apscheduler/util.py   2019-11-05 08:51:24.000000000 
+0100
+++ new/APScheduler-3.7.0/apscheduler/util.py   2021-01-19 15:34:44.000000000 
+0100
@@ -7,6 +7,7 @@
 from functools import partial
 from inspect import isclass, ismethod
 import re
+import sys
 
 from pytz import timezone, utc, FixedOffset
 import six
@@ -352,7 +353,10 @@
     has_varargs = has_var_kwargs = False
 
     try:
-        sig = signature(func)
+        if sys.version_info >= (3, 5):
+            sig = signature(func, follow_wrapped=False)
+        else:
+            sig = signature(func)
     except ValueError:
         # signature() doesn't work against every kind of callable
         return
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/docs/modules/schedulers/qt.rst 
new/APScheduler-3.7.0/docs/modules/schedulers/qt.rst
--- old/APScheduler-3.6.3/docs/modules/schedulers/qt.rst        2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/docs/modules/schedulers/qt.rst        2021-01-19 
15:34:44.000000000 +0100
@@ -13,7 +13,7 @@
 Introduction
 ------------
 
-QtScheduler lets you integrate APScheduler with your `PySide 
<https://en.wikipedia.org/wiki/PySide>` or
+QtScheduler lets you integrate APScheduler with your `PySide2 
<https://wiki.qt.io/Qt_for_Python>`, `PySide 
<https://en.wikipedia.org/wiki/PySide>` or
 `PyQt <http://www.riverbankcomputing.co.uk/software/pyqt/intro>`_ application.
 
 .. list-table::
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/APScheduler-3.6.3/docs/modules/triggers/combining.rst 
new/APScheduler-3.7.0/docs/modules/triggers/combining.rst
--- old/APScheduler-3.6.3/docs/modules/triggers/combining.rst   2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/docs/modules/triggers/combining.rst   2021-01-19 
15:34:44.000000000 +0100
@@ -28,8 +28,8 @@
                           CronTrigger(day_of_week='sat,sun')])
     scheduler.add_job(job_function, trigger)
 
-Run ``job_function`` every Monday at 2pm and every Tuesday at 3pm::
+Run ``job_function`` every Monday at 2am and every Tuesday at 3pm::
 
     trigger = OrTrigger([CronTrigger(day_of_week='mon', hour=2),
-                         CronTrigger(day_of_week='tue', hour=3)])
+                         CronTrigger(day_of_week='tue', hour=15)])
     scheduler.add_job(job_function, trigger)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/docs/modules/triggers/interval.rst 
new/APScheduler-3.7.0/docs/modules/triggers/interval.rst
--- old/APScheduler-3.6.3/docs/modules/triggers/interval.rst    2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/docs/modules/triggers/interval.rst    2021-01-19 
15:34:44.000000000 +0100
@@ -54,8 +54,7 @@
 
 The :meth:`~apscheduler.schedulers.base.BaseScheduler.scheduled_job` decorator 
works nicely too::
 
-    from apscheduler.scheduler import BlockingScheduler
-
+    
     @sched.scheduled_job('interval', id='my_job_id', hours=2)
     def job_function():
         print("Hello World")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/docs/versionhistory.rst 
new/APScheduler-3.7.0/docs/versionhistory.rst
--- old/APScheduler-3.6.3/docs/versionhistory.rst       2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/docs/versionhistory.rst       2021-01-19 
15:34:44.000000000 +0100
@@ -4,6 +4,36 @@
 To find out how to migrate your application from a previous version of
 APScheduler, see the :doc:`migration section <migration>`.
 
+3.7.0
+-----
+
+* Dropped support for Python 3.4
+* Added PySide2 support (PR by Abdulla Ibrahim)
+* Pinned ``tzlocal`` to a version compatible with pytz
+* Ensured that jitter is always non-negative to prevent triggers from firing 
more often than
+  intended
+* Changed ``AsyncIOScheduler`` to obtain the event loop in ``start()`` instead 
of ``__init__()``,
+  to prevent situations where the scheduler won't run because it's using a 
different event loop
+  than then one currently running
+* Made it possible to create weak references to ``Job`` instances
+* Made the schedulers explicitly raise a descriptive ``TypeError`` when 
serialization is attempted
+* Fixed Zookeeper job store using backslashes instead of forward slashes for 
paths
+  on Windows (PR by Laurel-rao)
+* Fixed deprecation warnings on the MongoDB job store and increased the 
minimum PyMongo
+  version to 3.0
+* Fixed ``BlockingScheduler`` and ``BackgroundScheduler`` shutdown hanging 
after the user has
+  erroneously tried to start it twice
+* Fixed memory leak when coroutine jobs raise exceptions (due to reference 
cycles in tracebacks)
+* Fixed inability to schedule wrapped functions with extra arguments when the 
wrapped function
+  cannot accept them but the wrapper can (original PR by Egor Malykh)
+* Fixed potential ``where`` clause error in the SQLAlchemy job store when a 
subclass uses more than
+  one search condition
+* Fixed a problem where bound methods added as jobs via textual references 
were called with an
+  unwanted extra ``self`` argument (PR by Pengjie Song)
+* Fixed ``BrokenPoolError`` in ``ProcessPoolExecutor`` so that it will 
automatically replace the
+  broken pool with a fresh instance
+
+
 3.6.3
 -----
 
@@ -343,7 +373,7 @@
 * Added optional job execution coalescing for situations where several
   executions of the job are due
 
-* Added an option to limit the maximum number of concurrenctly executing
+* Added an option to limit the maximum number of concurrently executing
   instances of the job
 
 * Allowed configuration of misfire grace times on a per-job basis
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/examples/schedulers/qt.py 
new/APScheduler-3.7.0/examples/schedulers/qt.py
--- old/APScheduler-3.6.3/examples/schedulers/qt.py     2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/examples/schedulers/qt.py     2021-01-19 
15:34:44.000000000 +0100
@@ -15,7 +15,10 @@
     try:
         from PyQt4.QtGui import QApplication, QLabel
     except ImportError:
-        from PySide.QtGui import QApplication, QLabel
+        try:
+            from PySide2.QtWidgets import QApplication, QLabel
+        except ImportError:
+            from PySide.QtGui import QApplication, QLabel
 
 
 def tick():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/setup.py 
new/APScheduler-3.7.0/setup.py
--- old/APScheduler-3.6.3/setup.py      2019-11-05 08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/setup.py      2021-01-19 15:34:44.000000000 +0100
@@ -26,7 +26,6 @@
         'Programming Language :: Python',
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.4',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7'
@@ -34,6 +33,7 @@
     keywords='scheduling cron',
     license='MIT',
     packages=find_packages(exclude=['tests']),
+    python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4',
     setup_requires=[
         'setuptools_scm'
     ],
@@ -41,13 +41,14 @@
         'setuptools >= 0.7',
         'six >= 1.4.0',
         'pytz',
-        'tzlocal >= 1.2',
+        'tzlocal ~= 2.0',
     ],
     extras_require={
-        ':python_version == "2.7"': ['futures', 'funcsigs'],
+        ':python_version == "2.7"': ['futures'],
+        ':python_version < "3.5"': ['funcsigs'],
         'asyncio:python_version == "2.7"': ['trollius'],
         'gevent': ['gevent'],
-        'mongodb': ['pymongo >= 2.8'],
+        'mongodb': ['pymongo >= 3.0'],
         'redis': ['redis >= 3.0'],
         'rethinkdb': ['rethinkdb >= 2.4.0'],
         'sqlalchemy': ['sqlalchemy >= 0.8'],
@@ -55,7 +56,7 @@
         'twisted': ['twisted'],
         'zookeeper': ['kazoo'],
         'testing': [
-            'pytest',
+            'pytest < 6',
             'pytest-cov',
             'pytest-tornado5'
         ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/tests/test_executors.py 
new/APScheduler-3.7.0/tests/test_executors.py
--- old/APScheduler-3.6.3/tests/test_executors.py       2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/tests/test_executors.py       2021-01-19 
15:34:44.000000000 +0100
@@ -2,15 +2,20 @@
 from threading import Event
 from types import TracebackType
 import gc
+import os
+import signal
 import time
 
 import pytest
 from pytz import UTC
 
-from apscheduler.events import EVENT_JOB_ERROR, EVENT_JOB_MISSED, 
EVENT_JOB_EXECUTED
+from apscheduler.events import EVENT_JOB_ERROR, EVENT_JOB_EXECUTED, 
EVENT_JOB_MISSED
 from apscheduler.executors.base import MaxInstancesReachedError, run_job
+from apscheduler.executors.pool import ProcessPoolExecutor
 from apscheduler.job import Job
+from apscheduler.schedulers.background import BackgroundScheduler
 from apscheduler.schedulers.base import BaseScheduler
+from tests.conftest import minpython
 
 try:
     from unittest.mock import Mock, MagicMock, patch
@@ -144,3 +149,31 @@
 
     foos = [x for x in gc.get_objects() if type(x) is FooBar]
     assert len(foos) == 0
+
+
+@minpython(3, 3)
+def test_broken_pool():
+    def listener(evt):
+        pid[0] = evt.retval
+        event.set()
+
+    pid = [None]
+    event = Event()
+    scheduler = BackgroundScheduler(executors={'default': 
ProcessPoolExecutor(1)})
+    scheduler.add_listener(listener, EVENT_JOB_EXECUTED)
+    scheduler.add_job(os.getpid, 'date', run_date=datetime.now(UTC))
+    scheduler.start()
+
+    event.wait(3)
+    killed_pid = pid[0]
+    os.kill(pid[0], signal.SIGTERM)
+    try:
+        os.waitpid(pid[0], 0)
+    except OSError:
+        pass
+
+    event.clear()
+    scheduler.add_job(os.getpid, 'date', run_date=datetime.now(UTC))
+    event.wait(3)
+    assert pid[0] != killed_pid
+    scheduler.shutdown(True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/tests/test_executors_py35.py 
new/APScheduler-3.7.0/tests/test_executors_py35.py
--- old/APScheduler-3.6.3/tests/test_executors_py35.py  2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/tests/test_executors_py35.py  2021-01-19 
15:34:44.000000000 +0100
@@ -1,13 +1,18 @@
 """Contains test functions using Python 3.3+ syntax."""
+import gc
 from asyncio import CancelledError
 from datetime import datetime
+from unittest.mock import Mock, patch
 
 import pytest
+from pytz import utc
+
 from apscheduler.executors.asyncio import AsyncIOExecutor
+from apscheduler.executors.base_py3 import run_coroutine_job
 from apscheduler.executors.tornado import TornadoExecutor
+from apscheduler.job import Job
 from apscheduler.schedulers.asyncio import AsyncIOScheduler
 from apscheduler.schedulers.tornado import TornadoScheduler
-from pytz import utc
 
 
 @pytest.fixture
@@ -100,3 +105,21 @@
     asyncio_executor.shutdown()
     with pytest.raises(CancelledError):
         await futures.pop()
+
+
+@pytest.mark.asyncio
+async def test_run_job_memory_leak():
+    class FooBar:
+        pass
+
+    async def func():
+        foo = FooBar()  # noqa: F841
+        raise Exception('dummy')
+
+    fake_job = Mock(Job, func=func, args=(), kwargs={}, misfire_grace_time=1)
+    with patch('logging.getLogger'):
+        for _ in range(5):
+            await run_coroutine_job(fake_job, 'foo', [datetime.now(utc)], 
__name__)
+
+    foos = [x for x in gc.get_objects() if type(x) is FooBar]
+    assert len(foos) == 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/tests/test_job.py 
new/APScheduler-3.7.0/tests/test_job.py
--- old/APScheduler-3.6.3/tests/test_job.py     2019-11-05 08:51:24.000000000 
+0100
+++ new/APScheduler-3.7.0/tests/test_job.py     2021-01-19 15:34:44.000000000 
+0100
@@ -1,4 +1,6 @@
 # coding: utf-8
+import gc
+import weakref
 from datetime import datetime, timedelta
 from functools import partial
 
@@ -64,6 +66,14 @@
     job._scheduler.remove_job.assert_called_once_with(job.id, None)
 
 
+def test_weakref(create_job):
+    job = create_job(func=dummyfunc)
+    ref = weakref.ref(job)
+    del job
+    gc.collect()
+    assert ref() is None
+
+
 def test_pending(job):
     """
     Tests that the "pending" property return True when _jobstore_alias is a 
string, ``False``
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/tests/test_jobstores.py 
new/APScheduler-3.7.0/tests/test_jobstores.py
--- old/APScheduler-3.6.3/tests/test_jobstores.py       2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/tests/test_jobstores.py       2021-01-19 
15:34:44.000000000 +0100
@@ -27,6 +27,9 @@
         return a + b
 
 
+dummy_instance = DummyClass()
+
+
 @pytest.fixture
 def memjobstore():
     yield MemoryJobStore()
@@ -112,18 +115,32 @@
     return create
 
 
-def test_add_instance_method_job(jobstore, create_add_job):
+def test_add_callable_instance_method_job(jobstore, create_add_job):
     instance = DummyClass()
     initial_job = create_add_job(jobstore, instance.dummy_method, kwargs={'a': 
1, 'b': 2})
     job = jobstore.lookup_job(initial_job.id)
     assert job.func(*job.args, **job.kwargs) == 3
 
 
-def test_add_class_method_job(jobstore, create_add_job):
+def test_add_callable_class_method_job(jobstore, create_add_job):
     initial_job = create_add_job(jobstore, DummyClass.dummy_classmethod, 
kwargs={'a': 1, 'b': 2})
     job = jobstore.lookup_job(initial_job.id)
     assert job.func(*job.args, **job.kwargs) == 3
 
+
+def test_add_textual_instance_method_job(jobstore, create_add_job):
+    initial_job = create_add_job(jobstore, 
'tests.test_jobstores:dummy_instance.dummy_method',
+                                 kwargs={'a': 1, 'b': 2})
+    job = jobstore.lookup_job(initial_job.id)
+    assert job.func(*job.args, **job.kwargs) == 3
+
+
+def test_add_textual_class_method_job(jobstore, create_add_job):
+    initial_job = create_add_job(jobstore, 
'tests.test_jobstores:DummyClass.dummy_classmethod',
+                                 kwargs={'a': 1, 'b': 2})
+    job = jobstore.lookup_job(initial_job.id)
+    assert job.func(*job.args, **job.kwargs) == 3
+
 
 def test_lookup_job(jobstore, create_add_job):
     initial_job = create_add_job(jobstore)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/tests/test_schedulers.py 
new/APScheduler-3.7.0/tests/test_schedulers.py
--- old/APScheduler-3.6.3/tests/test_schedulers.py      2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/tests/test_schedulers.py      2021-01-19 
15:34:44.000000000 +0100
@@ -1,4 +1,5 @@
 import logging
+import pickle
 from datetime import datetime, timedelta
 from threading import Thread
 
@@ -772,6 +773,9 @@
         assert len(scheduler_events) == 1
         assert scheduler_events[0].scheduled_run_times == 
[freeze_time.get(scheduler.timezone)]
 
+    def test_serialize_scheduler(self, scheduler):
+        pytest.raises(TypeError, pickle.dumps, scheduler).match('Schedulers 
cannot be serialized')
+
 
 class TestProcessJobs(object):
     @pytest.fixture
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/tests/test_triggers.py 
new/APScheduler-3.7.0/tests/test_triggers.py
--- old/APScheduler-3.6.3/tests/test_triggers.py        2019-11-05 
08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/tests/test_triggers.py        2021-01-19 
15:34:44.000000000 +0100
@@ -50,16 +50,6 @@
         trigger = _DummyTriggerWithJitter(dt, 60)
         assert trigger.get_next_fire_time(None, now) == expected_dt
 
-    def test_jitter_in_past_but_initial_date_in_future(self, monkeypatch):
-        monkeypatch.setattr(random, 'uniform', lambda a, b: -30.)
-
-        now = datetime(2017, 5, 25, 13, 40, 44)
-        dt = datetime(2017, 5, 25, 13, 40, 47)
-        expected_dt = dt
-
-        trigger = _DummyTriggerWithJitter(dt, 60)
-        assert trigger.get_next_fire_time(None, now) == expected_dt
-
     def test_jitter_in_future_but_initial_date_in_past(self, monkeypatch):
         monkeypatch.setattr(random, 'uniform', lambda a, b: 30.)
 
@@ -69,16 +59,6 @@
 
         trigger = _DummyTriggerWithJitter(dt, 60)
         assert trigger.get_next_fire_time(None, now) == expected_dt
-
-    def test_jitter_misfire(self, monkeypatch):
-        monkeypatch.setattr(random, 'uniform', lambda a, b: -30.)
-
-        now = datetime(2017, 5, 25, 13, 40, 44)
-        dt = datetime(2017, 5, 25, 13, 40, 40)
-        expected_dt = dt
-
-        trigger = _DummyTriggerWithJitter(dt, 60)
-        assert trigger.get_next_fire_time(None, now) == expected_dt
 
     def test_jitter_is_now(self, monkeypatch):
         monkeypatch.setattr(random, 'uniform', lambda a, b: 4.)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/tests/test_util.py 
new/APScheduler-3.7.0/tests/test_util.py
--- old/APScheduler-3.6.3/tests/test_util.py    2019-11-05 08:51:24.000000000 
+0100
+++ new/APScheduler-3.7.0/tests/test_util.py    2021-01-19 15:34:44.000000000 
+0100
@@ -1,20 +1,22 @@
 # coding: utf-8
 import platform
+import sys
 from datetime import date, datetime, timedelta, tzinfo
-from functools import partial
+from functools import partial, wraps
 from types import ModuleType
 
 import pytest
 import pytz
 import six
-import sys
 
 from apscheduler.job import Job
-from apscheduler.util import (
-    asint, asbool, astimezone, convert_to_datetime, datetime_to_utc_timestamp,
-    utc_timestamp_to_datetime, timedelta_seconds, datetime_ceil, 
get_callable_name, obj_to_ref,
-    ref_to_obj, maybe_ref, check_callable_args, datetime_repr, repr_escape)
-from tests.conftest import minpython, maxpython
+from apscheduler.util import (asbool, asint, astimezone, check_callable_args,
+                              convert_to_datetime, datetime_ceil,
+                              datetime_repr, datetime_to_utc_timestamp,
+                              get_callable_name, maybe_ref, obj_to_ref,
+                              ref_to_obj, repr_escape, timedelta_seconds,
+                              utc_timestamp_to_datetime)
+from tests.conftest import maxpython, minpython
 
 try:
     from unittest.mock import Mock
@@ -351,3 +353,17 @@
         exc = pytest.raises(ValueError, check_callable_args, func, [1], {})
         assert str(exc.value) == ('The following keyword-only arguments have 
not been supplied in '
                                   'kwargs: y')
+
+    def test_wrapped_func(self):
+        """
+        Test that a wrapped function can be scheduled even if it cannot accept 
the arguments given
+        in add_job() if the wrapper can.
+        """
+        def func():
+            pass
+
+        @wraps(func)
+        def wrapper(arg):
+            func()
+
+        check_callable_args(wrapper, (1,), {})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.6.3/tox.ini 
new/APScheduler-3.7.0/tox.ini
--- old/APScheduler-3.6.3/tox.ini       2019-11-05 08:51:24.000000000 +0100
+++ new/APScheduler-3.7.0/tox.ini       2021-01-19 15:34:44.000000000 +0100
@@ -1,8 +1,9 @@
 [tox]
-envlist = py27, py34, py35, py36, py37, pypy, pypy3, flake8
+envlist = py27, py35, py36, py37, pypy, pypy3, flake8
 skip_missing_interpreters = true
 
 [testenv]
+download = true
 commands = pytest {posargs}
 extras = testing
     asyncio

Reply via email to