CHANGES.txt | ●●●●● patch | view | raw | blame | history | |
pyramid/request.py | ●●●●● patch | view | raw | blame | history | |
pyramid/tests/test_request.py | ●●●●● patch | view | raw | blame | history | |
pyramid/tests/test_traversal.py | ●●●●● patch | view | raw | blame | history | |
pyramid/traversal.py | ●●●●● patch | view | raw | blame | history | |
setup.py | ●●●●● patch | view | raw | blame | history |
CHANGES.txt
@@ -151,3 +151,32 @@ featureful ``pyramid.config.Configurator.set_request_method`` should be used in its place (it has all of the same capabilities but can also extend the request object with methods). Backwards Incompatibilities --------------------------- - The Pyramid router no longer adds the values ``bfg.routes.route`` and ``bfg.routes.matchdict`` to the request's WSGI environment dictionary. These values were docs-deprecated in ``repoze.bfg`` 1.0 (effectively seven minor releases ago). If your code depended on these values, use request.matched_route and request.matchdict instead. - It is no longer possible to pass an environ dictionary directly to ``pyramid.traversal.ResourceTreeTraverser.__call__`` (aka ``ModelGraphTraverser.__call__``). Instead, you must pass a request object. Passing an environment instead of a request has generated a deprecation warning since Pyramid 1.1. - Pyramid will no longer work properly if you use the ``webob.request.LegacyRequest`` as a request factory. Instances of the LegacyRequest class have a ``request.path_info`` which return a string. This Pyramid release assumes that ``request.path_info`` will unconditionally be Unicode. Dependencies ------------ - Pyramid now requires WebOb 1.2b3+ (the prior Pyramid release only relied on 1.2dev+). This is to ensure that we obtain a version of WebOb that returns ``request.path_info`` as text. pyramid/request.py
@@ -454,13 +454,4 @@ new_request.environ['SCRIPT_NAME'] = new_script_name new_request.environ['PATH_INFO'] = new_path_info # In case downstream WSGI app is a Pyramid app, hack around existence of # these envars until we can safely remove them (see router.py); in any # case, even if these get removed, it might be better to not copy the # existing environ but to create a new one instead. if 'bfg.routes.route' in new_request.environ: del new_request.environ['bfg.routes.route'] if 'bfg.routes.matchdict' in new_request.environ: del new_request.environ['bfg.routes.matchdict'] return new_request.get_response(app) pyramid/tests/test_request.py
@@ -549,18 +549,6 @@ self.assertEqual(request.environ['SCRIPT_NAME'], '/' + encoded) self.assertEqual(request.environ['PATH_INFO'], '/' + encoded) def test_it_removes_bfg_routes_info(self): request = DummyRequest({}) request.environ['bfg.routes.route'] = True request.environ['bfg.routes.matchdict'] = True response = self._callFUT(request, 'app') self.assertTrue(request.copied) self.assertEqual(response, 'app') self.assertEqual(request.environ['SCRIPT_NAME'], '') self.assertEqual(request.environ['PATH_INFO'], '/') self.assertFalse('bfg.routes.route' in request.environ) self.assertFalse('bfg.routes.matchdict' in request.environ) class DummyRequest: def __init__(self, environ=None): if environ is None: pyramid/tests/test_traversal.py
@@ -71,8 +71,6 @@ self.assertEqual(self._callFUT('../../bar'), (text_('bar'),)) def test_segments_are_unicode(self): # breaks because lru_cached holds on to strings? possibly from # other tests. not good. result = self._callFUT('/foo/bar') self.assertEqual(type(result[0]), text_type) self.assertEqual(type(result[1]), text_type) @@ -162,7 +160,7 @@ def test_call_pathel_with_no_getitem(self): policy = self._makeOne(None) environ = self._getEnviron() request = DummyRequest(environ, path_info='/foo/bar') request = DummyRequest(environ, path_info=text_('/foo/bar')) result = policy(request) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], 'foo') @@ -176,7 +174,7 @@ root = DummyContext() policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info='') request = DummyRequest(environ, path_info=text_('')) result = policy(request) self.assertEqual(result['context'], root) self.assertEqual(result['view_name'], '') @@ -191,7 +189,7 @@ root = DummyContext(foo) policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info='/foo/bar') request = DummyRequest(environ, path_info=text_('/foo/bar')) result = policy(request) self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], 'bar') @@ -206,7 +204,7 @@ root = DummyContext(foo) policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info='/foo/bar/baz/buz') request = DummyRequest(environ, path_info=text_('/foo/bar/baz/buz')) result = policy(request) self.assertEqual(result['context'], foo) self.assertEqual(result['view_name'], 'bar') @@ -221,7 +219,7 @@ root = DummyContext(foo) policy = self._makeOne(root) environ = self._getEnviron() request = DummyRequest(environ, path_info='/@@foo') request = DummyRequest(environ, path_info=text_('/@@foo')) result = policy(request) self.assertEqual(result['context'], root) self.assertEqual(result['view_name'], 'foo') @@ -238,7 +236,7 @@ foo = DummyContext(bar, 'foo') root = DummyContext(foo, 'root') policy = self._makeOne(root) request = DummyRequest(environ, path_info='/baz') request = DummyRequest(environ, path_info=text_('/baz')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') @@ -257,7 +255,7 @@ foo = DummyContext(bar, 'foo') root = DummyContext(foo, 'root') policy = self._makeOne(root) request = DummyRequest(environ, path_info='/bar/baz') request = DummyRequest(environ, path_info=text_('/bar/baz')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') @@ -275,7 +273,7 @@ foo = DummyContext(bar) root = DummyContext(foo) policy = self._makeOne(root) request = DummyRequest(environ, path_info='/foo/bar/baz') request = DummyRequest(environ, path_info=text_('/foo/bar/baz')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') @@ -293,7 +291,7 @@ foo = DummyContext(bar, 'foo') root = DummyContext(foo, 'root') policy = self._makeOne(root) request = DummyRequest(environ, path_info='/') request = DummyRequest(environ, path_info=text_('/')) result = policy(request) self.assertEqual(result['context'], baz) self.assertEqual(result['view_name'], '') @@ -308,7 +306,7 @@ def test_call_with_vh_root_path_root(self): policy = self._makeOne(None) environ = self._getEnviron(HTTP_X_VHM_ROOT='/') request = DummyRequest(environ, path_info='/') request = DummyRequest(environ, path_info=text_('/')) result = policy(request) self.assertEqual(result['context'], None) self.assertEqual(result['view_name'], '') @@ -329,7 +327,7 @@ else: vhm_root = b'/Qu\xc3\xa9bec' environ = self._getEnviron(HTTP_X_VHM_ROOT=vhm_root) request = DummyRequest(environ, path_info='/bar') request = DummyRequest(environ, path_info=text_('/bar')) result = policy(request) self.assertEqual(result['context'], bar) self.assertEqual(result['view_name'], '') @@ -351,7 +349,7 @@ root = DummyContext(foo) policy = self._makeOne(root) environ = self._getEnviron() toraise = UnicodeDecodeError('ascii', 'a', 2, 3, '5') toraise = UnicodeDecodeError('ascii', b'a', 2, 3, '5') request = DummyRequest(environ, toraise=toraise) request.matchdict = None self.assertRaises(URLDecodeError, policy, request) @@ -403,7 +401,7 @@ def test_withroute_and_traverse_string(self): resource = DummyContext() traverser = self._makeOne(resource) matchdict = {'traverse':'foo/bar'} matchdict = {'traverse':text_('foo/bar')} request = DummyRequest({}) request.matchdict = matchdict result = traverser(request) @@ -1287,7 +1285,7 @@ matchdict = None matched_route = None def __init__(self, environ=None, path_info='/', toraise=None): def __init__(self, environ=None, path_info=text_('/'), toraise=None): if environ is None: environ = {} self.environ = environ pyramid/traversal.py
@@ -614,6 +614,7 @@ _segment_cache[(segment, safe)] = result return result slash = text_('/') @implementer(ITraverser) class ResourceTreeTraverser(object): @@ -629,17 +630,17 @@ self.root = root def __call__(self, request): matchdict = request.matchdict environ = request.environ matchdict = request.matchdict if matchdict is not None: path = matchdict.get('traverse', '/') or '/' path = matchdict.get('traverse', slash) or slash if is_nonstr_iter(path): # this is a *traverse stararg (not a {traverse}) # routing has already decoded these elements, so we just # need to join them path = '/'.join(path) or '/' path = slash.join(path) or slash subpath = matchdict.get('subpath', ()) if not is_nonstr_iter(subpath): @@ -653,9 +654,10 @@ subpath = () try: # empty if mounted under a path in mod_wsgi, for example path = request.path_info path = request.path_info or slash except KeyError: path = '/' # if environ['PATH_INFO'] is just not there path = slash except UnicodeDecodeError as e: raise URLDecodeError(e.encoding, e.object, e.start, e.end, e.reason) @@ -674,7 +676,7 @@ root = self.root ob = vroot = root if vpath == '/': # invariant: vpath must not be empty if vpath == slash: # invariant: vpath must not be empty # prevent a call to traversal_path if we know it's going # to return the empty tuple vpath_tuple = () setup.py
@@ -39,7 +39,7 @@ 'setuptools', 'Chameleon >= 1.2.3', 'Mako >= 0.3.6', # strict_undefined 'WebOb >= 1.2dev', # response.text / py3 compat 'WebOb >= 1.2b3', # request.path_info is unicode 'repoze.lru >= 0.4', # py3 compat 'zope.interface >= 3.8.0', # has zope.interface.registry 'zope.deprecation >= 3.5.0', # py3 compat