summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Jian <yangjian5077@gmail.com>2019-03-22 16:54:39 +0800
committerAlex Grönholm <alex.gronholm@nextday.fi>2019-03-22 10:54:39 +0200
commitf2e039e5584253282e2187c2efcdb86274ea6e06 (patch)
treef732408e0420b80c38fa50f94a587871810bbc4a
parent92dc6cfcb09529cbde60e9e7d30b76d51fee38e7 (diff)
downloadapscheduler-f2e039e5584253282e2187c2efcdb86274ea6e06.tar.gz
Fixed methods inherited from base class could not be executed by processpool executor (#367)
-rw-r--r--apscheduler/util.py15
-rw-r--r--tests/test_util.py12
2 files changed, 24 insertions, 3 deletions
diff --git a/apscheduler/util.py b/apscheduler/util.py
index 3c48e55..e7b4869 100644
--- a/apscheduler/util.py
+++ b/apscheduler/util.py
@@ -5,7 +5,7 @@ from __future__ import division
from datetime import date, datetime, time, timedelta, tzinfo
from calendar import timegm
from functools import partial
-from inspect import isclass
+from inspect import isclass, ismethod
import re
from pytz import timezone, utc, FixedOffset
@@ -263,7 +263,18 @@ def obj_to_ref(obj):
if '<locals>' in name:
raise ValueError('Cannot create a reference to a nested function')
- return '%s:%s' % (obj.__module__, name)
+ 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__
+ else:
+ module = obj.__module__
+ return '%s:%s' % (module, name)
def ref_to_obj(ref):
diff --git a/tests/test_util.py b/tests/test_util.py
index 973b81a..f1f07e6 100644
--- a/tests/test_util.py
+++ b/tests/test_util.py
@@ -9,6 +9,7 @@ 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,
@@ -42,6 +43,10 @@ class DummyClass(object):
pass
+class InheritedDummyClass(Job):
+ pass
+
+
class TestAsint(object):
@pytest.mark.parametrize('value', ['5s', 'shplse'], ids=['digit first', 'text'])
def test_invalid_value(self, value):
@@ -229,8 +234,13 @@ class TestObjToRef(object):
reason="Requires __qualname__ (Python 3.3+)")(
(DummyClass.staticmeth, 'tests.test_util:DummyClass.staticmeth')
),
+ pytest.mark.skipif(sys.version_info >= (3, 2),
+ reason="Unbound methods (Python 3.2) and __qualname__ (Python 3.3+)")(
+ (InheritedDummyClass.pause, 'tests.test_util:InheritedDummyClass.pause')
+ ),
(timedelta, 'datetime:timedelta'),
- ], ids=['unbound method', 'class method', 'inner class method', 'static method', 'timedelta'])
+ ], ids=['unbound method', 'class method', 'inner class method', 'static method',
+ 'inherited class method', 'timedelta'])
def test_valid_refs(self, input, expected):
assert obj_to_ref(input) == expected