Hello community, here is the log from the commit of package python-APScheduler for openSUSE:Factory checked in at 2019-03-20 13:20:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-APScheduler (Old) and /work/SRC/openSUSE:Factory/.python-APScheduler.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-APScheduler" Wed Mar 20 13:20:37 2019 rev:6 rq:686446 version:3.6.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-APScheduler/python-APScheduler.changes 2019-02-04 14:25:31.113050733 +0100 +++ /work/SRC/openSUSE:Factory/.python-APScheduler.new.28833/python-APScheduler.changes 2019-03-20 13:20:42.609323176 +0100 @@ -1,0 +2,11 @@ +Tue Mar 19 14:30:17 UTC 2019 - Tomáš Chvátal <[email protected]> + +- Update to 3.6.0: + * Adapted RedisJobStore to v3.0 of the redis library + * Adapted RethinkDBJobStore to v2.4 of the rethink library + * Fixed DeprecationWarnings about collections.abc on Python 3.7 (PR by Roman Levin) +- Remove merged patches: + * fix-tests.patch + * 0001-Correct-update_job-to-raise-with-job-id.patch + +------------------------------------------------------------------- Old: ---- 0001-Correct-update_job-to-raise-with-job-id.patch APScheduler-3.5.3.tar.gz fix-tests.patch New: ---- APScheduler-3.6.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-APScheduler.spec ++++++ --- /var/tmp/diff_new_pack.k6grT2/_old 2019-03-20 13:20:43.937322853 +0100 +++ /var/tmp/diff_new_pack.k6grT2/_new 2019-03-20 13:20:43.957322848 +0100 @@ -18,17 +18,13 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-APScheduler -Version: 3.5.3 +Version: 3.6.0 Release: 0 Summary: In-process task scheduler with Cron-like capabilities License: MIT Group: Development/Languages/Python -URL: http://pypi.python.org/pypi/APScheduler/ +URL: https://github.com/agronholm/apscheduler Source: https://files.pythonhosted.org/packages/source/A/APScheduler/APScheduler-%{version}.tar.gz -# PATCH-FIX-UPSTREAM fix-tests.patch -- Fix python 3.7 incompatibilities -Patch0: fix-tests.patch -# PATCH-FIX-UPSTREAM 0001-Correct-update_job-to-raise-with-job-id.patch -Patch1: 0001-Correct-update_job-to-raise-with-job-id.patch BuildRequires: %{python_module SQLAlchemy >= 0.8} BuildRequires: %{python_module Twisted} BuildRequires: %{python_module gevent} @@ -88,8 +84,6 @@ %prep %setup -q -n APScheduler-%{version} -%patch0 -p1 -%patch1 -p1 # we don't want the tweaked pytest config options rm setup.cfg ++++++ APScheduler-3.5.3.tar.gz -> APScheduler-3.6.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/.gitignore new/APScheduler-3.6.0/.gitignore --- old/APScheduler-3.5.3/.gitignore 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/.gitignore 2018-12-15 20:44:43.000000000 +0100 @@ -3,7 +3,9 @@ .idea/ .coverage .cache/ +.pytest_cache/ .tox/ +.eggs/ *.egg-info/ *.pyc dist/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/.readthedocs.yml new/APScheduler-3.6.0/.readthedocs.yml --- old/APScheduler-3.5.3/.readthedocs.yml 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/.readthedocs.yml 2018-12-06 00:53:49.000000000 +0100 @@ -11,3 +11,4 @@ - tornado - twisted - zookeeper + - doc diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/.travis.yml new/APScheduler-3.6.0/.travis.yml --- old/APScheduler-3.5.3/.travis.yml 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/.travis.yml 2018-12-16 10:38:28.000000000 +0100 @@ -1,46 +1,56 @@ -sudo: required +dist: xenial language: python +cache: pip +python: "3.6" stages: + - name: static analysis - name: test - name: deploy to pypi if: type = push AND tag =~ ^v\d+\.\d+\.\d+ jobs: include: - - env: TOXENV=pypy - python: pypy + - stage: static analysis + env: TOXENV=flake8 + before_install: skip + after_success: skip + + - stage: test + env: TOXENV=pypy + python: pypy2.7-6.0 after_success: skip - - env: TOXENV=pypy3 - python: pypy3 + - stage: test + env: TOXENV=pypy3 + python: pypy3.5-6.0 after_success: skip - - env: TOXENV=py27 + - stage: test + env: TOXENV=py27 python: "2.7" - - env: TOXENV=py34 + - stage: test + env: TOXENV=py34 python: "3.4" - - env: TOXENV=py35 + - stage: test + env: TOXENV=py35 python: "3.5" - - env: TOXENV=py36 + - stage: test + env: TOXENV=py36 python: "3.6" - - env: TOXENV=flake8 - sudo: false - python: "3.5" - before_install: skip - after_success: skip + - stage: test + env: TOXENV=py37 + python: "3.7" - - stage: deploy to PyPI - sudo: false - python: "3.5" + - stage: deploy to pypi before_install: skip - install: pip install -U setuptools + install: true script: skip - after_success: true + after_success: skip deploy: provider: pypi user: agronholm @@ -49,7 +59,6 @@ distributions: sdist bdist_wheel on: tags: true - repo: agronholm/apscheduler before_install: docker-compose up -d diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/APScheduler.egg-info/PKG-INFO new/APScheduler-3.6.0/APScheduler.egg-info/PKG-INFO --- old/APScheduler-3.5.3/APScheduler.egg-info/PKG-INFO 2018-08-15 07:53:41.000000000 +0200 +++ new/APScheduler-3.6.0/APScheduler.egg-info/PKG-INFO 2019-03-18 11:15:38.000000000 +0100 @@ -1,13 +1,13 @@ Metadata-Version: 2.1 Name: APScheduler -Version: 3.5.3 +Version: 3.6.0 Summary: In-process task scheduler with Cron-like capabilities Home-page: https://github.com/agronholm/apscheduler Author: Alex Grönholm Author-email: [email protected] License: MIT -Description: .. image:: https://travis-ci.org/agronholm/apscheduler.svg?branch=master - :target: https://travis-ci.org/agronholm/apscheduler +Description: .. image:: https://travis-ci.com/agronholm/apscheduler.svg?branch=master + :target: https://travis-ci.com/agronholm/apscheduler :alt: Build Status .. image:: https://coveralls.io/repos/github/agronholm/apscheduler/badge.svg?branch=master :target: https://coveralls.io/github/agronholm/apscheduler?branch=master @@ -94,13 +94,15 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 -Provides-Extra: testing +Classifier: Programming Language :: Python :: 3.7 +Provides-Extra: sqlalchemy Provides-Extra: rethinkdb +Provides-Extra: testing Provides-Extra: redis -Provides-Extra: tornado -Provides-Extra: sqlalchemy -Provides-Extra: mongodb Provides-Extra: zookeeper -Provides-Extra: gevent Provides-Extra: asyncio +Provides-Extra: doc Provides-Extra: twisted +Provides-Extra: tornado +Provides-Extra: mongodb +Provides-Extra: gevent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/APScheduler.egg-info/SOURCES.txt new/APScheduler-3.6.0/APScheduler.egg-info/SOURCES.txt --- old/APScheduler-3.5.3/APScheduler.egg-info/SOURCES.txt 2018-08-15 07:53:41.000000000 +0200 +++ new/APScheduler-3.6.0/APScheduler.egg-info/SOURCES.txt 2019-03-18 11:15:38.000000000 +0100 @@ -60,6 +60,7 @@ docs/faq.rst docs/index.rst docs/migration.rst +docs/py-modindex.rst docs/userguide.rst docs/versionhistory.rst docs/modules/events.rst diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/APScheduler.egg-info/requires.txt new/APScheduler-3.6.0/APScheduler.egg-info/requires.txt --- old/APScheduler-3.5.3/APScheduler.egg-info/requires.txt 2018-08-15 07:53:41.000000000 +0200 +++ new/APScheduler-3.6.0/APScheduler.egg-info/requires.txt 2019-03-18 11:15:38.000000000 +0100 @@ -10,6 +10,10 @@ [asyncio:python_version == "2.7"] trollius +[doc] +sphinx +sphinx-rtd-theme + [gevent] gevent @@ -17,10 +21,10 @@ pymongo>=2.8 [redis] -redis +redis>=3.0 [rethinkdb] -rethinkdb +rethinkdb>=2.4.0 [sqlalchemy] sqlalchemy>=0.8 @@ -30,12 +34,15 @@ pytest-cov pytest-tornado5 -[testing:python_version != "2.7"] -pytest_asyncio<0.6.0 - [testing:python_version == "2.7"] mock +[testing:python_version == "3.4"] +pytest_asyncio<0.6 + +[testing:python_version >= "3.5"] +pytest_asyncio + [tornado] tornado>=4.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/PKG-INFO new/APScheduler-3.6.0/PKG-INFO --- old/APScheduler-3.5.3/PKG-INFO 2018-08-15 07:53:41.000000000 +0200 +++ new/APScheduler-3.6.0/PKG-INFO 2019-03-18 11:15:38.000000000 +0100 @@ -1,13 +1,13 @@ Metadata-Version: 2.1 Name: APScheduler -Version: 3.5.3 +Version: 3.6.0 Summary: In-process task scheduler with Cron-like capabilities Home-page: https://github.com/agronholm/apscheduler Author: Alex Grönholm Author-email: [email protected] License: MIT -Description: .. image:: https://travis-ci.org/agronholm/apscheduler.svg?branch=master - :target: https://travis-ci.org/agronholm/apscheduler +Description: .. image:: https://travis-ci.com/agronholm/apscheduler.svg?branch=master + :target: https://travis-ci.com/agronholm/apscheduler :alt: Build Status .. image:: https://coveralls.io/repos/github/agronholm/apscheduler/badge.svg?branch=master :target: https://coveralls.io/github/agronholm/apscheduler?branch=master @@ -94,13 +94,15 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 -Provides-Extra: testing +Classifier: Programming Language :: Python :: 3.7 +Provides-Extra: sqlalchemy Provides-Extra: rethinkdb +Provides-Extra: testing Provides-Extra: redis -Provides-Extra: tornado -Provides-Extra: sqlalchemy -Provides-Extra: mongodb Provides-Extra: zookeeper -Provides-Extra: gevent Provides-Extra: asyncio +Provides-Extra: doc Provides-Extra: twisted +Provides-Extra: tornado +Provides-Extra: mongodb +Provides-Extra: gevent diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/README.rst new/APScheduler-3.6.0/README.rst --- old/APScheduler-3.5.3/README.rst 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/README.rst 2018-12-16 10:38:18.000000000 +0100 @@ -1,5 +1,5 @@ -.. image:: https://travis-ci.org/agronholm/apscheduler.svg?branch=master - :target: https://travis-ci.org/agronholm/apscheduler +.. image:: https://travis-ci.com/agronholm/apscheduler.svg?branch=master + :target: https://travis-ci.com/agronholm/apscheduler :alt: Build Status .. image:: https://coveralls.io/repos/github/agronholm/apscheduler/badge.svg?branch=master :target: https://coveralls.io/github/agronholm/apscheduler?branch=master diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/apscheduler/events.py new/APScheduler-3.6.0/apscheduler/events.py --- old/APScheduler-3.5.3/apscheduler/events.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/apscheduler/events.py 2018-12-16 10:38:18.000000000 +0100 @@ -3,7 +3,7 @@ 'EVENT_JOBSTORE_ADDED', 'EVENT_JOBSTORE_REMOVED', 'EVENT_ALL_JOBS_REMOVED', 'EVENT_JOB_ADDED', 'EVENT_JOB_REMOVED', 'EVENT_JOB_MODIFIED', 'EVENT_JOB_EXECUTED', 'EVENT_JOB_ERROR', 'EVENT_JOB_MISSED', 'EVENT_JOB_SUBMITTED', 'EVENT_JOB_MAX_INSTANCES', - 'SchedulerEvent', 'JobEvent', 'JobExecutionEvent') + 'SchedulerEvent', 'JobEvent', 'JobExecutionEvent', 'JobSubmissionEvent') EVENT_SCHEDULER_STARTED = EVENT_SCHEDULER_START = 2 ** 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/apscheduler/job.py new/APScheduler-3.6.0/apscheduler/job.py --- old/APScheduler-3.5.3/apscheduler/job.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/apscheduler/job.py 2018-12-16 10:38:18.000000000 +0100 @@ -1,4 +1,3 @@ -from collections import Iterable, Mapping from inspect import ismethod, isclass from uuid import uuid4 @@ -9,6 +8,11 @@ ref_to_obj, obj_to_ref, datetime_repr, repr_escape, get_callable_name, check_callable_args, convert_to_datetime) +try: + from collections.abc import Iterable, Mapping +except ImportError: + from collections import Iterable, Mapping + class Job(object): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/apscheduler/jobstores/redis.py new/APScheduler-3.6.0/apscheduler/jobstores/redis.py --- old/APScheduler-3.5.3/apscheduler/jobstores/redis.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/apscheduler/jobstores/redis.py 2018-12-16 10:38:18.000000000 +0100 @@ -14,7 +14,7 @@ import pickle try: - from redis import StrictRedis + from redis import Redis except ImportError: # pragma: nocover raise ImportError('RedisJobStore requires redis installed') @@ -47,7 +47,7 @@ self.pickle_protocol = pickle_protocol self.jobs_key = jobs_key self.run_times_key = run_times_key - self.redis = StrictRedis(db=int(db), **connect_args) + self.redis = Redis(db=int(db), **connect_args) def lookup_job(self, job_id): job_state = self.redis.hget(self.jobs_key, job_id) @@ -81,7 +81,9 @@ pipe.hset(self.jobs_key, job.id, pickle.dumps(job.__getstate__(), self.pickle_protocol)) if job.next_run_time: - pipe.zadd(self.run_times_key, datetime_to_utc_timestamp(job.next_run_time), job.id) + pipe.zadd(self.run_times_key, + {job.id: datetime_to_utc_timestamp(job.next_run_time)}) + pipe.execute() def update_job(self, job): @@ -92,9 +94,11 @@ pipe.hset(self.jobs_key, job.id, pickle.dumps(job.__getstate__(), self.pickle_protocol)) if job.next_run_time: - pipe.zadd(self.run_times_key, datetime_to_utc_timestamp(job.next_run_time), job.id) + pipe.zadd(self.run_times_key, + {job.id: datetime_to_utc_timestamp(job.next_run_time)}) else: pipe.zrem(self.run_times_key, job.id) + pipe.execute() def remove_job(self, job_id): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/apscheduler/jobstores/rethinkdb.py new/APScheduler-3.6.0/apscheduler/jobstores/rethinkdb.py --- old/APScheduler-3.5.3/apscheduler/jobstores/rethinkdb.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/apscheduler/jobstores/rethinkdb.py 2019-03-18 10:10:31.000000000 +0100 @@ -10,7 +10,7 @@ import pickle try: - import rethinkdb as r + from rethinkdb import RethinkDB except ImportError: # pragma: nocover raise ImportError('RethinkDBJobStore requires rethinkdb installed') @@ -40,10 +40,12 @@ raise ValueError('The "table" parameter must not be empty') self.database = database - self.table = table + self.table_name = table + self.table = None self.client = client self.pickle_protocol = pickle_protocol self.connect_args = connect_args + self.r = RethinkDB() self.conn = None def start(self, scheduler, alias): @@ -52,31 +54,31 @@ if self.client: self.conn = maybe_ref(self.client) else: - self.conn = r.connect(db=self.database, **self.connect_args) + self.conn = self.r.connect(db=self.database, **self.connect_args) - if self.database not in r.db_list().run(self.conn): - r.db_create(self.database).run(self.conn) + if self.database not in self.r.db_list().run(self.conn): + self.r.db_create(self.database).run(self.conn) - if self.table not in r.table_list().run(self.conn): - r.table_create(self.table).run(self.conn) + if self.table_name not in self.r.table_list().run(self.conn): + self.r.table_create(self.table_name).run(self.conn) - if 'next_run_time' not in r.table(self.table).index_list().run(self.conn): - r.table(self.table).index_create('next_run_time').run(self.conn) + if 'next_run_time' not in self.r.table(self.table_name).index_list().run(self.conn): + self.r.table(self.table_name).index_create('next_run_time').run(self.conn) - self.table = r.db(self.database).table(self.table) + self.table = self.r.db(self.database).table(self.table_name) def lookup_job(self, job_id): results = list(self.table.get_all(job_id).pluck('job_state').run(self.conn)) return self._reconstitute_job(results[0]['job_state']) if results else None def get_due_jobs(self, now): - return self._get_jobs(r.row['next_run_time'] <= datetime_to_utc_timestamp(now)) + return self._get_jobs(self.r.row['next_run_time'] <= datetime_to_utc_timestamp(now)) def get_next_run_time(self): results = list( self.table - .filter(r.row['next_run_time'] != None) # flake8: noqa - .order_by(r.asc('next_run_time')) + .filter(self.r.row['next_run_time'] != None) # noqa + .order_by(self.r.asc('next_run_time')) .map(lambda x: x['next_run_time']) .limit(1) .run(self.conn) @@ -92,7 +94,7 @@ job_dict = { 'id': job.id, 'next_run_time': datetime_to_utc_timestamp(job.next_run_time), - 'job_state': r.binary(pickle.dumps(job.__getstate__(), self.pickle_protocol)) + 'job_state': self.r.binary(pickle.dumps(job.__getstate__(), self.pickle_protocol)) } results = self.table.insert(job_dict).run(self.conn) if results['errors'] > 0: @@ -101,7 +103,7 @@ def update_job(self, job): changes = { 'next_run_time': datetime_to_utc_timestamp(job.next_run_time), - 'job_state': r.binary(pickle.dumps(job.__getstate__(), self.pickle_protocol)) + 'job_state': self.r.binary(pickle.dumps(job.__getstate__(), self.pickle_protocol)) } results = self.table.get_all(job.id).update(changes).run(self.conn) skipped = False in map(lambda x: results[x] == 0, results.keys()) @@ -130,20 +132,20 @@ def _get_jobs(self, predicate=None): jobs = [] failed_job_ids = [] - query = (self.table.filter(r.row['next_run_time'] != None).filter(predicate) if - predicate else self.table) + query = (self.table.filter(self.r.row['next_run_time'] != None).filter(predicate) # noqa + if predicate else self.table) query = query.order_by('next_run_time', 'id').pluck('id', 'job_state') for document in query.run(self.conn): try: jobs.append(self._reconstitute_job(document['job_state'])) - except: + except Exception: self._logger.exception('Unable to restore job "%s" -- removing it', document['id']) failed_job_ids.append(document['id']) # Remove all the jobs we failed to restore if failed_job_ids: - r.expr(failed_job_ids).for_each( + self.r.expr(failed_job_ids).for_each( lambda job_id: self.table.get_all(job_id).delete()).run(self.conn) return jobs diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/apscheduler/jobstores/sqlalchemy.py new/APScheduler-3.6.0/apscheduler/jobstores/sqlalchemy.py --- old/APScheduler-3.5.3/apscheduler/jobstores/sqlalchemy.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/apscheduler/jobstores/sqlalchemy.py 2018-12-16 10:38:18.000000000 +0100 @@ -106,7 +106,7 @@ }).where(self.jobs_t.c.id == job.id) result = self.engine.execute(update) if result.rowcount == 0: - raise JobLookupError(id) + raise JobLookupError(job.id) def remove_job(self, job_id): delete = self.jobs_t.delete().where(self.jobs_t.c.id == job_id) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/apscheduler/schedulers/base.py new/APScheduler-3.6.0/apscheduler/schedulers/base.py --- old/APScheduler-3.5.3/apscheduler/schedulers/base.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/apscheduler/schedulers/base.py 2019-02-03 16:28:47.000000000 +0100 @@ -1,7 +1,6 @@ from __future__ import print_function from abc import ABCMeta, abstractmethod -from collections import MutableMapping from threading import RLock from datetime import datetime, timedelta from logging import getLogger @@ -27,6 +26,11 @@ EVENT_JOB_ADDED, EVENT_EXECUTOR_ADDED, EVENT_EXECUTOR_REMOVED, EVENT_ALL_JOBS_REMOVED, EVENT_JOB_SUBMITTED, EVENT_JOB_MAX_INSTANCES, EVENT_SCHEDULER_RESUMED, EVENT_SCHEDULER_PAUSED) +try: + from collections.abc import MutableMapping +except ImportError: + from collections import MutableMapping + #: constant indicating a scheduler's stopped state STATE_STOPPED = 0 #: constant indicating a scheduler's running state (started and processing jobs) @@ -594,14 +598,13 @@ """ jobstore_alias = None with self._jobstores_lock: + # Check if the job is among the pending jobs if self.state == STATE_STOPPED: - # Check if the job is among the pending jobs - if self.state == STATE_STOPPED: - for i, (job, alias, replace_existing) in enumerate(self._pending_jobs): - if job.id == job_id and jobstore in (None, alias): - del self._pending_jobs[i] - jobstore_alias = alias - break + for i, (job, alias, replace_existing) in enumerate(self._pending_jobs): + if job.id == job_id and jobstore in (None, alias): + del self._pending_jobs[i] + jobstore_alias = alias + break else: # Otherwise, try to remove it from each store until it succeeds or we run out of # stores to check diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/apscheduler/schedulers/qt.py new/APScheduler-3.6.0/apscheduler/schedulers/qt.py --- old/APScheduler-3.5.3/apscheduler/schedulers/qt.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/apscheduler/schedulers/qt.py 2018-12-16 10:38:18.000000000 +0100 @@ -9,7 +9,7 @@ from PyQt4.QtCore import QObject, QTimer except ImportError: try: - from PySide.QtCore import QObject, QTimer # flake8: noqa + from PySide.QtCore import QObject, QTimer # noqa except ImportError: raise ImportError('QtScheduler requires either PyQt5, PyQt4 or PySide installed') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/docs/conf.py new/APScheduler-3.6.0/docs/conf.py --- old/APScheduler-3.5.3/docs/conf.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/docs/conf.py 2018-12-06 00:53:49.000000000 +0100 @@ -92,7 +92,7 @@ # The theme to use for HTML and HTML Help pages. Major themes that come with # Sphinx are currently 'default' and 'sphinxdoc'. -html_theme = 'default' +html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/docs/faq.rst new/APScheduler-3.6.0/docs/faq.rst --- old/APScheduler-3.5.3/docs/faq.rst 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/docs/faq.rst 2019-02-03 16:28:47.000000000 +0100 @@ -29,6 +29,36 @@ If you're having any other issue, then enabling debug logging as instructed in the :ref:`troubleshooting` section should shed some light into the problem. +Why am I getting a ValueError? +============================== + +If you're receiving an error like the following:: + + ValueError: This Job cannot be serialized since the reference to its callable (<bound method xxxxxxxx.on_crn_field_submission + of <__main__.xxxxxxx object at xxxxxxxxxxxxx>>) could not be determined. Consider giving a textual reference (module:function + name) instead. + +This means that the function you are attempting to schedule has one of the following problems: + +* It is a lambda function (e.g. ``lambda x: x + 1``) +* It is a bound method (function tied to a particular instance of some class) +* It is a nested function (function inside another function) +* You are trying to schedule a function that is not tied to any actual module (such as a function + defined in the REPL, hence ``__main__`` as the module name) + +In these cases, it is impossible for the scheduler to determine a "lookup path" to find that +specific function instance in situations where, for example, the scheduler process is restarted, +or a process pool worker is being sent the related job object. + +Common workarounds for these problems include: + +* Converting a lambda to a regular function +* Moving a nested function to the module level or to class level as either a class method or a + static method +* In case of a bound method, passing the unbound version (``YourClass.method_name``) as the target + function to ``add_job()`` with the class instance as the first argument (so it gets passed as the + ``self`` argument) + How can I use APScheduler with uWSGI? ===================================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/docs/index.rst new/APScheduler-3.6.0/docs/index.rst --- old/APScheduler-3.5.3/docs/index.rst 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/docs/index.rst 2018-12-06 00:53:49.000000000 +0100 @@ -17,9 +17,4 @@ contributing extending faq - - -Indices and tables -================== - -* :ref:`API reference <modindex>` + py-modindex diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/docs/py-modindex.rst new/APScheduler-3.6.0/docs/py-modindex.rst --- old/APScheduler-3.5.3/docs/py-modindex.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/APScheduler-3.6.0/docs/py-modindex.rst 2018-12-06 00:53:49.000000000 +0100 @@ -0,0 +1,2 @@ +API reference +============= diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/docs/versionhistory.rst new/APScheduler-3.6.0/docs/versionhistory.rst --- old/APScheduler-3.5.3/docs/versionhistory.rst 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/docs/versionhistory.rst 2019-03-18 10:19:55.000000000 +0100 @@ -4,6 +4,13 @@ To find out how to migrate your application from a previous version of APScheduler, see the :doc:`migration section <migration>`. +3.6.0 +----- + +* Adapted ``RedisJobStore`` to v3.0 of the ``redis`` library +* Adapted ``RethinkDBJobStore`` to v2.4 of the ``rethink`` library +* Fixed ``DeprecationWarnings`` about ``collections.abc`` on Python 3.7 (PR by Roman Levin) + 3.5.3 ----- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/setup.py new/APScheduler-3.6.0/setup.py --- old/APScheduler-3.5.3/setup.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/setup.py 2019-03-18 10:10:31.000000000 +0100 @@ -28,7 +28,8 @@ 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6' + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7' ], keywords='scheduling cron', license='MIT', @@ -47,8 +48,8 @@ 'asyncio:python_version == "2.7"': ['trollius'], 'gevent': ['gevent'], 'mongodb': ['pymongo >= 2.8'], - 'redis': ['redis'], - 'rethinkdb': ['rethinkdb'], + 'redis': ['redis >= 3.0'], + 'rethinkdb': ['rethinkdb >= 2.4.0'], 'sqlalchemy': ['sqlalchemy >= 0.8'], 'tornado': ['tornado >= 4.3'], 'twisted': ['twisted'], @@ -59,7 +60,12 @@ 'pytest-tornado5' ], 'testing:python_version == "2.7"': ['mock'], - 'testing:python_version != "2.7"': ['pytest_asyncio < 0.6.0'] + 'testing:python_version == "3.4"': ['pytest_asyncio < 0.6'], + 'testing:python_version >= "3.5"': ['pytest_asyncio'], + 'doc': [ + 'sphinx', + 'sphinx-rtd-theme', + ], }, zip_safe=False, entry_points={ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/tests/test_executors.py new/APScheduler-3.6.0/tests/test_executors.py --- old/APScheduler-3.5.3/tests/test_executors.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/tests/test_executors.py 2019-03-18 10:10:31.000000000 +0100 @@ -25,7 +25,7 @@ return scheduler_ [email protected]_fixture(params=['threadpool', 'processpool']) [email protected](params=['threadpool', 'processpool']) def executor(request, mock_scheduler): if request.param == 'threadpool': from apscheduler.executors.pool import ThreadPoolExecutor diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/tests/test_jobstores.py new/APScheduler-3.6.0/tests/test_jobstores.py --- old/APScheduler-3.5.3/tests/test_jobstores.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/tests/test_jobstores.py 2019-03-18 10:10:31.000000000 +0100 @@ -27,12 +27,12 @@ return a + b [email protected]_fixture [email protected] def memjobstore(): yield MemoryJobStore() [email protected]_fixture [email protected] def sqlalchemyjobstore(tmpdir): db_path = tmpdir.join('apscheduler_unittest.sqlite') sqlalchemy = pytest.importorskip('apscheduler.jobstores.sqlalchemy') @@ -43,17 +43,17 @@ db_path.remove() [email protected]_fixture [email protected] def rethinkdbjobstore(): rethinkdb = pytest.importorskip('apscheduler.jobstores.rethinkdb') store = rethinkdb.RethinkDBJobStore(database='apscheduler_unittest') store.start(None, 'rethinkdb') yield store - rethinkdb.r.db_drop('apscheduler_unittest').run(store.conn) + store.r.db_drop('apscheduler_unittest').run(store.conn) store.shutdown() [email protected]_fixture [email protected] def mongodbjobstore(): mongodb = pytest.importorskip('apscheduler.jobstores.mongodb') store = mongodb.MongoDBJobStore(database='apscheduler_unittest') @@ -63,7 +63,7 @@ store.shutdown() [email protected]_fixture [email protected] def redisjobstore(): redis = pytest.importorskip('apscheduler.jobstores.redis') store = redis.RedisJobStore() @@ -73,7 +73,7 @@ store.shutdown() [email protected]_fixture [email protected] def zookeeperjobstore(): zookeeper = pytest.importorskip('apscheduler.jobstores.zookeeper') store = zookeeper.ZooKeeperJobStore(path='/apscheduler_unittest') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/tests/test_schedulers.py new/APScheduler-3.6.0/tests/test_schedulers.py --- old/APScheduler-3.5.3/tests/test_schedulers.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/tests/test_schedulers.py 2019-03-18 10:10:31.000000000 +0100 @@ -728,8 +728,10 @@ assert str(exc.value) == 'Expected a trigger instance or string, got int instead' def test_create_trigger_bad_plugin_type(self, scheduler): + mock_plugin = MagicMock() + mock_plugin.load.configure_mock(return_value=object) scheduler._trigger_classes = {} - scheduler._trigger_plugins = {'dummy': MagicMock(return_value=object)} + scheduler._trigger_plugins = {'dummy': mock_plugin} exc = pytest.raises(TypeError, scheduler._create_trigger, 'dummy', {}) assert str(exc.value) == 'The trigger entry point does not point to a trigger class' @@ -867,7 +869,7 @@ def executor(self, scheduler): scheduler.add_executor(DebugExecutor()) - @pytest.yield_fixture + @pytest.fixture def start_scheduler(self, request, scheduler): yield scheduler.start if scheduler.running: @@ -928,7 +930,7 @@ from apscheduler.schedulers.blocking import BlockingScheduler return BlockingScheduler() - @pytest.yield_fixture + @pytest.fixture def start_scheduler(self, request, scheduler): thread = Thread(target=scheduler.start) yield thread.start @@ -956,7 +958,7 @@ asyncio = pytest.importorskip('apscheduler.schedulers.asyncio') return asyncio.AsyncIOScheduler(event_loop=event_loop) - @pytest.yield_fixture + @pytest.fixture def start_scheduler(self, request, event_loop, scheduler): event_loop.call_soon_threadsafe(scheduler.start) thread = Thread(target=event_loop.run_forever) @@ -998,7 +1000,7 @@ tornado = pytest.importorskip('apscheduler.schedulers.tornado') return tornado.TornadoScheduler(io_loop=io_loop) - @pytest.yield_fixture + @pytest.fixture def start_scheduler(self, request, io_loop, scheduler): io_loop.add_callback(scheduler.start) thread = Thread(target=io_loop.start) @@ -1021,7 +1023,7 @@ twisted = pytest.importorskip('apscheduler.schedulers.twisted') return twisted.TwistedScheduler(reactor=reactor) - @pytest.yield_fixture + @pytest.fixture def start_scheduler(self, request, reactor, scheduler): reactor.callFromThread(scheduler.start) thread = Thread(target=reactor.run, args=(False,)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/tests/test_triggers.py new/APScheduler-3.6.0/tests/test_triggers.py --- old/APScheduler-3.5.3/tests/test_triggers.py 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/tests/test_triggers.py 2018-12-16 10:38:18.000000000 +0100 @@ -1,5 +1,6 @@ import pickle import random +import sys from datetime import datetime, timedelta, date import pytest @@ -383,14 +384,14 @@ assert next_fire_time is None or next_fire_time <= end_date @pytest.mark.parametrize('values, expected', [ - (dict(day='*/31'), "Error validating expression '\*/31': the step value \(31\) is higher " - "than the total range of the expression \(30\)"), - (dict(day='4-6/3'), "Error validating expression '4-6/3': the step value \(3\) is higher " - "than the total range of the expression \(2\)"), - (dict(hour='0-24'), "Error validating expression '0-24': the last value \(24\) is higher " - "than the maximum value \(23\)"), - (dict(day='0-3'), "Error validating expression '0-3': the first value \(0\) is lower than " - "the minimum value \(1\)") + (dict(day='*/31'), r"Error validating expression '\*/31': the step value \(31\) is higher " + r"than the total range of the expression \(30\)"), + (dict(day='4-6/3'), r"Error validating expression '4-6/3': the step value \(3\) is higher " + r"than the total range of the expression \(2\)"), + (dict(hour='0-24'), r"Error validating expression '0-24': the last value \(24\) is higher " + r"than the maximum value \(23\)"), + (dict(day='0-3'), r"Error validating expression '0-3': the first value \(0\) is lower " + r"than the minimum value \(1\)") ], ids=['too_large_step_all', 'too_large_step_range', 'too_high_last', 'too_low_first']) def test_invalid_ranges(self, values, expected): pytest.raises(ValueError, CronTrigger, **values).match(expected) @@ -538,9 +539,14 @@ assert repr(trigger) == "<CronTrigger (day='1-2,4-7', timezone='Europe/Berlin')>" def test_repr(self, trigger): - assert repr(trigger) == ("<IntervalTrigger (interval=datetime.timedelta(0, 1), " + if sys.version_info[:2] < (3, 7): + timedelta_args = '0, 1' + else: + timedelta_args = 'seconds=1' + + assert repr(trigger) == ("<IntervalTrigger (interval=datetime.timedelta({}), " "start_date='2009-08-04 00:00:02 CEST', " - "timezone='Europe/Berlin')>") + "timezone='Europe/Berlin')>".format(timedelta_args)) def test_str(self, trigger): assert str(trigger) == "interval[0:00:01]" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/APScheduler-3.5.3/tox.ini new/APScheduler-3.6.0/tox.ini --- old/APScheduler-3.5.3/tox.ini 2018-08-15 07:53:22.000000000 +0200 +++ new/APScheduler-3.6.0/tox.ini 2018-12-16 10:38:18.000000000 +0100 @@ -1,5 +1,5 @@ [tox] -envlist = py27, py34, py35, py36, pypy, pypy3, flake8 +envlist = py27, py34, py35, py36, py37, pypy, pypy3, flake8 skip_missing_interpreters = true [testenv] @@ -14,7 +14,7 @@ tornado twisted zookeeper -deps = {py35,py36}: PyQt5 +deps = {py35,py36,py37}: PyQt5 [testenv:flake8] deps = flake8
