Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ Maintenance: mypy webserver part 2 #6142

Closed

Conversation

GitHK
Copy link
Contributor

@GitHK GitHK commented Aug 6, 2024

What do these changes do?

Remaining: Found 164 errors in 52 files (checked 388 source files)

The following modules have been touched:

  • email
  • notifications
  • db
  • statics
  • wallets
  • products
  • studies_dispatcher
  • version_control
  • log
  • rabbitmq
  • login

Related issue/s

How to test

Dev-ops checklist

@GitHK GitHK self-assigned this Aug 6, 2024
@GitHK GitHK added the a:webserver issue related to the webserver service label Aug 6, 2024
@GitHK GitHK added the t:maintenance Some planned maintenance work label Aug 6, 2024
@GitHK GitHK added this to the Tom Bombadil milestone Aug 6, 2024
Copy link

codecov bot commented Aug 6, 2024

Codecov Report

Attention: Patch coverage is 97.26027% with 2 lines in your changes missing coverage. Please review.

Project coverage is 82.0%. Comparing base (cafbf96) to head (9462d65).
Report is 442 commits behind head on master.

Files Patch % Lines
...e_service_webserver/login/handlers_confirmation.py 50.0% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #6142      +/-   ##
=========================================
- Coverage    84.5%   82.0%    -2.6%     
=========================================
  Files          10     577     +567     
  Lines         214   29422   +29208     
  Branches       25     234     +209     
=========================================
+ Hits          181   24136   +23955     
- Misses         23    5226    +5203     
- Partials       10      60      +50     
Flag Coverage Δ
integrationtests 64.8% <53.4%> (?)
unittests 87.5% <97.2%> (+2.9%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
.../server/src/simcore_service_webserver/db/plugin.py 88.8% <100.0%> (ø)
...erver/src/simcore_service_webserver/email/_core.py 83.1% <100.0%> (ø)
...rver/src/simcore_service_webserver/email/plugin.py 88.2% <100.0%> (ø)
...rc/simcore_service_webserver/exporter/_handlers.py 94.7% <ø> (ø)
...es/web/server/src/simcore_service_webserver/log.py 94.4% <100.0%> (ø)
...r/src/simcore_service_webserver/login/_auth_api.py 96.9% <100.0%> (ø)
...c/simcore_service_webserver/login/_registration.py 78.4% <100.0%> (ø)
..._service_webserver/login/_registration_handlers.py 93.1% <100.0%> (ø)
...rver/src/simcore_service_webserver/login/plugin.py 90.3% <100.0%> (ø)
...ver/src/simcore_service_webserver/login/storage.py 95.7% <100.0%> (ø)
... and 19 more

... and 558 files with indirect coverage changes

@GitHK GitHK marked this pull request as ready for review August 8, 2024 12:17
Copy link

sonarqubecloud bot commented Aug 8, 2024

Copy link
Contributor

@matusdrobuliak66 matusdrobuliak66 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

Copy link
Member

@sanderegg sanderegg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there a few things to discuss maybe

confirmation_token
).data
validated = _InvitationValidator.parse_obj(confirmation_token)
invitation_data: InvitationData = validated.data # type: ignore[assignment]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually you should not have to do that. Json[InvitationData] is of type InvitationData as it is a wrapper. The problem is that you enforce the type here and mypy rightfully complains.

async with self.pool.acquire() as conn:
return await _sql.find_one(conn, self.user_tbl, with_data)
result: asyncpg.Record | None = await _sql.find_one(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when you put a type like this, you actually force it to be so. normally that is not needed. and both pylance and mypy shall know it is asyncpg.Record | None.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also you are now changing the syntax of that function. what happens if the user is None? is it handled?

async with self.pool.acquire() as conn:
await _sql.update(conn, self.user_tbl, {"id": user["id"]}, updates)

async def delete_user(self, user):
async def delete_user(self, user) -> None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for delete_user and update_user

Comment on lines +53 to +55
ProductPriceInfo | None,
await repo.get_product_latest_price_info_or_none(current_product_name),
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this cast needed here?? this repo is in the code right? this should be defined as the return type is it not?

@@ -91,7 +95,9 @@ async def get_product_stripe_info(
app: web.Application, *, product_name: ProductName
) -> ProductStripeInfoGet:
repo = ProductRepository.create_from_app(app)
product_stripe_info = await repo.get_product_stripe_info(product_name)
product_stripe_info: ProductStripeInfoGet = await repo.get_product_stripe_info(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is also very weird

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why if not product_stipe_info? if this is the type then this is wrong.

@@ -48,7 +48,7 @@ async def auto_create_products_groups(app: web.Application) -> None:

async with engine.acquire() as connection:
async for row in iter_products(connection):
product_name = row.name
product_name = row.name # type: ignore[attr-defined]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why you ignore it here over casting?

Comment on lines +42 to +47
lrange = redis_client.lrange(
get_notification_key(user_id), -1 * MAX_NOTIFICATIONS_FOR_USER_TO_SHOW, -1
)
raw_notifications: list[str] = (
await lrange if isinstance(lrange, Awaitable) else lrange
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we use it async so we know it is an awaitable right? why use the if here and not just cast or ignore?

all_user_notifications: list[UserNotification] = [
UserNotification.parse_raw(x) for x in await redis_client.lrange(key, 0, -1)
UserNotification.parse_raw(x)
for x in (await lrange if isinstance(lrange, Awaitable) else lrange)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

]
for k, user_notification in enumerate(all_user_notifications):
if req_path_params.notification_id == user_notification.id:
user_notification.read = body.read
await redis_client.lset(key, k, user_notification.json())
lset = redis_client.lset(key, k, user_notification.json())
if isinstance(lset, Awaitable):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here

@@ -71,8 +71,10 @@ def _parse_extra_credits_in_usd_or_none(
confirmation: ConfirmationTokenDict,
) -> PositiveInt | None:
with suppress(ValidationError, JSONDecodeError):
invitation = InvitationData.parse_raw(confirmation.get("data", "EMPTY"))
return invitation.extra_credits_in_usd
confirmation_data: str | None = confirmation.get("data", "EMPTY")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now more convoluted. The idea here is to raise ValudationErrorif something goes wrong and then suppressed.
if confirmation_data is None, then parse_raw will raise. There is no need for this check


repo = await self.ReposOrm(conn).set_filter(id=repo_id).fetch("project_uuid")
assert repo # nosec
return repo.project_uuid
return ProjectIDStr(repo.project_uuid)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NOTE that using the constractor or a constrainted str type simply calls the constructor of str but does NOT run any validation. For that you need to do parse_obj_as(ProjectIDStr, repo.project_uuid)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

normally this comes with sqlalchemy[mypy]

@@ -78,14 +78,14 @@ async def load_products_on_startup(app: web.Application):
async with engine.acquire() as connection:
async for row in iter_products(connection):
try:
name = row.name
name = row.name # type: ignore[attr-defined]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know why mypy cannot access the attributes of row? Could it be that we are missing here another mypy stub?

@GitHK
Copy link
Contributor Author

GitHK commented Aug 19, 2024

this will be taken care of in different PRs

@GitHK GitHK closed this Aug 19, 2024
@GitHK GitHK deleted the pr-osparc-mypy-webserver-round2 branch August 19, 2024 07:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:webserver issue related to the webserver service t:maintenance Some planned maintenance work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants