summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Grönholm <alex.gronholm@nextday.fi>2018-08-14 23:37:19 +0300
committerAlex Grönholm <alex.gronholm@nextday.fi>2018-08-14 23:56:08 +0300
commit8ebdae9bfe468a836079c26f8ed2b2362f9bebf9 (patch)
tree6ec70c1b1b951e5cbf3082dfada7b8c69b3e8a17
parentd00b3e413dc689314f2da33ec6f277824ee68338 (diff)
downloadapscheduler-8ebdae9bfe468a836079c26f8ed2b2362f9bebf9.tar.gz
Fixed class methods being mistaken for instance methodsv3.5.3
Fixes #330.
-rw-r--r--apscheduler/job.py7
-rw-r--r--docs/versionhistory.rst2
-rw-r--r--tests/test_jobstores.py12
3 files changed, 17 insertions, 4 deletions
diff --git a/apscheduler/job.py b/apscheduler/job.py
index 33081b2..4e24bec 100644
--- a/apscheduler/job.py
+++ b/apscheduler/job.py
@@ -1,5 +1,5 @@
from collections import Iterable, Mapping
-from inspect import ismethod
+from inspect import ismethod, isclass
from uuid import uuid4
import six
@@ -236,8 +236,9 @@ class Job(object):
'be determined. Consider giving a textual reference (module:function name) '
'instead.' % (self.func,))
- # Bound methods cannot survive serialization as-is, so store the "self" argument explicitly
- if ismethod(self.func):
+ # 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)
else:
args = self.args
diff --git a/docs/versionhistory.rst b/docs/versionhistory.rst
index fba72a8..ce4e862 100644
--- a/docs/versionhistory.rst
+++ b/docs/versionhistory.rst
@@ -7,6 +7,8 @@ APScheduler, see the :doc:`migration section <migration>`.
3.5.3
-----
+* Fixed regression introduced in 3.5.2: Class methods were mistaken for instance methods and thus
+ were broken during serialization
* Fixed callable name detection for methods in old style classes
diff --git a/tests/test_jobstores.py b/tests/test_jobstores.py
index 4b9aefa..2138a6b 100644
--- a/tests/test_jobstores.py
+++ b/tests/test_jobstores.py
@@ -22,6 +22,10 @@ class DummyClass:
def dummy_method(self, a, b):
return a + b
+ @classmethod
+ def dummy_classmethod(cls, a, b):
+ return a + b
+
@pytest.yield_fixture
def memjobstore():
@@ -108,13 +112,19 @@ def create_add_job(timezone, create_job):
return create
-def test_add_method_job(jobstore, create_add_job):
+def test_add_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):
+ 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_lookup_job(jobstore, create_add_job):
initial_job = create_add_job(jobstore)
job = jobstore.lookup_job(initial_job.id)