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 2023-09-20 13:28:48
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-APScheduler (Old)
 and      /work/SRC/openSUSE:Factory/.python-APScheduler.new.16627 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-APScheduler"

Wed Sep 20 13:28:48 2023 rev:22 rq:1112069 version:3.10.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-APScheduler/python-APScheduler.changes    
2023-08-17 19:44:52.622938803 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-APScheduler.new.16627/python-APScheduler.changes
 2023-09-20 13:31:19.275227464 +0200
@@ -1,0 +2,20 @@
+Mon Sep 18 19:32:28 UTC 2023 - Dirk Müller <dmuel...@suse.com>
+
+- update to 3.10.4:
+  * Fixed incorrect module name being generated for references to
+    class methods via a subclass where the subclass does not
+    override the method
+  * Fixed ``TypeError`` related to entry point iteration on
+    Python 3.9
+  * Ensured consistent support for both PySide and PyQt (v6 to
+    v2) on QtScheduler
+  * Replaced uses of the deprecated ``pkg_resources`` module with
+    ``importlib.metadata``
+  * Fixed scheduling class methods like ``B.methodname`` where
+    the ``B`` class inherits from class ``A`` and ``methodname``
+    is a class method of class ``A``
+  * Fixed scheduler sleeping for too long (and thus jobs missing
+    their scheduled run times) if its wakeup cycle takes too much
+    time
+
+-------------------------------------------------------------------

Old:
----
  APScheduler-3.10.1.tar.gz

New:
----
  APScheduler-3.10.4.tar.gz

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

Other differences:
------------------
++++++ python-APScheduler.spec ++++++
--- /var/tmp/diff_new_pack.FUj2NE/_old  2023-09-20 13:31:20.455269739 +0200
+++ /var/tmp/diff_new_pack.FUj2NE/_new  2023-09-20 13:31:20.459269883 +0200
@@ -18,7 +18,7 @@
 
 %{?sle15_python_module_pythons}
 Name:           python-APScheduler
-Version:        3.10.1
+Version:        3.10.4
 Release:        0
 Summary:        In-process task scheduler with Cron-like capabilities
 License:        MIT

++++++ APScheduler-3.10.1.tar.gz -> APScheduler-3.10.4.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/APScheduler-3.10.1/.github/workflows/codeqa_test.yaml 
new/APScheduler-3.10.4/.github/workflows/codeqa_test.yaml
--- old/APScheduler-3.10.1/.github/workflows/codeqa_test.yaml   2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/.github/workflows/codeqa_test.yaml   1970-01-01 
01:00:00.000000000 +0100
@@ -1,48 +0,0 @@
-name: Python codeqa/test
-
-on:
-  push:
-    branches: [3.x]
-  pull_request:
-
-jobs:
-  lint:
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@v3
-    - name: Set up Python
-      uses: actions/setup-python@v4
-      with:
-        python-version: 3.x
-    - uses: actions/cache@v3
-      with:
-        path: ~/.cache/pip
-        key: pip-lint
-    - name: Install dependencies
-      run: pip install tox
-    - name: Run flake8
-      run: tox -e flake8
-
-  test-linux:
-    needs: [lint]
-    strategy:
-      fail-fast: false
-      matrix:
-        python-version: ["3.7", "3.11"]
-    runs-on: ubuntu-latest
-    steps:
-    - uses: actions/checkout@v3
-    - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v4
-      with:
-        python-version: ${{ matrix.python-version }}
-    - uses: actions/cache@v3
-      with:
-        path: ~/.cache/pip
-        key: pip-test-${{ matrix.python-version }}-ubuntu-latest
-    - name: Start external services
-      run: docker-compose up -d
-    - name: Install the project and its dependencies
-      run: pip install -e 
.[testing,asyncio,gevent,mongodb,redis,rethinkdb,sqlalchemy,tornado,twisted,zookeeper]
-    - name: Test with pytest
-      run: pytest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/.github/workflows/publish.yml 
new/APScheduler-3.10.4/.github/workflows/publish.yml
--- old/APScheduler-3.10.1/.github/workflows/publish.yml        2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/.github/workflows/publish.yml        2023-08-19 
18:44:04.000000000 +0200
@@ -4,13 +4,14 @@
   push:
     tags:
       - "[0-9]+.[0-9]+.[0-9]+"
-      - "[0-9]+.[0-9]+.[0-9].post[0-9]+"
-      - "[0-9]+.[0-9]+.[0-9][a-b][0-9]+"
-      - "[0-9]+.[0-9]+.[0-9]rc[0-9]+"
+      - "[0-9]+.[0-9]+.[0-9]+.post[0-9]+"
+      - "[0-9]+.[0-9]+.[0-9]+[a-b][0-9]+"
+      - "[0-9]+.[0-9]+.[0-9]+rc[0-9]+"
 
 jobs:
-  publish:
+  build:
     runs-on: ubuntu-latest
+    environment: release
     steps:
     - uses: actions/checkout@v3
     - name: Set up Python
@@ -20,8 +21,21 @@
     - name: Install dependencies
       run: pip install build
     - name: Create packages
-      run: python -m build -s -w .
+      run: python -m build
+    - name: Archive packages
+      uses: actions/upload-artifact@v3
+      with:
+        name: dist
+        path: dist
+
+  publish:
+    needs: build
+    runs-on: ubuntu-latest
+    environment: release
+    permissions:
+      id-token: write
+    steps:
+    - name: Retrieve packages
+      uses: actions/download-artifact@v3
     - name: Upload packages
       uses: pypa/gh-action-pypi-publish@release/v1
-      with:
-        password: ${{ secrets.pypi_password }}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/.github/workflows/test.yaml 
new/APScheduler-3.10.4/.github/workflows/test.yaml
--- old/APScheduler-3.10.1/.github/workflows/test.yaml  1970-01-01 
01:00:00.000000000 +0100
+++ new/APScheduler-3.10.4/.github/workflows/test.yaml  2023-08-19 
18:44:04.000000000 +0200
@@ -0,0 +1,28 @@
+name: test suite
+
+on:
+  push:
+    branches: [3.x]
+  pull_request:
+
+jobs:
+  test:
+    strategy:
+      fail-fast: false
+      matrix:
+        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v3
+    - name: Set up Python ${{ matrix.python-version }}
+      uses: actions/setup-python@v4
+      with:
+        python-version: ${{ matrix.python-version }}
+        cache: pip
+        cache-dependency-path: setup.py
+    - name: Start external services
+      run: docker-compose up -d
+    - name: Install the project and its dependencies
+      run: pip install -e 
.[testing,asyncio,gevent,mongodb,redis,rethinkdb,sqlalchemy,tornado,twisted,zookeeper]
+    - name: Test with pytest
+      run: pytest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/.pre-commit-config.yaml 
new/APScheduler-3.10.4/.pre-commit-config.yaml
--- old/APScheduler-3.10.1/.pre-commit-config.yaml      1970-01-01 
01:00:00.000000000 +0100
+++ new/APScheduler-3.10.4/.pre-commit-config.yaml      2023-08-19 
18:44:04.000000000 +0200
@@ -0,0 +1,32 @@
+# This is the configuration file for pre-commit (https://pre-commit.com/).
+# To use:
+# * Install pre-commit (https://pre-commit.com/#installation)
+# * Copy this file as ".pre-commit-config.yaml"
+# * Run "pre-commit install".
+repos:
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.4.0
+    hooks:
+      - id: check-added-large-files
+      - id: check-case-conflict
+      - id: check-merge-conflict
+      - id: check-symlinks
+      - id: check-toml
+      - id: check-yaml
+      - id: debug-statements
+      - id: end-of-file-fixer
+      - id: mixed-line-ending
+        args: [ "--fix=lf" ]
+      - id: trailing-whitespace
+
+  - repo: https://github.com/codespell-project/codespell
+    rev: v2.2.5
+    hooks:
+      - id: codespell
+
+  - repo: https://github.com/pre-commit/pygrep-hooks
+    rev: v1.10.0
+    hooks:
+      - id: rst-backticks
+      - id: rst-directive-colons
+      - id: rst-inline-touching-normal
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/.readthedocs.yml 
new/APScheduler-3.10.4/.readthedocs.yml
--- old/APScheduler-3.10.1/.readthedocs.yml     2023-03-03 10:02:56.000000000 
+0100
+++ new/APScheduler-3.10.4/.readthedocs.yml     2023-08-19 18:44:04.000000000 
+0200
@@ -1,14 +1,24 @@
-type: sphinx
+version: 2
+
+build:
+  os: ubuntu-22.04
+  tools:
+    python: "3.7"
+
+sphinx:
+  configuration: docs/conf.py
+
 python:
-  version: "3.5"
-  pip_install: true
-  extra_requirements:
-    - gevent
-    - mongodb
-    - redis
-    - rethinkdb
-    - sqlalchemy
-    - tornado
-    - twisted
-    - zookeeper
-    - doc
+   install:
+      - method: pip
+        path: .
+        extra_requirements:
+          - gevent
+          - mongodb
+          - redis
+          - rethinkdb
+          - sqlalchemy
+          - tornado
+          - twisted
+          - zookeeper
+          - doc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/APScheduler.egg-info/PKG-INFO 
new/APScheduler-3.10.4/APScheduler.egg-info/PKG-INFO
--- old/APScheduler-3.10.1/APScheduler.egg-info/PKG-INFO        2023-03-03 
10:03:06.000000000 +0100
+++ new/APScheduler-3.10.4/APScheduler.egg-info/PKG-INFO        2023-08-19 
18:44:14.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: APScheduler
-Version: 3.10.1
+Version: 3.10.4
 Summary: In-process task scheduler with Cron-like capabilities
 Home-page: https://github.com/agronholm/apscheduler
 Author: Alex Grönholm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/APScheduler.egg-info/SOURCES.txt 
new/APScheduler-3.10.4/APScheduler.egg-info/SOURCES.txt
--- old/APScheduler-3.10.1/APScheduler.egg-info/SOURCES.txt     2023-03-03 
10:03:06.000000000 +0100
+++ new/APScheduler-3.10.4/APScheduler.egg-info/SOURCES.txt     2023-08-19 
18:44:14.000000000 +0200
@@ -1,5 +1,6 @@
 .gitignore
 .mailmap
+.pre-commit-config.yaml
 .readthedocs.yml
 LICENSE.txt
 README.rst
@@ -8,8 +9,8 @@
 setup.py
 tox.ini
 .github/ISSUE_TEMPLATE.md
-.github/workflows/codeqa_test.yaml
 .github/workflows/publish.yml
+.github/workflows/test.yaml
 APScheduler.egg-info/PKG-INFO
 APScheduler.egg-info/SOURCES.txt
 APScheduler.egg-info/dependency_links.txt
@@ -118,5 +119,4 @@
 tests/test_jobstores.py
 tests/test_schedulers.py
 tests/test_triggers.py
-tests/test_util.py
-tests/test_util_py35.py
\ No newline at end of file
+tests/test_util.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/APScheduler.egg-info/requires.txt 
new/APScheduler-3.10.4/APScheduler.egg-info/requires.txt
--- old/APScheduler-3.10.1/APScheduler.egg-info/requires.txt    2023-03-03 
10:03:06.000000000 +0100
+++ new/APScheduler-3.10.4/APScheduler.egg-info/requires.txt    2023-08-19 
18:44:14.000000000 +0200
@@ -1,8 +1,10 @@
-setuptools>=0.7
 six>=1.4.0
 pytz
 tzlocal!=3.*,>=2.0
 
+[:python_version < "3.8"]
+importlib-metadata>=3.6.0
+
 [doc]
 sphinx
 sphinx-rtd-theme
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/PKG-INFO 
new/APScheduler-3.10.4/PKG-INFO
--- old/APScheduler-3.10.1/PKG-INFO     2023-03-03 10:03:06.213973800 +0100
+++ new/APScheduler-3.10.4/PKG-INFO     2023-08-19 18:44:14.539897200 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: APScheduler
-Version: 3.10.1
+Version: 3.10.4
 Summary: In-process task scheduler with Cron-like capabilities
 Home-page: https://github.com/agronholm/apscheduler
 Author: Alex Grönholm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/apscheduler/__init__.py 
new/APScheduler-3.10.4/apscheduler/__init__.py
--- old/APScheduler-3.10.1/apscheduler/__init__.py      2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/apscheduler/__init__.py      2023-08-19 
18:44:04.000000000 +0200
@@ -1,10 +1,15 @@
-from pkg_resources import get_distribution, DistributionNotFound
+import sys
+if sys.version_info >= (3, 8):
+    import importlib.metadata as importlib_metadata
+else:
+    import importlib_metadata
+
 
 try:
-    release = get_distribution('APScheduler').version.split('-')[0]
-except DistributionNotFound:
+    release = importlib_metadata.version('APScheduler').split('-')[0]
+except importlib_metadata.PackageNotFoundError:
     release = '3.5.0'
 
 version_info = tuple(int(x) if x.isdigit() else x for x in release.split('.'))
 version = __version__ = '.'.join(str(x) for x in version_info[:3])
-del get_distribution, DistributionNotFound
+del sys, importlib_metadata
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/apscheduler/schedulers/base.py 
new/APScheduler-3.10.4/apscheduler/schedulers/base.py
--- old/APScheduler-3.10.1/apscheduler/schedulers/base.py       2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/apscheduler/schedulers/base.py       2023-08-19 
18:44:04.000000000 +0200
@@ -7,7 +7,6 @@
 import warnings
 import sys
 
-from pkg_resources import iter_entry_points
 from tzlocal import get_localzone
 import six
 
@@ -31,6 +30,11 @@
 except ImportError:
     from collections import MutableMapping
 
+try:
+    from importlib.metadata import entry_points
+except ModuleNotFoundError:
+    from importlib_metadata import entry_points
+
 #: constant indicating a scheduler's stopped state
 STATE_STOPPED = 0
 #: constant indicating a scheduler's running state (started and processing 
jobs)
@@ -62,12 +66,18 @@
 
     .. seealso:: :ref:`scheduler-config`
     """
+    # The `group=...` API is only available in the backport, used in <=3.7, 
and in std>=3.10.
+    if (3, 8) <= sys.version_info < (3, 10):
+        _trigger_plugins = {ep.name: ep for ep in 
entry_points()['apscheduler.triggers']}
+        _executor_plugins = {ep.name: ep for ep in 
entry_points()['apscheduler.executors']}
+        _jobstore_plugins = {ep.name: ep for ep in 
entry_points()['apscheduler.jobstores']}
+    else:
+        _trigger_plugins = {ep.name: ep for ep in 
entry_points(group='apscheduler.triggers')}
+        _executor_plugins = {ep.name: ep for ep in 
entry_points(group='apscheduler.executors')}
+        _jobstore_plugins = {ep.name: ep for ep in 
entry_points(group='apscheduler.jobstores')}
 
-    _trigger_plugins = dict((ep.name, ep) for ep in 
iter_entry_points('apscheduler.triggers'))
     _trigger_classes = {}
-    _executor_plugins = dict((ep.name, ep) for ep in 
iter_entry_points('apscheduler.executors'))
     _executor_classes = {}
-    _jobstore_plugins = dict((ep.name, ep) for ep in 
iter_entry_points('apscheduler.jobstores'))
     _jobstore_classes = {}
 
     #
@@ -1019,6 +1029,7 @@
             wait_seconds = None
             self._logger.debug('No jobs; waiting until a job is added')
         else:
+            now = datetime.now(self.timezone)
             wait_seconds = min(max(timedelta_seconds(next_wakeup_time - now), 
0), TIMEOUT_MAX)
             self._logger.debug('Next wakeup is due at %s (in %f seconds)', 
next_wakeup_time,
                                wait_seconds)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/apscheduler/schedulers/qt.py 
new/APScheduler-3.10.4/apscheduler/schedulers/qt.py
--- old/APScheduler-3.10.1/apscheduler/schedulers/qt.py 2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/apscheduler/schedulers/qt.py 2023-08-19 
18:44:04.000000000 +0200
@@ -1,24 +1,22 @@
 from __future__ import absolute_import
 
+from importlib import import_module
+from itertools import product
+
 from apscheduler.schedulers.base import BaseScheduler
 
-try:
-    from PyQt5.QtCore import QObject, QTimer
-except (ImportError, RuntimeError):  # pragma: nocover
+for version, pkgname in product(range(6, 1, -1), ("PySide", "PyQt")):
     try:
-        from PyQt4.QtCore import QObject, QTimer
+        qtcore = import_module(pkgname + str(version) + ".QtCore")
     except ImportError:
-        try:
-            from PySide6.QtCore import QObject, QTimer  # noqa
-        except ImportError:
-            try:
-                from PySide2.QtCore import QObject, QTimer  # noqa
-            except ImportError:
-                try:
-                    from PySide.QtCore import QObject, QTimer  # noqa
-                except ImportError:
-                    raise ImportError('QtScheduler requires either PyQt5, 
PyQt4, PySide6, PySide2 '
-                                      'or PySide installed')
+        pass
+    else:
+        QTimer = qtcore.QTimer
+        break
+else:
+    raise ImportError(
+        "QtScheduler requires either PySide/PyQt (v6 to v2) installed"
+    )
 
 
 class QtScheduler(BaseScheduler):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/apscheduler/util.py 
new/APScheduler-3.10.4/apscheduler/util.py
--- old/APScheduler-3.10.1/apscheduler/util.py  2023-03-03 10:02:56.000000000 
+0100
+++ new/APScheduler-3.10.4/apscheduler/util.py  2023-08-19 18:44:04.000000000 
+0200
@@ -6,7 +6,7 @@
 from datetime import date, datetime, time, timedelta, tzinfo
 from calendar import timegm
 from functools import partial
-from inspect import isclass, ismethod
+from inspect import isbuiltin, isclass, isfunction, ismethod
 import re
 import sys
 
@@ -214,28 +214,15 @@
     :rtype: str
 
     """
-    # the easy case (on Python 3.3+)
-    if hasattr(func, '__qualname__'):
+    if ismethod(func):
+        self = func.__self__
+        cls = self if isclass(self) else type(self)
+        return f"{cls.__qualname__}.{func.__name__}"
+    elif isclass(func) or isfunction(func) or isbuiltin(func):
         return func.__qualname__
-
-    # class methods, bound and unbound methods
-    f_self = getattr(func, '__self__', None) or getattr(func, 'im_self', None)
-    if f_self and hasattr(func, '__name__'):
-        f_class = f_self if isclass(f_self) else f_self.__class__
-    else:
-        f_class = getattr(func, 'im_class', None)
-
-    if f_class and hasattr(func, '__name__'):
-        return '%s.%s' % (f_class.__name__, func.__name__)
-
-    # class or class instance
-    if hasattr(func, '__call__'):
-        # class
-        if hasattr(func, '__name__'):
-            return func.__name__
-
+    elif hasattr(func, '__call__') and callable(func.__call__):
         # instance of a class with a __call__ method
-        return func.__class__.__name__
+        return type(func).__qualname__
 
     raise TypeError('Unable to determine a name for %r -- maybe it is not a 
callable?' % func)
 
@@ -260,16 +247,10 @@
         raise ValueError('Cannot create a reference to a nested function')
 
     if ismethod(obj):
-        if hasattr(obj, 'im_self') and obj.im_self:
-            # bound method
-            module = obj.im_self.__module__
-        elif hasattr(obj, 'im_class') and obj.im_class:
-            # unbound method
-            module = obj.im_class.__module__
-        else:
-            module = obj.__module__
+        module = obj.__self__.__module__
     else:
         module = obj.__module__
+
     return '%s:%s' % (module, name)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/docs/modules/executors/base.rst 
new/APScheduler-3.10.4/docs/modules/executors/base.rst
--- old/APScheduler-3.10.1/docs/modules/executors/base.rst      2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/docs/modules/executors/base.rst      2023-08-19 
18:44:04.000000000 +0200
@@ -8,4 +8,3 @@
 
 .. autoclass:: BaseExecutor
     :members:
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/APScheduler-3.10.1/docs/modules/schedulers/asyncio.rst 
new/APScheduler-3.10.4/docs/modules/schedulers/asyncio.rst
--- old/APScheduler-3.10.1/docs/modules/schedulers/asyncio.rst  2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/docs/modules/schedulers/asyncio.rst  2023-08-19 
18:44:04.000000000 +0200
@@ -24,9 +24,7 @@
    * - Default executor
      - :class:`~apscheduler.executors.asyncio.AsyncIOExecutor`
    * - External dependencies
-     - * Python >= 3.4: none
-       * Python 3.3: `asyncio <https://pypi.python.org/pypi/asyncio/>`_
-       * Python <= 3.2: `trollius <https://pypi.python.org/pypi/trollius/>`_
+     - none
    * - Example
      - ``examples/schedulers/asyncio_.py``
        (`view online 
<https://github.com/agronholm/apscheduler/tree/3.x/examples/schedulers/asyncio_.py>`_).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/docs/modules/schedulers/qt.rst 
new/APScheduler-3.10.4/docs/modules/schedulers/qt.rst
--- old/APScheduler-3.10.1/docs/modules/schedulers/qt.rst       2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/docs/modules/schedulers/qt.rst       2023-08-19 
18:44:04.000000000 +0200
@@ -13,7 +13,7 @@
 Introduction
 ------------
 
-QtScheduler lets you integrate APScheduler with your `PySide2 
<https://wiki.qt.io/Qt_for_Python>`, `PySide 
<https://en.wikipedia.org/wiki/PySide>` or
+QtScheduler lets you integrate APScheduler with your `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.10.1/docs/modules/triggers/cron.rst 
new/APScheduler-3.10.4/docs/modules/triggers/cron.rst
--- old/APScheduler-3.10.1/docs/modules/triggers/cron.rst       2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/docs/modules/triggers/cron.rst       2023-08-19 
18:44:04.000000000 +0200
@@ -66,8 +66,8 @@
 forward, depending on the time zone. Likewise, when switching back to standard 
time, clocks are moved one hour or half
 an hour backward. This will cause some time periods to either not exist at 
all, or be repeated. If your schedule would
 have the job executed on either one of these periods, it may execute more 
often or less often than expected.
-This is not a bug. If you wish to avoid this, either use a timezone that does 
not observe DST, for instance UTC.
-Alternatively, just find out about the DST switch times and avoid them in your 
scheduling.
+This is not a bug. If you wish to avoid this, either use a timezone that does 
not observe DST, e.g. UTC, or find out
+about the DST-switch times and avoid using them in your scheduling.
 
 For example, the following schedule may be problematic::
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/APScheduler-3.10.1/docs/modules/triggers/interval.rst 
new/APScheduler-3.10.4/docs/modules/triggers/interval.rst
--- old/APScheduler-3.10.1/docs/modules/triggers/interval.rst   2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/docs/modules/triggers/interval.rst   2023-08-19 
18:44:04.000000000 +0200
@@ -54,7 +54,7 @@
 
 The :meth:`~apscheduler.schedulers.base.BaseScheduler.scheduled_job` decorator 
works nicely too::
 
-    
+
     @sched.scheduled_job('interval', id='my_job_id', hours=2)
     def job_function():
         print("Hello World")
@@ -64,5 +64,5 @@
 multiple servers and don't want them to run a job at the exact same moment or 
if you want to prevent multiple jobs
 with similar options from always running concurrently::
 
-    # Run the `job_function` every hour with an extra-delay picked randomly in 
a [-120,+120] seconds window.
+    # Run the `job_function` every hour with an extra delay picked randomly 
between 0 and 120 seconds.
     sched.add_job(job_function, 'interval', hours=1, jitter=120)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/docs/userguide.rst 
new/APScheduler-3.10.4/docs/userguide.rst
--- old/APScheduler-3.10.1/docs/userguide.rst   2023-03-03 10:02:56.000000000 
+0100
+++ new/APScheduler-3.10.4/docs/userguide.rst   2023-08-19 18:44:04.000000000 
+0200
@@ -420,7 +420,7 @@
 scheduler) to see if the execution should still be triggered. This can lead 
into the job being
 executed several times in succession.
 
-If this behavior is undesirable for your particular use case, it is possible 
to use `coalescing` to
+If this behavior is undesirable for your particular use case, it is possible 
to use ``coalescing`` to
 roll all these missed executions into one. In other words, if coalescing is 
enabled for the job and
 the scheduler sees one or more queued executions for the job, it will only 
trigger it once. No
 misfire events will be sent for the "bypassed" runs.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/docs/versionhistory.rst 
new/APScheduler-3.10.4/docs/versionhistory.rst
--- old/APScheduler-3.10.1/docs/versionhistory.rst      2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/docs/versionhistory.rst      2023-08-19 
18:44:04.000000000 +0200
@@ -4,6 +4,32 @@
 To find out how to migrate your application from a previous version of
 APScheduler, see the :doc:`migration section <migration>`.
 
+3.10.4
+------
+
+- Fixed incorrect module name being generated for references to class methods 
via a
+  subclass where the subclass does not override the method
+
+
+3.10.3
+------
+
+- Fixed ``TypeError`` related to entry point iteration on Python 3.9
+  (PR by CrypticDriver)
+
+
+3.10.2
+------
+
+* Ensured consistent support for both PySide and PyQt (v6 to v2) on QtScheduler
+* Replaced uses of the deprecated ``pkg_resources`` module with 
``importlib.metadata``
+  (PR by Ran Benita)
+* Fixed scheduling class methods like ``B.methodname`` where the ``B`` class 
inherits
+  from class ``A`` and ``methodname`` is a class method of class ``A``
+* Fixed scheduler sleeping for too long (and thus jobs missing their scheduled 
run
+  times) if its wakeup cycle takes too much time (fix by kbasten)
+
+
 3.10.1
 ------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/examples/schedulers/asyncio_.py 
new/APScheduler-3.10.4/examples/schedulers/asyncio_.py
--- old/APScheduler-3.10.1/examples/schedulers/asyncio_.py      2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/examples/schedulers/asyncio_.py      2023-08-19 
18:44:04.000000000 +0200
@@ -4,28 +4,28 @@
 """
 
 from datetime import datetime
+import asyncio
 import os
 
 from apscheduler.schedulers.asyncio import AsyncIOScheduler
 
-try:
-    import asyncio
-except ImportError:
-    import trollius as asyncio
-
 
 def tick():
     print('Tick! The time is: %s' % datetime.now())
 
 
-if __name__ == '__main__':
+async def main():
     scheduler = AsyncIOScheduler()
     scheduler.add_job(tick, 'interval', seconds=3)
     scheduler.start()
     print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))
+    while True:
+        await asyncio.sleep(1000)
 
+
+if __name__ == '__main__':
     # Execution will block here until Ctrl+C (Ctrl+Break on Windows) is 
pressed.
     try:
-        asyncio.get_event_loop().run_forever()
+        asyncio.run(main())
     except (KeyboardInterrupt, SystemExit):
         pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/examples/schedulers/qt.py 
new/APScheduler-3.10.4/examples/schedulers/qt.py
--- old/APScheduler-3.10.1/examples/schedulers/qt.py    2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/examples/schedulers/qt.py    2023-08-19 
18:44:04.000000000 +0200
@@ -6,22 +6,24 @@
 from datetime import datetime
 import signal
 import sys
+from importlib import import_module
+from itertools import product
 
 from apscheduler.schedulers.qt import QtScheduler
 
-try:
-    from PyQt5.QtWidgets import QApplication, QLabel
-except ImportError:
+for version, pkgname in product(range(6, 1, -1), ("PySide", "PyQt")):
     try:
-        from PyQt4.QtGui import QApplication, QLabel
+        qtwidgets = import_module(pkgname + str(version) + ".QtWidgets")
     except ImportError:
-        try:
-            from PySide6.QtWidgets import QApplication, QLabel
-        except ImportError:
-            try:
-                from PySide2.QtWidgets import QApplication, QLabel
-            except ImportError:
-                from PySide.QtGui import QApplication, QLabel
+        pass
+    else:
+        QApplication = qtwidgets.QApplication
+        QLabel = qtwidgets.QLabel
+        break
+else:
+    raise ImportError(
+        "Could not import the QtWidgets module from either PySide or PyQt"
+    )
 
 
 def tick():
@@ -44,4 +46,4 @@
     scheduler.start()
 
     # Execution will block here until the user closes the windows or Ctrl+C is 
pressed.
-    app.exec_()
+    app.exec()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/setup.py 
new/APScheduler-3.10.4/setup.py
--- old/APScheduler-3.10.1/setup.py     2023-03-03 10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/setup.py     2023-08-19 18:44:04.000000000 +0200
@@ -39,10 +39,10 @@
         'setuptools_scm'
     ],
     install_requires=[
-        'setuptools >= 0.7',
         'six >= 1.4.0',
         'pytz',
-        'tzlocal >= 2.0, != 3.*'
+        'tzlocal >= 2.0, != 3.*',
+        'importlib-metadata >= 3.6.0; python_version < "3.8"',
     ],
     extras_require={
         'gevent': ['gevent'],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/tests/conftest.py 
new/APScheduler-3.10.4/tests/conftest.py
--- old/APScheduler-3.10.1/tests/conftest.py    2023-03-03 10:02:56.000000000 
+0100
+++ new/APScheduler-3.10.4/tests/conftest.py    2023-08-19 18:44:04.000000000 
+0200
@@ -1,43 +1,13 @@
-# coding: utf-8
 from datetime import datetime
-import sys
 
 import pytest
 import pytz
+from unittest.mock import Mock
 
 from apscheduler.job import Job
 from apscheduler.schedulers.base import BaseScheduler
 from apscheduler.schedulers.blocking import BlockingScheduler
 
-try:
-    from unittest.mock import Mock
-except ImportError:
-    from mock import Mock
-
-
-def pytest_ignore_collect(path, config):
-    return path.basename.endswith('_py35.py') and sys.version_info < (3, 5)
-
-
-def minpython(*version):
-    version_str = '.'.join([str(num) for num in version])
-
-    def outer(func):
-        dec = pytest.mark.skipif(sys.version_info < version,
-                                 reason='Requires Python >= %s' % version_str)
-        return dec(func)
-    return outer
-
-
-def maxpython(*version):
-    version_str = '.'.join([str(num) for num in version])
-
-    def outer(func):
-        dec = pytest.mark.skipif(sys.version_info >= version,
-                                 reason='Requires Python < %s' % version_str)
-        return dec(func)
-    return outer
-
 
 @pytest.fixture
 def timezone(monkeypatch):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/tests/test_executors.py 
new/APScheduler-3.10.4/tests/test_executors.py
--- old/APScheduler-3.10.1/tests/test_executors.py      2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/tests/test_executors.py      2023-08-19 
18:44:04.000000000 +0200
@@ -15,7 +15,6 @@
 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
@@ -151,7 +150,6 @@
     assert len(foos) == 0
 
 
-@minpython(3, 3)
 def test_broken_pool():
     def listener(evt):
         pid[0] = evt.retval
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/tests/test_util.py 
new/APScheduler-3.10.4/tests/test_util.py
--- old/APScheduler-3.10.1/tests/test_util.py   2023-03-03 10:02:56.000000000 
+0100
+++ new/APScheduler-3.10.4/tests/test_util.py   2023-08-19 18:44:04.000000000 
+0200
@@ -1,27 +1,22 @@
-# coding: utf-8
+import os
 import platform
 import sys
 from datetime import date, datetime, timedelta, tzinfo
 from functools import partial, wraps
 from types import ModuleType
+from unittest.mock import Mock
 
 import pytest
 import pytz
-import six
 
-from apscheduler.job import Job
-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
-except ImportError:
-    from mock import Mock
+from apscheduler.util import (
+    asbool, asint, astimezone, check_callable_args,
+    convert_to_datetime, datetime_ceil,
+    datetime_repr, datetime_to_utc_timestamp,
+    get_callable_name, iscoroutinefunction_partial, maybe_ref, obj_to_ref,
+    ref_to_obj, timedelta_seconds,
+    utc_timestamp_to_datetime,
+)
 
 
 class DummyClass(object):
@@ -45,7 +40,7 @@
             pass
 
 
-class InheritedDummyClass(Job):
+class InheritedDummyClass(DummyClass):
     pass
 
 
@@ -182,15 +177,18 @@
 class TestGetCallableName(object):
     @pytest.mark.parametrize('input,expected', [
         (asint, 'asint'),
-        (DummyClass.staticmeth, 'DummyClass.staticmeth' if
-         hasattr(DummyClass, '__qualname__') else 'staticmeth'),
+        (os.getpid, "getpid"),
+        (DummyClass.staticmeth, 'DummyClass.staticmeth'),
         (DummyClass.classmeth, 'DummyClass.classmeth'),
-        (DummyClass.meth, 'meth' if sys.version_info[:2] == (3, 2) else 
'DummyClass.meth'),
+        (DummyClass.meth, 'DummyClass.meth'),
         (DummyClass().meth, 'DummyClass.meth'),
         (DummyClass, 'DummyClass'),
-        (DummyClass(), 'DummyClass')
-    ], ids=['function', 'static method', 'class method', 'unbounded method', 
'bounded method',
-            'class', 'instance'])
+        (DummyClass(), 'DummyClass'),
+        (InheritedDummyClass.classmeth, 'InheritedDummyClass.classmeth'),
+        (DummyClass.InnerDummyClass.innerclassmeth, 
'DummyClass.InnerDummyClass.innerclassmeth'),
+    ], ids=['function', 'builtin', 'static method', 'class method', 'unbounded 
method',
+            'bounded method', 'class', 'instance', 'class method in inherited',
+            'inner class method'])
     def test_inputs(self, input, expected):
         assert get_callable_name(input) == expected
 
@@ -199,6 +197,11 @@
 
 
 class TestObjToRef(object):
+    class InnerInheritedDummy(DummyClass):
+        pass
+
+    InnerInheritedDummy.__module__ = "foo"
+
     @pytest.mark.parametrize('obj, error', [
         (partial(DummyClass.meth), 'Cannot create a reference to a partial()'),
         (lambda: None, 'Cannot create a reference to a lambda')
@@ -237,6 +240,11 @@
     def test_valid_refs(self, input, expected):
         assert obj_to_ref(input) == expected
 
+    def test_inherited_classmethod(self):
+        assert obj_to_ref(TestObjToRef.InnerInheritedDummy.classmeth) == (
+            "foo:TestObjToRef.InnerInheritedDummy.classmeth"
+        )
+
 
 class TestRefToObj(object):
     def test_valid_ref(self):
@@ -269,15 +277,6 @@
     assert maybe_ref(input) == expected
 
 
-@pytest.mark.parametrize('input,expected', [
-    (b'T\xc3\xa9st'.decode('utf-8'), 'T\\xe9st' if six.PY2 else 'Tést'),
-    (1, 1)
-], ids=['string', 'int'])
-@maxpython(3)
-def test_repr_escape_py2(input, expected):
-    assert repr_escape(input) == expected
-
-
 class TestCheckCallableArgs(object):
     def test_invalid_callable_args(self):
         """
@@ -323,7 +322,6 @@
         """Tests that a function where signature() fails is accepted."""
         check_callable_args(object().__setattr__, ('blah', 1), {})
 
-    @minpython(3, 4)
     @pytest.mark.skipif(platform.python_implementation() == 'PyPy',
                         reason='PyPy does not expose signatures of builtins')
     def test_positional_only_args(self):
@@ -337,7 +335,6 @@
         assert str(exc.value) == ('The following arguments cannot be given as 
keyword arguments: '
                                   'value')
 
-    @minpython(3)
     def test_unfulfilled_kwargs(self):
         """
         Tests that attempting to schedule a job where not all keyword-only 
arguments are fulfilled
@@ -362,3 +359,22 @@
             func()
 
         check_callable_args(wrapper, (1,), {})
+
+
+class TestIsCoroutineFunctionPartial:
+    @staticmethod
+    def not_a_coro(x):
+        pass
+
+    @staticmethod
+    async def a_coro(x):
+        pass
+
+    def test_non_coro(self):
+        assert not iscoroutinefunction_partial(self.not_a_coro)
+
+    def test_coro(self):
+        assert iscoroutinefunction_partial(self.a_coro)
+
+    def test_coro_partial(self):
+        assert iscoroutinefunction_partial(partial(self.a_coro, 1))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/APScheduler-3.10.1/tests/test_util_py35.py 
new/APScheduler-3.10.4/tests/test_util_py35.py
--- old/APScheduler-3.10.1/tests/test_util_py35.py      2023-03-03 
10:02:56.000000000 +0100
+++ new/APScheduler-3.10.4/tests/test_util_py35.py      1970-01-01 
01:00:00.000000000 +0100
@@ -1,22 +0,0 @@
-from functools import partial
-
-from apscheduler.util import iscoroutinefunction_partial
-
-
-class TestIsCoroutineFunctionPartial:
-    @staticmethod
-    def not_a_coro(x):
-        pass
-
-    @staticmethod
-    async def a_coro(x):
-        pass
-
-    def test_non_coro(self):
-        assert not iscoroutinefunction_partial(self.not_a_coro)
-
-    def test_coro(self):
-        assert iscoroutinefunction_partial(self.a_coro)
-
-    def test_coro_partial(self):
-        assert iscoroutinefunction_partial(partial(self.a_coro, 1))

Reply via email to