Require newer aiohttp for blackd (#4451)
This commit is contained in:
parent
058da5f81a
commit
ac018c16ca
@ -34,6 +34,7 @@
|
|||||||
<!-- Changes to how Black is packaged, such as dependency requirements -->
|
<!-- Changes to how Black is packaged, such as dependency requirements -->
|
||||||
|
|
||||||
- Upgrade version of mypyc used to 1.11.2 (#4450)
|
- Upgrade version of mypyc used to 1.11.2 (#4450)
|
||||||
|
- `blackd` now requires a newer version of aiohttp. (#4451)
|
||||||
|
|
||||||
### Parser
|
### Parser
|
||||||
|
|
||||||
|
@ -78,10 +78,7 @@ dynamic = ["readme", "version"]
|
|||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
colorama = ["colorama>=0.4.3"]
|
colorama = ["colorama>=0.4.3"]
|
||||||
uvloop = ["uvloop>=0.15.2"]
|
uvloop = ["uvloop>=0.15.2"]
|
||||||
d = [
|
d = ["aiohttp>=3.10"]
|
||||||
"aiohttp>=3.7.4; sys_platform != 'win32' or implementation_name != 'pypy'",
|
|
||||||
"aiohttp>=3.7.4, !=3.9.0; sys_platform == 'win32' and implementation_name == 'pypy'",
|
|
||||||
]
|
|
||||||
jupyter = [
|
jupyter = [
|
||||||
"ipython>=7.8.0",
|
"ipython>=7.8.0",
|
||||||
"tokenize-rt>=3.2.0",
|
"tokenize-rt>=3.2.0",
|
||||||
@ -219,23 +216,7 @@ markers = [
|
|||||||
"incompatible_with_mypyc: run when testing mypyc compiled black"
|
"incompatible_with_mypyc: run when testing mypyc compiled black"
|
||||||
]
|
]
|
||||||
xfail_strict = true
|
xfail_strict = true
|
||||||
filterwarnings = [
|
filterwarnings = ["error"]
|
||||||
"error",
|
|
||||||
# this is mitigated by a try/catch in https://github.com/psf/black/pull/2974/
|
|
||||||
# this ignore can be removed when support for aiohttp 3.7 is dropped.
|
|
||||||
'''ignore:Decorator `@unittest_run_loop` is no longer needed in aiohttp 3\.8\+:DeprecationWarning''',
|
|
||||||
# this is mitigated by a try/catch in https://github.com/psf/black/pull/3198/
|
|
||||||
# this ignore can be removed when support for aiohttp 3.x is dropped.
|
|
||||||
'''ignore:Middleware decorator is deprecated since 4\.0 and its behaviour is default, you can simply remove this decorator:DeprecationWarning''',
|
|
||||||
# aiohttp is using deprecated cgi modules - Safe to remove when fixed:
|
|
||||||
# https://github.com/aio-libs/aiohttp/issues/6905
|
|
||||||
'''ignore:'cgi' is deprecated and slated for removal in Python 3.13:DeprecationWarning''',
|
|
||||||
# Work around https://github.com/pytest-dev/pytest/issues/10977 for Python 3.12
|
|
||||||
'''ignore:(Attribute s|Attribute n|ast.Str|ast.Bytes|ast.NameConstant|ast.Num) is deprecated and will be removed in Python 3.14:DeprecationWarning''',
|
|
||||||
# Will be fixed with aiohttp 3.9.0
|
|
||||||
# https://github.com/aio-libs/aiohttp/pull/7302
|
|
||||||
"ignore:datetime.*utcfromtimestamp\\(\\) is deprecated and scheduled for removal:DeprecationWarning",
|
|
||||||
]
|
|
||||||
[tool.coverage.report]
|
[tool.coverage.report]
|
||||||
omit = [
|
omit = [
|
||||||
"src/blib2to3/*",
|
"src/blib2to3/*",
|
||||||
|
@ -1,29 +1,12 @@
|
|||||||
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Iterable, TypeVar
|
from typing import Awaitable, Callable, Iterable
|
||||||
|
|
||||||
|
from aiohttp.typedefs import Middleware
|
||||||
|
from aiohttp.web_middlewares import middleware
|
||||||
from aiohttp.web_request import Request
|
from aiohttp.web_request import Request
|
||||||
from aiohttp.web_response import StreamResponse
|
from aiohttp.web_response import StreamResponse
|
||||||
|
|
||||||
Handler = Callable[[Request], Awaitable[StreamResponse]]
|
Handler = Callable[[Request], Awaitable[StreamResponse]]
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from aiohttp.typedefs import Middleware
|
|
||||||
|
|
||||||
F = TypeVar("F", bound=Callable[..., Any])
|
|
||||||
middleware: Callable[[F], F]
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
# Available in aiohttp 3.9 and newer
|
|
||||||
from aiohttp.typedefs import Middleware
|
|
||||||
except ImportError:
|
|
||||||
Middleware = Callable[[Request, Handler], Awaitable[StreamResponse]]
|
|
||||||
|
|
||||||
try:
|
|
||||||
from aiohttp.web_middlewares import middleware
|
|
||||||
except ImportError:
|
|
||||||
# @middleware is deprecated and its behaviour is the default since aiohttp 4.0
|
|
||||||
# so if it doesn't exist anymore, define a no-op for forward compatibility.
|
|
||||||
middleware = lambda x: x # noqa: E731
|
|
||||||
|
|
||||||
|
|
||||||
def cors(allow_headers: Iterable[str]) -> Middleware:
|
def cors(allow_headers: Iterable[str]) -> Middleware:
|
||||||
@middleware
|
@middleware
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import re
|
import re
|
||||||
from typing import TYPE_CHECKING, Any, Callable, TypeVar
|
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -15,20 +14,6 @@
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise RuntimeError("Please install Black with the 'd' extra") from e
|
raise RuntimeError("Please install Black with the 'd' extra") from e
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
F = TypeVar("F", bound=Callable[..., Any])
|
|
||||||
|
|
||||||
unittest_run_loop: Callable[[F], F] = lambda x: x
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
from aiohttp.test_utils import unittest_run_loop
|
|
||||||
except ImportError:
|
|
||||||
# unittest_run_loop is unnecessary and a no-op since aiohttp 3.8, and
|
|
||||||
# aiohttp 4 removed it. To maintain compatibility we can make our own
|
|
||||||
# no-op decorator.
|
|
||||||
def unittest_run_loop(func, *args, **kwargs):
|
|
||||||
return func
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.blackd
|
@pytest.mark.blackd
|
||||||
class BlackDTestCase(AioHTTPTestCase):
|
class BlackDTestCase(AioHTTPTestCase):
|
||||||
@ -42,20 +27,17 @@ def test_blackd_main(self) -> None:
|
|||||||
async def get_application(self) -> web.Application:
|
async def get_application(self) -> web.Application:
|
||||||
return blackd.make_app()
|
return blackd.make_app()
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_request_needs_formatting(self) -> None:
|
async def test_blackd_request_needs_formatting(self) -> None:
|
||||||
response = await self.client.post("/", data=b"print('hello world')")
|
response = await self.client.post("/", data=b"print('hello world')")
|
||||||
self.assertEqual(response.status, 200)
|
self.assertEqual(response.status, 200)
|
||||||
self.assertEqual(response.charset, "utf8")
|
self.assertEqual(response.charset, "utf8")
|
||||||
self.assertEqual(await response.read(), b'print("hello world")\n')
|
self.assertEqual(await response.read(), b'print("hello world")\n')
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_request_no_change(self) -> None:
|
async def test_blackd_request_no_change(self) -> None:
|
||||||
response = await self.client.post("/", data=b'print("hello world")\n')
|
response = await self.client.post("/", data=b'print("hello world")\n')
|
||||||
self.assertEqual(response.status, 204)
|
self.assertEqual(response.status, 204)
|
||||||
self.assertEqual(await response.read(), b"")
|
self.assertEqual(await response.read(), b"")
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_request_syntax_error(self) -> None:
|
async def test_blackd_request_syntax_error(self) -> None:
|
||||||
response = await self.client.post("/", data=b"what even ( is")
|
response = await self.client.post("/", data=b"what even ( is")
|
||||||
self.assertEqual(response.status, 400)
|
self.assertEqual(response.status, 400)
|
||||||
@ -65,21 +47,18 @@ async def test_blackd_request_syntax_error(self) -> None:
|
|||||||
msg=f"Expected error to start with 'Cannot parse', got {repr(content)}",
|
msg=f"Expected error to start with 'Cannot parse', got {repr(content)}",
|
||||||
)
|
)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_unsupported_version(self) -> None:
|
async def test_blackd_unsupported_version(self) -> None:
|
||||||
response = await self.client.post(
|
response = await self.client.post(
|
||||||
"/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "2"}
|
"/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "2"}
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status, 501)
|
self.assertEqual(response.status, 501)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_supported_version(self) -> None:
|
async def test_blackd_supported_version(self) -> None:
|
||||||
response = await self.client.post(
|
response = await self.client.post(
|
||||||
"/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "1"}
|
"/", data=b"what", headers={blackd.PROTOCOL_VERSION_HEADER: "1"}
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status, 200)
|
self.assertEqual(response.status, 200)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_invalid_python_variant(self) -> None:
|
async def test_blackd_invalid_python_variant(self) -> None:
|
||||||
async def check(header_value: str, expected_status: int = 400) -> None:
|
async def check(header_value: str, expected_status: int = 400) -> None:
|
||||||
response = await self.client.post(
|
response = await self.client.post(
|
||||||
@ -102,7 +81,6 @@ async def check(header_value: str, expected_status: int = 400) -> None:
|
|||||||
await check("pypy3.0")
|
await check("pypy3.0")
|
||||||
await check("jython3.4")
|
await check("jython3.4")
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_pyi(self) -> None:
|
async def test_blackd_pyi(self) -> None:
|
||||||
source, expected = read_data("cases", "stub.py")
|
source, expected = read_data("cases", "stub.py")
|
||||||
response = await self.client.post(
|
response = await self.client.post(
|
||||||
@ -111,7 +89,6 @@ async def test_blackd_pyi(self) -> None:
|
|||||||
self.assertEqual(response.status, 200)
|
self.assertEqual(response.status, 200)
|
||||||
self.assertEqual(await response.text(), expected)
|
self.assertEqual(await response.text(), expected)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_diff(self) -> None:
|
async def test_blackd_diff(self) -> None:
|
||||||
diff_header = re.compile(
|
diff_header = re.compile(
|
||||||
r"(In|Out)\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d\d\d\d\+\d\d:\d\d"
|
r"(In|Out)\t\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d\d\d\d\+\d\d:\d\d"
|
||||||
@ -129,7 +106,6 @@ async def test_blackd_diff(self) -> None:
|
|||||||
actual = diff_header.sub(DETERMINISTIC_HEADER, actual)
|
actual = diff_header.sub(DETERMINISTIC_HEADER, actual)
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_python_variant(self) -> None:
|
async def test_blackd_python_variant(self) -> None:
|
||||||
code = (
|
code = (
|
||||||
"def f(\n"
|
"def f(\n"
|
||||||
@ -161,14 +137,12 @@ async def check(header_value: str, expected_status: int) -> None:
|
|||||||
await check("py34,py36", 204)
|
await check("py34,py36", 204)
|
||||||
await check("34", 204)
|
await check("34", 204)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_line_length(self) -> None:
|
async def test_blackd_line_length(self) -> None:
|
||||||
response = await self.client.post(
|
response = await self.client.post(
|
||||||
"/", data=b'print("hello")\n', headers={blackd.LINE_LENGTH_HEADER: "7"}
|
"/", data=b'print("hello")\n', headers={blackd.LINE_LENGTH_HEADER: "7"}
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status, 200)
|
self.assertEqual(response.status, 200)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_invalid_line_length(self) -> None:
|
async def test_blackd_invalid_line_length(self) -> None:
|
||||||
response = await self.client.post(
|
response = await self.client.post(
|
||||||
"/",
|
"/",
|
||||||
@ -177,7 +151,6 @@ async def test_blackd_invalid_line_length(self) -> None:
|
|||||||
)
|
)
|
||||||
self.assertEqual(response.status, 400)
|
self.assertEqual(response.status, 400)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_skip_first_source_line(self) -> None:
|
async def test_blackd_skip_first_source_line(self) -> None:
|
||||||
invalid_first_line = b"Header will be skipped\r\ni = [1,2,3]\nj = [1,2,3]\n"
|
invalid_first_line = b"Header will be skipped\r\ni = [1,2,3]\nj = [1,2,3]\n"
|
||||||
expected_result = b"Header will be skipped\r\ni = [1, 2, 3]\nj = [1, 2, 3]\n"
|
expected_result = b"Header will be skipped\r\ni = [1, 2, 3]\nj = [1, 2, 3]\n"
|
||||||
@ -191,19 +164,16 @@ async def test_blackd_skip_first_source_line(self) -> None:
|
|||||||
self.assertEqual(response.status, 200)
|
self.assertEqual(response.status, 200)
|
||||||
self.assertEqual(await response.read(), expected_result)
|
self.assertEqual(await response.read(), expected_result)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_preview(self) -> None:
|
async def test_blackd_preview(self) -> None:
|
||||||
response = await self.client.post(
|
response = await self.client.post(
|
||||||
"/", data=b'print("hello")\n', headers={blackd.PREVIEW: "true"}
|
"/", data=b'print("hello")\n', headers={blackd.PREVIEW: "true"}
|
||||||
)
|
)
|
||||||
self.assertEqual(response.status, 204)
|
self.assertEqual(response.status, 204)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_blackd_response_black_version_header(self) -> None:
|
async def test_blackd_response_black_version_header(self) -> None:
|
||||||
response = await self.client.post("/")
|
response = await self.client.post("/")
|
||||||
self.assertIsNotNone(response.headers.get(blackd.BLACK_VERSION_HEADER))
|
self.assertIsNotNone(response.headers.get(blackd.BLACK_VERSION_HEADER))
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_cors_preflight(self) -> None:
|
async def test_cors_preflight(self) -> None:
|
||||||
response = await self.client.options(
|
response = await self.client.options(
|
||||||
"/",
|
"/",
|
||||||
@ -218,13 +188,11 @@ async def test_cors_preflight(self) -> None:
|
|||||||
self.assertIsNotNone(response.headers.get("Access-Control-Allow-Headers"))
|
self.assertIsNotNone(response.headers.get("Access-Control-Allow-Headers"))
|
||||||
self.assertIsNotNone(response.headers.get("Access-Control-Allow-Methods"))
|
self.assertIsNotNone(response.headers.get("Access-Control-Allow-Methods"))
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_cors_headers_present(self) -> None:
|
async def test_cors_headers_present(self) -> None:
|
||||||
response = await self.client.post("/", headers={"Origin": "*"})
|
response = await self.client.post("/", headers={"Origin": "*"})
|
||||||
self.assertIsNotNone(response.headers.get("Access-Control-Allow-Origin"))
|
self.assertIsNotNone(response.headers.get("Access-Control-Allow-Origin"))
|
||||||
self.assertIsNotNone(response.headers.get("Access-Control-Expose-Headers"))
|
self.assertIsNotNone(response.headers.get("Access-Control-Expose-Headers"))
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_preserves_line_endings(self) -> None:
|
async def test_preserves_line_endings(self) -> None:
|
||||||
for data in (b"c\r\nc\r\n", b"l\nl\n"):
|
for data in (b"c\r\nc\r\n", b"l\nl\n"):
|
||||||
# test preserved newlines when reformatted
|
# test preserved newlines when reformatted
|
||||||
@ -234,14 +202,12 @@ async def test_preserves_line_endings(self) -> None:
|
|||||||
response = await self.client.post("/", data=data)
|
response = await self.client.post("/", data=data)
|
||||||
self.assertEqual(response.status, 204)
|
self.assertEqual(response.status, 204)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_normalizes_line_endings(self) -> None:
|
async def test_normalizes_line_endings(self) -> None:
|
||||||
for data, expected in ((b"c\r\nc\n", "c\r\nc\r\n"), (b"l\nl\r\n", "l\nl\n")):
|
for data, expected in ((b"c\r\nc\n", "c\r\nc\r\n"), (b"l\nl\r\n", "l\nl\n")):
|
||||||
response = await self.client.post("/", data=data)
|
response = await self.client.post("/", data=data)
|
||||||
self.assertEqual(await response.text(), expected)
|
self.assertEqual(await response.text(), expected)
|
||||||
self.assertEqual(response.status, 200)
|
self.assertEqual(response.status, 200)
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_single_character(self) -> None:
|
async def test_single_character(self) -> None:
|
||||||
response = await self.client.post("/", data="1")
|
response = await self.client.post("/", data="1")
|
||||||
self.assertEqual(await response.text(), "1\n")
|
self.assertEqual(await response.text(), "1\n")
|
||||||
|
Loading…
Reference in New Issue
Block a user