Don't swallow AttributeError in core.urlresolvers.get_callable.
This commit is contained in:
parent
37c9318748
commit
367bfaa522
|
@ -89,18 +89,11 @@ def get_callable(lookup_view, can_fail=False):
|
|||
"""
|
||||
if not callable(lookup_view):
|
||||
mod_name, func_name = get_mod_func(lookup_view)
|
||||
if func_name == '':
|
||||
return lookup_view
|
||||
|
||||
try:
|
||||
if func_name != '':
|
||||
lookup_view = getattr(import_module(mod_name), func_name)
|
||||
if not callable(lookup_view):
|
||||
raise ViewDoesNotExist(
|
||||
"Could not import %s.%s. View is not callable." %
|
||||
(mod_name, func_name))
|
||||
except AttributeError:
|
||||
if not can_fail:
|
||||
raise ViewDoesNotExist(
|
||||
"Could not import %s. View does not exist in module %s." %
|
||||
(lookup_view, mod_name))
|
||||
mod = import_module(mod_name)
|
||||
except ImportError:
|
||||
parentmod, submod = get_mod_func(mod_name)
|
||||
if (not can_fail and submod != '' and
|
||||
|
@ -110,6 +103,18 @@ def get_callable(lookup_view, can_fail=False):
|
|||
(lookup_view, mod_name))
|
||||
if not can_fail:
|
||||
raise
|
||||
else:
|
||||
try:
|
||||
lookup_view = getattr(mod, func_name)
|
||||
if not callable(lookup_view):
|
||||
raise ViewDoesNotExist(
|
||||
"Could not import %s.%s. View is not callable." %
|
||||
(mod_name, func_name))
|
||||
except AttributeError:
|
||||
if not can_fail:
|
||||
raise ViewDoesNotExist(
|
||||
"Could not import %s. View does not exist in module %s." %
|
||||
(lookup_view, mod_name))
|
||||
return lookup_view
|
||||
get_callable = memoize(get_callable, _callable_cache, 1)
|
||||
|
||||
|
|
|
@ -5,8 +5,9 @@ from __future__ import absolute_import, unicode_literals
|
|||
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
|
||||
from django.core.urlresolvers import (reverse, resolve, NoReverseMatch,
|
||||
Resolver404, ResolverMatch, RegexURLResolver, RegexURLPattern)
|
||||
from django.core.urlresolvers import (reverse, resolve, get_callable,
|
||||
NoReverseMatch, Resolver404, ResolverMatch, RegexURLResolver,
|
||||
RegexURLPattern)
|
||||
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
|
||||
from django.shortcuts import redirect
|
||||
from django.test import TestCase
|
||||
|
@ -519,3 +520,16 @@ class ErroneousViewTests(TestCase):
|
|||
"""
|
||||
# The regex error will be hit before NoReverseMatch can be raised
|
||||
self.assertRaises(ImproperlyConfigured, reverse, 'whatever blah blah')
|
||||
|
||||
class ViewLoadingTests(TestCase):
|
||||
def test_view_loading(self):
|
||||
# A missing view (identified by an AttributeError) should raise
|
||||
# ViewDoesNotExist, ...
|
||||
self.assertRaisesRegexp(ViewDoesNotExist, ".*View does not exist in.*",
|
||||
get_callable,
|
||||
'regressiontests.urlpatterns_reverse.views.i_should_not_exist')
|
||||
# ... but if the AttributeError is caused by something else don't
|
||||
# swallow it.
|
||||
self.assertRaises(AttributeError, get_callable,
|
||||
'regressiontests.urlpatterns_reverse.views_broken.i_am_broken')
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# I just raise an AttributeError to confuse the view loading mechanism
|
||||
raise AttributeError('I am here to confuse django.core.urlresolvers.get_callable')
|
Loading…
Reference in New Issue