Commit 7838493b authored by Malcolm Tredinnick's avatar Malcolm Tredinnick
Browse files

Fixed #8726 -- When doing reverse URL resolving, make sure we're consistently

dealing with unicode strings throughout by promoting up from UTF-8 as necessary.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8777 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent ab13303e
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -228,12 +228,14 @@ class RegexURLResolver(object):
            if args:
                if len(args) != len(params):
                    continue
                candidate =  result % dict(zip(params, args))
                unicode_args = [force_unicode(val) for val in args]
                candidate =  result % dict(zip(params, unicode_args))
            else:
                if set(kwargs.keys()) != set(params):
                    continue
                candidate = result % kwargs
            if re.search('^%s' % pattern, candidate, re.UNICODE):
                unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()])
                candidate = result % unicode_kwargs
            if re.search(u'^%s' % pattern, candidate, re.UNICODE):
                return candidate
        raise NoReverseMatch("Reverse for '%s' with arguments '%s' and keyword "
                "arguments '%s' not found." % (lookup_view, args, kwargs))
+15 −15
Original line number Diff line number Diff line
@@ -13,12 +13,12 @@ ESCAPE_MAPPINGS = {
    "A": None,
    "b": None,
    "B": None,
    "d": '0',
    "D": "x",
    "s": " ",
    "S": "x",
    "w": "x",
    "W": "!",
    "d": u"0",
    "D": u"x",
    "s": u" ",
    "S": u"x",
    "w": u"x",
    "W": u"!",
    "Z": None,
}

@@ -77,7 +77,7 @@ def normalize(pattern):
    try:
        ch, escaped = pattern_iter.next()
    except StopIteration:
        return zip([''],  [[]])
        return zip([u''],  [[]])

    try:
        while True:
@@ -85,7 +85,7 @@ def normalize(pattern):
                result.append(ch)
            elif ch == '.':
                # Replace "any character" with an arbitrary representative.
                result.append("x")
                result.append(u"x")
            elif ch == '|':
                # FIXME: One day we'll should do this, but not in 1.0.
                raise NotImplementedError
@@ -117,7 +117,7 @@ def normalize(pattern):
                    # A positional group
                    name = "_%d" % num_args
                    num_args += 1
                    result.append(Group((("%%(%s)s" % name), name)))
                    result.append(Group(((u"%%(%s)s" % name), name)))
                    walk_to_end(ch, pattern_iter)
                else:
                    ch, escaped = pattern_iter.next()
@@ -144,7 +144,7 @@ def normalize(pattern):
                            name.append(ch)
                            ch, escaped = pattern_iter.next()
                        param = ''.join(name)
                        result.append(Group((("%%(%s)s" % param), param)))
                        result.append(Group(((u"%%(%s)s" % param), param)))
                        walk_to_end(ch, pattern_iter)
            elif ch in "*?+{":
                # Quanitifers affect the previous item in the result list.
@@ -180,7 +180,7 @@ def normalize(pattern):
        pass
    except NotImplementedError:
        # A case of using the disjunctive form. No results for you!
        return zip([''],  [[]])
        return zip([u''],  [[]])

    return zip(*flatten_result(result))

@@ -279,20 +279,20 @@ def flatten_result(source):
    Each of the two lists will be of the same length.
    """
    if source is None:
        return [''], [[]]
        return [u''], [[]]
    if isinstance(source, Group):
        if source[1] is None:
            params = []
        else:
            params = [source[1]]
        return [source[0]], [params]
    result = ['']
    result = [u'']
    result_args = [[]]
    pos = last = 0
    for pos, elt in enumerate(source):
        if isinstance(elt, basestring):
            continue
        piece = ''.join(source[last:pos])
        piece = u''.join(source[last:pos])
        if isinstance(elt, Group):
            piece += elt[0]
            param = elt[1]
@@ -320,7 +320,7 @@ def flatten_result(source):
            result = new_result
            result_args = new_args
    if pos >= last:
        piece = ''.join(source[last:])
        piece = u''.join(source[last:])
        for i in range(len(result)):
            result[i] += piece
    return result, result_args
+3 −0
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ class Templates(unittest.TestCase):
                    output = self.render(test_template, vals)
                except Exception, e:
                    if e.__class__ != result:
                        raise
                        failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s" % (invalid_str, name, e.__class__, e))
                    continue
                if output != result:
@@ -899,6 +900,8 @@ class Templates(unittest.TestCase):
            'url05': (u'{% url метка_оператора v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
            'url06': (u'{% url метка_оператора_2 tag=v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
            'url07': (u'{% url regressiontests.templates.views.client2 tag=v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
            'url08': (u'{% url метка_оператора v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),
            'url09': (u'{% url метка_оператора_2 tag=v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'),

            # Failures
            'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),