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:
@@ -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
|
||||
# ------------------------------------------------------------------------
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user