Opened 5 years ago

Closed 5 years ago

#30731 closed Bug (fixed)

simplify_regexp() doesn't replace trailing groups.

Reported by: Alan Crosswell Owned by: Alan Crosswell
Component: contrib.admindocs Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

replace_named_groups() fails to replace the final named group if the urlpattern passed in is missing a trailing '/'.

For example, with input r'entries/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)' the "related_field" does not get properly replaced. A workaround is to tack on a '/' at the end and then it works.

Code that reproduces this is attached.

This function is used downstream in Django REST Framework. See issue 6888

Attachments (1)

demo.py (813 bytes ) - added by Alan Crosswell 5 years ago.

Download all attachments as: .zip

Change History (8)

by Alan Crosswell, 5 years ago

Attachment: demo.py added

comment:1 by Alan Crosswell, 5 years ago

Here's execution of the example code:

(env) django-example$ python demo.py
         path: entries/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)
     expected: entries/<pk>/relationships/<related_field>
          got: entries/<pk>/relationships/(?P<related_field>\w+)

path_trailing: entries/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)/
     expected: entries/<pk>/relationships/<related_field>/
          got: entries/<pk>/relationships/<related_field>/
Traceback (most recent call last):
  File "demo.py", line 21, in <module>
    assert path == expected_path, "path without trailing slash didn't match expected"
AssertionError: path without trailing slash didn't match expected
(env) django-example$ 

comment:2 by Mariusz Felisiak, 5 years ago

Summary: django.contrib.admindocs.utils.replace_named_groups() fails substitution if missing trailing /simplify_regexp() doesn't replace trailing groups.
Triage Stage: UnreviewedAccepted
Version: 2.2master

Thanks for the ticket, trailing slash is not necessary regexp patterns could be also enclosed by $, by I agree that this could be easily fix by:

diff --git a/django/contrib/admindocs/utils.py b/django/contrib/admindocs/utils.py
index 1ce4594501..db27f82deb 100644
--- a/django/contrib/admindocs/utils.py
+++ b/django/contrib/admindocs/utils.py
@@ -167,12 +167,6 @@ def replace_named_groups(pattern):
         # Handle nested parentheses, e.g. '^(?P<a>(x|y))/b'.
         unmatched_open_brackets, prev_char = 1, None
         for idx, val in enumerate(pattern[end:]):
-            # If brackets are balanced, the end of the string for the current
-            # named capture group pattern has been reached.
-            if unmatched_open_brackets == 0:
-                group_pattern_and_name.append((pattern[start:end + idx], group_name))
-                break
-
             # Check for unescaped `(` and `)`. They mark the start and end of a
             # nested group.
             if val == '(' and prev_char != '\\':
@@ -180,6 +174,11 @@ def replace_named_groups(pattern):
             elif val == ')' and prev_char != '\\':
                 unmatched_open_brackets -= 1
             prev_char = val
+            # If brackets are balanced, the end of the string for the current
+            # named capture group pattern has been reached.
+            if unmatched_open_brackets == 0:
+                group_pattern_and_name.append((pattern[start:end + idx + 1], group_name))
+                break
 
     # Replace the string for named capture groups with their group names.
     for group_pattern, group_name in group_pattern_and_name:

Similar change should be made in replace_unnamed_groups(). Please add testcases to admin_docs.test_views.AdminDocViewFunctionsTests.test_simplify_regex.

comment:3 by Mariusz Felisiak, 5 years ago

Easy pickings: set

comment:4 by Alan Crosswell, 5 years ago

Owner: changed from nobody to Alan Crosswell
Status: newassigned

comment:5 by Alan Crosswell, 5 years ago

See PR 11728

comment:6 by Mariusz Felisiak, 5 years ago

Has patch: set

comment:7 by Mariusz Felisiak <felisiak.mariusz@…>, 5 years ago

Resolution: fixed
Status: assignedclosed

In 03fa846c:

Fixed #30731 -- Fixed handling trailing groups in simplify_regex().

Previously simplify_regex() didn't handle trailing groups for regexp
without the end of string character ("$").

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