added tests for get_func_args() and support for more cases

This commit is contained in:
Pablo Hoffman 2012-09-04 18:07:44 -03:00
parent fff2871828
commit caa64908d2
2 changed files with 37 additions and 5 deletions

View File

@ -4,7 +4,7 @@ from itertools import count
from scrapy.utils.python import str_to_unicode, unicode_to_str, \
memoizemethod_noargs, isbinarytext, equal_attributes, \
WeakKeyCache, stringify_dict
WeakKeyCache, stringify_dict, get_func_args
__doctests__ = ['scrapy.utils.python']
@ -154,5 +154,33 @@ class UtilsPythonTestCase(unittest.TestCase):
self.failIf(d is d2) # shouldn't modify in place
self.failIf(any(isinstance(x, unicode) for x in d2.keys()))
def test_get_func_args(self):
def f1(a, b, c):
pass
def f2(a, b=None, c=None):
pass
class A(object):
def __init__(self, a, b, c):
pass
def method(self, a, b, c):
pass
class Callable(object):
def __call__(self, a, b, c):
pass
a = A(1, 2, 3)
cal = Callable()
self.assertEqual(get_func_args(f1), ['a', 'b', 'c'])
self.assertEqual(get_func_args(f2), ['a', 'b', 'c'])
self.assertEqual(get_func_args(A), ['a', 'b', 'c'])
self.assertEqual(get_func_args(a.method), ['a', 'b', 'c'])
self.assertEqual(get_func_args(cal), ['a', 'b', 'c'])
if __name__ == "__main__":
unittest.main()

View File

@ -150,11 +150,15 @@ def get_func_args(func):
"""Return the argument name list of a callable"""
if inspect.isfunction(func):
func_args, _, _, _ = inspect.getargspec(func)
elif inspect.isclass(func):
func_args, _, _, _ = inspect.getargspec(func.__init__)
func_args.pop(0) # self
elif inspect.ismethod(func):
func_args, _, _, _ = inspect.getargspec(func.__func__)
func_args.pop(0) # self
elif hasattr(func, '__call__'):
try:
func_args, _, _, _ = inspect.getargspec(func.__call__)
except Exception:
func_args = []
func_args, _, _, _ = inspect.getargspec(func.__call__)
func_args.pop(0) # self
else:
raise TypeError('%s is not callable' % type(func))
return func_args