Code

Ticket #10802: django-10802.2.diff

File django-10802.2.diff, 5.1 KB (added by bpeschier, 3 years ago)
Line 
1diff -r f7582637764c django/core/urlresolvers.py
2--- a/django/core/urlresolvers.py       Tue Jun 14 23:37:12 2011 +0000
3+++ b/django/core/urlresolvers.py       Wed Jun 15 13:50:49 2011 +0200
4@@ -17,6 +17,7 @@
5 from django.utils.encoding import iri_to_uri, force_unicode, smart_str
6 from django.utils.functional import memoize, lazy
7 from django.utils.importlib import import_module
8+from django.utils.module_loading import module_has_submodule
9 from django.utils.regex_helper import normalize
10 
11 _resolver_cache = {} # Maps URLconf modules to RegexURLResolver instances.
12@@ -83,19 +84,21 @@
13     during the import fail and the string is returned.
14     """
15     if not callable(lookup_view):
16+        mod_name, func_name = get_mod_func(lookup_view)
17         try:
18-            # Bail early for non-ASCII strings (they can't be functions).
19-            lookup_view = lookup_view.encode('ascii')
20-            mod_name, func_name = get_mod_func(lookup_view)
21             if func_name != '':
22                 lookup_view = getattr(import_module(mod_name), func_name)
23                 if not callable(lookup_view):
24-                    raise AttributeError("'%s.%s' is not a callable." % (mod_name, func_name))
25-        except (ImportError, AttributeError):
26+                    raise ViewDoesNotExist("Could not import %s.%s. View is not callable." % (mod_name, func_name))
27+        except AttributeError:
28+            if not can_fail:
29+                raise ViewDoesNotExist("Could not import %s. View does not exist in module %s." % (lookup_view, mod_name))
30+        except ImportError:
31+            ownermod, submod = get_mod_func(mod_name)
32+            if not can_fail and submod != '' and not module_has_submodule(import_module(ownermod), submod):
33+                raise ViewDoesNotExist("Could not import %s. Owning module %s does not exist." % (lookup_view, mod_name))
34             if not can_fail:
35                 raise
36-        except UnicodeEncodeError:
37-            pass
38     return lookup_view
39 get_callable = memoize(get_callable, _callable_cache, 1)
40 
41@@ -160,14 +163,8 @@
42     def _get_callback(self):
43         if self._callback is not None:
44             return self._callback
45-        try:
46-            self._callback = get_callable(self._callback_str)
47-        except ImportError, e:
48-            mod_name, _ = get_mod_func(self._callback_str)
49-            raise ViewDoesNotExist("Could not import %s. Error was: %s" % (mod_name, str(e)))
50-        except AttributeError, e:
51-            mod_name, func_name = get_mod_func(self._callback_str)
52-            raise ViewDoesNotExist("Tried %s in module %s. Error was: %s" % (func_name, mod_name, str(e)))
53+
54+        self._callback = get_callable(self._callback_str)
55         return self._callback
56     callback = property(_get_callback)
57 
58@@ -291,10 +288,7 @@
59             # Lazy import, since urls.defaults imports this file
60             from django.conf.urls import defaults
61             callback = getattr(defaults, 'handler%s' % view_type)
62-        try:
63-            return get_callable(callback), {}
64-        except (ImportError, AttributeError), e:
65-            raise ViewDoesNotExist("Tried %s. Error was: %s" % (callback, str(e)))
66+        return get_callable(callback), {}
67 
68     def resolve404(self):
69         return self._resolve_special('404')
70diff -r f7582637764c tests/regressiontests/urlpatterns_reverse/tests.py
71--- a/tests/regressiontests/urlpatterns_reverse/tests.py        Tue Jun 14 23:37:12 2011 +0000
72+++ b/tests/regressiontests/urlpatterns_reverse/tests.py        Wed Jun 15 13:50:49 2011 +0200
73@@ -2,7 +2,7 @@
74 Unit tests for reverse URL lookups.
75 """
76 from django.conf import settings
77-from django.core.exceptions import ImproperlyConfigured
78+from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
79 from django.core.urlresolvers import reverse, resolve, NoReverseMatch,\
80                                      Resolver404, ResolverMatch,\
81                                      RegexURLResolver, RegexURLPattern
82@@ -470,3 +470,14 @@
83             self.assertEqual(match[0], func)
84             self.assertEqual(match[1], args)
85             self.assertEqual(match[2], kwargs)
86+
87+class ErroneousViewTests(TestCase):
88+    urls = 'regressiontests.urlpatterns_reverse.erroneous_urls'
89+
90+    def test_erroneous_resolve(self):
91+        self.assertRaises(ImportError, self.client.get, '/erroneous_inner/')
92+        self.assertRaises(ImportError, self.client.get, '/erroneous_outer/')
93+        self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_inner/')
94+        self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_outer/')
95+        self.assertRaises(ViewDoesNotExist, self.client.get, '/uncallable/')
96+
97diff -r f7582637764c tests/regressiontests/urlpatterns_reverse/views.py
98--- a/tests/regressiontests/urlpatterns_reverse/views.py        Tue Jun 14 23:37:12 2011 +0000
99+++ b/tests/regressiontests/urlpatterns_reverse/views.py        Wed Jun 15 13:50:49 2011 +0200
100@@ -16,6 +16,11 @@
101 def defaults_view(request, arg1, arg2):
102     pass
103 
104+def erroneous_view(request):
105+    import non_existent
106+
107+uncallable = "Can I be a view? Pleeeease?"
108+
109 class ViewClass(object):
110     def __call__(self, request, *args, **kwargs):
111         return HttpResponse('')