#29415: custom url converters are not picked up on reverse when part of included
patterns
---------------------------------------+------------------------
               Reporter:  Xaroth       |          Owner:  nobody
                   Type:  Bug          |         Status:  new
              Component:  Core (URLs)  |        Version:  2.1
               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            |
---------------------------------------+------------------------
 Under normal circumstances, url converters `to_url` methods are called
 when reversing a url, however, this behavior is inconsistent when used
 with included sub-patterns

 To demonstrate:
 {{{
 from django.urls import path, include, register_converter
 from django.urls.converters import StringConverter


 class ReverseConverter(StringConverter):
     def to_python(self, value):
         """More complex use cases are possible, but this simple case of
 reversing the string already shows it in effect"""
         return value[::-1]

     def to_url(self, obj):
         """More complex use cases are possible, but this simple case of
 reversing the string already shows it in effect"""
         return obj[::-1]

 register_converter(ReverseConverter, 'rstr')


 def noop(request):  # A noop since we are merely testing reverse()
     pass


 # Patterns in here will
 included_patterns = [
     path('', noop, name='fail-case-1'),
     path('<rstr:itemb>', noop, name='fail-case-2'),
 ]

 direct_patterns = [
     path('<rstr:item>', noop, name='success-case-1'),
     path('<rstr:item>/<rstr:itemb>', noop, name='success-case-2'),
 ]

 urlpatterns = [
     path('<rstr:item>/', include(included_patterns)),
     path('', include(direct_patterns)),
     path('<rstr:item>', noop, name='success-case-3'),
 ]
 }}}

 When running the following test, both patterns -should- return the same
 URL, however, they do not:

 {{{
 In [1]: from django.urls import reverse

 In [2]: reverse('success-case-1', kwargs={'item': 'abc123'})  # Expected:
 '/321cba'
 Out[2]: '/321cba'

 In [3]: reverse('success-case-2', kwargs={'item': 'abc123', 'itemb':
 'xyz789'})  # Expected: '/321cba/987zyx'
 Out[3]: '/321cba/987zyx'

 In [4]: reverse('success-case-3', kwargs={'item': 'abc123'})  # Expected:
 '/321cba'
 Out[4]: '/321cba'

 In [5]: reverse('fail-case-1', kwargs={'item': 'abc123'})  # Expected:
 '/321cba/'
 Out[5]: '/abc123/'

 In [6]: reverse('fail-case-2', kwargs={'item': 'abc123', 'itemb':
 'xyz789'})  # Expected: '/321cba/987zyx'
 Out[6]: '/abc123/987zyx'
 }}}
 Note that at the last case, `item` is not reversed, where `itemb` is.

 The main culprit (I think) is that when populating the URLResolver's
 reverse_dict, included sub-resolvers are not updated with the converters
 of the resolver that includes them, as such, they skip the converters for
 the base resolver when reversing the URL.

 I have confirmed this inconsistency in versions 2.0 through 2.0.5, 2.1a1
 as well as master (@9f6188b).

-- 
Ticket URL: <https://code.djangoproject.com/ticket/29415>
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 post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/049.b2bfc22436fe8d509a621cc0ab2eb21c%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to