Don't swallow AttributeError in core.urlresolvers.get_callable.

This commit is contained in:
Florian Apolloner 2012-08-14 21:12:08 +02:00
parent 37c9318748
commit 367bfaa522
3 changed files with 34 additions and 13 deletions

View File

@ -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)

View File

@ -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')

View File

@ -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')