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
This commit is contained in:
parent
ab13303ea4
commit
7838493b9e
|
@ -228,12 +228,14 @@ class RegexURLResolver(object):
|
||||||
if args:
|
if args:
|
||||||
if len(args) != len(params):
|
if len(args) != len(params):
|
||||||
continue
|
continue
|
||||||
candidate = result % dict(zip(params, args))
|
unicode_args = [force_unicode(val) for val in args]
|
||||||
|
candidate = result % dict(zip(params, unicode_args))
|
||||||
else:
|
else:
|
||||||
if set(kwargs.keys()) != set(params):
|
if set(kwargs.keys()) != set(params):
|
||||||
continue
|
continue
|
||||||
candidate = result % kwargs
|
unicode_kwargs = dict([(k, force_unicode(v)) for (k, v) in kwargs.items()])
|
||||||
if re.search('^%s' % pattern, candidate, re.UNICODE):
|
candidate = result % unicode_kwargs
|
||||||
|
if re.search(u'^%s' % pattern, candidate, re.UNICODE):
|
||||||
return candidate
|
return candidate
|
||||||
raise NoReverseMatch("Reverse for '%s' with arguments '%s' and keyword "
|
raise NoReverseMatch("Reverse for '%s' with arguments '%s' and keyword "
|
||||||
"arguments '%s' not found." % (lookup_view, args, kwargs))
|
"arguments '%s' not found." % (lookup_view, args, kwargs))
|
||||||
|
|
|
@ -13,12 +13,12 @@ ESCAPE_MAPPINGS = {
|
||||||
"A": None,
|
"A": None,
|
||||||
"b": None,
|
"b": None,
|
||||||
"B": None,
|
"B": None,
|
||||||
"d": '0',
|
"d": u"0",
|
||||||
"D": "x",
|
"D": u"x",
|
||||||
"s": " ",
|
"s": u" ",
|
||||||
"S": "x",
|
"S": u"x",
|
||||||
"w": "x",
|
"w": u"x",
|
||||||
"W": "!",
|
"W": u"!",
|
||||||
"Z": None,
|
"Z": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ def normalize(pattern):
|
||||||
try:
|
try:
|
||||||
ch, escaped = pattern_iter.next()
|
ch, escaped = pattern_iter.next()
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
return zip([''], [[]])
|
return zip([u''], [[]])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
|
@ -85,7 +85,7 @@ def normalize(pattern):
|
||||||
result.append(ch)
|
result.append(ch)
|
||||||
elif ch == '.':
|
elif ch == '.':
|
||||||
# Replace "any character" with an arbitrary representative.
|
# Replace "any character" with an arbitrary representative.
|
||||||
result.append("x")
|
result.append(u"x")
|
||||||
elif ch == '|':
|
elif ch == '|':
|
||||||
# FIXME: One day we'll should do this, but not in 1.0.
|
# FIXME: One day we'll should do this, but not in 1.0.
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -117,7 +117,7 @@ def normalize(pattern):
|
||||||
# A positional group
|
# A positional group
|
||||||
name = "_%d" % num_args
|
name = "_%d" % num_args
|
||||||
num_args += 1
|
num_args += 1
|
||||||
result.append(Group((("%%(%s)s" % name), name)))
|
result.append(Group(((u"%%(%s)s" % name), name)))
|
||||||
walk_to_end(ch, pattern_iter)
|
walk_to_end(ch, pattern_iter)
|
||||||
else:
|
else:
|
||||||
ch, escaped = pattern_iter.next()
|
ch, escaped = pattern_iter.next()
|
||||||
|
@ -144,7 +144,7 @@ def normalize(pattern):
|
||||||
name.append(ch)
|
name.append(ch)
|
||||||
ch, escaped = pattern_iter.next()
|
ch, escaped = pattern_iter.next()
|
||||||
param = ''.join(name)
|
param = ''.join(name)
|
||||||
result.append(Group((("%%(%s)s" % param), param)))
|
result.append(Group(((u"%%(%s)s" % param), param)))
|
||||||
walk_to_end(ch, pattern_iter)
|
walk_to_end(ch, pattern_iter)
|
||||||
elif ch in "*?+{":
|
elif ch in "*?+{":
|
||||||
# Quanitifers affect the previous item in the result list.
|
# Quanitifers affect the previous item in the result list.
|
||||||
|
@ -180,7 +180,7 @@ def normalize(pattern):
|
||||||
pass
|
pass
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
# A case of using the disjunctive form. No results for you!
|
# A case of using the disjunctive form. No results for you!
|
||||||
return zip([''], [[]])
|
return zip([u''], [[]])
|
||||||
|
|
||||||
return zip(*flatten_result(result))
|
return zip(*flatten_result(result))
|
||||||
|
|
||||||
|
@ -279,20 +279,20 @@ def flatten_result(source):
|
||||||
Each of the two lists will be of the same length.
|
Each of the two lists will be of the same length.
|
||||||
"""
|
"""
|
||||||
if source is None:
|
if source is None:
|
||||||
return [''], [[]]
|
return [u''], [[]]
|
||||||
if isinstance(source, Group):
|
if isinstance(source, Group):
|
||||||
if source[1] is None:
|
if source[1] is None:
|
||||||
params = []
|
params = []
|
||||||
else:
|
else:
|
||||||
params = [source[1]]
|
params = [source[1]]
|
||||||
return [source[0]], [params]
|
return [source[0]], [params]
|
||||||
result = ['']
|
result = [u'']
|
||||||
result_args = [[]]
|
result_args = [[]]
|
||||||
pos = last = 0
|
pos = last = 0
|
||||||
for pos, elt in enumerate(source):
|
for pos, elt in enumerate(source):
|
||||||
if isinstance(elt, basestring):
|
if isinstance(elt, basestring):
|
||||||
continue
|
continue
|
||||||
piece = ''.join(source[last:pos])
|
piece = u''.join(source[last:pos])
|
||||||
if isinstance(elt, Group):
|
if isinstance(elt, Group):
|
||||||
piece += elt[0]
|
piece += elt[0]
|
||||||
param = elt[1]
|
param = elt[1]
|
||||||
|
@ -320,7 +320,7 @@ def flatten_result(source):
|
||||||
result = new_result
|
result = new_result
|
||||||
result_args = new_args
|
result_args = new_args
|
||||||
if pos >= last:
|
if pos >= last:
|
||||||
piece = ''.join(source[last:])
|
piece = u''.join(source[last:])
|
||||||
for i in range(len(result)):
|
for i in range(len(result)):
|
||||||
result[i] += piece
|
result[i] += piece
|
||||||
return result, result_args
|
return result, result_args
|
||||||
|
|
|
@ -194,6 +194,7 @@ class Templates(unittest.TestCase):
|
||||||
output = self.render(test_template, vals)
|
output = self.render(test_template, vals)
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
if e.__class__ != result:
|
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))
|
failures.append("Template test (TEMPLATE_STRING_IF_INVALID='%s'): %s -- FAILED. Got %s, exception: %s" % (invalid_str, name, e.__class__, e))
|
||||||
continue
|
continue
|
||||||
if output != result:
|
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/'),
|
'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/'),
|
'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/'),
|
'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
|
# Failures
|
||||||
'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
|
'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),
|
||||||
|
|
Loading…
Reference in New Issue