﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
31070	Add a check for URLconfs that mix named and unnamed capture groups	Baptiste Mispelon	Baptiste Mispelon	"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"	New feature	closed	Core (System checks)	dev	Normal	needsinfo			Accepted	1	0	0	1	0	0
