Skip to content

Commit db5f8e7

Browse files
committed
add strict rules to mypy
1 parent 0dd13a2 commit db5f8e7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+307
-266
lines changed

docs/monitor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ Reactions are defined as a list of **async functions** that are triggered when s
268268
Below is an example of defining a reaction function that responds to the creation of a new issue:
269269

270270
```python
271-
async def reaction_issue_created(event_payload: dict[str, Any]):
271+
async def reaction_issue_created(event_payload: dict[str, Any]) -> None:
272272
# Do something
273273
```
274274

internal_monitors/active_notification_alert_solved/active_notification_alert_solved.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def is_solved(issue_data: IssueDataType) -> bool:
6868

6969
# Reactions
7070

71-
async def close_notification(event_payload: dict[str, Any]):
71+
async def close_notification(event_payload: dict[str, Any]) -> None:
7272
"""Fix the notification by closing it"""
7373
issue_object = event_payload["event_data"]
7474
notification = await Notification.get_by_id(issue_object["data"]["notification_id"])

pyproject.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,19 @@ mypy_path = "src"
5656
ignore_missing_imports = true
5757
warn_return_any = true
5858
check_untyped_defs = true
59+
disallow_any_generics = true
60+
disallow_incomplete_defs = true
61+
disallow_subclassing_any = true
62+
disallow_untyped_calls = true
63+
disallow_untyped_decorators = true
64+
disallow_untyped_defs = true
65+
no_implicit_optional = true
5966

6067
[[tool.mypy.overrides]]
6168
module = "tests.*"
6269
disable_error_code = ["arg-type", "empty-body", "misc", "list-item"]
70+
disallow_incomplete_defs = false
71+
disallow_untyped_defs = false
6372

6473
[tool.isort]
6574
src_paths = ["src", "tests"]

src/components/controller/controller.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async def diagnostics() -> tuple[dict[str, Any], list[str]]:
5858
return status, issues
5959

6060

61-
async def _queue_task(monitor: Monitor, tasks: list[str]):
61+
async def _queue_task(monitor: Monitor, tasks: list[str]) -> None:
6262
"""Send a message to the queue with the monitor tasks that should be executed"""
6363
monitor.set_queued(True)
6464
await monitor.save()
@@ -80,7 +80,7 @@ async def _queue_task(monitor: Monitor, tasks: list[str]):
8080
await monitor.save()
8181

8282

83-
async def _process_monitor(monitor: Monitor):
83+
async def _process_monitor(monitor: Monitor) -> None:
8484
"""Check if the monitor triggers any task and queue them if there're any"""
8585
global last_monitor_processed_at
8686

@@ -106,7 +106,7 @@ async def _process_monitor(monitor: Monitor):
106106
await _queue_task(monitor, tasks)
107107

108108

109-
async def _run_task(semaphore: asyncio.Semaphore, monitor: Monitor):
109+
async def _run_task(semaphore: asyncio.Semaphore, monitor: Monitor) -> None:
110110
"""Keep one of the semaphore's lock while the monitor is being processed"""
111111
_logger.info(f"Processing monitor {monitor}")
112112
async with semaphore:
@@ -116,7 +116,7 @@ async def _run_task(semaphore: asyncio.Semaphore, monitor: Monitor):
116116
async def _create_process_task(
117117
semaphore: asyncio.Semaphore,
118118
monitor: Monitor
119-
) -> asyncio.Task | None:
119+
) -> asyncio.Task[Any] | None:
120120
"""Create a task to process the monitor"""
121121
# Instead of registering the monitor, skip if it's not registered yet
122122
# If processing a monitor that is not yet registered, the executor won't have
@@ -132,7 +132,7 @@ async def _create_process_task(
132132
return asyncio.create_task(_run_task(semaphore, monitor))
133133

134134

135-
async def run():
135+
async def run() -> None:
136136
global last_loop_at
137137
global running
138138

@@ -146,7 +146,7 @@ async def run():
146146
# Queue setup
147147
semaphore = asyncio.Semaphore(configs.controller_concurrency)
148148

149-
tasks: list[asyncio.Task] = []
149+
tasks: list[asyncio.Task[Any]] = []
150150

151151
while app.running():
152152
with catch_exceptions(_logger):

src/components/controller/procedures.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
SQL_FILES_PATH = Path(__file__).parent / "sql_files"
2121

2222

23-
async def _monitors_stuck():
23+
async def _monitors_stuck() -> None:
2424
with open(SQL_FILES_PATH / "monitors_stuck.sql") as file:
2525
query = file.read()
2626

@@ -64,14 +64,14 @@ def _check_procedure_triggered(schedule: str, last_execution: datetime | None) -
6464
async def _execute_procedure(
6565
procedure_name: str,
6666
procedure: Callable[[], Coroutine[None, None, None]],
67-
):
67+
) -> None:
6868
"""Execute the 'procedure' and update the 'last_executions' variable"""
6969
with catch_exceptions(logger=_logger):
7070
await procedure()
7171
last_executions[procedure_name] = datetime.now()
7272

7373

74-
async def run_procedures():
74+
async def run_procedures() -> None:
7575
"""Check and run all procedures that are triggered"""
7676
for procedure_name, procedure in procedures.items():
7777
last_execution = last_executions.get(procedure_name)

src/components/executor/executor.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ async def diagnostics() -> tuple[dict[str, Any], list[str]]:
6060
return status, issues
6161

6262

63-
async def _change_visibility_loop(message: message_queue.Message):
63+
async def _change_visibility_loop(message: message_queue.Message) -> None:
6464
"""Change the message visibility while it's been processed"""
6565
try:
6666
while app.running():
@@ -71,7 +71,7 @@ async def _change_visibility_loop(message: message_queue.Message):
7171

7272

7373
class Executor:
74-
task: asyncio.Task
74+
task: asyncio.Task[Any]
7575
_logger: logging.Logger
7676

7777
_handlers = {
@@ -81,10 +81,10 @@ class Executor:
8181
}
8282
_current_message_type: str
8383

84-
def __init__(self, number: int):
84+
def __init__(self, number: int) -> None:
8585
self._logger = logging.getLogger(f"executor_{number}")
8686

87-
def init(self):
87+
def init(self) -> None:
8888
"""Create the internal loop task"""
8989
self.task = asyncio.create_task(self.run())
9090

@@ -115,7 +115,7 @@ async def process_message(
115115
self,
116116
handler: Callable[[dict[Any, Any]], Coroutine[Any, Any, Any]],
117117
message: message_queue.Message
118-
):
118+
) -> None:
119119
"""Process the message with the provided handler, protecting from possible exceptions.
120120
During the message processing, another task will be spawned to change it's visibility in
121121
the queue, preventing other messages from processing it too"""
@@ -151,7 +151,7 @@ async def process_message(
151151
change_visibility_task.cancel()
152152
await change_visibility_task
153153

154-
async def process(self):
154+
async def process(self) -> None:
155155
"""Get a message and process it"""
156156
# Wait for the monitors to be ready
157157
await registry.wait_monitors_ready()
@@ -169,7 +169,7 @@ async def process(self):
169169

170170
await self.process_message(handler, message)
171171

172-
async def run(self):
172+
async def run(self) -> None:
173173
"""Run the executor process continuously, until the application finishes"""
174174
self._logger.info("Executor running")
175175

@@ -180,7 +180,7 @@ async def run(self):
180180
self._logger.info("Finishing")
181181

182182

183-
async def run():
183+
async def run() -> None:
184184
global executors
185185
global running
186186

src/components/executor/monitor_handler.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def _make_dict_json_compatible(data: Any) -> dict[Any, Any] | None:
7171
return cast(dict[Any, Any] | None, _convert_types(data))
7272

7373

74-
async def _search_routine(monitor: Monitor):
74+
async def _search_routine(monitor: Monitor) -> None:
7575
"""Search routine for the monitor, executing the 'search' function and processing the returned
7676
data"""
7777
found_issues_data = await monitor.search_function()
@@ -154,7 +154,7 @@ async def _search_routine(monitor: Monitor):
154154
monitor.add_issues(issues)
155155

156156

157-
async def _update_routine(monitor: Monitor):
157+
async def _update_routine(monitor: Monitor) -> None:
158158
"""Update routine for the monitor, executing the 'update' function and processing the returned
159159
data"""
160160
# Skip the update routine if there're no active issues
@@ -220,14 +220,14 @@ async def _update_routine(monitor: Monitor):
220220
await issue.update_data(raw_issue_data, session=session)
221221

222222

223-
async def _issues_solve_routine(monitor: Monitor):
223+
async def _issues_solve_routine(monitor: Monitor) -> None:
224224
"""Issue solve routine for the monitor, checking all issues against the 'is_solved' function"""
225225
async with get_session() as session:
226226
for issue in monitor.active_issues:
227227
await issue.check_solved(session=session)
228228

229229

230-
async def _alerts_routine(monitor: Monitor):
230+
async def _alerts_routine(monitor: Monitor) -> None:
231231
"""Alert routine for the monitor, creating, linking issues, updating and solving them"""
232232
# As 'alert_options' can be None, check it before executing
233233
if monitor.alert_options is None:
@@ -260,7 +260,7 @@ async def _alerts_routine(monitor: Monitor):
260260
await do_concurrently(*[alert.update() for alert in monitor.active_alerts])
261261

262262

263-
async def _run_routines(monitor: Monitor, tasks: list[str]):
263+
async def _run_routines(monitor: Monitor, tasks: list[str]) -> None:
264264
"""Run all routines for a monitor, based on a list of tasks"""
265265
# Monitor instrumentation metrics
266266
prometheus_labels = {
@@ -299,7 +299,7 @@ async def _run_routines(monitor: Monitor, tasks: list[str]):
299299
await _alerts_routine(monitor)
300300

301301

302-
async def run(message: dict[Any, Any]):
302+
async def run(message: dict[Any, Any]) -> None:
303303
"""Process a message with type 'process_monitor', loading the monitor and executing it's
304304
routines, while also detecting errors and reporting them accordingly"""
305305
message_payload = message["payload"]

src/components/executor/reaction_handler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
)
3232

3333

34-
async def run(message: dict[Any, Any]):
34+
async def run(message: dict[Any, Any]) -> None:
3535
"""Process a message with type 'event' using the monitor's defined list of reactions for the
3636
event. The execution timeout is for each function individually"""
3737
message_payload = message["payload"]

src/components/executor/request_handler.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import json
33
import logging
44
import traceback
5-
from typing import Any
5+
from typing import Any, Coroutine, Callable, cast
66

77
import plugins
88
import registry as registry
@@ -13,7 +13,7 @@
1313
_logger = logging.getLogger("request_handler")
1414

1515

16-
async def alert_acknowledge(message_payload: dict[Any, Any]):
16+
async def alert_acknowledge(message_payload: dict[Any, Any]) -> None:
1717
"""Acknowledge an alert"""
1818
alert_id = message_payload["target_id"]
1919
alert = await Alert.get_by_id(alert_id)
@@ -24,7 +24,7 @@ async def alert_acknowledge(message_payload: dict[Any, Any]):
2424
await alert.acknowledge()
2525

2626

27-
async def alert_lock(message_payload: dict[Any, Any]):
27+
async def alert_lock(message_payload: dict[Any, Any]) -> None:
2828
"""Lock an alert"""
2929
alert_id = message_payload["target_id"]
3030
alert = await Alert.get_by_id(alert_id)
@@ -35,7 +35,7 @@ async def alert_lock(message_payload: dict[Any, Any]):
3535
await alert.lock()
3636

3737

38-
async def alert_solve(message_payload: dict[Any, Any]):
38+
async def alert_solve(message_payload: dict[Any, Any]) -> None:
3939
"""Solve all alert's issues"""
4040
alert_id = message_payload["target_id"]
4141
alert = await Alert.get_by_id(alert_id)
@@ -46,7 +46,7 @@ async def alert_solve(message_payload: dict[Any, Any]):
4646
await alert.solve_issues()
4747

4848

49-
async def issue_drop(message_payload: dict[Any, Any]):
49+
async def issue_drop(message_payload: dict[Any, Any]) -> None:
5050
"""Drop an issue"""
5151
issue_id = message_payload["target_id"]
5252
issue = await Issue.get_by_id(issue_id)
@@ -65,7 +65,7 @@ async def issue_drop(message_payload: dict[Any, Any]):
6565
}
6666

6767

68-
def get_action(action_name: str):
68+
def get_action(action_name: str) -> Callable[[dict[Any, Any]], Coroutine[Any, Any, None]] | None:
6969
"""Get the action function by its name, checking if it is a plugin action"""
7070
if action_name.startswith("plugin."):
7171
plugin_name, action_name = action_name.split(".")[1:3]
@@ -85,12 +85,12 @@ def get_action(action_name: str):
8585
_logger.warning(f"Action '{plugin_name}.{action_name}' unknown")
8686
return None
8787

88-
return action
88+
return cast(Callable[[dict[Any, Any]], Coroutine[Any, Any, None]], action)
8989

9090
return actions.get(action_name)
9191

9292

93-
async def run(message: dict[Any, Any]):
93+
async def run(message: dict[Any, Any]) -> None:
9494
"""Process a received request"""
9595
message_payload = message["payload"]
9696
action_name = message_payload["action"]

src/components/http_server/alert_routes.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from aiohttp import web
2+
from aiohttp.web_request import Request
23
from aiohttp.web_response import Response
34

45
import external_requests as external_requests
@@ -10,7 +11,7 @@
1011

1112
@alert_routes.post(base_route + "/{alert_id}/acknowledge")
1213
@alert_routes.post(base_route + "/{alert_id}/acknowledge/")
13-
async def alert_acknowledge(request) -> Response:
14+
async def alert_acknowledge(request: Request) -> Response:
1415
"""Route to acknowledge an alert"""
1516
alert_id = int(request.match_info["alert_id"])
1617

@@ -31,7 +32,7 @@ async def alert_acknowledge(request) -> Response:
3132

3233
@alert_routes.post(base_route + "/{alert_id}/lock")
3334
@alert_routes.post(base_route + "/{alert_id}/lock/")
34-
async def alert_lock(request) -> Response:
35+
async def alert_lock(request: Request) -> Response:
3536
"""Route to lock an alert"""
3637
alert_id = int(request.match_info["alert_id"])
3738

@@ -52,7 +53,7 @@ async def alert_lock(request) -> Response:
5253

5354
@alert_routes.post(base_route + "/{alert_id}/solve")
5455
@alert_routes.post(base_route + "/{alert_id}/solve/")
55-
async def alert_solve(request) -> Response:
56+
async def alert_solve(request: Request) -> Response:
5657
"""Route to solve an alert's issues"""
5758
alert_id = int(request.match_info["alert_id"])
5859

0 commit comments

Comments
 (0)