Code

Ticket #10802: django-10802.diff

File django-10802.diff, 6.3 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:57:41 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/erroneous_urls.py
71--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
72+++ b/tests/regressiontests/urlpatterns_reverse/erroneous_urls.py       Wed Jun 15 13:57:41 2011 +0200
73@@ -0,0 +1,15 @@
74+
75+from django.conf.urls.defaults import *
76+
77+urlpatterns = patterns('',
78+    # View has erroneous import
79+    url(r'erroneous_inner/$', 'regressiontests.urlpatterns_reverse.views.erroneous_view'),
80+    # Module has erroneous import
81+    url(r'erroneous_outer/$', 'regressiontests.urlpatterns_reverse.erroneous_views_module.erroneous_view'),
82+    # View does not exist
83+    url(r'missing_inner/$', 'regressiontests.urlpatterns_reverse.views.missing_view'),
84+    # View is not callable
85+    url(r'uncallable/$', 'regressiontests.urlpatterns_reverse.views.uncallable'),
86+    # Module does not exist
87+    url(r'missing_outer/$', 'regressiontests.urlpatterns_reverse.missing_module.missing_view'),
88+)
89diff -r f7582637764c tests/regressiontests/urlpatterns_reverse/erroneous_views_module.py
90--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
91+++ b/tests/regressiontests/urlpatterns_reverse/erroneous_views_module.py       Wed Jun 15 13:57:41 2011 +0200
92@@ -0,0 +1,4 @@
93+import non_existent
94+
95+def erroneous_view(request):
96+    pass
97diff -r f7582637764c tests/regressiontests/urlpatterns_reverse/tests.py
98--- a/tests/regressiontests/urlpatterns_reverse/tests.py        Tue Jun 14 23:37:12 2011 +0000
99+++ b/tests/regressiontests/urlpatterns_reverse/tests.py        Wed Jun 15 13:57:41 2011 +0200
100@@ -2,7 +2,7 @@
101 Unit tests for reverse URL lookups.
102 """
103 from django.conf import settings
104-from django.core.exceptions import ImproperlyConfigured
105+from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
106 from django.core.urlresolvers import reverse, resolve, NoReverseMatch,\
107                                      Resolver404, ResolverMatch,\
108                                      RegexURLResolver, RegexURLPattern
109@@ -470,3 +470,14 @@
110             self.assertEqual(match[0], func)
111             self.assertEqual(match[1], args)
112             self.assertEqual(match[2], kwargs)
113+
114+class ErroneousViewTests(TestCase):
115+    urls = 'regressiontests.urlpatterns_reverse.erroneous_urls'
116+
117+    def test_erroneous_resolve(self):
118+        self.assertRaises(ImportError, self.client.get, '/erroneous_inner/')
119+        self.assertRaises(ImportError, self.client.get, '/erroneous_outer/')
120+        self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_inner/')
121+        self.assertRaises(ViewDoesNotExist, self.client.get, '/missing_outer/')
122+        self.assertRaises(ViewDoesNotExist, self.client.get, '/uncallable/')
123+
124diff -r f7582637764c tests/regressiontests/urlpatterns_reverse/views.py
125--- a/tests/regressiontests/urlpatterns_reverse/views.py        Tue Jun 14 23:37:12 2011 +0000
126+++ b/tests/regressiontests/urlpatterns_reverse/views.py        Wed Jun 15 13:57:41 2011 +0200
127@@ -16,6 +16,11 @@
128 def defaults_view(request, arg1, arg2):
129     pass
130 
131+def erroneous_view(request):
132+    import non_existent
133+
134+uncallable = "Can I be a view? Pleeeease?"
135+
136 class ViewClass(object):
137     def __call__(self, request, *args, **kwargs):
138         return HttpResponse('')