mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-07 13:54:47 +03:00
Merge b3afcb25d9
into 4ff9e96b4c
This commit is contained in:
commit
e98b1215b7
|
@ -14,7 +14,6 @@ env:
|
||||||
- TOX_ENV=py35-django18
|
- TOX_ENV=py35-django18
|
||||||
- TOX_ENV=py34-django18
|
- TOX_ENV=py34-django18
|
||||||
- TOX_ENV=py33-django18
|
- TOX_ENV=py33-django18
|
||||||
- TOX_ENV=py32-django18
|
|
||||||
- TOX_ENV=py27-django18
|
- TOX_ENV=py27-django18
|
||||||
- TOX_ENV=py27-django110
|
- TOX_ENV=py27-django110
|
||||||
- TOX_ENV=py35-django110
|
- TOX_ENV=py35-django110
|
||||||
|
|
|
@ -49,20 +49,34 @@ class empty:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def is_simple_callable(obj):
|
if six.PY3:
|
||||||
"""
|
def is_simple_callable(obj):
|
||||||
True if the object is a callable that takes no arguments.
|
"""
|
||||||
"""
|
True if the object is a callable that takes no arguments.
|
||||||
function = inspect.isfunction(obj)
|
"""
|
||||||
method = inspect.ismethod(obj)
|
if not callable(obj):
|
||||||
|
return False
|
||||||
|
|
||||||
if not (function or method):
|
sig = inspect.signature(obj)
|
||||||
return False
|
params = sig.parameters.values()
|
||||||
|
return all(param.default != param.empty for param in params)
|
||||||
|
|
||||||
args, _, _, defaults = inspect.getargspec(obj)
|
else:
|
||||||
len_args = len(args) if function else len(args) - 1
|
def is_simple_callable(obj):
|
||||||
len_defaults = len(defaults) if defaults else 0
|
function = inspect.isfunction(obj)
|
||||||
return len_args <= len_defaults
|
method = inspect.ismethod(obj)
|
||||||
|
|
||||||
|
if not (function or method):
|
||||||
|
return False
|
||||||
|
|
||||||
|
if method:
|
||||||
|
is_unbound = obj.im_self is None
|
||||||
|
|
||||||
|
args, _, _, defaults = inspect.getargspec(obj)
|
||||||
|
|
||||||
|
len_args = len(args) if function or is_unbound else len(args) - 1
|
||||||
|
len_defaults = len(defaults) if defaults else 0
|
||||||
|
return len_args <= len_defaults
|
||||||
|
|
||||||
|
|
||||||
def get_attribute(instance, attrs):
|
def get_attribute(instance, attrs):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import unittest
|
||||||
import uuid
|
import uuid
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
|
|
||||||
|
@ -11,6 +12,67 @@ from django.utils import six, timezone
|
||||||
|
|
||||||
import rest_framework
|
import rest_framework
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
from rest_framework.fields import is_simple_callable
|
||||||
|
|
||||||
|
try:
|
||||||
|
import typings
|
||||||
|
except ImportError:
|
||||||
|
typings = False
|
||||||
|
|
||||||
|
|
||||||
|
# Tests for helper functions.
|
||||||
|
# ---------------------------
|
||||||
|
|
||||||
|
class TestIsSimpleCallable:
|
||||||
|
|
||||||
|
def test_method(self):
|
||||||
|
class Foo:
|
||||||
|
@classmethod
|
||||||
|
def classmethod(cls):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def valid(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def valid_kwargs(self, param='value'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def invalid(self, param):
|
||||||
|
pass
|
||||||
|
|
||||||
|
assert is_simple_callable(Foo.classmethod)
|
||||||
|
|
||||||
|
# unbound methods
|
||||||
|
assert not is_simple_callable(Foo.valid)
|
||||||
|
assert not is_simple_callable(Foo.valid_kwargs)
|
||||||
|
assert not is_simple_callable(Foo.invalid)
|
||||||
|
|
||||||
|
# bound methods
|
||||||
|
assert is_simple_callable(Foo().valid)
|
||||||
|
assert is_simple_callable(Foo().valid_kwargs)
|
||||||
|
assert not is_simple_callable(Foo().invalid)
|
||||||
|
|
||||||
|
def test_function(self):
|
||||||
|
def simple():
|
||||||
|
pass
|
||||||
|
|
||||||
|
def valid(param='value', param2='value'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def invalid(param, param2='value'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
assert is_simple_callable(simple)
|
||||||
|
assert is_simple_callable(valid)
|
||||||
|
assert not is_simple_callable(invalid)
|
||||||
|
|
||||||
|
@unittest.skipUnless(typings, 'requires python 3.5')
|
||||||
|
def test_type_annotation(self):
|
||||||
|
# The annotation will otherwise raise a syntax error in python < 3.5
|
||||||
|
exec("def valid(param: str='value'): pass", locals())
|
||||||
|
valid = locals()['valid']
|
||||||
|
|
||||||
|
assert is_simple_callable(valid)
|
||||||
|
|
||||||
|
|
||||||
# Tests for field keyword arguments and core functionality.
|
# Tests for field keyword arguments and core functionality.
|
||||||
|
|
3
tox.ini
3
tox.ini
|
@ -4,7 +4,7 @@ addopts=--tb=short
|
||||||
[tox]
|
[tox]
|
||||||
envlist =
|
envlist =
|
||||||
py27-{lint,docs},
|
py27-{lint,docs},
|
||||||
{py27,py32,py33,py34,py35}-django18,
|
{py27,py33,py34,py35}-django18,
|
||||||
{py27,py34,py35}-django19,
|
{py27,py34,py35}-django19,
|
||||||
{py27,py34,py35}-django110,
|
{py27,py34,py35}-django110,
|
||||||
{py27,py34,py35}-django{master}
|
{py27,py34,py35}-django{master}
|
||||||
|
@ -25,7 +25,6 @@ basepython =
|
||||||
py35: python3.5
|
py35: python3.5
|
||||||
py34: python3.4
|
py34: python3.4
|
||||||
py33: python3.3
|
py33: python3.3
|
||||||
py32: python3.2
|
|
||||||
py27: python2.7
|
py27: python2.7
|
||||||
|
|
||||||
[testenv:py27-lint]
|
[testenv:py27-lint]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user