From 73bd7038fbefdb1c6a61fa1edf16ff61613050a5 Mon Sep 17 00:00:00 2001 From: Linus Groh Date: Sun, 13 Oct 2019 20:35:31 +0200 Subject: [PATCH] Add black version header to blackd responses (#1046) --- README.md | 11 ++++++++--- blackd.py | 24 +++++++++++++++++------- tests/test_black.py | 11 +++++++++-- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 90c169f..76ae9cf 100644 --- a/README.md +++ b/README.md @@ -297,7 +297,7 @@ ignore = E501,W503,E203 ``` You'll find *Black*'s own .flake8 config file is configured like this. -If you're curious about the reasoning behind B950, +If you're curious about the reasoning behind B950, [Bugbear's documentation](https://github.com/PyCQA/flake8-bugbear#opinionated-warnings) explains it. The tl;dr is "it's like highway speed limits, we won't bother you if you overdo it by a few km/h". @@ -682,7 +682,7 @@ $ where black -### Wing IDE +### Wing IDE Wing supports black via the OS Commands tool, as explained in the Wing documentation on [pep8 formatting](https://wingware.com/doc/edit/pep8). The detailed procedure is: @@ -704,7 +704,7 @@ $ black --help - click on **+** in **OS Commands** -> New: Command line.. - Title: black - Command Line: black %s - - I/O Encoding: Use Default + - I/O Encoding: Use Default - Key Binding: F1 - [x] Raise OS Commands when executed - [x] Auto-save files before execution @@ -893,6 +893,9 @@ Apart from the above, `blackd` can produce the following response codes: - `HTTP 500`: If there was any kind of error while trying to format the input. The response body contains a textual representation of the error. +The response headers include a `X-Black-Version` header containing the version +of *Black*. + ## Version control integration Use [pre-commit](https://pre-commit.com/). Once you [have it @@ -1051,6 +1054,8 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md). * *Black* is now able to format Python code that uses positional-only arguments (`/` as described in PEP-570) (#946) +* `blackd` now returns the version of *Black* in the response headers (#1013) + ### 19.3b0 diff --git a/blackd.py b/blackd.py index 37fcec3..055f268 100644 --- a/blackd.py +++ b/blackd.py @@ -10,23 +10,29 @@ import aiohttp_cors import black import click +from _version import version as __version__ + # This is used internally by tests to shut down the server prematurely _stop_signal = asyncio.Event() -VERSION_HEADER = "X-Protocol-Version" +# Request headers +PROTOCOL_VERSION_HEADER = "X-Protocol-Version" LINE_LENGTH_HEADER = "X-Line-Length" PYTHON_VARIANT_HEADER = "X-Python-Variant" SKIP_STRING_NORMALIZATION_HEADER = "X-Skip-String-Normalization" FAST_OR_SAFE_HEADER = "X-Fast-Or-Safe" BLACK_HEADERS = [ - VERSION_HEADER, + PROTOCOL_VERSION_HEADER, LINE_LENGTH_HEADER, PYTHON_VARIANT_HEADER, SKIP_STRING_NORMALIZATION_HEADER, FAST_OR_SAFE_HEADER, ] +# Response headers +BLACK_VERSION_HEADER = "X-Black-Version" + class InvalidVariantHeader(Exception): pass @@ -65,8 +71,9 @@ def make_app() -> web.Application: async def handle(request: web.Request, executor: Executor) -> web.Response: + headers = {BLACK_VERSION_HEADER: __version__} try: - if request.headers.get(VERSION_HEADER, "1") != "1": + if request.headers.get(PROTOCOL_VERSION_HEADER, "1") != "1": return web.Response( status=501, text="This server only supports protocol version 1" ) @@ -110,15 +117,18 @@ async def handle(request: web.Request, executor: Executor) -> web.Response: executor, partial(black.format_file_contents, req_str, fast=fast, mode=mode) ) return web.Response( - content_type=request.content_type, charset=charset, text=formatted_str + content_type=request.content_type, + charset=charset, + headers=headers, + text=formatted_str, ) except black.NothingChanged: - return web.Response(status=204) + return web.Response(status=204, headers=headers) except black.InvalidInput as e: - return web.Response(status=400, text=str(e)) + return web.Response(status=400, headers=headers, text=str(e)) except Exception as e: logging.exception("Exception during handling a request") - return web.Response(status=500, text=str(e)) + return web.Response(status=500, headers=headers, text=str(e)) def parse_python_variant_header(value: str) -> Tuple[bool, Set[black.TargetVersion]]: diff --git a/tests/test_black.py b/tests/test_black.py index 92d77ac..10efbcf 100644 --- a/tests/test_black.py +++ b/tests/test_black.py @@ -1569,7 +1569,7 @@ class BlackDTestCase(AioHTTPTestCase): @unittest_run_loop async def test_blackd_unsupported_version(self) -> None: response = await self.client.post( - "/", data=b"what", headers={blackd.VERSION_HEADER: "2"} + "/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "2"} ) self.assertEqual(response.status, 501) @@ -1578,7 +1578,7 @@ class BlackDTestCase(AioHTTPTestCase): @unittest_run_loop async def test_blackd_supported_version(self) -> None: response = await self.client.post( - "/", data=b"what", headers={blackd.VERSION_HEADER: "1"} + "/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "1"} ) self.assertEqual(response.status, 200) @@ -1669,6 +1669,13 @@ class BlackDTestCase(AioHTTPTestCase): ) self.assertEqual(response.status, 400) + @skip_if_exception("ClientOSError") + @unittest.skipUnless(has_blackd_deps, "blackd's dependencies are not installed") + @unittest_run_loop + async def test_blackd_response_black_version_header(self) -> None: + response = await self.client.post("/") + self.assertIsNotNone(response.headers.get(blackd.BLACK_VERSION_HEADER)) + if __name__ == "__main__": unittest.main(module="test_black") -- 2.39.5