From 4eac013087f807cafa244b8a6b7b0ed4c82ff150 Mon Sep 17 00:00:00 2001 From: Miguel Grinberg Date: Sun, 10 Nov 2024 00:34:21 +0000 Subject: [PATCH] Accept responses with just a status code (Fixes #263) --- src/microdot/microdot.py | 15 ++++++++++----- tests/test_response.py | 16 ++++++++++++++-- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/microdot/microdot.py b/src/microdot/microdot.py index d60f1bb..17a1bba 100644 --- a/src/microdot/microdot.py +++ b/src/microdot/microdot.py @@ -520,8 +520,10 @@ class Response: :param body: The body of the response. If a dictionary or list is given, a JSON formatter is used to generate the body. If a file-like object or an async generator is given, a streaming response is - used. If a string is given, it is encoded from UTF-8. Else, - the body should be a byte sequence. + used. If a string is given, it is encoded from UTF-8. If an + integer is given and ``status_code`` isn't given, then the + status code is assigned and the body is kept empty. Else, the + body should be a byte sequence. :param status_code: The numeric HTTP status code of the response. The default is 200. :param headers: A dictionary of headers to include in the response. @@ -554,11 +556,14 @@ class Response: #: written to the client. Used to exit WebSocket connections cleanly. already_handled = None - def __init__(self, body='', status_code=200, headers=None, reason=None): - if body is None and status_code == 200: + def __init__(self, body='', status_code=None, headers=None, reason=None): + if body is None and status_code is None: body = '' status_code = 204 - self.status_code = status_code + elif isinstance(body, int) and status_code is None: + status_code = int(body) + body = '' + self.status_code = status_code or 200 self.headers = NoCaseDict(headers or {}) self.reason = reason if isinstance(body, (dict, list)): diff --git a/tests/test_response.py b/tests/test_response.py index e27f0a2..8591ab0 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -109,6 +109,18 @@ def test_create_json(self): fd.response) self.assertTrue(fd.response.endswith(b'\r\n\r\n[1, "2"]')) + def test_create_status_code(self): + res = Response(202) + self.assertEqual(res.status_code, 202) + self.assertEqual(res.body, b'') + fd = FakeStreamAsync() + self._run(res.write(fd)) + self.assertIn(b'HTTP/1.0 202 N/A\r\n', fd.response) + self.assertIn(b'Content-Length: 0\r\n', fd.response) + self.assertIn(b'Content-Type: text/plain; charset=UTF-8\r\n', + fd.response) + self.assertTrue(fd.response.endswith(b'\r\n\r\n')) + def test_create_from_none(self): res = Response(None) self.assertEqual(res.status_code, 204) @@ -136,10 +148,10 @@ def gen(): self.assertTrue(fd.response.endswith(b'\r\n\r\nfoobar')) def test_create_from_other(self): - res = Response(123) + res = Response(23.7) self.assertEqual(res.status_code, 200) self.assertEqual(res.headers, {}) - self.assertEqual(res.body, 123) + self.assertEqual(res.body, 23.7) def test_create_with_status_code(self): res = Response('not found', 404)