Add tests for private method name mangling

This commit is contained in:
Andrew Baxter 2019-06-05 23:43:56 +09:00
parent bcad8947e8
commit 9c81721c40
2 changed files with 26 additions and 8 deletions

View File

@ -71,6 +71,16 @@ def _is_private_method(name):
return name.startswith('__') and not name.endswith('__')
def _mangle_private_name(obj, func, name):
qualname = getattr(func, '__qualname__', None)
if qualname is None:
classname = obj.__class__.__name__.lstrip('_')
return '_%s%s' % (classname, name)
else:
splits = qualname.split('.')
return '_%s%s' % (splits[-2], splits[-1])
def _find_method(obj, func):
if obj:
try:
@ -81,13 +91,7 @@ def _find_method(obj, func):
if func_self is obj:
name = six.get_method_function(func).__name__
if _is_private_method(name):
qualname = getattr(func, '__qualname__', None)
if qualname is None:
classname = obj.__class__.__name__.lstrip('_')
name = '_%s%s' % (classname, name)
else:
splits = qualname.split('.')
name = '_%s%s' % (splits[-2], splits[-1])
return _mangle_private_name(obj, func, name)
return name
raise ValueError("Function %s is not a method of: %s" % (func, obj))

View File

@ -2,9 +2,11 @@
import unittest
import sys
import six
from scrapy.http import Request, FormRequest
from scrapy.spiders import Spider
from scrapy.utils.reqser import request_to_dict, request_from_dict, _is_private_method
from scrapy.utils.reqser import request_to_dict, request_from_dict, _is_private_method, _mangle_private_name
class RequestSerializationTest(unittest.TestCase):
@ -105,6 +107,18 @@ class RequestSerializationTest(unittest.TestCase):
self.assertFalse(_is_private_method('___'))
self.assertFalse(_is_private_method('____'))
def _assert_mangles_to(self, obj, name):
self.assertEqual(
_mangle_private_name(obj, getattr(obj, name), name),
name
)
def test_private_name_mangling(self):
self._assert_mangles_to(
self.spider, '_TestSpider__parse_item_private')
self._assert_mangles_to(
self.spider, '_TestSpiderMixin__mixin_callback')
def test_unserializable_callback1(self):
r = Request("http://www.example.com", callback=lambda x: x)
self.assertRaises(ValueError, request_to_dict, r)