mirror of https://github.com/scrapy/scrapy.git
Merge pull request #4756 from ivanprado/master
Support for delegated methods as callbacks
This commit is contained in:
commit
0ccaf89a6f
|
|
@ -71,25 +71,20 @@ def request_from_dict(d, spider=None):
|
|||
|
||||
|
||||
def _find_method(obj, func):
|
||||
if obj:
|
||||
try:
|
||||
func_self = func.__self__
|
||||
except AttributeError: # func has no __self__
|
||||
pass
|
||||
else:
|
||||
if func_self is obj:
|
||||
members = inspect.getmembers(obj, predicate=inspect.ismethod)
|
||||
for name, obj_func in members:
|
||||
# We need to use __func__ to access the original
|
||||
# function object because instance method objects
|
||||
# are generated each time attribute is retrieved from
|
||||
# instance.
|
||||
#
|
||||
# Reference: The standard type hierarchy
|
||||
# https://docs.python.org/3/reference/datamodel.html
|
||||
if obj_func.__func__ is func.__func__:
|
||||
return name
|
||||
raise ValueError("Function %s is not a method of: %s" % (func, obj))
|
||||
# Only instance methods contain ``__func__``
|
||||
if obj and hasattr(func, '__func__'):
|
||||
members = inspect.getmembers(obj, predicate=inspect.ismethod)
|
||||
for name, obj_func in members:
|
||||
# We need to use __func__ to access the original
|
||||
# function object because instance method objects
|
||||
# are generated each time attribute is retrieved from
|
||||
# instance.
|
||||
#
|
||||
# Reference: The standard type hierarchy
|
||||
# https://docs.python.org/3/reference/datamodel.html
|
||||
if obj_func.__func__ is func.__func__:
|
||||
return name
|
||||
raise ValueError("Function %s is not an instance method in: %s" % (func, obj))
|
||||
|
||||
|
||||
def _get_method(obj, name):
|
||||
|
|
|
|||
|
|
@ -102,6 +102,12 @@ class RequestSerializationTest(unittest.TestCase):
|
|||
errback=self.spider.handle_error)
|
||||
self._assert_serializes_ok(r, spider=self.spider)
|
||||
|
||||
def test_delegated_callback_serialization(self):
|
||||
r = Request("http://www.example.com",
|
||||
callback=self.spider.delegated_callback,
|
||||
errback=self.spider.handle_error)
|
||||
self._assert_serializes_ok(r, spider=self.spider)
|
||||
|
||||
def test_unserializable_callback1(self):
|
||||
r = Request("http://www.example.com", callback=lambda x: x)
|
||||
self.assertRaises(ValueError, request_to_dict, r)
|
||||
|
|
@ -132,6 +138,11 @@ class TestSpiderMixin:
|
|||
pass
|
||||
|
||||
|
||||
class TestSpiderDelegation:
|
||||
def delegated_callback(self, response):
|
||||
pass
|
||||
|
||||
|
||||
def parse_item(response):
|
||||
pass
|
||||
|
||||
|
|
@ -155,6 +166,9 @@ class TestSpider(Spider, TestSpiderMixin):
|
|||
__parse_item_reference = private_parse_item
|
||||
__handle_error_reference = private_handle_error
|
||||
|
||||
def __init__(self):
|
||||
self.delegated_callback = TestSpiderDelegation().delegated_callback
|
||||
|
||||
def parse_item(self, response):
|
||||
pass
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue