Opened 4 weeks ago

Closed 2 weeks ago

Last modified 2 weeks ago

#36796 closed Bug (fixed)

URL resolution breaks if route defined with lazy string and uses an include

Reported by: Andrea Angelini Owned by: Kundan Yadav
Component: Core (URLs) Version: 6.0
Severity: Release blocker Keywords: gettext_lazy, lazy
Cc: Andrea Angelini, Jake Howard Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

After this commit:

https://github.com/django/django/commit/f920937c8a63df6bea220e4386f59cdb45b2e355

this is not working if self._route is gettext_lazy('test'):

        elif path.startswith(self._route):
            return path.removeprefix(self._route), (), {}

More info here:
https://forum.djangoproject.com/t/gettext-lazy-and-url-patterns/43703

Change History (13)

comment:1 by Andrea Angelini, 4 weeks ago

Cc: Andrea Angelini added
Type: UncategorizedBug

comment:2 by Jacob Walls, 4 weeks ago

Cc: Jake Howard added
Keywords: gettext_lazy lazy added
Severity: NormalRelease blocker
Summary: gettext_lazy and url patternsURL resolution breaks if route defined with lazy string and uses an include
Triage Stage: UnreviewedAccepted

Thanks, replicated like this (traceback given in forum post):

from django.urls import path, include
from django.utils.translation import gettext_lazy as _

urlpatterns = [
    path(_(''), include("django.conf.urls.i18n"), name='index'),
]

It's documented that the route arg to path() can take a lazy string.

Last edited 4 weeks ago by Jacob Walls (previous) (diff)

comment:3 by Andrea Angelini, 4 weeks ago

Amended like following fixes this issue:

elif path.startswith(str(self._route)):
    return path.removeprefix(str(self._route)), (), {}

comment:4 by Jake Howard, 4 weeks ago

I'd missed that lazy string were accepted, and surprised a test didn't cover this behaviour.

Just handling the elif case won't quite work, since there's also the endpoint case. Converting self._route to a string (as part of match, rather than the constructor so it's evaluated in the correct context) sounds like the right solution. It'd be nice if the conversion only happens once per match to avoid unnecessary extra work.

comment:5 by Andrea Angelini, 4 weeks ago

I agree with you that it should be converted to a string as part of match and not as I proposed here

Last edited 4 weeks ago by Andrea Angelini (previous) (diff)

comment:6 by Andrea Angelini, 4 weeks ago

In the endpoint seems accidentally to work though because gettext_lazy('test') == 'test' returns True, while
'test'.startswith(gettext_lazy('test')) and 'test'.removeprefix(gettext_lazy('test')) throw an error

Last edited 4 weeks ago by Andrea Angelini (previous) (diff)

comment:7 by Kundan Yadav, 4 weeks ago

Owner: set to Kundan Yadav
Status: newassigned

comment:8 by Jacob Walls, 4 weeks ago

Has patch: set

comment:9 by Jacob Walls, 4 weeks ago

Needs tests: set
Patch needs improvement: set

comment:10 by Natalia Bidart, 3 weeks ago

Needs documentation: set

comment:11 by Natalia Bidart, 2 weeks ago

Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:12 by nessita <124304+nessita@…>, 2 weeks ago

Resolution: fixed
Status: assignedclosed

In 7bf3ac3e:

Fixed #36796 -- Handled lazy routes correctly in RoutePattern.match().

Coerce lazy route values to str at match time to support prefix and
endpoint matching when using gettext_lazy() route paths.

Regression in f920937c8a63df6bea220e4386f59cdb45b2e355.

Thanks to Andrea Angelini for the report, and to Jake Howard and Jacob
Walls for reviews.

Co-authored-by: Natalia <124304+nessita@…>

comment:13 by Natalia <124304+nessita@…>, 2 weeks ago

In d35daf86:

[6.0.x] Fixed #36796 -- Handled lazy routes correctly in RoutePattern.match().

Coerce lazy route values to str at match time to support prefix and
endpoint matching when using gettext_lazy() route paths.

Regression in f920937c8a63df6bea220e4386f59cdb45b2e355.

Thanks to Andrea Angelini for the report, and to Jake Howard and Jacob
Walls for reviews.

Co-authored-by: Natalia <124304+nessita@…>

Backport of 7bf3ac3ee255bcfe329e3203c7a2555b1275d506 from main.

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