Skip to content

Commit 89e9945

Browse files
committed
Add more ruff rules, to enforce typing
1 parent cff70ce commit 89e9945

File tree

9 files changed

+45
-10
lines changed

9 files changed

+45
-10
lines changed

flask_inputfilter/filters/to_base64_image_filter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def apply(self, value: Any) -> Any:
7070
try:
7171
Image.open(io.BytesIO(base64.b64decode(value))).verify()
7272
return value
73-
except Exception:
73+
except (ValueError, OSError, base64.binascii.Error):
7474
pass
7575

7676
# Try to open as raw bytes

flask_inputfilter/filters/to_image_filter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def apply(self, value: Any) -> Any:
5151
# Try to decode as base64
5252
try:
5353
return Image.open(io.BytesIO(base64.b64decode(value)))
54-
except Exception:
54+
except (ValueError, OSError, base64.binascii.Error):
5555
pass
5656

5757
# Try to open as raw bytes

flask_inputfilter/filters/to_typed_dict_filter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any
3+
from typing import Any, Type
44

55
from flask_inputfilter.models import BaseFilter
66

@@ -34,7 +34,7 @@ def __init__(self):
3434

3535
__slots__ = ("typed_dict",)
3636

37-
def __init__(self, typed_dict) -> None:
37+
def __init__(self, typed_dict: Type) -> None:
3838
"""
3939
Parameters:
4040
typed_dict (Type[TypedDict]): The TypedDict class

flask_inputfilter/input_filter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def decorator(
104104
"""
105105

106106
def wrapper(
107-
*args, **kwargs
107+
*args: Any, **kwargs: Any
108108
) -> Union[Response, tuple[Any, dict[str, Any]]]:
109109
"""
110110
Wrapper function to handle input validation and error handling

flask_inputfilter/mixins/external_api_mixin/external_api_mixin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def call_external_api(
8383
request_data["method"] = config.method
8484

8585
try:
86-
response = requests.request(**request_data)
86+
response = requests.request(timeout=30, **request_data)
8787
result = response.json()
8888
except requests.exceptions.RequestException:
8989
if fallback is None:

flask_inputfilter/validators/is_dataclass_validator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ def __init__(
113113
)
114114
)
115115

116-
def _format_error(self, error_type: str, **kwargs) -> str:
116+
def _format_error(self, error_type: str, **kwargs: Any) -> str:
117117
"""Format error message using template or custom message."""
118118
if self.error_message:
119119
return self.error_message

flask_inputfilter/validators/is_horizontal_image_validator.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import base64
44
import binascii
55
import io
6+
from typing import Any, Optional
67

78
from PIL import Image
89
from PIL.Image import Image as ImageType
@@ -41,10 +42,10 @@ def __init__(self):
4142

4243
__slots__ = ("error_message",)
4344

44-
def __init__(self, error_message=None):
45+
def __init__(self, error_message: Optional[str] = None) -> None:
4546
self.error_message = error_message
4647

47-
def validate(self, value):
48+
def validate(self, value: Any) -> None:
4849
if not isinstance(value, (str, ImageType)):
4950
raise ValidationError(
5051
"The value is not an image or its base 64 representation."

flask_inputfilter/validators/is_vertical_image_validator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def __init__(self):
4242

4343
__slots__ = ("error_message",)
4444

45-
def __init__(self, error_message: Optional[str] = None):
45+
def __init__(self, error_message: Optional[str] = None) -> None:
4646
self.error_message = (
4747
error_message or "The image is not vertically oriented."
4848
)

pyproject.toml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,16 @@ select = [
125125
"TCH", # flake8-type-checking
126126
"PTH", # flake8-use-pathlib
127127
"RUF", # Ruff-specific rules
128+
"S", # flake8-bandit (Security)
129+
"BLE", # flake8-blind-except
130+
"ANN", # flake8-annotations
131+
"ARG", # flake8-unused-arguments
132+
"ERA", # eradicate
133+
"PERF", # Perflint
134+
"FURB", # refurb
135+
"TRY", # tryceratops
136+
"SLF", # flake8-self
137+
"A", # flake8-builtins
128138
]
129139
fixable = ["ALL"]
130140
unfixable = []
@@ -136,11 +146,35 @@ ignore = [
136146
"UP006", # Use `list` instead of `List` (Python 3.9+)
137147
"UP007", # Use `X | Y` for unions (Python 3.10+)
138148
"UP035", # Import from collections.abc (Python 3.9+)
149+
"ANN101", # Missing type annotation for self
150+
"ANN102", # Missing type annotation for cls
151+
"ANN401", # Dynamically typed expressions (Any) - OK for flexible library
152+
"TRY003", # Long exception messages (ok for Libraries)
153+
"TRY300", # Consider moving to else block - not always applicable
154+
"TRY301", # Abstract raise to inner function - not needed for simple cases
155+
"PERF203", # try-except in loop - acceptable for validation patterns
156+
"A001", # Variable shadowing builtin - OK in specific contexts (e.g. copyright)
157+
"A002", # Variable shadowing builtin
139158
]
140159
pyupgrade = [
141160
true
142161
]
143162

163+
[tool.ruff.lint.per-file-ignores]
164+
"tests/*" = [
165+
"S101", # Assert usage ist OK in Tests
166+
"ANN", # Type annotations optional in Tests
167+
"ARG", # Unused arguments OK in Test fixtures
168+
]
169+
"examples/*" = [
170+
"ANN201", # Missing return type annotation in examples
171+
"ANN204", # Missing return type annotation for __init__ in examples
172+
"S201", # debug=True is OK in examples
173+
]
174+
"docs/*" = [
175+
"A001", # Variable shadowing builtin (copyright) is OK in docs
176+
]
177+
144178
[tool.ruff.lint.isort]
145179
force-single-line = false
146180
split-on-trailing-comma = true

0 commit comments

Comments
 (0)