mirror of https://github.com/scrapy/scrapy.git
serialize requests with callback references as spider attribute
You could define a spider attribute that references a callback method but if this method has a different name than your spider attribute, the request serializer is not able to find it on the spider class. With this commit we're fixing this behavior as we're searching for callback references in the spider object itself instead of looking for attributes with the same function's name, that could be different.
This commit is contained in:
parent
36abe9235c
commit
47a992615a
|
|
@ -1,6 +1,8 @@
|
|||
"""
|
||||
Helper functions for serializing (and deserializing) requests.
|
||||
"""
|
||||
import inspect
|
||||
|
||||
from scrapy.http import Request
|
||||
from scrapy.utils.python import to_unicode
|
||||
from scrapy.utils.misc import load_object
|
||||
|
|
@ -90,10 +92,12 @@ def _find_method(obj, func):
|
|||
pass
|
||||
else:
|
||||
if func_self is obj:
|
||||
name = func.__func__.__name__
|
||||
if _is_private_method(name):
|
||||
return _mangle_private_name(obj, func, name)
|
||||
return name
|
||||
members = inspect.getmembers(obj, predicate=inspect.ismethod)
|
||||
for name, obj_func in members:
|
||||
if obj_func.__func__ is func.__func__:
|
||||
if _is_private_method(name):
|
||||
return _mangle_private_name(obj, func, name)
|
||||
return name
|
||||
raise ValueError("Function %s is not a method of: %s" % (func, obj))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -69,6 +69,26 @@ class RequestSerializationTest(unittest.TestCase):
|
|||
errback=self.spider.handle_error)
|
||||
self._assert_serializes_ok(r, spider=self.spider)
|
||||
|
||||
def test_reference_callback_serialization(self):
|
||||
r = Request("http://www.example.com",
|
||||
callback=self.spider.parse_item_reference,
|
||||
errback=self.spider.handle_error_reference)
|
||||
self._assert_serializes_ok(r, spider=self.spider)
|
||||
request_dict = request_to_dict(r, self.spider)
|
||||
self.assertEqual(request_dict['callback'], 'parse_item_reference')
|
||||
self.assertEqual(request_dict['errback'], 'handle_error_reference')
|
||||
|
||||
def test_private_reference_callback_serialization(self):
|
||||
r = Request("http://www.example.com",
|
||||
callback=self.spider._TestSpider__parse_item_reference,
|
||||
errback=self.spider._TestSpider__handle_error_reference)
|
||||
self._assert_serializes_ok(r, spider=self.spider)
|
||||
request_dict = request_to_dict(r, self.spider)
|
||||
self.assertEqual(request_dict['callback'],
|
||||
'_TestSpider__parse_item_reference')
|
||||
self.assertEqual(request_dict['errback'],
|
||||
'_TestSpider__handle_error_reference')
|
||||
|
||||
def test_private_callback_serialization(self):
|
||||
r = Request("http://www.example.com",
|
||||
callback=self.spider._TestSpider__parse_item_private,
|
||||
|
|
@ -131,8 +151,28 @@ class TestSpiderMixin:
|
|||
pass
|
||||
|
||||
|
||||
def parse_item(response):
|
||||
pass
|
||||
|
||||
|
||||
def handle_error(failure):
|
||||
pass
|
||||
|
||||
|
||||
def private_parse_item(response):
|
||||
pass
|
||||
|
||||
|
||||
def private_handle_error(failure):
|
||||
pass
|
||||
|
||||
|
||||
class TestSpider(Spider, TestSpiderMixin):
|
||||
name = 'test'
|
||||
parse_item_reference = parse_item
|
||||
handle_error_reference = handle_error
|
||||
__parse_item_reference = private_parse_item
|
||||
__handle_error_reference = private_handle_error
|
||||
|
||||
def parse_item(self, response):
|
||||
pass
|
||||
|
|
|
|||
Loading…
Reference in New Issue