added a new behaviour for responses that enable the tuple to be in the form of (response, headers) and continiue to support the (response, status, headers) format.
This commit is contained in:
parent
afd3c4532b
commit
70f8b39c52
3 changed files with 39 additions and 12 deletions
|
|
@ -676,9 +676,9 @@ converting return values into response objects is as follows:
|
|||
default parameters.
|
||||
3. If a tuple is returned the items in the tuple can provide extra
|
||||
information. Such tuples have to be in the form ``(response, status,
|
||||
headers)`` where at least one item has to be in the tuple. The
|
||||
`status` value will override the status code and `headers` can be a
|
||||
list or dictionary of additional header values.
|
||||
headers)`` or ``(response, headers)`` where at least one item has
|
||||
to be in the tuple. The `status` value will override the status code
|
||||
and `headers` can be a list or dictionary of additional header values.
|
||||
4. If none of that works, Flask will assume the return value is a
|
||||
valid WSGI application and convert that into a response object.
|
||||
|
||||
|
|
|
|||
23
flask/app.py
23
flask/app.py
|
|
@ -1544,7 +1544,8 @@ class Flask(_PackageBoundObject):
|
|||
a WSGI function the function is called as WSGI application
|
||||
and buffered as response object
|
||||
:class:`tuple` A tuple in the form ``(response, status,
|
||||
headers)`` where `response` is any of the
|
||||
headers)`` or ``(response, headers)``
|
||||
where `response` is any of the
|
||||
types defined here, `status` is a string
|
||||
or an integer and `headers` is a list or
|
||||
a dictionary with header values.
|
||||
|
|
@ -1556,34 +1557,38 @@ class Flask(_PackageBoundObject):
|
|||
Previously a tuple was interpreted as the arguments for the
|
||||
response object.
|
||||
"""
|
||||
status = headers = None
|
||||
status_or_headers = headers = None
|
||||
if isinstance(rv, tuple):
|
||||
rv, status, headers = rv + (None,) * (3 - len(rv))
|
||||
rv, status_or_headers, headers = rv + (None,) * (3 - len(rv))
|
||||
|
||||
if rv is None:
|
||||
raise ValueError('View function did not return a response')
|
||||
|
||||
if isinstance(status_or_headers, (dict, list)):
|
||||
headers, status_or_headers = status_or_headers, None
|
||||
|
||||
if not isinstance(rv, self.response_class):
|
||||
# When we create a response object directly, we let the constructor
|
||||
# set the headers and status. We do this because there can be
|
||||
# some extra logic involved when creating these objects with
|
||||
# specific values (like default content type selection).
|
||||
if isinstance(rv, (text_type, bytes, bytearray)):
|
||||
rv = self.response_class(rv, headers=headers, status=status)
|
||||
headers = status = None
|
||||
rv = self.response_class(rv, headers=headers, status=status_or_headers)
|
||||
headers = status_or_headers = None
|
||||
else:
|
||||
rv = self.response_class.force_type(rv, request.environ)
|
||||
|
||||
if status is not None:
|
||||
if isinstance(status, string_types):
|
||||
rv.status = status
|
||||
if status_or_headers is not None:
|
||||
if isinstance(status_or_headers, string_types):
|
||||
rv.status = status_or_headers
|
||||
else:
|
||||
rv.status_code = status
|
||||
rv.status_code = status_or_headers
|
||||
if headers:
|
||||
rv.headers.extend(headers)
|
||||
|
||||
return rv
|
||||
|
||||
|
||||
def create_url_adapter(self, request):
|
||||
"""Creates a URL adapter for the given request. The URL adapter
|
||||
is created at a point where the request context is not yet set up
|
||||
|
|
|
|||
|
|
@ -735,7 +735,17 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
|||
return 'Meh', 400, {
|
||||
'X-Foo': 'Testing',
|
||||
'Content-Type': 'text/plain; charset=utf-8'
|
||||
}
|
||||
@app.route("/two_args")
|
||||
def from_two_args_tuple():
|
||||
return "Hello", {
|
||||
'X-Foo': 'Test',
|
||||
'Content-Type': 'text/plain; charset=utf-8'
|
||||
}
|
||||
@app.route("/args_status")
|
||||
def from_status_tuple():
|
||||
return "Hi, status!", 400
|
||||
|
||||
c = app.test_client()
|
||||
self.assert_equal(c.get('/unicode').data, u'Hällo Wörld'.encode('utf-8'))
|
||||
self.assert_equal(c.get('/string').data, u'Hällo Wörld'.encode('utf-8'))
|
||||
|
|
@ -745,6 +755,18 @@ class BasicFunctionalityTestCase(FlaskTestCase):
|
|||
self.assert_equal(rv.status_code, 400)
|
||||
self.assert_equal(rv.mimetype, 'text/plain')
|
||||
|
||||
rv2 = c.get("/two_args")
|
||||
self.assert_equal(rv2.data, b'Hello')
|
||||
self.assert_equal(rv2.headers['X-Foo'], 'Test')
|
||||
self.assert_equal(rv2.status_code, 200)
|
||||
self.assert_equal(rv2.mimetype, 'text/plain')
|
||||
|
||||
rv3 = c.get("/args_status")
|
||||
self.assert_equal(rv3.data, b'Hi, status!')
|
||||
self.assert_equal(rv3.status_code, 400)
|
||||
self.assert_equal(rv3.mimetype, 'text/html')
|
||||
|
||||
|
||||
def test_make_response(self):
|
||||
app = flask.Flask(__name__)
|
||||
with app.test_request_context():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue