#31070: Add a check for URLconfs that mix named and unnamed capture groups
------------------------------------------------+------------------------
               Reporter:  Baptiste Mispelon     |          Owner:  nobody
                   Type:  New feature           |         Status:  new
              Component:  Core (System checks)  |        Version:  master
               Severity:  Normal                |       Keywords:
           Triage Stage:  Unreviewed            |      Has patch:  0
    Needs documentation:  0                     |    Needs tests:  0
Patch needs improvement:  0                     |  Easy pickings:  0
                  UI/UX:  0                     |
------------------------------------------------+------------------------
 When using `re_path()`, Django supports the following types of capture
 groups:

 1) Named: `(?P<year>\d+)/(?P<month>\d+)/`
 2) Unnamed: `(\d+)/(?\d+)/`
 3) Mixed: `(?P<year>\d+)/(\d+)/`

 If you have a view with the following signature: `def view(request, *args,
 **kwargs)` and a URL `/2019/11/`, then the view will be called with the
 following arguments (respectively):

 1) `args=(), kwargs={'year': '2019', 'month': '11'}`
 2) `args=('2019', '11'), kwargs={}`
 3) `args=(), kwargs={'year': '2019'}`


 Case number 3 is a bit surprising but it's documented both in the
 reference docs [1]:
     When a match is made, captured groups from the regular expression are
 passed to the view – as named arguments if the groups are named, and as
 positional arguments otherwise.

 and in the topics docs [2]:
     When both styles are mixed, any unnamed groups are ignored and only
 named groups are passed to the view function.


 The topics doc actually discourages the use of unnamed capture group:
     This usage isn’t particularly recommended as it makes it easier to
 accidentally introduce errors between the intended meaning of a match and
 the arguments of the view.


 I propose introducing a new `urls.W009` check for the URLConfs that would
 warn the user when they've configured a route that mixes both named and
 unnamed capture groups. As a remedy, it would suggest converting the
 unnamed groups to non-capturing groups (`(?:\d+)` syntax with our current
 example).




 [1] https://docs.djangoproject.com/en/dev/ref/urls/#re-path
 [2] https://docs.djangoproject.com/en/dev/topics/http/urls/#using-unnamed-
 regular-expression-groups

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31070>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/052.b8109dfc7186cf8aeb2bc8c5ca2a4da2%40djangoproject.com.

Reply via email to