diff --git a/.flake8 b/.flake8
index 18c72168cb..3a7da2c652 100644
--- a/.flake8
+++ b/.flake8
@@ -13,5 +13,7 @@ ignore =
# flake8 and black disagree about
# W503 line break before binary operator
# E203 whitespace before ':'
- W503,E203
+ # E701/E704 multiple statements on one line
+ # https://black.readthedocs.io/en/latest/guides/using_black_with_other_tools.html#labels-why-pycodestyle-warnings
+ W503,E203,E701,E704
doctests = true
diff --git a/demos/blog/blog.py b/demos/blog/blog.py
index bd0c5b3f18..e6e23f85b4 100755
--- a/demos/blog/blog.py
+++ b/demos/blog/blog.py
@@ -40,13 +40,13 @@ class NoResultError(Exception):
async def maybe_create_tables(db):
try:
- with (await db.cursor()) as cur:
+ with await db.cursor() as cur:
await cur.execute("SELECT COUNT(*) FROM entries LIMIT 1")
await cur.fetchone()
except psycopg2.ProgrammingError:
with open("schema.sql") as f:
schema = f.read()
- with (await db.cursor()) as cur:
+ with await db.cursor() as cur:
await cur.execute(schema)
@@ -89,7 +89,7 @@ async def execute(self, stmt, *args):
Must be called with ``await self.execute(...)``
"""
- with (await self.application.db.cursor()) as cur:
+ with await self.application.db.cursor() as cur:
await cur.execute(stmt, args)
async def query(self, stmt, *args):
@@ -103,7 +103,7 @@ async def query(self, stmt, *args):
for row in await self.query(...)
"""
- with (await self.application.db.cursor()) as cur:
+ with await self.application.db.cursor() as cur:
await cur.execute(stmt, args)
return [self.row_to_obj(row, cur) for row in await cur.fetchall()]
diff --git a/demos/google_auth/main.py b/demos/google_auth/main.py
index 06dd3b5cdb..40cdd7a4fd 100644
--- a/demos/google_auth/main.py
+++ b/demos/google_auth/main.py
@@ -10,6 +10,7 @@
- Run this file with `python main.py --config_file=main.cfg`
- Visit "http://localhost:8888" in your browser.
"""
+
import asyncio
import json
import tornado
diff --git a/requirements.txt b/requirements.txt
index 5efd55be90..9118bdfde6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,7 +8,7 @@ alabaster==0.7.13
# via sphinx
babel==2.11.0
# via sphinx
-black==22.12.0
+black==24.4.2
# via -r requirements.in
build==0.10.0
# via pip-tools
@@ -56,6 +56,7 @@ mypy-extensions==0.4.3
# mypy
packaging==23.1
# via
+ # black
# build
# pyproject-api
# sphinx
diff --git a/tornado/concurrent.py b/tornado/concurrent.py
index 86bbd703c1..5047c5389f 100644
--- a/tornado/concurrent.py
+++ b/tornado/concurrent.py
@@ -118,6 +118,7 @@ def foo(self):
The ``callback`` argument was removed.
"""
+
# Fully type-checking decorators is tricky, and this one is
# discouraged anyway so it doesn't have all the generic magic.
def run_on_executor_decorator(fn: Callable) -> Callable[..., Future]:
diff --git a/tornado/gen.py b/tornado/gen.py
index dab4fd09db..0e3c7a6fc2 100644
--- a/tornado/gen.py
+++ b/tornado/gen.py
@@ -66,6 +66,7 @@ def get(self):
via ``singledispatch``.
"""
+
import asyncio
import builtins
import collections
@@ -165,13 +166,11 @@ def _fake_ctx_run(f: Callable[..., _T], *args: Any, **kw: Any) -> _T:
@overload
def coroutine(
func: Callable[..., "Generator[Any, Any, _T]"]
-) -> Callable[..., "Future[_T]"]:
- ...
+) -> Callable[..., "Future[_T]"]: ...
@overload
-def coroutine(func: Callable[..., _T]) -> Callable[..., "Future[_T]"]:
- ...
+def coroutine(func: Callable[..., _T]) -> Callable[..., "Future[_T]"]: ...
def coroutine(
diff --git a/tornado/simple_httpclient.py b/tornado/simple_httpclient.py
index 2460863fc1..5b2d4dcd98 100644
--- a/tornado/simple_httpclient.py
+++ b/tornado/simple_httpclient.py
@@ -429,9 +429,9 @@ async def run(self) -> None:
self.request.method == "POST"
and "Content-Type" not in self.request.headers
):
- self.request.headers[
- "Content-Type"
- ] = "application/x-www-form-urlencoded"
+ self.request.headers["Content-Type"] = (
+ "application/x-www-form-urlencoded"
+ )
if self.request.decompress_response:
self.request.headers["Accept-Encoding"] = "gzip"
req_path = (self.parsed.path or "/") + (
diff --git a/tornado/test/__main__.py b/tornado/test/__main__.py
index 430c895fa2..890bd505b4 100644
--- a/tornado/test/__main__.py
+++ b/tornado/test/__main__.py
@@ -2,6 +2,7 @@
This only works in python 2.7+.
"""
+
from tornado.test.runtests import all, main
# tornado.testing.main autodiscovery relies on 'all' being present in
diff --git a/tornado/test/escape_test.py b/tornado/test/escape_test.py
index 6bd2ae79e4..3115a19409 100644
--- a/tornado/test/escape_test.py
+++ b/tornado/test/escape_test.py
@@ -194,9 +194,11 @@
(
"www.external-link.com and www.internal-link.com/blogs extra",
{
- "extra_params": lambda href: 'class="internal"'
- if href.startswith("http://www.internal-link.com")
- else 'rel="nofollow" class="external"'
+ "extra_params": lambda href: (
+ 'class="internal"'
+ if href.startswith("http://www.internal-link.com")
+ else 'rel="nofollow" class="external"'
+ )
},
'www.external-link.com' # noqa: E501
' and www.internal-link.com/blogs extra', # noqa: E501
diff --git a/tornado/test/ioloop_test.py b/tornado/test/ioloop_test.py
index 9485afeaeb..d07438aa63 100644
--- a/tornado/test/ioloop_test.py
+++ b/tornado/test/ioloop_test.py
@@ -261,6 +261,7 @@ def test_close_file_object(self):
the object should be closed (by IOLoop.close(all_fds=True),
not just the fd.
"""
+
# Use a socket since they are supported by IOLoop on all platforms.
# Unfortunately, sockets don't support the .closed attribute for
# inspecting their close status, so we must use a wrapper.
diff --git a/tornado/websocket.py b/tornado/websocket.py
index fbfd700887..8f0e0aefe8 100644
--- a/tornado/websocket.py
+++ b/tornado/websocket.py
@@ -1392,9 +1392,9 @@ def __init__(
# from the server).
# TODO: set server parameters for deflate extension
# if requested in self.compression_options.
- request.headers[
- "Sec-WebSocket-Extensions"
- ] = "permessage-deflate; client_max_window_bits"
+ request.headers["Sec-WebSocket-Extensions"] = (
+ "permessage-deflate; client_max_window_bits"
+ )
# Websocket connection is currently unable to follow redirects
request.follow_redirects = False