Skip to content

Commit

Permalink
Fixed class methods being mistaken for instance methods
Browse files Browse the repository at this point in the history
  • Loading branch information
agronholm committed Aug 14, 2018
1 parent d00b3e4 commit 8ebdae9
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 4 deletions.
7 changes: 4 additions & 3 deletions apscheduler/job.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from collections import Iterable, Mapping
from inspect import ismethod
from inspect import ismethod, isclass
from uuid import uuid4

import six
Expand Down Expand Up @@ -236,8 +236,9 @@ def __getstate__(self):
'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
Expand Down
2 changes: 2 additions & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
12 changes: 11 additions & 1 deletion tests/test_jobstores.py
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down Expand Up @@ -108,13 +112,19 @@ def create(jobstore, func=dummy_job, run_date=datetime(2999, 1, 1), id=None, pau
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)
Expand Down

0 comments on commit 8ebdae9

Please sign in to comment.