We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
stop overriding certain webob properties like json_body
pyramid defined `request.json_body` before webob, but now webob has a better impl than pyramid and it can't be used. We should remove the impl and rely on inheriting the behavior from webob. There may be other attributes like this as well.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/pyramid/request.py`
Content:
```
1 from collections import deque
2 import json
3 
4 from zope.interface import implementer
5 from zope.interface.interface import InterfaceClass
6 
7 from webob import BaseRequest
8 
9 from pyramid.interfaces import (
10     IRequest,
11     IRequestExtensions,
12     IResponse,
13     ISessionFactory,
14 )
15 
16 from pyramid.decorator import reify
17 from pyramid.i18n import LocalizerRequestMixin
18 from pyramid.response import Response, _get_response_factory
19 from pyramid.security import AuthenticationAPIMixin, AuthorizationAPIMixin
20 from pyramid.url import URLMethodsMixin
21 from pyramid.util import (
22     InstancePropertyHelper,
23     InstancePropertyMixin,
24     text_,
25     bytes_,
26 )
27 from pyramid.view import ViewMethodsMixin
28 
29 
30 class TemplateContext(object):
31     pass
32 
33 
34 class CallbackMethodsMixin(object):
35     @reify
36     def finished_callbacks(self):
37         return deque()
38 
39     @reify
40     def response_callbacks(self):
41         return deque()
42 
43     def add_response_callback(self, callback):
44         """
45         Add a callback to the set of callbacks to be called by the
46         :term:`router` at a point after a :term:`response` object is
47         successfully created.  :app:`Pyramid` does not have a
48         global response object: this functionality allows an
49         application to register an action to be performed against the
50         response once one is created.
51 
52         A 'callback' is a callable which accepts two positional
53         parameters: ``request`` and ``response``.  For example:
54 
55         .. code-block:: python
56            :linenos:
57 
58            def cache_callback(request, response):
59                'Set the cache_control max_age for the response'
60                response.cache_control.max_age = 360
61            request.add_response_callback(cache_callback)
62 
63         Response callbacks are called in the order they're added
64         (first-to-most-recently-added).  No response callback is
65         called if an exception happens in application code, or if the
66         response object returned by :term:`view` code is invalid.
67 
68         All response callbacks are called *after* the tweens and
69         *before* the :class:`pyramid.events.NewResponse` event is sent.
70 
71         Errors raised by callbacks are not handled specially.  They
72         will be propagated to the caller of the :app:`Pyramid`
73         router application.
74 
75         .. seealso::
76 
77             See also :ref:`using_response_callbacks`.
78         """
79 
80         self.response_callbacks.append(callback)
81 
82     def _process_response_callbacks(self, response):
83         callbacks = self.response_callbacks
84         while callbacks:
85             callback = callbacks.popleft()
86             callback(self, response)
87 
88     def add_finished_callback(self, callback):
89         """
90         Add a callback to the set of callbacks to be called
91         unconditionally by the :term:`router` at the very end of
92         request processing.
93 
94         ``callback`` is a callable which accepts a single positional
95         parameter: ``request``.  For example:
96 
97         .. code-block:: python
98            :linenos:
99 
100            import transaction
101 
102            def commit_callback(request):
103                '''commit or abort the transaction associated with request'''
104                if request.exception is not None:
105                    transaction.abort()
106                else:
107                    transaction.commit()
108            request.add_finished_callback(commit_callback)
109 
110         Finished callbacks are called in the order they're added (
111         first- to most-recently- added).  Finished callbacks (unlike
112         response callbacks) are *always* called, even if an exception
113         happens in application code that prevents a response from
114         being generated.
115 
116         The set of finished callbacks associated with a request are
117         called *very late* in the processing of that request; they are
118         essentially the last thing called by the :term:`router`. They
119         are called after response processing has already occurred in a
120         top-level ``finally:`` block within the router request
121         processing code.  As a result, mutations performed to the
122         ``request`` provided to a finished callback will have no
123         meaningful effect, because response processing will have
124         already occurred, and the request's scope will expire almost
125         immediately after all finished callbacks have been processed.
126 
127         Errors raised by finished callbacks are not handled specially.
128         They will be propagated to the caller of the :app:`Pyramid`
129         router application.
130 
131         .. seealso::
132 
133             See also :ref:`using_finished_callbacks`.
134         """
135         self.finished_callbacks.append(callback)
136 
137     def _process_finished_callbacks(self):
138         callbacks = self.finished_callbacks
139         while callbacks:
140             callback = callbacks.popleft()
141             callback(self)
142 
143 
144 @implementer(IRequest)
145 class Request(
146     BaseRequest,
147     URLMethodsMixin,
148     CallbackMethodsMixin,
149     InstancePropertyMixin,
150     LocalizerRequestMixin,
151     AuthenticationAPIMixin,
152     AuthorizationAPIMixin,
153     ViewMethodsMixin,
154 ):
155     """
156     A subclass of the :term:`WebOb` Request class.  An instance of
157     this class is created by the :term:`router` and is provided to a
158     view callable (and to other subsystems) as the ``request``
159     argument.
160 
161     The documentation below (save for the ``add_response_callback`` and
162     ``add_finished_callback`` methods, which are defined in this subclass
163     itself, and the attributes ``context``, ``registry``, ``root``,
164     ``subpath``, ``traversed``, ``view_name``, ``virtual_root`` , and
165     ``virtual_root_path``, each of which is added to the request by the
166     :term:`router` at request ingress time) are autogenerated from the WebOb
167     source code used when this documentation was generated.
168 
169     Due to technical constraints, we can't yet display the WebOb
170     version number from which this documentation is autogenerated, but
171     it will be the 'prevailing WebOb version' at the time of the
172     release of this :app:`Pyramid` version.  See
173     https://webob.org/ for further information.
174     """
175 
176     exception = None
177     exc_info = None
178     matchdict = None
179     matched_route = None
180     request_iface = IRequest
181 
182     ResponseClass = Response
183 
184     @reify
185     def tmpl_context(self):
186         # docs-deprecated template context for Pylons-like apps; do not
187         # remove.
188         return TemplateContext()
189 
190     @reify
191     def session(self):
192         """ Obtain the :term:`session` object associated with this
193         request.  If a :term:`session factory` has not been registered
194         during application configuration, a
195         :class:`pyramid.exceptions.ConfigurationError` will be raised"""
196         factory = self.registry.queryUtility(ISessionFactory)
197         if factory is None:
198             raise AttributeError(
199                 'No session factory registered '
200                 '(see the Sessions chapter of the Pyramid documentation)'
201             )
202         return factory(self)
203 
204     @reify
205     def response(self):
206         """This attribute is actually a "reified" property which returns an
207         instance of the :class:`pyramid.response.Response`. class.  The
208         response object returned does not exist until this attribute is
209         accessed.  Subsequent accesses will return the same Response object.
210 
211         The ``request.response`` API is used by renderers.  A render obtains
212         the response object it will return from a view that uses that renderer
213         by accessing ``request.response``.  Therefore, it's possible to use the
214         ``request.response`` API to set up a response object with "the
215         right" attributes (e.g. by calling ``request.response.set_cookie()``)
216         within a view that uses a renderer.  Mutations to this response object
217         will be preserved in the response sent to the client."""
218         response_factory = _get_response_factory(self.registry)
219         return response_factory(self)
220 
221     def is_response(self, ob):
222         """ Return ``True`` if the object passed as ``ob`` is a valid
223         response object, ``False`` otherwise."""
224         if ob.__class__ is Response:
225             return True
226         registry = self.registry
227         adapted = registry.queryAdapterOrSelf(ob, IResponse)
228         if adapted is None:
229             return False
230         return adapted is ob
231 
232     @property
233     def json_body(self):
234         return json.loads(text_(self.body, self.charset))
235 
236 
237 def route_request_iface(name, bases=()):
238     # zope.interface treats the __name__ as the __doc__ and changes __name__
239     # to None for interfaces that contain spaces if you do not pass a
240     # nonempty __doc__ (insane); see
241     # zope.interface.interface.Element.__init__ and
242     # https://github.com/Pylons/pyramid/issues/232; as a result, always pass
243     # __doc__ to the InterfaceClass constructor.
244     iface = InterfaceClass(
245         '%s_IRequest' % name,
246         bases=bases,
247         __doc__="route_request_iface-generated interface",
248     )
249     # for exception view lookups
250     iface.combined = InterfaceClass(
251         '%s_combined_IRequest' % name,
252         bases=(iface, IRequest),
253         __doc__='route_request_iface-generated combined interface',
254     )
255     return iface
256 
257 
258 def add_global_response_headers(request, headerlist):
259     def add_headers(request, response):
260         for k, v in headerlist:
261             response.headerlist.append((k, v))
262 
263     request.add_response_callback(add_headers)
264 
265 
266 def call_app_with_subpath_as_path_info(request, app):
267     # Copy the request.  Use the source request's subpath (if it exists) as
268     # the new request's PATH_INFO.  Set the request copy's SCRIPT_NAME to the
269     # prefix before the subpath.  Call the application with the new request
270     # and return a response.
271     #
272     # Postconditions:
273     # - SCRIPT_NAME and PATH_INFO are empty or start with /
274     # - At least one of SCRIPT_NAME or PATH_INFO are set.
275     # - SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should
276     #   be '/').
277 
278     environ = request.environ
279     script_name = environ.get('SCRIPT_NAME', '')
280     path_info = environ.get('PATH_INFO', '/')
281     subpath = list(getattr(request, 'subpath', ()))
282 
283     new_script_name = ''
284 
285     # compute new_path_info
286     new_path_info = '/' + '/'.join(
287         [text_(x.encode('utf-8'), 'latin-1') for x in subpath]
288     )
289 
290     if new_path_info != '/':  # don't want a sole double-slash
291         if path_info != '/':  # if orig path_info is '/', we're already done
292             if path_info.endswith('/'):
293                 # readd trailing slash stripped by subpath (traversal)
294                 # conversion
295                 new_path_info += '/'
296 
297     # compute new_script_name
298     workback = (script_name + path_info).split('/')
299 
300     tmp = []
301     while workback:
302         if tmp == subpath:
303             break
304         el = workback.pop()
305         if el:
306             tmp.insert(0, text_(bytes_(el, 'latin-1'), 'utf-8'))
307 
308     # strip all trailing slashes from workback to avoid appending undue slashes
309     # to end of script_name
310     while workback and (workback[-1] == ''):
311         workback = workback[:-1]
312 
313     new_script_name = '/'.join(workback)
314 
315     new_request = request.copy()
316     new_request.environ['SCRIPT_NAME'] = new_script_name
317     new_request.environ['PATH_INFO'] = new_path_info
318 
319     return new_request.get_response(app)
320 
321 
322 def apply_request_extensions(request, extensions=None):
323     """Apply request extensions (methods and properties) to an instance of
324     :class:`pyramid.interfaces.IRequest`. This method is dependent on the
325     ``request`` containing a properly initialized registry.
326 
327     After invoking this method, the ``request`` should have the methods
328     and properties that were defined using
329     :meth:`pyramid.config.Configurator.add_request_method`.
330     """
331     if extensions is None:
332         extensions = request.registry.queryUtility(IRequestExtensions)
333     if extensions is not None:
334         for name, fn in extensions.methods.items():
335             method = fn.__get__(request, request.__class__)
336             setattr(request, name, method)
337 
338         InstancePropertyHelper.apply_properties(
339             request, extensions.descriptors
340         )
341
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/pyramid/request.py b/src/pyramid/request.py
--- a/src/pyramid/request.py
+++ b/src/pyramid/request.py
@@ -1,5 +1,4 @@
 from collections import deque
-import json
 
 from zope.interface import implementer
 from zope.interface.interface import InterfaceClass
@@ -229,10 +228,6 @@
             return False
         return adapted is ob
 
-    @property
-    def json_body(self):
-        return json.loads(text_(self.body, self.charset))
-
 
 def route_request_iface(name, bases=()):
     # zope.interface treats the __name__ as the __doc__ and changes __name__

{"golden_diff": "diff --git a/src/pyramid/request.py b/src/pyramid/request.py\n--- a/src/pyramid/request.py\n+++ b/src/pyramid/request.py\n@@ -1,5 +1,4 @@\n from collections import deque\n-import json\n \n from zope.interface import implementer\n from zope.interface.interface import InterfaceClass\n@@ -229,10 +228,6 @@\n             return False\n         return adapted is ob\n \n-    @property\n-    def json_body(self):\n-        return json.loads(text_(self.body, self.charset))\n-\n \n def route_request_iface(name, bases=()):\n     # zope.interface treats the __name__ as the __doc__ and changes __name__\n", "issue": "stop overriding certain webob properties like json_body\npyramid defined `request.json_body` before webob, but now webob has a better impl than pyramid and it can't be used. We should remove the impl and rely on inheriting the behavior from webob. There may be other attributes like this as well.\n", "before_files": [{"content": "from collections import deque\nimport json\n\nfrom zope.interface import implementer\nfrom zope.interface.interface import InterfaceClass\n\nfrom webob import BaseRequest\n\nfrom pyramid.interfaces import (\n    IRequest,\n    IRequestExtensions,\n    IResponse,\n    ISessionFactory,\n)\n\nfrom pyramid.decorator import reify\nfrom pyramid.i18n import LocalizerRequestMixin\nfrom pyramid.response import Response, _get_response_factory\nfrom pyramid.security import AuthenticationAPIMixin, AuthorizationAPIMixin\nfrom pyramid.url import URLMethodsMixin\nfrom pyramid.util import (\n    InstancePropertyHelper,\n    InstancePropertyMixin,\n    text_,\n    bytes_,\n)\nfrom pyramid.view import ViewMethodsMixin\n\n\nclass TemplateContext(object):\n    pass\n\n\nclass CallbackMethodsMixin(object):\n    @reify\n    def finished_callbacks(self):\n        return deque()\n\n    @reify\n    def response_callbacks(self):\n        return deque()\n\n    def add_response_callback(self, callback):\n        \"\"\"\n        Add a callback to the set of callbacks to be called by the\n        :term:`router` at a point after a :term:`response` object is\n        successfully created.  :app:`Pyramid` does not have a\n        global response object: this functionality allows an\n        application to register an action to be performed against the\n        response once one is created.\n\n        A 'callback' is a callable which accepts two positional\n        parameters: ``request`` and ``response``.  For example:\n\n        .. code-block:: python\n           :linenos:\n\n           def cache_callback(request, response):\n               'Set the cache_control max_age for the response'\n               response.cache_control.max_age = 360\n           request.add_response_callback(cache_callback)\n\n        Response callbacks are called in the order they're added\n        (first-to-most-recently-added).  No response callback is\n        called if an exception happens in application code, or if the\n        response object returned by :term:`view` code is invalid.\n\n        All response callbacks are called *after* the tweens and\n        *before* the :class:`pyramid.events.NewResponse` event is sent.\n\n        Errors raised by callbacks are not handled specially.  They\n        will be propagated to the caller of the :app:`Pyramid`\n        router application.\n\n        .. seealso::\n\n            See also :ref:`using_response_callbacks`.\n        \"\"\"\n\n        self.response_callbacks.append(callback)\n\n    def _process_response_callbacks(self, response):\n        callbacks = self.response_callbacks\n        while callbacks:\n            callback = callbacks.popleft()\n            callback(self, response)\n\n    def add_finished_callback(self, callback):\n        \"\"\"\n        Add a callback to the set of callbacks to be called\n        unconditionally by the :term:`router` at the very end of\n        request processing.\n\n        ``callback`` is a callable which accepts a single positional\n        parameter: ``request``.  For example:\n\n        .. code-block:: python\n           :linenos:\n\n           import transaction\n\n           def commit_callback(request):\n               '''commit or abort the transaction associated with request'''\n               if request.exception is not None:\n                   transaction.abort()\n               else:\n                   transaction.commit()\n           request.add_finished_callback(commit_callback)\n\n        Finished callbacks are called in the order they're added (\n        first- to most-recently- added).  Finished callbacks (unlike\n        response callbacks) are *always* called, even if an exception\n        happens in application code that prevents a response from\n        being generated.\n\n        The set of finished callbacks associated with a request are\n        called *very late* in the processing of that request; they are\n        essentially the last thing called by the :term:`router`. They\n        are called after response processing has already occurred in a\n        top-level ``finally:`` block within the router request\n        processing code.  As a result, mutations performed to the\n        ``request`` provided to a finished callback will have no\n        meaningful effect, because response processing will have\n        already occurred, and the request's scope will expire almost\n        immediately after all finished callbacks have been processed.\n\n        Errors raised by finished callbacks are not handled specially.\n        They will be propagated to the caller of the :app:`Pyramid`\n        router application.\n\n        .. seealso::\n\n            See also :ref:`using_finished_callbacks`.\n        \"\"\"\n        self.finished_callbacks.append(callback)\n\n    def _process_finished_callbacks(self):\n        callbacks = self.finished_callbacks\n        while callbacks:\n            callback = callbacks.popleft()\n            callback(self)\n\n\n@implementer(IRequest)\nclass Request(\n    BaseRequest,\n    URLMethodsMixin,\n    CallbackMethodsMixin,\n    InstancePropertyMixin,\n    LocalizerRequestMixin,\n    AuthenticationAPIMixin,\n    AuthorizationAPIMixin,\n    ViewMethodsMixin,\n):\n    \"\"\"\n    A subclass of the :term:`WebOb` Request class.  An instance of\n    this class is created by the :term:`router` and is provided to a\n    view callable (and to other subsystems) as the ``request``\n    argument.\n\n    The documentation below (save for the ``add_response_callback`` and\n    ``add_finished_callback`` methods, which are defined in this subclass\n    itself, and the attributes ``context``, ``registry``, ``root``,\n    ``subpath``, ``traversed``, ``view_name``, ``virtual_root`` , and\n    ``virtual_root_path``, each of which is added to the request by the\n    :term:`router` at request ingress time) are autogenerated from the WebOb\n    source code used when this documentation was generated.\n\n    Due to technical constraints, we can't yet display the WebOb\n    version number from which this documentation is autogenerated, but\n    it will be the 'prevailing WebOb version' at the time of the\n    release of this :app:`Pyramid` version.  See\n    https://webob.org/ for further information.\n    \"\"\"\n\n    exception = None\n    exc_info = None\n    matchdict = None\n    matched_route = None\n    request_iface = IRequest\n\n    ResponseClass = Response\n\n    @reify\n    def tmpl_context(self):\n        # docs-deprecated template context for Pylons-like apps; do not\n        # remove.\n        return TemplateContext()\n\n    @reify\n    def session(self):\n        \"\"\" Obtain the :term:`session` object associated with this\n        request.  If a :term:`session factory` has not been registered\n        during application configuration, a\n        :class:`pyramid.exceptions.ConfigurationError` will be raised\"\"\"\n        factory = self.registry.queryUtility(ISessionFactory)\n        if factory is None:\n            raise AttributeError(\n                'No session factory registered '\n                '(see the Sessions chapter of the Pyramid documentation)'\n            )\n        return factory(self)\n\n    @reify\n    def response(self):\n        \"\"\"This attribute is actually a \"reified\" property which returns an\n        instance of the :class:`pyramid.response.Response`. class.  The\n        response object returned does not exist until this attribute is\n        accessed.  Subsequent accesses will return the same Response object.\n\n        The ``request.response`` API is used by renderers.  A render obtains\n        the response object it will return from a view that uses that renderer\n        by accessing ``request.response``.  Therefore, it's possible to use the\n        ``request.response`` API to set up a response object with \"the\n        right\" attributes (e.g. by calling ``request.response.set_cookie()``)\n        within a view that uses a renderer.  Mutations to this response object\n        will be preserved in the response sent to the client.\"\"\"\n        response_factory = _get_response_factory(self.registry)\n        return response_factory(self)\n\n    def is_response(self, ob):\n        \"\"\" Return ``True`` if the object passed as ``ob`` is a valid\n        response object, ``False`` otherwise.\"\"\"\n        if ob.__class__ is Response:\n            return True\n        registry = self.registry\n        adapted = registry.queryAdapterOrSelf(ob, IResponse)\n        if adapted is None:\n            return False\n        return adapted is ob\n\n    @property\n    def json_body(self):\n        return json.loads(text_(self.body, self.charset))\n\n\ndef route_request_iface(name, bases=()):\n    # zope.interface treats the __name__ as the __doc__ and changes __name__\n    # to None for interfaces that contain spaces if you do not pass a\n    # nonempty __doc__ (insane); see\n    # zope.interface.interface.Element.__init__ and\n    # https://github.com/Pylons/pyramid/issues/232; as a result, always pass\n    # __doc__ to the InterfaceClass constructor.\n    iface = InterfaceClass(\n        '%s_IRequest' % name,\n        bases=bases,\n        __doc__=\"route_request_iface-generated interface\",\n    )\n    # for exception view lookups\n    iface.combined = InterfaceClass(\n        '%s_combined_IRequest' % name,\n        bases=(iface, IRequest),\n        __doc__='route_request_iface-generated combined interface',\n    )\n    return iface\n\n\ndef add_global_response_headers(request, headerlist):\n    def add_headers(request, response):\n        for k, v in headerlist:\n            response.headerlist.append((k, v))\n\n    request.add_response_callback(add_headers)\n\n\ndef call_app_with_subpath_as_path_info(request, app):\n    # Copy the request.  Use the source request's subpath (if it exists) as\n    # the new request's PATH_INFO.  Set the request copy's SCRIPT_NAME to the\n    # prefix before the subpath.  Call the application with the new request\n    # and return a response.\n    #\n    # Postconditions:\n    # - SCRIPT_NAME and PATH_INFO are empty or start with /\n    # - At least one of SCRIPT_NAME or PATH_INFO are set.\n    # - SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should\n    #   be '/').\n\n    environ = request.environ\n    script_name = environ.get('SCRIPT_NAME', '')\n    path_info = environ.get('PATH_INFO', '/')\n    subpath = list(getattr(request, 'subpath', ()))\n\n    new_script_name = ''\n\n    # compute new_path_info\n    new_path_info = '/' + '/'.join(\n        [text_(x.encode('utf-8'), 'latin-1') for x in subpath]\n    )\n\n    if new_path_info != '/':  # don't want a sole double-slash\n        if path_info != '/':  # if orig path_info is '/', we're already done\n            if path_info.endswith('/'):\n                # readd trailing slash stripped by subpath (traversal)\n                # conversion\n                new_path_info += '/'\n\n    # compute new_script_name\n    workback = (script_name + path_info).split('/')\n\n    tmp = []\n    while workback:\n        if tmp == subpath:\n            break\n        el = workback.pop()\n        if el:\n            tmp.insert(0, text_(bytes_(el, 'latin-1'), 'utf-8'))\n\n    # strip all trailing slashes from workback to avoid appending undue slashes\n    # to end of script_name\n    while workback and (workback[-1] == ''):\n        workback = workback[:-1]\n\n    new_script_name = '/'.join(workback)\n\n    new_request = request.copy()\n    new_request.environ['SCRIPT_NAME'] = new_script_name\n    new_request.environ['PATH_INFO'] = new_path_info\n\n    return new_request.get_response(app)\n\n\ndef apply_request_extensions(request, extensions=None):\n    \"\"\"Apply request extensions (methods and properties) to an instance of\n    :class:`pyramid.interfaces.IRequest`. This method is dependent on the\n    ``request`` containing a properly initialized registry.\n\n    After invoking this method, the ``request`` should have the methods\n    and properties that were defined using\n    :meth:`pyramid.config.Configurator.add_request_method`.\n    \"\"\"\n    if extensions is None:\n        extensions = request.registry.queryUtility(IRequestExtensions)\n    if extensions is not None:\n        for name, fn in extensions.methods.items():\n            method = fn.__get__(request, request.__class__)\n            setattr(request, name, method)\n\n        InstancePropertyHelper.apply_properties(\n            request, extensions.descriptors\n        )\n", "path": "src/pyramid/request.py"}], "after_files": [{"content": "from collections import deque\n\nfrom zope.interface import implementer\nfrom zope.interface.interface import InterfaceClass\n\nfrom webob import BaseRequest\n\nfrom pyramid.interfaces import (\n    IRequest,\n    IRequestExtensions,\n    IResponse,\n    ISessionFactory,\n)\n\nfrom pyramid.decorator import reify\nfrom pyramid.i18n import LocalizerRequestMixin\nfrom pyramid.response import Response, _get_response_factory\nfrom pyramid.security import AuthenticationAPIMixin, AuthorizationAPIMixin\nfrom pyramid.url import URLMethodsMixin\nfrom pyramid.util import (\n    InstancePropertyHelper,\n    InstancePropertyMixin,\n    text_,\n    bytes_,\n)\nfrom pyramid.view import ViewMethodsMixin\n\n\nclass TemplateContext(object):\n    pass\n\n\nclass CallbackMethodsMixin(object):\n    @reify\n    def finished_callbacks(self):\n        return deque()\n\n    @reify\n    def response_callbacks(self):\n        return deque()\n\n    def add_response_callback(self, callback):\n        \"\"\"\n        Add a callback to the set of callbacks to be called by the\n        :term:`router` at a point after a :term:`response` object is\n        successfully created.  :app:`Pyramid` does not have a\n        global response object: this functionality allows an\n        application to register an action to be performed against the\n        response once one is created.\n\n        A 'callback' is a callable which accepts two positional\n        parameters: ``request`` and ``response``.  For example:\n\n        .. code-block:: python\n           :linenos:\n\n           def cache_callback(request, response):\n               'Set the cache_control max_age for the response'\n               response.cache_control.max_age = 360\n           request.add_response_callback(cache_callback)\n\n        Response callbacks are called in the order they're added\n        (first-to-most-recently-added).  No response callback is\n        called if an exception happens in application code, or if the\n        response object returned by :term:`view` code is invalid.\n\n        All response callbacks are called *after* the tweens and\n        *before* the :class:`pyramid.events.NewResponse` event is sent.\n\n        Errors raised by callbacks are not handled specially.  They\n        will be propagated to the caller of the :app:`Pyramid`\n        router application.\n\n        .. seealso::\n\n            See also :ref:`using_response_callbacks`.\n        \"\"\"\n\n        self.response_callbacks.append(callback)\n\n    def _process_response_callbacks(self, response):\n        callbacks = self.response_callbacks\n        while callbacks:\n            callback = callbacks.popleft()\n            callback(self, response)\n\n    def add_finished_callback(self, callback):\n        \"\"\"\n        Add a callback to the set of callbacks to be called\n        unconditionally by the :term:`router` at the very end of\n        request processing.\n\n        ``callback`` is a callable which accepts a single positional\n        parameter: ``request``.  For example:\n\n        .. code-block:: python\n           :linenos:\n\n           import transaction\n\n           def commit_callback(request):\n               '''commit or abort the transaction associated with request'''\n               if request.exception is not None:\n                   transaction.abort()\n               else:\n                   transaction.commit()\n           request.add_finished_callback(commit_callback)\n\n        Finished callbacks are called in the order they're added (\n        first- to most-recently- added).  Finished callbacks (unlike\n        response callbacks) are *always* called, even if an exception\n        happens in application code that prevents a response from\n        being generated.\n\n        The set of finished callbacks associated with a request are\n        called *very late* in the processing of that request; they are\n        essentially the last thing called by the :term:`router`. They\n        are called after response processing has already occurred in a\n        top-level ``finally:`` block within the router request\n        processing code.  As a result, mutations performed to the\n        ``request`` provided to a finished callback will have no\n        meaningful effect, because response processing will have\n        already occurred, and the request's scope will expire almost\n        immediately after all finished callbacks have been processed.\n\n        Errors raised by finished callbacks are not handled specially.\n        They will be propagated to the caller of the :app:`Pyramid`\n        router application.\n\n        .. seealso::\n\n            See also :ref:`using_finished_callbacks`.\n        \"\"\"\n        self.finished_callbacks.append(callback)\n\n    def _process_finished_callbacks(self):\n        callbacks = self.finished_callbacks\n        while callbacks:\n            callback = callbacks.popleft()\n            callback(self)\n\n\n@implementer(IRequest)\nclass Request(\n    BaseRequest,\n    URLMethodsMixin,\n    CallbackMethodsMixin,\n    InstancePropertyMixin,\n    LocalizerRequestMixin,\n    AuthenticationAPIMixin,\n    AuthorizationAPIMixin,\n    ViewMethodsMixin,\n):\n    \"\"\"\n    A subclass of the :term:`WebOb` Request class.  An instance of\n    this class is created by the :term:`router` and is provided to a\n    view callable (and to other subsystems) as the ``request``\n    argument.\n\n    The documentation below (save for the ``add_response_callback`` and\n    ``add_finished_callback`` methods, which are defined in this subclass\n    itself, and the attributes ``context``, ``registry``, ``root``,\n    ``subpath``, ``traversed``, ``view_name``, ``virtual_root`` , and\n    ``virtual_root_path``, each of which is added to the request by the\n    :term:`router` at request ingress time) are autogenerated from the WebOb\n    source code used when this documentation was generated.\n\n    Due to technical constraints, we can't yet display the WebOb\n    version number from which this documentation is autogenerated, but\n    it will be the 'prevailing WebOb version' at the time of the\n    release of this :app:`Pyramid` version.  See\n    https://webob.org/ for further information.\n    \"\"\"\n\n    exception = None\n    exc_info = None\n    matchdict = None\n    matched_route = None\n    request_iface = IRequest\n\n    ResponseClass = Response\n\n    @reify\n    def tmpl_context(self):\n        # docs-deprecated template context for Pylons-like apps; do not\n        # remove.\n        return TemplateContext()\n\n    @reify\n    def session(self):\n        \"\"\" Obtain the :term:`session` object associated with this\n        request.  If a :term:`session factory` has not been registered\n        during application configuration, a\n        :class:`pyramid.exceptions.ConfigurationError` will be raised\"\"\"\n        factory = self.registry.queryUtility(ISessionFactory)\n        if factory is None:\n            raise AttributeError(\n                'No session factory registered '\n                '(see the Sessions chapter of the Pyramid documentation)'\n            )\n        return factory(self)\n\n    @reify\n    def response(self):\n        \"\"\"This attribute is actually a \"reified\" property which returns an\n        instance of the :class:`pyramid.response.Response`. class.  The\n        response object returned does not exist until this attribute is\n        accessed.  Subsequent accesses will return the same Response object.\n\n        The ``request.response`` API is used by renderers.  A render obtains\n        the response object it will return from a view that uses that renderer\n        by accessing ``request.response``.  Therefore, it's possible to use the\n        ``request.response`` API to set up a response object with \"the\n        right\" attributes (e.g. by calling ``request.response.set_cookie()``)\n        within a view that uses a renderer.  Mutations to this response object\n        will be preserved in the response sent to the client.\"\"\"\n        response_factory = _get_response_factory(self.registry)\n        return response_factory(self)\n\n    def is_response(self, ob):\n        \"\"\" Return ``True`` if the object passed as ``ob`` is a valid\n        response object, ``False`` otherwise.\"\"\"\n        if ob.__class__ is Response:\n            return True\n        registry = self.registry\n        adapted = registry.queryAdapterOrSelf(ob, IResponse)\n        if adapted is None:\n            return False\n        return adapted is ob\n\n\ndef route_request_iface(name, bases=()):\n    # zope.interface treats the __name__ as the __doc__ and changes __name__\n    # to None for interfaces that contain spaces if you do not pass a\n    # nonempty __doc__ (insane); see\n    # zope.interface.interface.Element.__init__ and\n    # https://github.com/Pylons/pyramid/issues/232; as a result, always pass\n    # __doc__ to the InterfaceClass constructor.\n    iface = InterfaceClass(\n        '%s_IRequest' % name,\n        bases=bases,\n        __doc__=\"route_request_iface-generated interface\",\n    )\n    # for exception view lookups\n    iface.combined = InterfaceClass(\n        '%s_combined_IRequest' % name,\n        bases=(iface, IRequest),\n        __doc__='route_request_iface-generated combined interface',\n    )\n    return iface\n\n\ndef add_global_response_headers(request, headerlist):\n    def add_headers(request, response):\n        for k, v in headerlist:\n            response.headerlist.append((k, v))\n\n    request.add_response_callback(add_headers)\n\n\ndef call_app_with_subpath_as_path_info(request, app):\n    # Copy the request.  Use the source request's subpath (if it exists) as\n    # the new request's PATH_INFO.  Set the request copy's SCRIPT_NAME to the\n    # prefix before the subpath.  Call the application with the new request\n    # and return a response.\n    #\n    # Postconditions:\n    # - SCRIPT_NAME and PATH_INFO are empty or start with /\n    # - At least one of SCRIPT_NAME or PATH_INFO are set.\n    # - SCRIPT_NAME is not '/' (it should be '', and PATH_INFO should\n    #   be '/').\n\n    environ = request.environ\n    script_name = environ.get('SCRIPT_NAME', '')\n    path_info = environ.get('PATH_INFO', '/')\n    subpath = list(getattr(request, 'subpath', ()))\n\n    new_script_name = ''\n\n    # compute new_path_info\n    new_path_info = '/' + '/'.join(\n        [text_(x.encode('utf-8'), 'latin-1') for x in subpath]\n    )\n\n    if new_path_info != '/':  # don't want a sole double-slash\n        if path_info != '/':  # if orig path_info is '/', we're already done\n            if path_info.endswith('/'):\n                # readd trailing slash stripped by subpath (traversal)\n                # conversion\n                new_path_info += '/'\n\n    # compute new_script_name\n    workback = (script_name + path_info).split('/')\n\n    tmp = []\n    while workback:\n        if tmp == subpath:\n            break\n        el = workback.pop()\n        if el:\n            tmp.insert(0, text_(bytes_(el, 'latin-1'), 'utf-8'))\n\n    # strip all trailing slashes from workback to avoid appending undue slashes\n    # to end of script_name\n    while workback and (workback[-1] == ''):\n        workback = workback[:-1]\n\n    new_script_name = '/'.join(workback)\n\n    new_request = request.copy()\n    new_request.environ['SCRIPT_NAME'] = new_script_name\n    new_request.environ['PATH_INFO'] = new_path_info\n\n    return new_request.get_response(app)\n\n\ndef apply_request_extensions(request, extensions=None):\n    \"\"\"Apply request extensions (methods and properties) to an instance of\n    :class:`pyramid.interfaces.IRequest`. This method is dependent on the\n    ``request`` containing a properly initialized registry.\n\n    After invoking this method, the ``request`` should have the methods\n    and properties that were defined using\n    :meth:`pyramid.config.Configurator.add_request_method`.\n    \"\"\"\n    if extensions is None:\n        extensions = request.registry.queryUtility(IRequestExtensions)\n    if extensions is not None:\n        for name, fn in extensions.methods.items():\n            method = fn.__get__(request, request.__class__)\n            setattr(request, name, method)\n\n        InstancePropertyHelper.apply_properties(\n            request, extensions.descriptors\n        )\n", "path": "src/pyramid/request.py"}]}