Skip to content

Commit

Permalink
- The route_url and route_path APIs no longer quote /
Browse files Browse the repository at this point in the history
  to ``%2F`` when a replacement value contains a ``/``.  This was pointless,
  as WSGI servers always unquote the slash anyway, and Pyramid never sees the
  quoted value.
  • Loading branch information
mcdonc committed Aug 28, 2013
1 parent 001c232 commit 58951c0
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 7 deletions.
5 changes: 5 additions & 0 deletions CHANGES.txt
Expand Up @@ -207,6 +207,11 @@ Backwards Incompatibilities
previously returned the URL without the query string by default, it now does previously returned the URL without the query string by default, it now does
attach the query string unless it is overriden. attach the query string unless it is overriden.


- The ``route_url`` and ``route_path`` APIs no longer quote ``/``
to ``%2F`` when a replacement value contains a ``/``. This was pointless,
as WSGI servers always unquote the slash anyway, and Pyramid never sees the
quoted value.

1.4 (2012-12-18) 1.4 (2012-12-18)
================ ================


Expand Down
10 changes: 5 additions & 5 deletions pyramid/tests/test_urldispatch.py
Expand Up @@ -295,7 +295,7 @@ def test_with_bracket_star(self):
'remainder':'/everything/else/here'}) 'remainder':'/everything/else/here'})
self.assertEqual(matcher('foo/baz/biz/buz/bar'), None) self.assertEqual(matcher('foo/baz/biz/buz/bar'), None)
self.assertEqual(generator( self.assertEqual(generator(
{'baz':1, 'buz':2, 'remainder':'/a/b'}), '/foo/1/biz/2/bar%2Fa%2Fb') {'baz':1, 'buz':2, 'remainder':'/a/b'}), '/foo/1/biz/2/bar/a/b')


def test_no_beginning_slash(self): def test_no_beginning_slash(self):
matcher, generator = self._callFUT('foo/:baz/biz/:buz/bar') matcher, generator = self._callFUT('foo/:baz/biz/:buz/bar')
Expand Down Expand Up @@ -491,10 +491,10 @@ def test_generator_functional_newstyle(self):
self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':'/def/g'}, self.generates('zzz/{x}*traverse', {'x':'abc', 'traverse':'/def/g'},
'/zzz/abc/def/g') '/zzz/abc/def/g')
self.generates('/{x}', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')}, self.generates('/{x}', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')},
'/%2FLa%20Pe%C3%B1a') '//La%20Pe%C3%B1a')
self.generates('/{x}*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'), self.generates('/{x}*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'),
'y':'/rest/of/path'}, 'y':'/rest/of/path'},
'/%2FLa%20Pe%C3%B1a/rest/of/path') '//La%20Pe%C3%B1a/rest/of/path')
self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))}, self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))},
'/a/La%20Pe%C3%B1a') '/a/La%20Pe%C3%B1a')
self.generates('/foo/{id}.html', {'id':'bar'}, '/foo/bar.html') self.generates('/foo/{id}.html', {'id':'bar'}, '/foo/bar.html')
Expand All @@ -511,10 +511,10 @@ def test_generator_functional_oldstyle(self):
self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':'/def/g'}, self.generates('zzz/:x*traverse', {'x':'abc', 'traverse':'/def/g'},
'/zzz/abc/def/g') '/zzz/abc/def/g')
self.generates('/:x', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')}, self.generates('/:x', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8')},
'/%2FLa%20Pe%C3%B1a') '//La%20Pe%C3%B1a')
self.generates('/:x*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'), self.generates('/:x*y', {'x':text_(b'/La Pe\xc3\xb1a', 'utf-8'),
'y':'/rest/of/path'}, 'y':'/rest/of/path'},
'/%2FLa%20Pe%C3%B1a/rest/of/path') '//La%20Pe%C3%B1a/rest/of/path')
self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))}, self.generates('*traverse', {'traverse':('a', text_(b'La Pe\xf1a'))},
'/a/La%20Pe%C3%B1a') '/a/La%20Pe%C3%B1a')
self.generates('/foo/:id.html', {'id':'bar'}, '/foo/bar.html') self.generates('/foo/:id.html', {'id':'bar'}, '/foo/bar.html')
Expand Down
6 changes: 4 additions & 2 deletions pyramid/urldispatch.py
Expand Up @@ -213,7 +213,9 @@ def generator(dict):
if k == remainder: if k == remainder:
# a stararg argument # a stararg argument
if is_nonstr_iter(v): if is_nonstr_iter(v):
v = '/'.join([quote_path_segment(x) for x in v]) # native v = '/'.join(
[quote_path_segment(x, safe='/') for x in v]
) # native
else: else:
if v.__class__ not in string_types: if v.__class__ not in string_types:
v = str(v) v = str(v)
Expand All @@ -222,7 +224,7 @@ def generator(dict):
if v.__class__ not in string_types: if v.__class__ not in string_types:
v = str(v) v = str(v)
# v may be bytes (py2) or native string (py3) # v may be bytes (py2) or native string (py3)
v = quote_path_segment(v) v = quote_path_segment(v, safe='/')


# at this point, the value will be a native string # at this point, the value will be a native string
newdict[k] = v newdict[k] = v
Expand Down

0 comments on commit 58951c0

Please sign in to comment.