Fix is_simple_callable with variable args, kwargs (#4622)

This commit is contained in:
Ryan P Kilby 2016-10-25 15:47:24 -04:00 committed by Tom Christie
parent 1bd35ad355
commit eafc9a2393
2 changed files with 30 additions and 2 deletions

View File

@ -54,12 +54,17 @@ if six.PY3:
"""
True if the object is a callable that takes no arguments.
"""
if not callable(obj):
if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
return False
sig = inspect.signature(obj)
params = sig.parameters.values()
return all(param.default != param.empty for param in params)
return all(
param.kind == param.VAR_POSITIONAL or
param.kind == param.VAR_KEYWORD or
param.default != param.empty
for param in params
)
else:
def is_simple_callable(obj):

View File

@ -37,6 +37,9 @@ class TestIsSimpleCallable:
def valid_kwargs(self, param='value'):
pass
def valid_vargs_kwargs(self, *args, **kwargs):
pass
def invalid(self, param):
pass
@ -45,11 +48,13 @@ class TestIsSimpleCallable:
# unbound methods
assert not is_simple_callable(Foo.valid)
assert not is_simple_callable(Foo.valid_kwargs)
assert not is_simple_callable(Foo.valid_vargs_kwargs)
assert not is_simple_callable(Foo.invalid)
# bound methods
assert is_simple_callable(Foo().valid)
assert is_simple_callable(Foo().valid_kwargs)
assert is_simple_callable(Foo().valid_vargs_kwargs)
assert not is_simple_callable(Foo().invalid)
def test_function(self):
@ -59,13 +64,31 @@ class TestIsSimpleCallable:
def valid(param='value', param2='value'):
pass
def valid_vargs_kwargs(*args, **kwargs):
pass
def invalid(param, param2='value'):
pass
assert is_simple_callable(simple)
assert is_simple_callable(valid)
assert is_simple_callable(valid_vargs_kwargs)
assert not is_simple_callable(invalid)
def test_4602_regression(self):
from django.db import models
class ChoiceModel(models.Model):
choice_field = models.CharField(
max_length=1, default='a',
choices=(('a', 'A'), ('b', 'B')),
)
class Meta:
app_label = 'tests'
assert is_simple_callable(ChoiceModel().get_choice_field_display)
@unittest.skipUnless(typings, 'requires python 3.5')
def test_type_annotation(self):
# The annotation will otherwise raise a syntax error in python < 3.5