emit a warning when a setting has an unexpected type

This commit is contained in:
Craig Blaszczyk 2014-12-29 13:15:54 +00:00
parent 88ea5d6bb0
commit eb04133bb9
2 changed files with 37 additions and 8 deletions

View File

@ -18,6 +18,7 @@ REST framework settings, checking for user settings first, then falling
back to the defaults.
"""
from __future__ import unicode_literals
from collections import Iterable
import warnings
from django.conf import settings
from django.utils import importlib, six
@ -190,13 +191,21 @@ class APISettings(object):
# Fall back to defaults
val = self.defaults[attr]
else:
expected_class = self.defaults[attr].__class__
if val.__class__ != expected_class:
# Verify that the user hasn't accidentally given a string instead
# of an iterable, or vice-versa
default = self.defaults[attr]
if issubclass(val.__class__, Iterable) \
and (not issubclass(default.__class__, Iterable)
or isinstance(val, basestring)):
warnings.warn(
"The `{val}` setting has the class {val.__class__}, "
"but the expected class was {expected_class}".format(
**locals()
),
"The `{attr}` setting must be iterable".format(**locals()),
RESTFrameworkSettingHasUnexpectedClassWarning,
stacklevel=3
)
elif isinstance(default, basestring) and not \
isinstance(val, basestring):
warnings.warn(
"The `{attr}` setting must be a string".format(**locals()),
RESTFrameworkSettingHasUnexpectedClassWarning,
stacklevel=3
)

View File

@ -19,9 +19,10 @@ class TestSettings(TestCase):
with self.assertRaises(ImportError):
settings.DEFAULT_RENDERER_CLASSES
def test_bad_setting_class_raises_warning(self):
def test_bad_iterable_setting_class_raises_warning(self):
"""
Make sure warnings are emitted when settings have an unexpected class.
Make sure warnings are emitted when settings which should be iterable
are not.
"""
settings = APISettings({
'DEFAULT_RENDERER_CLASSES': 'rest_framework.renderers.JSONRenderer'
@ -35,3 +36,22 @@ class TestSettings(TestCase):
assert issubclass(
w[-1].category, RESTFrameworkSettingHasUnexpectedClassWarning
)
def test_bad_string_setting_class_raises_warning(self):
"""
Make sure warnings are emitted when settings which should be strings are
not.
"""
settings = APISettings({
'DEFAULT_METADATA_CLASS': []
})
with warnings.catch_warnings(record=True) as w:
# Trigger a warning.
settings.DEFAULT_METADATA_CLASS
# Verify that a warning is thrown
assert len(w) == 1
assert issubclass(
w[-1].category, RESTFrameworkSettingHasUnexpectedClassWarning
)