raise ImproperlyConfigured error when settings have the wrong type

This commit is contained in:
Craig Blaszczyk 2015-01-08 17:37:41 +00:00
parent 7308e34c2e
commit 49ad4750c6
3 changed files with 23 additions and 32 deletions

View File

@ -146,6 +146,3 @@ class Throttled(APIException):
self.extra_detail % {'wait': self.wait} self.extra_detail % {'wait': self.wait}
) )
class RESTFrameworkSettingHasUnexpectedClassWarning(Warning):
pass

View File

@ -19,11 +19,10 @@ back to the defaults.
""" """
from __future__ import unicode_literals from __future__ import unicode_literals
from collections import Iterable from collections import Iterable
import warnings from django.core.exceptions import ImproperlyConfigured
from django.conf import settings from django.conf import settings
from django.utils import importlib, six from django.utils import importlib, six
from rest_framework import ISO_8601 from rest_framework import ISO_8601
from rest_framework.exceptions import RESTFrameworkSettingHasUnexpectedClassWarning
USER_SETTINGS = getattr(settings, 'REST_FRAMEWORK', None) USER_SETTINGS = getattr(settings, 'REST_FRAMEWORK', None)
@ -197,17 +196,14 @@ class APISettings(object):
if issubclass(val.__class__, Iterable) \ if issubclass(val.__class__, Iterable) \
and (not issubclass(default.__class__, Iterable) and (not issubclass(default.__class__, Iterable)
or isinstance(val, six.string_types)): or isinstance(val, six.string_types)):
warnings.warn( raise ImproperlyConfigured(
"The `{attr}` setting must be iterable".format(**locals()), 'The "{attr}" setting must be a list or a tuple'
RESTFrameworkSettingHasUnexpectedClassWarning, .format(attr=attr)
stacklevel=3
) )
elif isinstance(default, six.string_types) and not \ elif isinstance(default, six.string_types) and not \
isinstance(val, six.string_types): isinstance(val, six.string_types):
warnings.warn( raise ImproperlyConfigured(
"The `{attr}` setting must be a string".format(**locals()), 'The "{attr}" setting must be a string'.format(attr=attr)
RESTFrameworkSettingHasUnexpectedClassWarning,
stacklevel=3
) )
# Coerce import strings into classes # Coerce import strings into classes

View File

@ -1,8 +1,8 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from django.core.exceptions import ImproperlyConfigured
import pytest
import warnings import warnings
from django.test import TestCase from django.test import TestCase
from rest_framework.exceptions import \
RESTFrameworkSettingHasUnexpectedClassWarning
from rest_framework.settings import APISettings from rest_framework.settings import APISettings
@ -21,37 +21,35 @@ class TestSettings(TestCase):
def test_bad_iterable_setting_class_raises_warning(self): def test_bad_iterable_setting_class_raises_warning(self):
""" """
Make sure warnings are emitted when settings which should be iterable Make sure errors are raised when settings which should be iterable are
are not. not.
""" """
settings = APISettings({ settings = APISettings({
'DEFAULT_RENDERER_CLASSES': 'rest_framework.renderers.JSONRenderer' 'DEFAULT_RENDERER_CLASSES': 'rest_framework.renderers.JSONRenderer'
}) })
with warnings.catch_warnings(record=True) as w: # Trigger the exception
# Trigger a warning. with pytest.raises(ImproperlyConfigured) as exc_info:
settings.DEFAULT_RENDERER_CLASSES settings.DEFAULT_RENDERER_CLASSES
# Verify that a warning is thrown expected_error = (
assert len(w) == 1 u'The "DEFAULT_RENDERER_CLASSES" setting must be a list or a tuple'
assert issubclass(
w[-1].category, RESTFrameworkSettingHasUnexpectedClassWarning
) )
assert exc_info.value[0] == expected_error
def test_bad_string_setting_class_raises_warning(self): def test_bad_string_setting_class_raises_warning(self):
""" """
Make sure warnings are emitted when settings which should be strings are Make sure errors are raised when settings which should be strings are
not. not.
""" """
settings = APISettings({ settings = APISettings({
'DEFAULT_METADATA_CLASS': [] 'DEFAULT_METADATA_CLASS': []
}) })
with warnings.catch_warnings(record=True) as w: # Trigger the exception
# Trigger a warning. with pytest.raises(ImproperlyConfigured) as exc_info:
settings.DEFAULT_METADATA_CLASS settings.DEFAULT_METADATA_CLASS
# Verify that a warning is thrown expected_error = (
assert len(w) == 1 u'The "DEFAULT_METADATA_CLASS" setting must be a string'
assert issubclass(
w[-1].category, RESTFrameworkSettingHasUnexpectedClassWarning
) )
assert exc_info.value[0] == expected_error