diff options
author | Ashley Camba Garrido <ashwoods@gmail.com> | 2017-12-04 22:59:10 +0100 |
---|---|---|
committer | Ashley Camba Garrido <ashwoods@gmail.com> | 2017-12-04 22:59:10 +0100 |
commit | 7c934529a9ed84cbd28d7c1a8e0cdbbe2fe32072 (patch) | |
tree | 05f70ca331ce88a4e70e7f14116c1ecdee10c0ff | |
parent | 1dd30934c034df6744bfbb14f9dcbf0e552241d4 (diff) | |
download | raven-7c934529a9ed84cbd28d7c1a8e0cdbbe2fe32072.tar.gz |
fix(django): Add support for Django 2.0 Urlresolver
Fixes:#1127
-rw-r--r-- | raven/contrib/django/resolver.py | 20 | ||||
-rw-r--r-- | tests/contrib/django/conftest.py | 39 | ||||
-rw-r--r-- | tests/contrib/django/test_resolver.py | 11 | ||||
-rw-r--r-- | tox.ini | 2 |
4 files changed, 66 insertions, 6 deletions
diff --git a/raven/contrib/django/resolver.py b/raven/contrib/django/resolver.py index 962d661..3f3c74f 100644 --- a/raven/contrib/django/resolver.py +++ b/raven/contrib/django/resolver.py @@ -8,6 +8,15 @@ except ImportError: from django.core.urlresolvers import get_resolver +def get_regex(resolver_or_pattern): + """Utility method for django's deprecated resolver.regex""" + try: + regex = resolver_or_pattern.regex + except AttributeError: + regex = resolver_or_pattern.pattern.regex + return regex + + class RouteResolver(object): _optional_group_matcher = re.compile(r'\(\?\:([^\)]+)\)') _named_group_matcher = re.compile(r'\(\?P<(\w+)>[^\)]+\)') @@ -50,7 +59,9 @@ class RouteResolver(object): return result def _resolve(self, resolver, path, parents=None): - match = resolver.regex.search(path) + + match = get_regex(resolver).search(path) # Django < 2.0 + if not match: return @@ -67,8 +78,7 @@ class RouteResolver(object): if match: return match continue - - elif not pattern.regex.search(new_path): + elif not get_regex(pattern).search(new_path): continue try: @@ -76,8 +86,8 @@ class RouteResolver(object): except KeyError: pass - prefix = ''.join(self._simplify(p.regex.pattern) for p in parents) - result = prefix + self._simplify(pattern.regex.pattern) + prefix = ''.join(self._simplify(get_regex(p).pattern) for p in parents) + result = prefix + self._simplify(get_regex(pattern).pattern) if not result.startswith('/'): result = '/' + result self._cache[pattern] = result diff --git a/tests/contrib/django/conftest.py b/tests/contrib/django/conftest.py new file mode 100644 index 0000000..b6faff6 --- /dev/null +++ b/tests/contrib/django/conftest.py @@ -0,0 +1,39 @@ +import pytest + +import django + +from raven.contrib.django.resolver import RouteResolver + +try: + from django.conf.urls import url, include +except ImportError: + # for Django version less than 1.4 + from django.conf.urls.defaults import url, include + + +@pytest.fixture +def route_resolver(): + return RouteResolver() + + +@pytest.fixture +def urlconf(): + if django.VERSION < (1, 9): + included_url_conf = ( + url(r'^foo/bar/(?P<param>[\w]+)', lambda x: ''), + ), '', '' + else: + included_url_conf = (( + url(r'^foo/bar/(?P<param>[\w]+)', lambda x: ''), + ), '') + + if django.VERSION >= (2, 0): + from django.urls import path, re_path + + example_url_conf = ( + re_path(r'^api/(?P<project_id>[\w_-]+)/store/$', lambda x: ''), + re_path(r'^report/', lambda x: ''), + re_path(r'^example/', include(included_url_conf)), + path('api/v2/<int:project_id>/store/', lambda x: '') + ) + return example_url_conf diff --git a/tests/contrib/django/test_resolver.py b/tests/contrib/django/test_resolver.py index 3f406cc..042715a 100644 --- a/tests/contrib/django/test_resolver.py +++ b/tests/contrib/django/test_resolver.py @@ -1,5 +1,6 @@ from __future__ import absolute_import +import pytest import django try: @@ -10,6 +11,7 @@ except ImportError: from raven.contrib.django.resolver import RouteResolver + if django.VERSION < (1, 9): included_url_conf = ( url(r'^foo/bar/(?P<param>[\w]+)', lambda x: ''), @@ -21,6 +23,7 @@ else: example_url_conf = ( url(r'^api/(?P<project_id>[\w_-]+)/store/$', lambda x: ''), + url(r'^report/', lambda x: ''), url(r'^example/', include(included_url_conf)), ) @@ -31,7 +34,7 @@ def test_no_match(): assert result == '/foo/bar' -def test_simple_match(): +def test_simple_match(): # TODO: ash add matchedstring to make this test actually test something resolver = RouteResolver() result = resolver.resolve('/report/', example_url_conf) assert result == '/report/' @@ -47,3 +50,9 @@ def test_included_match(): resolver = RouteResolver() result = resolver.resolve('/example/foo/bar/baz', example_url_conf) assert result == '/example/foo/bar/{param}' + + +@pytest.mark.skipif(django.VERSION < (2, 0), reason="Requires Django > 2.0") +def test_newstyle_django20_urlconf(urlconf, route_resolver): + result = route_resolver.resolve('/api/v2/1234/store/', urlconf) + assert result == '/api/v2/{project_id}/store/'
\ No newline at end of file @@ -11,6 +11,7 @@ envlist = flake8 # contrib {py35,py36}-django-dev-fix + {py35,py36}-django-{200}-fix {py27,py35}-django-111-fix {py27,py34,py35}-django-{18,19,110} {py27,py33,py34,py35}-django-18 @@ -35,6 +36,7 @@ deps = django-19: Django>=1.9,<1.10 django-110: Django>=1.10,<1.11 django-111: Django>=1.11,<1.12 + django-200: Django>=2.0,<2.1 django-dev: git+https://github.com/django/django.git#egg=Django flask-10: Flask>=0.10,<0.11 flask-11: Flask>=0.11,<0.12 |