Assumed iri_to_uri always returns a string

Thanks Tim Graham for the review.
This commit is contained in:
Claude Paroz 2017-01-23 17:44:25 +01:00
parent f0573aad4b
commit d2e7d15b4c
5 changed files with 18 additions and 17 deletions

View File

@ -164,7 +164,7 @@ def floatformat(text, arg=-1):
@stringfilter
def iriencode(value):
"""Escapes an IRI value for use in a URL."""
return force_text(iri_to_uri(value))
return iri_to_uri(value)
@register.filter(is_safe=True, needs_autoescape=True)

View File

@ -1,7 +1,7 @@
from threading import local
from urllib.parse import urlsplit, urlunsplit
from django.utils.encoding import force_text, iri_to_uri
from django.utils.encoding import iri_to_uri
from django.utils.functional import lazy
from django.utils.translation import override
@ -85,7 +85,7 @@ def reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None):
if ns_pattern:
resolver = get_ns_resolver(ns_pattern, resolver)
return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
reverse_lazy = lazy(reverse, str)

View File

@ -151,13 +151,13 @@ def iri_to_uri(iri):
Convert an Internationalized Resource Identifier (IRI) portion to a URI
portion that is suitable for inclusion in a URL.
This is the algorithm from section 3.1 of RFC 3987. However, since we are
assuming input is either UTF-8 or unicode already, we can simplify things a
little from the full method.
This is the algorithm from section 3.1 of RFC 3987, slightly simplified
since the input is assumed to be a string rather than an arbitrary byte
stream.
Takes an IRI in UTF-8 bytes (e.g. '/I \xe2\x99\xa5 Django/') or unicode
(e.g. '/I ♥ Django/') and returns ASCII bytes containing the encoded result
(e.g. '/I%20%E2%99%A5%20Django/').
Take an IRI (string or UTF-8 bytes, e.g. '/I ♥ Django/' or
b'/I \xe2\x99\xa5 Django/') and return a string containing the encoded
result with ASCII chars only (e.g. '/I%20%E2%99%A5%20Django/').
"""
# The list of safe characters here is constructed from the "reserved" and
# "unreserved" characters specified in sections 2.2 and 2.3 of RFC 3986:
@ -173,7 +173,9 @@ def iri_to_uri(iri):
# converted.
if iri is None:
return iri
return quote(force_bytes(iri), safe=b"/#%[]=:;$&()+,!?*@'~")
elif isinstance(iri, Promise):
iri = str(iri)
return quote(iri, safe="/#%[]=:;$&()+,!?*@'~")
def uri_to_iri(uri):

View File

@ -733,8 +733,7 @@ in ``get_absolute_url()`` and have all your other code call that one place.
Code and templates calling ``get_absolute_url()`` should be able to use the
result directly without any further processing. You may wish to use the
``django.utils.encoding.iri_to_uri()`` function to help with this if you
are using unicode strings containing characters outside the ASCII range at
all.
are using strings containing characters outside the ASCII range.
Extra instance methods
======================

View File

@ -262,12 +262,12 @@ The functions defined in this module share the following properties:
Convert an Internationalized Resource Identifier (IRI) portion to a URI
portion that is suitable for inclusion in a URL.
This is the algorithm from section 3.1 of :rfc:`3987#section-3.1`. However,
since we are assuming input is either UTF-8 or unicode already, we can
simplify things a little from the full method.
This is the algorithm from section 3.1 of :rfc:`3987#section-3.1`, slightly
simplified since the input is assumed to be a string rather than an
arbitrary byte stream.
Takes an IRI in UTF-8 bytes and returns ASCII bytes containing the encoded
result.
Takes an IRI (string or UTF-8 bytes) and returns a string containing the
encoded result.
.. function:: uri_to_iri(uri)