]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
✨ Use Ruff for linting (#5630)
authorSebastián Ramírez <tiangolo@gmail.com>
Sun, 13 Nov 2022 18:19:04 +0000 (19:19 +0100)
committerGitHub <noreply@github.com>
Sun, 13 Nov 2022 18:19:04 +0000 (19:19 +0100)
13 files changed:
.flake8 [deleted file]
.pre-commit-config.yaml
docs_src/security/tutorial005.py
docs_src/security/tutorial005_py310.py
docs_src/security/tutorial005_py39.py
fastapi/dependencies/utils.py
fastapi/routing.py
pyproject.toml
scripts/docs.py
scripts/format.sh
scripts/lint.sh
tests/test_custom_route_class.py
tests/test_ws_router.py

diff --git a/.flake8 b/.flake8
deleted file mode 100644 (file)
index 47ef7c0..0000000
--- a/.flake8
+++ /dev/null
@@ -1,5 +0,0 @@
-[flake8]
-max-line-length = 88
-select = C,E,F,W,B,B9
-ignore = E203, E501, W503
-exclude = __init__.py
index bd5b8641ad55b119e508a8d8856f58863cf691d5..e59e05abe4e3e3536c51d1848cd8cec328d2db93 100644 (file)
@@ -18,19 +18,12 @@ repos:
         args:
         - --py3-plus
         - --keep-runtime-typing
--   repo: https://github.com/PyCQA/autoflake
-    rev: v1.7.7
+-   repo: https://github.com/charliermarsh/ruff-pre-commit
+    rev: v0.0.114
     hooks:
-    -   id: autoflake
+    -   id: ruff
         args:
-        - --recursive
-        - --in-place
-        - --remove-all-unused-imports
-        - --remove-unused-variables
-        - --expand-star-imports
-        - --exclude
-        - __init__.py
-        - --remove-duplicate-keys
+        - --fix
 -   repo: https://github.com/pycqa/isort
     rev: 5.10.1
     hooks:
index ab3af9a6a9dd176799d480b9ff89f9eb24bcbf22..bd0a33581c21cc281da4e49d46edf1f2e975219b 100644 (file)
@@ -107,7 +107,7 @@ async def get_current_user(
     if security_scopes.scopes:
         authenticate_value = f'Bearer scope="{security_scopes.scope_str}"'
     else:
-        authenticate_value = f"Bearer"
+        authenticate_value = "Bearer"
     credentials_exception = HTTPException(
         status_code=status.HTTP_401_UNAUTHORIZED,
         detail="Could not validate credentials",
index c6a095d2ccfaae4d8803073224d55840db3d468e..ba756ef4f4d671fbc04d071b8bd30d75fba98126 100644 (file)
@@ -106,7 +106,7 @@ async def get_current_user(
     if security_scopes.scopes:
         authenticate_value = f'Bearer scope="{security_scopes.scope_str}"'
     else:
-        authenticate_value = f"Bearer"
+        authenticate_value = "Bearer"
     credentials_exception = HTTPException(
         status_code=status.HTTP_401_UNAUTHORIZED,
         detail="Could not validate credentials",
index 38391308af08c3e77c830000ab8aec23d18b9473..9e4dbcffba38d029a8f19f04e2b8f2642b058fd1 100644 (file)
@@ -107,7 +107,7 @@ async def get_current_user(
     if security_scopes.scopes:
         authenticate_value = f'Bearer scope="{security_scopes.scope_str}"'
     else:
-        authenticate_value = f"Bearer"
+        authenticate_value = "Bearer"
     credentials_exception = HTTPException(
         status_code=status.HTTP_401_UNAUTHORIZED,
         detail="Could not validate credentials",
index 64a6c127654c0e0027182cad82c15630a39ef4c8..3df5ccfc8b58eb72bdbd69784c16d874779ad675 100644 (file)
@@ -426,21 +426,21 @@ def is_coroutine_callable(call: Callable[..., Any]) -> bool:
         return inspect.iscoroutinefunction(call)
     if inspect.isclass(call):
         return False
-    dunder_call = getattr(call, "__call__", None)
+    dunder_call = getattr(call, "__call__", None)  # noqa: B004
     return inspect.iscoroutinefunction(dunder_call)
 
 
 def is_async_gen_callable(call: Callable[..., Any]) -> bool:
     if inspect.isasyncgenfunction(call):
         return True
-    dunder_call = getattr(call, "__call__", None)
+    dunder_call = getattr(call, "__call__", None)  # noqa: B004
     return inspect.isasyncgenfunction(dunder_call)
 
 
 def is_gen_callable(call: Callable[..., Any]) -> bool:
     if inspect.isgeneratorfunction(call):
         return True
-    dunder_call = getattr(call, "__call__", None)
+    dunder_call = getattr(call, "__call__", None)  # noqa: B004
     return inspect.isgeneratorfunction(dunder_call)
 
 
@@ -724,14 +724,14 @@ def get_body_field(*, dependant: Dependant, name: str) -> Optional[ModelField]:
     # in case a sub-dependency is evaluated with a single unique body field
     # That is combined (embedded) with other body fields
     for param in flat_dependant.body_params:
-        setattr(param.field_info, "embed", True)
+        setattr(param.field_info, "embed", True)  # noqa: B010
     model_name = "Body_" + name
     BodyModel: Type[BaseModel] = create_model(model_name)
     for f in flat_dependant.body_params:
         BodyModel.__fields__[f.name] = f
     required = any(True for f in flat_dependant.body_params if f.required)
 
-    BodyFieldInfo_kwargs: Dict[str, Any] = dict(default=None)
+    BodyFieldInfo_kwargs: Dict[str, Any] = {"default": None}
     if any(isinstance(f.field_info, params.File) for f in flat_dependant.body_params):
         BodyFieldInfo: Type[params.Body] = params.File
     elif any(isinstance(f.field_info, params.Form) for f in flat_dependant.body_params):
@@ -740,7 +740,7 @@ def get_body_field(*, dependant: Dependant, name: str) -> Optional[ModelField]:
         BodyFieldInfo = params.Body
 
         body_param_media_types = [
-            getattr(f.field_info, "media_type")
+            f.field_info.media_type
             for f in flat_dependant.body_params
             if isinstance(f.field_info, params.Body)
         ]
index 8c0bec5e612bf2e62ae13d2fc719f419a953a11c..9a7d88efc888ad66681c3e764e8f00056b61a47f 100644 (file)
@@ -701,7 +701,7 @@ class APIRouter(routing.Router):
             ), "A path prefix must not end with '/', as the routes will start with '/'"
         else:
             for r in router.routes:
-                path = getattr(r, "path")
+                path = getattr(r, "path")  # noqa: B009
                 name = getattr(r, "name", "unknown")
                 if path is not None and not path:
                     raise Exception(
index af20c8ef7862e0948475f08bc322c4a08958e609..3f7fd4e00edbcf4f42bd66934dd1c5e1615c5c9b 100644 (file)
@@ -53,7 +53,7 @@ test = [
     "pytest >=7.1.3,<8.0.0",
     "coverage[toml] >= 6.5.0,<7.0",
     "mypy ==0.982",
-    "flake8 >=3.8.3,<6.0.0",
+    "ruff ==0.0.114",
     "black == 22.8.0",
     "isort >=5.0.6,<6.0.0",
     "httpx >=0.23.0,<0.24.0",
@@ -87,8 +87,7 @@ doc = [
     "pyyaml >=5.3.1,<7.0.0",
 ]
 dev = [
-    "autoflake >=1.4.0,<2.0.0",
-    "flake8 >=3.8.3,<6.0.0",
+    "ruff ==0.0.114",
     "uvicorn[standard] >=0.12.0,<0.19.0",
     "pre-commit >=2.17.0,<3.0.0",
 ]
@@ -156,3 +155,30 @@ source = [
     "fastapi"
 ]
 context = '${CONTEXT}'
+
+[tool.ruff]
+select = [
+    "E",  # pycodestyle errors
+    "W",  # pycodestyle warnings
+    "F",  # pyflakes
+    # "I",  # isort
+    "C",  # flake8-comprehensions
+    "B",  # flake8-bugbear
+]
+ignore = [
+    "E501",  # line too long, handled by black
+    "B008",  # do not perform function calls in argument defaults
+]
+
+[tool.ruff.per-file-ignores]
+"__init__.py" = ["F401"]
+"docs_src/dependencies/tutorial007.py" = ["F821"]
+"docs_src/dependencies/tutorial008.py" = ["F821"]
+"docs_src/dependencies/tutorial009.py" = ["F821"]
+"docs_src/dependencies/tutorial010.py" = ["F821"]
+"docs_src/custom_response/tutorial007.py" = ["B007"]
+"docs_src/dataclasses/tutorial003.py" = ["I001"]
+
+
+[tool.ruff.isort]
+known-third-party = ["fastapi", "pydantic", "starlette"]
index d5fbacf59dd22d791dc4f7a463d0aa62d84a1254..622ba9202e4e155e7ef23290841b4067fbd0caf9 100644 (file)
@@ -332,7 +332,7 @@ def serve():
     os.chdir("site")
     server_address = ("", 8008)
     server = HTTPServer(server_address, SimpleHTTPRequestHandler)
-    typer.echo(f"Serving at: http://127.0.0.1:8008")
+    typer.echo("Serving at: http://127.0.0.1:8008")
     server.serve_forever()
 
 
@@ -420,7 +420,7 @@ def get_file_to_nav_map(nav: list) -> Dict[str, Tuple[str, ...]]:
     file_to_nav = {}
     for item in nav:
         if type(item) is str:
-            file_to_nav[item] = tuple()
+            file_to_nav[item] = ()
         elif type(item) is dict:
             item_key = list(item.keys())[0]
             sub_nav = item[item_key]
index ee4fbf1a5b82d046aaed43e7140835ab9d3f645f..3ac1fead86a4fca803728c34da5ef17d53b07cda 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh -e
 set -x
 
-autoflake --remove-all-unused-imports --recursive --remove-unused-variables --in-place docs_src fastapi tests scripts --exclude=__init__.py
+ruff fastapi tests docs_src scripts --fix
 black fastapi tests docs_src scripts
 isort fastapi tests docs_src scripts
index 2e2072cf180473e34488d661d90bf45bca24c461..0feb973a87f46fb5c5cf8c8a8e02a52b91883b42 100755 (executable)
@@ -4,6 +4,6 @@ set -e
 set -x
 
 mypy fastapi
-flake8 fastapi tests
+ruff fastapi tests docs_src scripts
 black fastapi tests --check
 isort fastapi tests docs_src scripts --check-only
index 1a9ea7199ad5431c44937900001e2691d4234aef..2e8d9c6de5e10eb721d45eb13141618b7618a448 100644 (file)
@@ -110,6 +110,6 @@ def test_route_classes():
     for r in app.router.routes:
         assert isinstance(r, Route)
         routes[r.path] = r
-    assert getattr(routes["/a/"], "x_type") == "A"
-    assert getattr(routes["/a/b/"], "x_type") == "B"
-    assert getattr(routes["/a/b/c/"], "x_type") == "C"
+    assert getattr(routes["/a/"], "x_type") == "A"  # noqa: B009
+    assert getattr(routes["/a/b/"], "x_type") == "B"  # noqa: B009
+    assert getattr(routes["/a/b/c/"], "x_type") == "C"  # noqa: B009
index 206d743bacaa4200313c6eeedd1e686cd33b8ad8..c312821e969064a53410cf93358dd04d1cd5d6f8 100644 (file)
@@ -111,7 +111,7 @@ def test_router_ws_depends():
 
 def test_router_ws_depends_with_override():
     client = TestClient(app)
-    app.dependency_overrides[ws_dependency] = lambda: "Override"
+    app.dependency_overrides[ws_dependency] = lambda: "Override"  # noqa: E731
     with client.websocket_connect("/router-ws-depends/") as websocket:
         assert websocket.receive_text() == "Override"