Skip to content

Commit 46e3c9b

Browse files
authored
♻️Maintenance: Mypy on servicelib (#6117)
1 parent eb1a259 commit 46e3c9b

File tree

41 files changed

+228
-142
lines changed

Some content is hidden

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

41 files changed

+228
-142
lines changed

.github/workflows/ci-testing-deploy.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,6 @@ jobs:
15121512
run: ./ci/github/unit-testing/service-library.bash install_all
15131513
- name: typecheck
15141514
run: ./ci/github/unit-testing/service-library.bash typecheck
1515-
continue-on-error: true
15161515
- name: test
15171516
if: always()
15181517
run: ./ci/github/unit-testing/service-library.bash test_all

packages/postgres-database/src/simcore_postgres_database/utils_aiosqlalchemy.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class DBMigrationError(RuntimeError):
1616
pass
1717

1818

19-
async def raise_if_migration_not_ready(engine: AsyncEngine):
19+
async def raise_if_migration_not_ready(engine: AsyncEngine) -> None:
2020
"""Ensures db migration is complete
2121
2222
:raises DBMigrationError

packages/service-library/requirements/_test.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,15 @@ pytest-asyncio
2525
pytest-benchmark
2626
pytest-cov
2727
pytest-docker
28+
pytest-icdiff
2829
pytest-instafail
2930
pytest-mock
3031
pytest-runner
3132
pytest-sugar
3233
pytest-xdist
3334
python-dotenv
3435
respx
36+
sqlalchemy[mypy]
37+
types_aiofiles
38+
types-psycopg2
39+
types_tqdm

packages/service-library/requirements/_test.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ frozenlist==1.4.1
6565
# -c requirements/_base.txt
6666
# aiohttp
6767
# aiosignal
68+
greenlet==3.0.3
69+
# via
70+
# -c requirements/_aiohttp.txt
71+
# sqlalchemy
6872
h11==0.14.0
6973
# via
7074
# -c requirements/_fastapi.txt
@@ -78,6 +82,8 @@ httpx==0.27.0
7882
# -c requirements/../../../requirements/constraints.txt
7983
# -c requirements/_fastapi.txt
8084
# respx
85+
icdiff==2.0.7
86+
# via pytest-icdiff
8187
idna==3.7
8288
# via
8389
# -c requirements/_aiohttp.txt
@@ -115,6 +121,10 @@ multidict==6.0.5
115121
# -c requirements/_base.txt
116122
# aiohttp
117123
# yarl
124+
mypy==1.11.0
125+
# via sqlalchemy
126+
mypy-extensions==1.0.0
127+
# via mypy
118128
openapi-schema-validator==0.6.2
119129
# via
120130
# -c requirements/_aiohttp.txt
@@ -133,6 +143,8 @@ pathable==0.4.3
133143
# jsonschema-path
134144
pluggy==1.5.0
135145
# via pytest
146+
pprintpp==0.4.0
147+
# via pytest-icdiff
136148
psutil==6.0.0
137149
# via -r requirements/_test.in
138150
py-cpuinfo==9.0.0
@@ -145,6 +157,7 @@ pytest==8.2.2
145157
# pytest-benchmark
146158
# pytest-cov
147159
# pytest-docker
160+
# pytest-icdiff
148161
# pytest-instafail
149162
# pytest-mock
150163
# pytest-sugar
@@ -162,6 +175,8 @@ pytest-cov==5.0.0
162175
# via -r requirements/_test.in
163176
pytest-docker==3.1.1
164177
# via -r requirements/_test.in
178+
pytest-icdiff==0.9
179+
# via -r requirements/_test.in
165180
pytest-instafail==0.5.0
166181
# via -r requirements/_test.in
167182
pytest-mock==3.14.0
@@ -221,17 +236,33 @@ sniffio==1.3.1
221236
# anyio
222237
# asgi-lifespan
223238
# httpx
239+
sqlalchemy==1.4.52
240+
# via
241+
# -c requirements/../../../requirements/constraints.txt
242+
# -c requirements/_aiohttp.txt
243+
# -r requirements/_test.in
244+
sqlalchemy2-stubs==0.0.2a38
245+
# via sqlalchemy
224246
termcolor==2.4.0
225247
# via pytest-sugar
226248
tomli==2.0.1
227249
# via
228250
# coverage
251+
# mypy
229252
# pytest
253+
types-aiofiles==24.1.0.20240626
254+
# via -r requirements/_test.in
255+
types-psycopg2==2.9.21.20240417
256+
# via -r requirements/_test.in
257+
types-tqdm==4.66.0.20240417
258+
# via -r requirements/_test.in
230259
typing-extensions==4.12.2
231260
# via
232261
# -c requirements/_base.txt
233262
# -c requirements/_fastapi.txt
234263
# anyio
264+
# mypy
265+
# sqlalchemy2-stubs
235266
urllib3==2.2.2
236267
# via
237268
# -c requirements/../../../requirements/constraints.txt

packages/service-library/requirements/_tools.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@ isort==5.13.2
2828
mccabe==0.7.0
2929
# via pylint
3030
mypy==1.11.0
31-
# via -r requirements/../../../requirements/devenv.txt
31+
# via
32+
# -c requirements/_test.txt
33+
# -r requirements/../../../requirements/devenv.txt
3234
mypy-extensions==1.0.0
3335
# via
36+
# -c requirements/_test.txt
3437
# black
3538
# mypy
3639
nodeenv==1.9.1

packages/service-library/setup.cfg

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,8 @@ markers =
2020
testit: "marks test to run during development"
2121
performance_test: "performance test"
2222
no_cleanup_check_rabbitmq_server_has_no_errors: "no check in rabbitmq logs"
23+
24+
[mypy]
25+
plugins =
26+
pydantic.mypy
27+
sqlalchemy.ext.mypy.plugin

packages/service-library/src/servicelib/aiohttp/aiopg_utils.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
SEE for underlying psycopg: http://initd.org/psycopg/docs/module.html
1111
SEE for extra keywords: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-PARAMKEYWORDS
1212
"""
13+
1314
# TODO: Towards implementing https://github.com/ITISFoundation/osparc-simcore/issues/1195
1415
# TODO: deprecate this module. Move utils into retry_policies, simcore_postgres_database.utils_aiopg
1516

@@ -63,9 +64,9 @@ def init_pg_tables(dsn: DataSourceName, schema: sa.schema.MetaData):
6364

6465

6566
def raise_http_unavailable_error(retry_state: RetryCallState):
66-
# TODO: mark incident on db to determine the quality of service. E.g. next time we do not stop. TIP: obj, query = retry_state.args; obj.app.register_incidents
67-
68-
exc: DatabaseError = retry_state.outcome.exception()
67+
assert retry_state.outcome # nosec
68+
exc = retry_state.outcome.exception()
69+
assert exc # nosec
6970
# StandardError
7071
# |__ Warning
7172
# |__ Error
@@ -101,13 +102,13 @@ class PostgresRetryPolicyUponOperation:
101102
def __init__(self, logger: logging.Logger | None = None):
102103
logger = logger or log
103104

104-
self.kwargs = dict(
105-
retry=retry_if_exception_type(DatabaseError),
106-
wait=wait_fixed(self.WAIT_SECS),
107-
stop=stop_after_attempt(self.ATTEMPTS_COUNT),
108-
after=after_log(logger, logging.WARNING),
109-
retry_error_callback=raise_http_unavailable_error,
110-
)
105+
self.kwargs = {
106+
"retry": retry_if_exception_type(DatabaseError),
107+
"wait": wait_fixed(self.WAIT_SECS),
108+
"stop": stop_after_attempt(self.ATTEMPTS_COUNT),
109+
"after": after_log(logger, logging.WARNING),
110+
"retry_error_callback": raise_http_unavailable_error,
111+
}
111112

112113

113114
__all__ = (

packages/service-library/src/servicelib/aiohttp/application_setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def _parse_and_validate_arguments(
7474
msg = "Can only set config_section or config_enabled but not both"
7575
raise ValueError(msg)
7676

77-
section = config_section or module_name.split(".")[-1]
77+
section: str | None = config_section or module_name.split(".")[-1]
7878
if config_enabled is None:
7979
config_enabled = f"{section}.enabled"
8080
else:

packages/service-library/src/servicelib/aiohttp/client_session.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from collections.abc import AsyncGenerator
2+
from typing import cast
23

34
from aiohttp import ClientSession, ClientTimeout, web
45
from models_library.utils.json_serialization import json_dumps
@@ -40,7 +41,7 @@ async def persistent_client_session(app: web.Application) -> AsyncGenerator[None
4041
def get_client_session(app: web.Application) -> ClientSession:
4142
"""Refers to the one-and-only client in the app"""
4243
assert APP_CLIENT_SESSION_KEY in app # nosec
43-
return app[APP_CLIENT_SESSION_KEY]
44+
return cast(ClientSession, app[APP_CLIENT_SESSION_KEY])
4445

4546

4647
__all__: tuple[str, ...] = (

packages/service-library/src/servicelib/aiohttp/dev_error_logger.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
import traceback
33

44
from aiohttp.web import Application, HTTPError, Request, middleware
5-
from servicelib.aiohttp.typing_extension import Handler, Middleware
5+
6+
from .typing_extension import Handler, Middleware
67

78
_logger = logging.getLogger(__name__)
89

@@ -23,12 +24,12 @@ async def middleware_handler(request: Request, handler: Handler):
2324
"Traceback": "\n".join(traceback.format_tb(err.__traceback__)),
2425
}
2526
formatted_error = "".join(
26-
[f"\n{_SEP}{k}{_SEP}\n{v}" for k, v in fields.items()]
27+
[f"\n{_SEP}{k!r}{_SEP}\n{v!r}" for k, v in fields.items()]
2728
)
2829
_logger.debug("Error serialized to client:%s", formatted_error)
2930
raise
3031

31-
return middleware_handler # type: ignore[no-any-return]
32+
return middleware_handler
3233

3334

3435
def setup_dev_error_logger(app: Application) -> None:

0 commit comments

Comments
 (0)