Skip to content

Commit c6595a6

Browse files
authored
lint: narrow types to ensure correct usage (#17519)
* lint: use type narrowing to confirm types Refs: https://mypy.readthedocs.io/en/stable/type_narrowing.html Signed-off-by: Mike Fiedler <[email protected]> * lint: use type narrowing with explicit casts Signed-off-by: Mike Fiedler <[email protected]> * lint: add type narrowing to returned certificate Refs: https://mypy.readthedocs.io/en/stable/type_narrowing.html#type-narrowing-expressions Refs: https://cryptography.io/en/latest/hazmat/primitives/asymmetric/#common-types Signed-off-by: Mike Fiedler <[email protected]> * make translations Signed-off-by: Mike Fiedler <[email protected]> --------- Signed-off-by: Mike Fiedler <[email protected]>
1 parent d673576 commit c6595a6

File tree

14 files changed

+79
-61
lines changed

14 files changed

+79
-61
lines changed

warehouse/admin/views/organizations.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def organization_list(request):
4949
)
5050

5151
if q:
52-
filters = []
52+
filters: list = []
5353
for term in terms:
5454
# Examples:
5555
# - search individual words or "whole phrase" in any field
@@ -223,7 +223,7 @@ def organization_applications_list(request):
223223
).order_by(OrganizationApplication.normalized_name)
224224

225225
if q:
226-
filters = []
226+
filters: list = []
227227
for term in terms:
228228
# Examples:
229229
# - search individual words or "whole phrase" in any field

warehouse/admin/views/prohibited_project_names.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def prohibited_project_names(request):
5757
if q:
5858
terms = shlex.split(q)
5959

60-
filters = []
60+
filters: list = []
6161
for term in terms:
6262
filters.append(
6363
ProhibitedProjectName.name.ilike(func.normalize_pep426_name(term))

warehouse/cli/sponsors.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
# See the License for the specific language governing permissions and
1111
# limitations under the License.
1212

13+
from typing import cast
14+
1315
import click
1416

1517
from warehouse.cli import warehouse
@@ -569,10 +571,12 @@ def populate_db(config):
569571
img = params.pop("image")
570572
params["is_active"] = True
571573
params["link_url"] = params.pop("url")
572-
params["activity_markdown"] = "\n\n".join(params.pop("activity", [])).strip()
573-
params["color_logo_url"] = BLACK_BASE_URL + img
574+
params["activity_markdown"] = "\n\n".join(
575+
cast(list, params.pop("activity", []))
576+
).strip()
577+
params["color_logo_url"] = BLACK_BASE_URL + str(img)
574578
if params["footer"] or params["infra_sponsor"]:
575-
params["white_logo_url"] = WHITE_BASE_URL + img
579+
params["white_logo_url"] = WHITE_BASE_URL + str(img)
576580

577581
sponsor = Sponsor(**params)
578582
try:

warehouse/forklift/legacy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ def file_upload(request):
461461
request.metrics.increment("warehouse.upload.attempt")
462462

463463
# This is a list of warnings that we'll emit *IF* the request is successful.
464-
warnings = []
464+
warnings: list[str] = []
465465

466466
# If we're in read-only mode, let upload clients know
467467
if request.flags.enabled(AdminFlagValue.READ_ONLY):
@@ -618,7 +618,7 @@ def file_upload(request):
618618
meta = metadata.parse(None, form_data=request.POST)
619619
except* metadata.InvalidMetadata as exc:
620620
# Turn our list of errors into a mapping of errors, keyed by the field
621-
errors = {}
621+
errors: dict = {}
622622
for error in exc.exceptions:
623623
errors.setdefault(error.field, []).append(error)
624624

warehouse/integrations/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
import base64
1414
import time
1515

16+
from typing import cast
17+
1618
from cryptography.exceptions import InvalidSignature
1719
from cryptography.hazmat.backends import default_backend
1820
from cryptography.hazmat.primitives import serialization
19-
from cryptography.hazmat.primitives.asymmetric.ec import ECDSA
21+
from cryptography.hazmat.primitives.asymmetric.ec import ECDSA, EllipticCurvePublicKey
2022
from cryptography.hazmat.primitives.hashes import SHA256
2123

2224

@@ -124,6 +126,8 @@ def _check_signature(self, payload, public_key, signature):
124126
loaded_public_key = serialization.load_pem_public_key(
125127
data=public_key.encode("utf-8"), backend=default_backend()
126128
)
129+
# Use Type Narrowing to confirm the loaded_public_key is the correct type
130+
loaded_public_key = cast(EllipticCurvePublicKey, loaded_public_key)
127131
loaded_public_key.verify(
128132
signature=base64.b64decode(signature),
129133
data=payload,

warehouse/legacy/api/json.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ def _json_data(request, project, release, *, all_releases):
8585

8686
# Map our releases + files into a dictionary that maps each release to a
8787
# list of all its files.
88-
releases = {}
88+
releases_and_files: dict[Release, list[File]] = {}
8989
for r, file_ in release_files:
90-
files = releases.setdefault(r, [])
90+
files = releases_and_files.setdefault(r, [])
9191
if file_ is not None:
9292
files.append(file_)
9393

@@ -122,7 +122,7 @@ def _json_data(request, project, release, *, all_releases):
122122
}
123123
for f in fs
124124
]
125-
for r, fs in releases.items()
125+
for r, fs in releases_and_files.items()
126126
}
127127

128128
# Serialize a list of vulnerabilities for this release

warehouse/locale/messages.pot

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ msgid "You are now ${role} of the '${project_name}' project."
297297
msgstr ""
298298

299299
#: warehouse/accounts/views.py:1593 warehouse/accounts/views.py:1836
300-
#: warehouse/manage/views/__init__.py:1417
300+
#: warehouse/manage/views/__init__.py:1419
301301
msgid ""
302302
"Trusted publishing is temporarily disabled. See https://pypi.org/help"
303303
"#admin-intervention for details."
@@ -317,19 +317,19 @@ msgstr ""
317317
msgid "You can't register more than 3 pending trusted publishers at once."
318318
msgstr ""
319319

320-
#: warehouse/accounts/views.py:1659 warehouse/manage/views/__init__.py:1586
321-
#: warehouse/manage/views/__init__.py:1699
322-
#: warehouse/manage/views/__init__.py:1811
323-
#: warehouse/manage/views/__init__.py:1921
320+
#: warehouse/accounts/views.py:1659 warehouse/manage/views/__init__.py:1588
321+
#: warehouse/manage/views/__init__.py:1701
322+
#: warehouse/manage/views/__init__.py:1813
323+
#: warehouse/manage/views/__init__.py:1923
324324
msgid ""
325325
"There have been too many attempted trusted publisher registrations. Try "
326326
"again later."
327327
msgstr ""
328328

329-
#: warehouse/accounts/views.py:1669 warehouse/manage/views/__init__.py:1599
330-
#: warehouse/manage/views/__init__.py:1712
331-
#: warehouse/manage/views/__init__.py:1824
332-
#: warehouse/manage/views/__init__.py:1934
329+
#: warehouse/accounts/views.py:1669 warehouse/manage/views/__init__.py:1601
330+
#: warehouse/manage/views/__init__.py:1714
331+
#: warehouse/manage/views/__init__.py:1826
332+
#: warehouse/manage/views/__init__.py:1936
333333
msgid "The trusted publisher could not be registered"
334334
msgstr ""
335335

@@ -478,150 +478,150 @@ msgstr ""
478478
msgid "Verify your email to create an API token."
479479
msgstr ""
480480

481-
#: warehouse/manage/views/__init__.py:1038
481+
#: warehouse/manage/views/__init__.py:1040
482482
msgid "API Token does not exist."
483483
msgstr ""
484484

485-
#: warehouse/manage/views/__init__.py:1070
485+
#: warehouse/manage/views/__init__.py:1072
486486
msgid "Invalid credentials. Try again"
487487
msgstr ""
488488

489-
#: warehouse/manage/views/__init__.py:1189
489+
#: warehouse/manage/views/__init__.py:1191
490490
msgid "Invalid alternate repository location details"
491491
msgstr ""
492492

493-
#: warehouse/manage/views/__init__.py:1227
493+
#: warehouse/manage/views/__init__.py:1229
494494
#, python-brace-format
495495
msgid "Added alternate repository '${name}'"
496496
msgstr ""
497497

498-
#: warehouse/manage/views/__init__.py:1260
499-
#: warehouse/manage/views/__init__.py:2267
500-
#: warehouse/manage/views/__init__.py:2352
501-
#: warehouse/manage/views/__init__.py:2453
502-
#: warehouse/manage/views/__init__.py:2553
498+
#: warehouse/manage/views/__init__.py:1262
499+
#: warehouse/manage/views/__init__.py:2269
500+
#: warehouse/manage/views/__init__.py:2354
501+
#: warehouse/manage/views/__init__.py:2455
502+
#: warehouse/manage/views/__init__.py:2555
503503
msgid "Confirm the request"
504504
msgstr ""
505505

506-
#: warehouse/manage/views/__init__.py:1272
506+
#: warehouse/manage/views/__init__.py:1274
507507
msgid "Invalid alternate repository id"
508508
msgstr ""
509509

510-
#: warehouse/manage/views/__init__.py:1283
510+
#: warehouse/manage/views/__init__.py:1285
511511
msgid "Invalid alternate repository for project"
512512
msgstr ""
513513

514-
#: warehouse/manage/views/__init__.py:1292
514+
#: warehouse/manage/views/__init__.py:1294
515515
#, python-brace-format
516516
msgid ""
517517
"Could not delete alternate repository - ${confirm} is not the same as "
518518
"${alt_repo_name}"
519519
msgstr ""
520520

521-
#: warehouse/manage/views/__init__.py:1322
521+
#: warehouse/manage/views/__init__.py:1324
522522
#, python-brace-format
523523
msgid "Deleted alternate repository '${name}'"
524524
msgstr ""
525525

526-
#: warehouse/manage/views/__init__.py:1466
526+
#: warehouse/manage/views/__init__.py:1468
527527
msgid "The trusted publisher could not be constrained"
528528
msgstr ""
529529

530-
#: warehouse/manage/views/__init__.py:1567
530+
#: warehouse/manage/views/__init__.py:1569
531531
msgid ""
532532
"GitHub-based trusted publishing is temporarily disabled. See "
533533
"https://pypi.org/help#admin-intervention for details."
534534
msgstr ""
535535

536-
#: warehouse/manage/views/__init__.py:1680
536+
#: warehouse/manage/views/__init__.py:1682
537537
msgid ""
538538
"GitLab-based trusted publishing is temporarily disabled. See "
539539
"https://pypi.org/help#admin-intervention for details."
540540
msgstr ""
541541

542-
#: warehouse/manage/views/__init__.py:1792
542+
#: warehouse/manage/views/__init__.py:1794
543543
msgid ""
544544
"Google-based trusted publishing is temporarily disabled. See "
545545
"https://pypi.org/help#admin-intervention for details."
546546
msgstr ""
547547

548-
#: warehouse/manage/views/__init__.py:1901
548+
#: warehouse/manage/views/__init__.py:1903
549549
msgid ""
550550
"ActiveState-based trusted publishing is temporarily disabled. See "
551551
"https://pypi.org/help#admin-intervention for details."
552552
msgstr ""
553553

554-
#: warehouse/manage/views/__init__.py:2136
555-
#: warehouse/manage/views/__init__.py:2437
556-
#: warehouse/manage/views/__init__.py:2545
554+
#: warehouse/manage/views/__init__.py:2138
555+
#: warehouse/manage/views/__init__.py:2439
556+
#: warehouse/manage/views/__init__.py:2547
557557
msgid ""
558558
"Project deletion temporarily disabled. See https://pypi.org/help#admin-"
559559
"intervention for details."
560560
msgstr ""
561561

562-
#: warehouse/manage/views/__init__.py:2280
562+
#: warehouse/manage/views/__init__.py:2282
563563
msgid "Could not yank release - "
564564
msgstr ""
565565

566-
#: warehouse/manage/views/__init__.py:2365
566+
#: warehouse/manage/views/__init__.py:2367
567567
msgid "Could not un-yank release - "
568568
msgstr ""
569569

570-
#: warehouse/manage/views/__init__.py:2466
570+
#: warehouse/manage/views/__init__.py:2468
571571
msgid "Could not delete release - "
572572
msgstr ""
573573

574-
#: warehouse/manage/views/__init__.py:2565
574+
#: warehouse/manage/views/__init__.py:2567
575575
msgid "Could not find file"
576576
msgstr ""
577577

578-
#: warehouse/manage/views/__init__.py:2570
578+
#: warehouse/manage/views/__init__.py:2572
579579
msgid "Could not delete file - "
580580
msgstr ""
581581

582-
#: warehouse/manage/views/__init__.py:2720
582+
#: warehouse/manage/views/__init__.py:2722
583583
#, python-brace-format
584584
msgid "Team '${team_name}' already has ${role_name} role for project"
585585
msgstr ""
586586

587-
#: warehouse/manage/views/__init__.py:2827
587+
#: warehouse/manage/views/__init__.py:2829
588588
#, python-brace-format
589589
msgid "User '${username}' already has ${role_name} role for project"
590590
msgstr ""
591591

592-
#: warehouse/manage/views/__init__.py:2894
592+
#: warehouse/manage/views/__init__.py:2896
593593
#, python-brace-format
594594
msgid "${username} is now ${role} of the '${project_name}' project."
595595
msgstr ""
596596

597-
#: warehouse/manage/views/__init__.py:2926
597+
#: warehouse/manage/views/__init__.py:2928
598598
#, python-brace-format
599599
msgid ""
600600
"User '${username}' does not have a verified primary email address and "
601601
"cannot be added as a ${role_name} for project"
602602
msgstr ""
603603

604-
#: warehouse/manage/views/__init__.py:2939
604+
#: warehouse/manage/views/__init__.py:2941
605605
#: warehouse/manage/views/organizations.py:890
606606
#, python-brace-format
607607
msgid "User '${username}' already has an active invite. Please try again later."
608608
msgstr ""
609609

610-
#: warehouse/manage/views/__init__.py:3004
610+
#: warehouse/manage/views/__init__.py:3006
611611
#: warehouse/manage/views/organizations.py:955
612612
#, python-brace-format
613613
msgid "Invitation sent to '${username}'"
614614
msgstr ""
615615

616-
#: warehouse/manage/views/__init__.py:3036
616+
#: warehouse/manage/views/__init__.py:3038
617617
msgid "Could not find role invitation."
618618
msgstr ""
619619

620-
#: warehouse/manage/views/__init__.py:3047
620+
#: warehouse/manage/views/__init__.py:3049
621621
msgid "Invitation already expired."
622622
msgstr ""
623623

624-
#: warehouse/manage/views/__init__.py:3080
624+
#: warehouse/manage/views/__init__.py:3082
625625
#: warehouse/manage/views/organizations.py:1142
626626
#, python-brace-format
627627
msgid "Invitation revoked from '${username}'."
@@ -814,7 +814,7 @@ msgstr ""
814814
msgid "Provide an Inspector link to specific lines of code."
815815
msgstr ""
816816

817-
#: warehouse/packaging/views.py:352
817+
#: warehouse/packaging/views.py:353
818818
msgid "Your report has been recorded. Thank you for your help."
819819
msgstr ""
820820

warehouse/macaroons/services.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# limitations under the License.
1212

1313
import datetime
14+
import typing
1415
import uuid
1516

1617
import pymacaroons
@@ -170,9 +171,10 @@ def create_macaroon(
170171
# NOTE: This is a bit of a hack: we keep a separate copy of the
171172
# permissions caveat in the DB, so that we can display scope information
172173
# in the UI.
173-
permissions = {}
174+
permissions: dict[str, list[str]] | str = {}
174175
for caveat in scopes:
175176
if isinstance(caveat, caveats.ProjectName):
177+
permissions = typing.cast(dict[str, list[str]], permissions)
176178
projects = permissions.setdefault("projects", [])
177179
projects.extend(caveat.normalized_names)
178180
elif isinstance(caveat, caveats.RequestUser):

warehouse/manage/views/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,8 @@ def create_macaroon(self):
949949

950950
response = {**self.default_response}
951951
if form.validate():
952+
macaroon_caveats: list[caveats.Caveat]
953+
952954
if form.validated_scope == "user":
953955
recorded_caveats = [{"permissions": form.validated_scope, "version": 1}]
954956
macaroon_caveats = [
@@ -2219,7 +2221,7 @@ def manage_project_releases(project, request):
22192221
# }
22202222
# }
22212223

2222-
version_to_file_counts = {}
2224+
version_to_file_counts: dict[str, dict[str, int]] = {}
22232225
for version, packagetype, count in filecounts:
22242226
packagetype_to_count = version_to_file_counts.setdefault(version, {})
22252227
packagetype_to_count.setdefault("total", 0)

0 commit comments

Comments
 (0)