Skip to content

Commit

Permalink
✨ Use Ruff for linting (#5630)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiangolo committed Nov 13, 2022
1 parent bcd9ab9 commit fa74093
Show file tree
Hide file tree
Showing 13 changed files with 51 additions and 37 deletions.
5 changes: 0 additions & 5 deletions .flake8

This file was deleted.

15 changes: 4 additions & 11 deletions .pre-commit-config.yaml
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion docs_src/security/tutorial005.py
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion docs_src/security/tutorial005_py310.py
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion docs_src/security/tutorial005_py39.py
Expand Up @@ -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",
Expand Down
12 changes: 6 additions & 6 deletions fastapi/dependencies/utils.py
Expand Up @@ -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)


Expand Down Expand Up @@ -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):
Expand All @@ -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)
]
Expand Down
2 changes: 1 addition & 1 deletion fastapi/routing.py
Expand Up @@ -701,7 +701,7 @@ def include_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(
Expand Down
32 changes: 29 additions & 3 deletions pyproject.toml
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
]
Expand Down Expand Up @@ -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"]
4 changes: 2 additions & 2 deletions scripts/docs.py
Expand Up @@ -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()


Expand Down Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion scripts/format.sh
@@ -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
2 changes: 1 addition & 1 deletion scripts/lint.sh
Expand Up @@ -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
6 changes: 3 additions & 3 deletions tests/test_custom_route_class.py
Expand Up @@ -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
2 changes: 1 addition & 1 deletion tests/test_ws_router.py
Expand Up @@ -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"

Expand Down

0 comments on commit fa74093

Please sign in to comment.