diff options
author | Yang Jian <yangjian5077@gmail.com> | 2019-03-22 16:54:39 +0800 |
---|---|---|
committer | Alex Grönholm <alex.gronholm@nextday.fi> | 2019-03-22 10:54:39 +0200 |
commit | f2e039e5584253282e2187c2efcdb86274ea6e06 (patch) | |
tree | f732408e0420b80c38fa50f94a587871810bbc4a | |
parent | 92dc6cfcb09529cbde60e9e7d30b76d51fee38e7 (diff) | |
download | apscheduler-f2e039e5584253282e2187c2efcdb86274ea6e06.tar.gz |
Fixed methods inherited from base class could not be executed by processpool executor (#367)
-rw-r--r-- | apscheduler/util.py | 15 | ||||
-rw-r--r-- | tests/test_util.py | 12 |
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 |