Kaydet (Commit) 367bfaa5 authored tarafından Florian Apolloner's avatar Florian Apolloner

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

üst 37c93187
...@@ -89,18 +89,11 @@ def get_callable(lookup_view, can_fail=False): ...@@ -89,18 +89,11 @@ def get_callable(lookup_view, can_fail=False):
""" """
if not callable(lookup_view): if not callable(lookup_view):
mod_name, func_name = get_mod_func(lookup_view) mod_name, func_name = get_mod_func(lookup_view)
if func_name == '':
return lookup_view
try: try:
if func_name != '': mod = import_module(mod_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))
except ImportError: except ImportError:
parentmod, submod = get_mod_func(mod_name) parentmod, submod = get_mod_func(mod_name)
if (not can_fail and submod != '' and if (not can_fail and submod != '' and
...@@ -110,6 +103,18 @@ def get_callable(lookup_view, can_fail=False): ...@@ -110,6 +103,18 @@ def get_callable(lookup_view, can_fail=False):
(lookup_view, mod_name)) (lookup_view, mod_name))
if not can_fail: if not can_fail:
raise 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 return lookup_view
get_callable = memoize(get_callable, _callable_cache, 1) get_callable = memoize(get_callable, _callable_cache, 1)
......
...@@ -5,8 +5,9 @@ from __future__ import absolute_import, unicode_literals ...@@ -5,8 +5,9 @@ from __future__ import absolute_import, unicode_literals
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
from django.core.urlresolvers import (reverse, resolve, NoReverseMatch, from django.core.urlresolvers import (reverse, resolve, get_callable,
Resolver404, ResolverMatch, RegexURLResolver, RegexURLPattern) NoReverseMatch, Resolver404, ResolverMatch, RegexURLResolver,
RegexURLPattern)
from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect from django.http import HttpResponseRedirect, HttpResponsePermanentRedirect
from django.shortcuts import redirect from django.shortcuts import redirect
from django.test import TestCase from django.test import TestCase
...@@ -519,3 +520,16 @@ class ErroneousViewTests(TestCase): ...@@ -519,3 +520,16 @@ class ErroneousViewTests(TestCase):
""" """
# The regex error will be hit before NoReverseMatch can be raised # The regex error will be hit before NoReverseMatch can be raised
self.assertRaises(ImproperlyConfigured, reverse, 'whatever blah blah') 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')
# I just raise an AttributeError to confuse the view loading mechanism
raise AttributeError('I am here to confuse django.core.urlresolvers.get_callable')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment