7

I am trying to update my 1.9 application to 1.10 and I am getting the following error on running all my unit tests:

Traceback (most recent call last):   File "/home/…/tests/views/test_configurator.py", line 261, in test_view_configurator_post
    args=[self.configurator.id]),   File "/home/…/.virtualenvs/intranet/lib/python2.7/site-packages/django/urls/base.py", line 87, in reverse
    raise NoReverseMatch("%s is not a registered namespace" % key) NoReverseMatch: 'en-gb' is not a registered namespace

My setting.py file contains the following:

LANGUAGE_CODE = 'en-gb'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
TIME_ZONE = 'Europe/London'

What am I missing?

Sardathrion - against SE abuse
  • 17,269
  • 27
  • 101
  • 156

6 Answers6

15

I encountered this as well, and I narrowed down the cause. I think it's a regression in Django, but I don't have time to write up a full bug report. Here's what I know.

Django waits until the first call to django.urls.reverse to populate all the namespaces to a cached dict.

There's been some changes to that population procedure recently. They added a populating flag that is set to True when you start populating, and is shared across calls to reverse. If the population process happens to make a call to django.urls.reverse, the flag will prevent infinite recursion.

The population process involves importing URL patterns - the urls.py files you have in your apps. If anything during that import process raises an exception, e.g. an undefined name at the top-level of a module in my case, the population algorithm doesn't catch that, and just stops outright, and leaves the populating flag to True. That error, at least for me, was propagated to the top level and I saw it in test runner output.

All subsequent calls to django.urls.reverse raise a NoReverseMatch error for the en-us namespace. Following the code, this is because at the start of the population procedure, if the populating flag is truthy, the process just returns and returns the cached namespace dict, which is empty, causing a KeyError for en-us, causing a NoReverseMatch for en-us.

You should look at the errors that occurred before the first NoReverseMatch to find your culprit. For more info, I think this is the commit that introduced the regression. It has a link to the Django issue it fixed. I think the fix would be to set the populating flag to False in case of an exception, but I'm not sure.

Tommi Kaikkonen
  • 1,911
  • 2
  • 8
  • 6
  • Thank you, this helped me solve the issue on Django 1.10.7 :) – F.X. Nov 17 '17 at 17:13
  • Thanks. For me the issue was a malformed urlpatterns definition and this let me to discover the source of the error. – kevgathuku Feb 07 '18 at 12:26
  • 1
    I had this error under pretty particular conditions. I wrote a standalone script that loads [django](https://stackoverflow.com/a/39724171/52499). There I did a reverse match, and one of my `urls.py` also had `reverse()` calls. The second (the one down the stack) `reverse()` call failed with this error. I remedied it by doing `from django.core import checks; checks.run_checks()` before doing reverse match. I'm running `django-2.0.2`. – x-yuri Sep 06 '18 at 18:16
  • I am experiencing this issue on django 1.11.16 -- I was able to alleviate the error by wrapping the 'for pattern in reversed(self.url_patterns):' with a try / except that sets populating to false on exception. How can i narrow down the actuall problem? My exception says; 'The included URLconf 'portal.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import.' -- https://github.com/django/django/blob/stable/1.11.x/django/urls/resolvers.py#L347 – phenicie Oct 30 '18 at 19:48
  • Nice research, thanks. In my case it was wrong version of DRF that could not support `@detail_route(url_name=...)` and tests failed. – abcdn Dec 02 '18 at 23:33
4

Run django system check command it may show the underlying problem:

python manage.py check
Janusz Skonieczny
  • 17,642
  • 11
  • 55
  • 63
1

I updated to django 1.10.5 and the problem went away.

Go figure!

Sardathrion - against SE abuse
  • 17,269
  • 27
  • 101
  • 156
0

It could be that your base urls.py has an included urls.py that has a $ sign mistakenly put into it. This will cause issues with the urlresolvers. Scan your included urls and make sure that there are no dollar signs in them.

Another thing to look out for is if you have any views that throw exceptions in any of your urls.

The Pied Pipes
  • 1,425
  • 2
  • 16
  • 29
0

Building on Tommi Kaikkonen's answer, one cause of urls.py evaluation failing might be due to a heavy queryset failing on production in a non-reproducible fashion due to heavy load on the server/db.

The easiest way to find the root cause is to set a breakpoint on core queryset evaluation function(s) and do a django runserver in debug mode, anywhere that it triggers, you should re-write the code to make it lazily evalute and optimize the queryset as well if that's a possilibity.

Maziyar Mk
  • 1,179
  • 14
  • 17
-1

Your LANGUAGE_CODE setting is set to en_gb. Notice the underscore character. It should be en-gb.

Vojtech Ruzicka
  • 16,384
  • 15
  • 63
  • 66
Sagar Ramachandrappa
  • 1,411
  • 12
  • 18