diff options
| author | Michael Merickel <michael@merickel.org> | 2018-11-14 20:35:39 -0600 |
|---|---|---|
| committer | Michael Merickel <michael@merickel.org> | 2018-11-14 20:36:00 -0600 |
| commit | a705f56c3ebf34f25ab567d85b7d5b421983aa4a (patch) | |
| tree | 515498bb3f375807db95391b240a7df3ab247aca | |
| parent | 0b570220d9f442700eb97c5a5c4eca6ab03a1ee4 (diff) | |
| download | pyramid-a705f56c3ebf34f25ab567d85b7d5b421983aa4a.tar.gz pyramid-a705f56c3ebf34f25ab567d85b7d5b421983aa4a.tar.bz2 pyramid-a705f56c3ebf34f25ab567d85b7d5b421983aa4a.zip | |
rely on webob for request.path_info and request.scheme
| -rw-r--r-- | src/pyramid/compat.py | 17 | ||||
| -rw-r--r-- | src/pyramid/config/testing.py | 4 | ||||
| -rw-r--r-- | src/pyramid/config/views.py | 4 | ||||
| -rw-r--r-- | src/pyramid/scripts/pviews.py | 2 | ||||
| -rw-r--r-- | src/pyramid/static.py | 2 | ||||
| -rw-r--r-- | src/pyramid/traversal.py | 19 | ||||
| -rw-r--r-- | src/pyramid/urldispatch.py | 13 | ||||
| -rw-r--r-- | src/pyramid/view.py | 4 | ||||
| -rw-r--r-- | tests/test_config/test_testing.py | 14 | ||||
| -rw-r--r-- | tests/test_config/test_views.py | 6 | ||||
| -rw-r--r-- | tests/test_scripts/dummy.py | 5 | ||||
| -rw-r--r-- | tests/test_scripts/test_pviews.py | 18 | ||||
| -rw-r--r-- | tests/test_url.py | 1 | ||||
| -rw-r--r-- | tests/test_urldispatch.py | 44 |
14 files changed, 78 insertions, 75 deletions
diff --git a/src/pyramid/compat.py b/src/pyramid/compat.py index 10d3c4998..30fc10395 100644 --- a/src/pyramid/compat.py +++ b/src/pyramid/compat.py @@ -1,7 +1,4 @@ -import inspect import platform -import sys -import types WIN = platform.system() == 'Windows' @@ -47,17 +44,3 @@ def native_(s, encoding='latin-1', errors='strict'): if isinstance(s, str): return s return str(s, encoding, errors) - - -# see PEP 3333 for why we encode WSGI PATH_INFO to latin-1 before -# decoding it to utf-8 -def decode_path_info(path): - return path.encode('latin-1').decode('utf-8') - - -# see PEP 3333 for why we decode the path to latin-1 -from urllib.parse import unquote_to_bytes - - -def unquote_bytes_to_wsgi(bytestring): - return unquote_to_bytes(bytestring).decode('latin-1') diff --git a/src/pyramid/config/testing.py b/src/pyramid/config/testing.py index bba5054e6..9c998840a 100644 --- a/src/pyramid/config/testing.py +++ b/src/pyramid/config/testing.py @@ -9,7 +9,7 @@ from pyramid.interfaces import ( from pyramid.renderers import RendererHelper -from pyramid.traversal import decode_path_info, split_path_info +from pyramid.traversal import split_path_info from pyramid.config.actions import action_method @@ -95,7 +95,7 @@ class TestingConfiguratorMixin(object): self.context = context def __call__(self, request): - path = decode_path_info(request.environ['PATH_INFO']) + path = request.path_info ob = resources[path] traversed = split_path_info(path) return { diff --git a/src/pyramid/config/views.py b/src/pyramid/config/views.py index 484c0d754..412e30304 100644 --- a/src/pyramid/config/views.py +++ b/src/pyramid/config/views.py @@ -2192,9 +2192,7 @@ class StaticURLInfo(object): parsed = urlparse(url) if not parsed.scheme: url = urlunparse( - parsed._replace( - scheme=request.environ['wsgi.url_scheme'] - ) + parsed._replace(scheme=request.scheme) ) subpath = quote(subpath) result = urljoin(url, subpath) diff --git a/src/pyramid/scripts/pviews.py b/src/pyramid/scripts/pviews.py index 891dc4709..d2a4bfa40 100644 --- a/src/pyramid/scripts/pviews.py +++ b/src/pyramid/scripts/pviews.py @@ -70,7 +70,7 @@ class PViewsCommand(object): def _find_multi_routes(self, mapper, request): infos = [] - path = request.environ['PATH_INFO'] + path = request.path_info # find all routes that match path, regardless of predicates for route in mapper.get_routes(): match = route.match(path) diff --git a/src/pyramid/static.py b/src/pyramid/static.py index b300df9ee..e3561e93e 100644 --- a/src/pyramid/static.py +++ b/src/pyramid/static.py @@ -88,7 +88,7 @@ class static_view(object): if self.use_subpath: path_tuple = request.subpath else: - path_tuple = traversal_path_info(request.environ['PATH_INFO']) + path_tuple = traversal_path_info(request.path_info) path = _secure_path(path_tuple) if path is None: diff --git a/src/pyramid/traversal.py b/src/pyramid/traversal.py index 429b12e23..e846881f3 100644 --- a/src/pyramid/traversal.py +++ b/src/pyramid/traversal.py @@ -1,4 +1,6 @@ from functools import lru_cache +from urllib.parse import unquote_to_bytes + from zope.interface import implementer from zope.interface.interfaces import IInterface @@ -9,12 +11,7 @@ from pyramid.interfaces import ( VH_ROOT_KEY, ) -from pyramid.compat import ( - native_, - ascii_native_, - decode_path_info, - unquote_bytes_to_wsgi, -) +from pyramid.compat import native_, ascii_native_ from pyramid.encode import url_quote from pyramid.exceptions import URLDecodeError @@ -543,6 +540,16 @@ def split_path_info(path): return tuple(clean) +# see PEP 3333 for why we encode to latin-1 then decode to utf-8 +def decode_path_info(path): + return path.encode('latin-1').decode('utf-8') + + +# see PEP 3333 for why we decode the path to latin-1 +def unquote_bytes_to_wsgi(bytestring): + return unquote_to_bytes(bytestring).decode('latin-1') + + _segment_cache = {} diff --git a/src/pyramid/urldispatch.py b/src/pyramid/urldispatch.py index 6d25b2dd5..6348ae7e2 100644 --- a/src/pyramid/urldispatch.py +++ b/src/pyramid/urldispatch.py @@ -3,7 +3,7 @@ from zope.interface import implementer from pyramid.interfaces import IRoutesMapper, IRoute -from pyramid.compat import native_, text_, decode_path_info +from pyramid.compat import text_ from pyramid.exceptions import URLDecodeError @@ -75,10 +75,9 @@ class RoutesMapper(object): return self.routes[name].generate(kw) def __call__(self, request): - environ = request.environ try: # empty if mounted under a path in mod_wsgi, for example - path = decode_path_info(environ['PATH_INFO'] or '/') + path = request.path_info or '/' except KeyError: path = '/' except UnicodeDecodeError as e: @@ -202,14 +201,10 @@ def _compile_route(route): return None d = {} for k, v in m.groupdict().items(): - # k and v will be Unicode 2.6.4 and lower doesnt accept unicode - # kwargs as **kw, so we explicitly cast the keys to native - # strings in case someone wants to pass the result as **kw - nk = native_(k, 'ascii') if k == remainder: - d[nk] = split_path_info(v) + d[k] = split_path_info(v) else: - d[nk] = v + d[k] = v return d gen = ''.join(gen) diff --git a/src/pyramid/view.py b/src/pyramid/view.py index 9e85d7281..944ad93ea 100644 --- a/src/pyramid/view.py +++ b/src/pyramid/view.py @@ -15,8 +15,6 @@ from pyramid.interfaces import ( IExceptionViewClassifier, ) -from pyramid.compat import decode_path_info - from pyramid.exceptions import ConfigurationError, PredicateMismatch from pyramid.httpexceptions import ( @@ -305,7 +303,7 @@ class AppendSlashNotFoundViewFactory(object): self.redirect_class = redirect_class def __call__(self, context, request): - path = decode_path_info(request.environ['PATH_INFO'] or '/') + path = request.path_info registry = request.registry mapper = registry.queryUtility(IRoutesMapper) if mapper is not None and not path.endswith('/'): diff --git a/tests/test_config/test_testing.py b/tests/test_config/test_testing.py index ede31e1b6..870bbe9fa 100644 --- a/tests/test_config/test_testing.py +++ b/tests/test_config/test_testing.py @@ -69,23 +69,27 @@ class TestingConfiguratorMixinTests(unittest.TestCase): config = self._makeOne(autocommit=True) config.testing_resources(resources) adapter = config.registry.getAdapter(None, ITraverser) - result = adapter(DummyRequest({'PATH_INFO': '/ob1'})) + request = DummyRequest() + request.path_info = '/ob1' + result = adapter(request) self.assertEqual(result['context'], ob1) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (text_('ob1'),)) self.assertEqual(result['virtual_root'], ob1) self.assertEqual(result['virtual_root_path'], ()) - result = adapter(DummyRequest({'PATH_INFO': '/ob2'})) + request = DummyRequest() + request.path_info = '/ob2' + result = adapter(request) self.assertEqual(result['context'], ob2) self.assertEqual(result['view_name'], '') self.assertEqual(result['subpath'], ()) self.assertEqual(result['traversed'], (text_('ob2'),)) self.assertEqual(result['virtual_root'], ob2) self.assertEqual(result['virtual_root_path'], ()) - self.assertRaises( - KeyError, adapter, DummyRequest({'PATH_INFO': '/ob3'}) - ) + request = DummyRequest() + request.path_info = '/ob3' + self.assertRaises(KeyError, adapter, request) try: config.begin() self.assertEqual(find_resource(None, '/ob1'), ob1) diff --git a/tests/test_config/test_views.py b/tests/test_config/test_views.py index d530542b7..e25ee881e 100644 --- a/tests/test_config/test_views.py +++ b/tests/test_config/test_views.py @@ -1357,6 +1357,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): request_method='POST', ) request = self._makeRequest(config) + request.path_info = '/' request.method = 'POST' request.params = {} router = Router(config.registry) @@ -1412,6 +1413,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): request_method='POST', ) request = self._makeRequest(config) + request.path_info = '/' request.method = 'POST' request.params = {} router = Router(config.registry) @@ -2722,7 +2724,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): view, renderer=null_renderer, append_slash=True ) request = self._makeRequest(config) - request.environ['PATH_INFO'] = '/foo' + request.path_info = '/foo' request.query_string = 'a=1&b=2' request.path = '/scriptname/foo' view = self._getViewCallable( @@ -2751,7 +2753,7 @@ class TestViewsConfigurationMixin(unittest.TestCase): view, renderer=null_renderer, append_slash=HTTPMovedPermanently ) request = self._makeRequest(config) - request.environ['PATH_INFO'] = '/foo' + request.path_info = '/foo' request.query_string = 'a=1&b=2' request.path = '/scriptname/foo' view = self._getViewCallable( diff --git a/tests/test_scripts/dummy.py b/tests/test_scripts/dummy.py index 8e340f645..bb3475d39 100644 --- a/tests/test_scripts/dummy.py +++ b/tests/test_scripts/dummy.py @@ -81,8 +81,11 @@ class DummyRoute(object): class DummyRequest: application_url = 'http://example.com:5432' script_name = '' + path_info = '/' - def __init__(self, environ): + def __init__(self, environ=None): + if environ is None: + environ = {} self.environ = environ self.matchdict = {} diff --git a/tests/test_scripts/test_pviews.py b/tests/test_scripts/test_pviews.py index 0b26a9cf3..c8d29113f 100644 --- a/tests/test_scripts/test_pviews.py +++ b/tests/test_scripts/test_pviews.py @@ -53,7 +53,8 @@ class TestPViewsCommand(unittest.TestCase): class View1(object): pass - request = dummy.DummyRequest({'PATH_INFO': '/a'}) + request = dummy.DummyRequest() + request.path_info = '/a' root = DefaultRootFactory(request) root_iface = providedBy(root) registry.registerAdapter( @@ -78,7 +79,8 @@ class TestPViewsCommand(unittest.TestCase): def view1(): # pragma: no cover pass - request = dummy.DummyRequest({'PATH_INFO': '/a'}) + request = dummy.DummyRequest() + request.path_info = '/a' root = DefaultRootFactory(request) root_iface = providedBy(root) registry.registerAdapter( @@ -105,7 +107,8 @@ class TestPViewsCommand(unittest.TestCase): class View1(object): pass - request = dummy.DummyRequest({'PATH_INFO': '/a'}) + request = dummy.DummyRequest() + request.path_info = '/a' root = DefaultRootFactory(request) root_iface = providedBy(root) view = View1() @@ -267,7 +270,8 @@ class TestPViewsCommand(unittest.TestCase): dummy.DummyRoute('b', '/a', factory=factory, matchdict={}), ] mapper = dummy.DummyMapper(*routes) - request = dummy.DummyRequest({'PATH_INFO': '/a'}) + request = dummy.DummyRequest() + request.path_info = '/a' result = command._find_multi_routes(mapper, request) self.assertEqual( result, @@ -288,7 +292,8 @@ class TestPViewsCommand(unittest.TestCase): dummy.DummyRoute('b', '/a', factory=factory, matchdict={}), ] mapper = dummy.DummyMapper(*routes) - request = dummy.DummyRequest({'PATH_INFO': '/a'}) + request = dummy.DummyRequest() + request.path_info = '/a' result = command._find_multi_routes(mapper, request) self.assertEqual(result, [{'match': {}, 'route': routes[1]}]) @@ -303,7 +308,8 @@ class TestPViewsCommand(unittest.TestCase): dummy.DummyRoute('b', '/a', factory=factory), ] mapper = dummy.DummyMapper(*routes) - request = dummy.DummyRequest({'PATH_INFO': '/a'}) + request = dummy.DummyRequest() + request.path_info = '/a' result = command._find_multi_routes(mapper, request) self.assertEqual(result, []) diff --git a/tests/test_url.py b/tests/test_url.py index 94a0a61c9..a852f3301 100644 --- a/tests/test_url.py +++ b/tests/test_url.py @@ -25,6 +25,7 @@ class TestURLMethodsMixin(unittest.TestCase): def __init__(self, environ): self.environ = environ + self.scheme = environ.get('wsgi.url_scheme', 'http') request = Request(environ) request.registry = self.config.registry diff --git a/tests/test_urldispatch.py b/tests/test_urldispatch.py index b50e86b99..9296a50e1 100644 --- a/tests/test_urldispatch.py +++ b/tests/test_urldispatch.py @@ -59,9 +59,7 @@ class RoutesMapperTests(unittest.TestCase): def _getRequest(self, **kw): from pyramid.threadlocal import get_current_registry - environ = {'SERVER_NAME': 'localhost', 'wsgi.url_scheme': 'http'} - environ.update(kw) - request = DummyRequest(environ) + request = DummyRequest(**kw) reg = get_current_registry() request.registry = reg return request @@ -83,7 +81,7 @@ class RoutesMapperTests(unittest.TestCase): def test_no_route_matches(self): mapper = self._makeOne() - request = self._getRequest(PATH_INFO='/') + request = self._getRequest(path_info='/') result = mapper(request) self.assertEqual(result['match'], None) self.assertEqual(result['route'], None) @@ -130,16 +128,22 @@ class RoutesMapperTests(unittest.TestCase): def test___call__pathinfo_cant_be_decoded(self): from pyramid.exceptions import URLDecodeError + from pyramid.threadlocal import get_current_registry + + class DummyRequest: + @property + def path_info(self): + return b'\xff\xfe\xe6\x00'.decode('utf-8') mapper = self._makeOne() - path_info = b'\xff\xfe\xe6\x00'.decode('latin-1') - request = self._getRequest(PATH_INFO=path_info) + request = DummyRequest() + request.registry = get_current_registry() self.assertRaises(URLDecodeError, mapper, request) def test___call__route_matches(self): mapper = self._makeOne() mapper.connect('foo', 'archives/:action/:article') - request = self._getRequest(PATH_INFO='/archives/action1/article1') + request = self._getRequest(path_info='/archives/action1/article1') result = mapper(request) self.assertEqual(result['route'], mapper.routes['foo']) self.assertEqual(result['match']['action'], 'action1') @@ -150,7 +154,7 @@ class RoutesMapperTests(unittest.TestCase): mapper.connect( 'foo', 'archives/:action/:article', predicates=[lambda *arg: True] ) - request = self._getRequest(PATH_INFO='/archives/action1/article1') + request = self._getRequest(path_info='/archives/action1/article1') result = mapper(request) self.assertEqual(result['route'], mapper.routes['foo']) self.assertEqual(result['match']['action'], 'action1') @@ -164,7 +168,7 @@ class RoutesMapperTests(unittest.TestCase): predicates=[lambda *arg: True, lambda *arg: False], ) mapper.connect('bar', 'archives/:action/:article') - request = self._getRequest(PATH_INFO='/archives/action1/article1') + request = self._getRequest(path_info='/archives/action1/article1') result = mapper(request) self.assertEqual(result['route'], mapper.routes['bar']) self.assertEqual(result['match']['action'], 'action1') @@ -179,7 +183,7 @@ class RoutesMapperTests(unittest.TestCase): return True mapper.connect('foo', 'archives/:action/article1', predicates=[pred]) - request = self._getRequest(PATH_INFO='/archives/action1/article1') + request = self._getRequest(path_info='/archives/action1/article1') mapper(request) def test_cc_bug(self): @@ -191,13 +195,13 @@ class RoutesMapperTests(unittest.TestCase): 'juri', 'licenses/:license_code/:license_version/:jurisdiction' ) - request = self._getRequest(PATH_INFO='/licenses/1/v2/rdf') + request = self._getRequest(path_info='/licenses/1/v2/rdf') result = mapper(request) self.assertEqual(result['route'], mapper.routes['rdf']) self.assertEqual(result['match']['license_code'], '1') self.assertEqual(result['match']['license_version'], 'v2') - request = self._getRequest(PATH_INFO='/licenses/1/v2/usa') + request = self._getRequest(path_info='/licenses/1/v2/usa') result = mapper(request) self.assertEqual(result['route'], mapper.routes['juri']) self.assertEqual(result['match']['license_code'], '1') @@ -207,7 +211,7 @@ class RoutesMapperTests(unittest.TestCase): def test___call__root_route_matches(self): mapper = self._makeOne() mapper.connect('root', '') - request = self._getRequest(PATH_INFO='/') + request = self._getRequest(path_info='/') result = mapper(request) self.assertEqual(result['route'], mapper.routes['root']) self.assertEqual(result['match'], {}) @@ -215,7 +219,7 @@ class RoutesMapperTests(unittest.TestCase): def test___call__root_route_matches2(self): mapper = self._makeOne() mapper.connect('root', '/') - request = self._getRequest(PATH_INFO='/') + request = self._getRequest(path_info='/') result = mapper(request) self.assertEqual(result['route'], mapper.routes['root']) self.assertEqual(result['match'], {}) @@ -223,7 +227,7 @@ class RoutesMapperTests(unittest.TestCase): def test___call__root_route_when_path_info_empty(self): mapper = self._makeOne() mapper.connect('root', '/') - request = self._getRequest(PATH_INFO='') + request = self._getRequest(path_info='') result = mapper(request) self.assertEqual(result['route'], mapper.routes['root']) self.assertEqual(result['match'], {}) @@ -231,7 +235,7 @@ class RoutesMapperTests(unittest.TestCase): def test___call__root_route_when_path_info_notempty(self): mapper = self._makeOne() mapper.connect('root', '/') - request = self._getRequest(PATH_INFO='/') + request = self._getRequest(path_info='/') result = mapper(request) self.assertEqual(result['route'], mapper.routes['root']) self.assertEqual(result['match'], {}) @@ -239,7 +243,7 @@ class RoutesMapperTests(unittest.TestCase): def test___call__no_path_info(self): mapper = self._makeOne() mapper.connect('root', '/') - request = self._getRequest() + request = self._getRequest(path_info='') result = mapper(request) self.assertEqual(result['route'], mapper.routes['root']) self.assertEqual(result['match'], {}) @@ -643,8 +647,10 @@ class DummyContext(object): class DummyRequest(object): - def __init__(self, environ): - self.environ = environ + scheme = 'http' + + def __init__(self, **kw): + self.__dict__.update(kw) class DummyRoute(object): |
