fix(Request): context_type function raises AttributeError

Moving the instantiation of Request context to the end of
Request.__init__, so that all Request properties are set up
and accessible from within a context_type function.

Fixes #567
This commit is contained in:
maresp
2015-07-16 09:58:58 +00:00
committed by Kurt Griffiths
parent 3431ac3261
commit 5ce3528077
2 changed files with 29 additions and 8 deletions

View File

@@ -95,6 +95,13 @@ class Request(object):
by creating a custom child class of ``falcon.Request``, and
then passing that new class to `falcon.API()` by way of the
latter's `request_type` parameter.
Note:
When overriding ``context_type`` with a factory function, the
function is called like a method of the current Request
instance. Therefore the first argument is the Request instance
itself (self).
uri (str): The fully-qualified URI for the request.
url (str): alias for `uri`.
relative_uri (str): The path + query string portion of the full URI.
@@ -209,14 +216,6 @@ class Request(object):
self.env = env
self.options = options if options else RequestOptions()
if self.context_type is None:
# Literal syntax is more efficient than using dict()
self.context = {}
else:
# pylint will detect this as not-callable because it only sees the
# declaration of None, not whatever type a subclass may have set.
self.context = self.context_type() # pylint: disable=not-callable
self._wsgierrors = env['wsgi.errors']
self.stream = env['wsgi.input']
self.method = env['REQUEST_METHOD']
@@ -284,6 +283,14 @@ class Request(object):
'application/x-www-form-urlencoded' in self.content_type):
self._parse_form_urlencoded()
if self.context_type is None:
# Literal syntax is more efficient than using dict()
self.context = {}
else:
# pylint will detect this as not-callable because it only sees the
# declaration of None, not whatever type a subclass may have set.
self.context = self.context_type() # pylint: disable=not-callable
# ------------------------------------------------------------------------
# Properties
# ------------------------------------------------------------------------

View File

@@ -31,3 +31,17 @@ class TestRequestContext(testing.TestBase):
env = testing.create_environ()
self.assertRaises(TypeError, MyCustomRequest, env)
def test_custom_request_context_request_access(self):
def create_context(req):
return {'uri': req.uri}
# Define a Request-alike with a custom context type
class MyCustomRequest(Request):
context_type = create_context
env = testing.create_environ()
req = MyCustomRequest(env)
self.assertIsInstance(req.context, dict)
self.assertEqual(req.context['uri'], req.uri)