This commit is contained in:
lexdene 2016-05-31 00:39:17 +00:00
commit eb9fc08bd0
3 changed files with 40 additions and 20 deletions

View File

@ -6,6 +6,8 @@ versions of Django/Python, and compatibility wrappers around optional packages.
# flake8: noqa # flake8: noqa
from __future__ import unicode_literals from __future__ import unicode_literals
import inspect
import django import django
from django.conf import settings from django.conf import settings
from django.db import connection, transaction from django.db import connection, transaction
@ -185,3 +187,36 @@ def template_render(template, context=None, request=None):
# backends template, e.g. django.template.backends.django.Template # backends template, e.g. django.template.backends.django.Template
else: else:
return template.render(context, request=request) return template.render(context, request=request)
def is_simple_callable(obj):
"""
True if the object is a callable that takes no arguments.
"""
function = inspect.isfunction(obj)
method = inspect.ismethod(obj)
if not (function or method):
return False
# - `inspect.signature` is introduced in Python 3.3
# - `inspect.getfullargspec` is introduced in Python 3.0
# and deprecated since Python 3.5
# - `inspect.getargspec` is deprecated since Python 3.0
if hasattr(inspect, 'signature'):
sig = inspect.signature(obj)
for name, param in sig.parameters.items():
if param.default is not inspect.Parameter.empty:
return False
return True
else:
if hasattr(inspect, 'getfullargspec'):
spec = inspect.getfullargspec(obj)
args, defaults = spec.args, spec.defaults
else:
args, _, _, defaults = inspect.getargspec(obj)
len_args = len(args) if function else len(args) - 1
len_defaults = len(defaults) if defaults else 0
return len_args <= len_defaults

View File

@ -30,7 +30,9 @@ from django.utils.ipv6 import clean_ipv6_address
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework import ISO_8601 from rest_framework import ISO_8601
from rest_framework.compat import unicode_repr, unicode_to_repr from rest_framework.compat import (
is_simple_callable, unicode_repr, unicode_to_repr
)
from rest_framework.exceptions import ValidationError from rest_framework.exceptions import ValidationError
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
from rest_framework.utils import html, humanize_datetime, representation from rest_framework.utils import html, humanize_datetime, representation
@ -46,22 +48,6 @@ class empty:
pass pass
def is_simple_callable(obj):
"""
True if the object is a callable that takes no arguments.
"""
function = inspect.isfunction(obj)
method = inspect.ismethod(obj)
if not (function or method):
return False
args, _, _, defaults = inspect.getargspec(obj)
len_args = len(args) if function 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):
""" """
Similar to Python's built in `getattr(instance, attr)`, Similar to Python's built in `getattr(instance, attr)`,

View File

@ -14,9 +14,8 @@ from django.utils.encoding import smart_text
from django.utils.six.moves.urllib import parse as urlparse from django.utils.six.moves.urllib import parse as urlparse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from rest_framework.fields import ( from rest_framework.compat import is_simple_callable
Field, empty, get_attribute, is_simple_callable, iter_options from rest_framework.fields import Field, empty, get_attribute, iter_options
)
from rest_framework.reverse import reverse from rest_framework.reverse import reverse
from rest_framework.utils import html from rest_framework.utils import html