From 6212db897aa5cb61615f9fdefc08adf4cb7f7476 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Wed, 4 Jan 2012 17:53:42 -0500 Subject: more speculative changes regarding matching --- pyramid/traversal.py | 13 +++++++++---- pyramid/urldispatch.py | 19 +++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/pyramid/traversal.py b/pyramid/traversal.py index 3489dade0..2443e2d1c 100644 --- a/pyramid/traversal.py +++ b/pyramid/traversal.py @@ -444,11 +444,12 @@ def traversal_path(path): path = unquote_bytes_to_wsgi(path) # result will be a native string return traversal_path_info(path) +@lru_cache(1000) def traversal_path_info(path): """ Given``path``, return a tuple representing that path which can be used to traverse a resource tree. ``path`` is assumed to be an already-URL-decoded ``str`` type as if it had come to us from an upstream - WSGI server as the ``PATH_INFO`` environment variable. + WSGI server as the ``PATH_INFO`` environ variable. The ``path`` is first decoded to from its WSGI representation to Unicode; it is decoded differently depending on platform: @@ -457,9 +458,9 @@ def traversal_path_info(path): decoding directly; a :exc:`pyramid.exc.URLDecodeError` is raised if a the URL cannot be decoded. - - On Python 3, as per the WSGI spec, ``path`` is first encoded to bytes - using the Latin-1 encoding; the resulting set of bytes is subsequently - decoded to text using the UTF-8 encoding; a + - On Python 3, as per the PEP 3333 spec, ``path`` is first encoded to + bytes using the Latin-1 encoding; the resulting set of bytes is + subsequently decoded to text using the UTF-8 encoding; a :exc:`pyramid.exc.URLDecodeError` is raised if a the URL cannot be decoded. @@ -654,9 +655,13 @@ class ResourceTreeTraverser(object): # this request did not match a route subpath = () try: + # empty if mounted under a path in mod_wsgi, for example path = decode_path_info(environ['PATH_INFO'] or '/') except KeyError: path = '/' + except UnicodeDecodeError as e: + raise URLDecodeError(e.encoding, e.object, e.start, e.end, + e.reason) if VH_ROOT_KEY in environ: # HTTP_X_VHM_ROOT diff --git a/pyramid/urldispatch.py b/pyramid/urldispatch.py index c7520b8d2..73875b675 100644 --- a/pyramid/urldispatch.py +++ b/pyramid/urldispatch.py @@ -18,8 +18,9 @@ from pyramid.compat import ( from pyramid.exceptions import URLDecodeError from pyramid.traversal import ( - traversal_path_info, quote_path_segment, + decode_path_info, + split_path_info, ) _marker = object() @@ -70,9 +71,11 @@ class RoutesMapper(object): environ = request.environ try: # empty if mounted under a path in mod_wsgi, for example - path = environ['PATH_INFO'] or '/' + path = decode_path_info(environ['PATH_INFO'] or '/') except KeyError: path = '/' + except UnicodeDecodeError as e: + raise URLDecodeError(e.encoding, e.object, e.start, e.end, e.reason) for route in self.routelist: match = route.match(path) @@ -147,17 +150,9 @@ def _compile_route(route): d = {} for k, v in m.groupdict().items(): if k == star: - d[k] = traversal_path_info(v) + d[k] = split_path_info(v) else: - try: - val = bytes_(v).decode('utf-8', 'strict') - d[k] = val - except UnicodeDecodeError as e: - raise URLDecodeError( - e.encoding, e.object, e.start, e.end, e.reason - ) - - + d[k] = v return d -- cgit v1.2.3