Opened 4 years ago

Closed 4 years ago

#21766 closed Bug (invalid)

Can't use reverse() or is_valid_path() with dynamically set TestCase.urls

Reported by: paulmelnikow Owned by: nobody
Component: Uncategorized Version: 1.6
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


I'm writing a component and need to override urls in a TestCase. This works fine if I set urls to a string with a module name, but the common middleware raises an exception if I specify a set of patterns.

Traceback (most recent call last):
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/test/", line 249, in inner
    return test_func(*args, **kwargs)
  File "/Users/pnm/code/django-url-bug/", line 26, in test_hello_2
    resp = self.client.get('/hello')
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/test/", line 473, in get
    response = super(Client, self).get(path, data=data, **extra)
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/test/", line 280, in get
    return self.request(**r)
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/test/", line 426, in request
    response = self.handler(environ)
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/test/", line 109, in __call__
    response = self.get_response(request)
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/core/handlers/", line 196, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/core/handlers/", line 90, in get_response
    response = middleware_method(request)
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/middleware/", line 71, in process_request
    if (not urlresolvers.is_valid_path(request.path_info, urlconf) and
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/core/", line 573, in is_valid_path
    resolve(path, urlconf)
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/core/", line 453, in resolve
    return get_resolver(urlconf).resolve(path)
  File "/Users/pnm/code/django-url-bug/venv/lib/python2.7/site-packages/django/utils/", line 30, in wrapper
    if mem_args in cache:
TypeError: unhashable type: 'list'

If the patterns end with slashes, or if APPEND_SLASH is False, the problem goes away.

Here's code with a test example. In the test below, test_hello_2 fails with the stack trace above. test_hello_1 and test_hello_3 pass.

from django.test import TestCase
from django.test.utils import override_settings

def view_func(r):
    from django.http import HttpResponse
    return HttpResponse('Hello, World!')

class UrlTestOverriddenExplicit(TestCase):
    from django.conf.urls import patterns, url
    urls = patterns('',
        url(r'^hello/$', view_func),

    def test_hello_1(self):
        resp = self.client.get('/hello/')
        self.assertEquals(resp.status_code, 200)

class UrlTestOverriddenExplicitWithoutSlash(TestCase):
    from django.conf.urls import patterns, url
    urls = patterns('',
        url(r'^hello$', view_func),

    def test_hello_2(self):
        resp = self.client.get('/hello')
        self.assertEquals(resp.status_code, 200)

    def test_hello_3(self):
        resp = self.client.get('/hello')
        self.assertEquals(resp.status_code, 200)

Change History (2)

comment:1 Changed 4 years ago by paulmelnikow

Summary: Exception with dynamic TestCase.urls and settings.APPEND_SLASH=TrueCan't use reverse() or is_valid_path() with dynamically set TestCase.urls

This issue also seems to affect reverse() as well as is_valid_path(). To test views which require reverse(), setting APPEND_SLASH=False won't work, so I put the urlconf into the test module instead.

urlpatterns = patterns('',
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),

class TestLogin(TestCase):
    urls = 'myapp.tests.test_login'

comment:2 Changed 4 years ago by Baptiste Mispelon

Resolution: invalid
Status: newclosed


The problem is that django.test.TestCase.urls is supposed to be a string pointing to the URLconf module, not a list of patterns.

This is documented there:

Though I agree that the documentation is not completely clear, it does say that this attribute should be like settings.ROOT_URLCONF which is itself clearly documented as being a string.

Consequently, I'll close this ticket as invalid.
Feel free to reopen it if, for example, you have suggestions for how to improve the documentation or if you think this should be a new feature.


Note: See TracTickets for help on using tickets.
Back to Top