Skip to content

Commit 5919704

Browse files
committed
Fix typing warnings
- and enable failOnWarnings for basedpyright
1 parent 61a5ceb commit 5919704

File tree

4 files changed

+50
-41
lines changed

4 files changed

+50
-41
lines changed

orgs/org_management/org_management.py

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import os
1111
import re
1212
from pathlib import Path
13-
from typing import Any, final, override
13+
from typing import Any, TextIO, final, override
1414

1515
import jsonschema
1616
import yaml
@@ -22,10 +22,10 @@
2222
# https://yaml.org/spec/1.2.2/ requires unique keys
2323
class UniqueKeyLoader(yaml.SafeLoader):
2424
@override
25-
def construct_mapping(self, node, deep=False):
26-
mapping = set()
25+
def construct_mapping(self, node: Any, deep: bool = False):
26+
mapping = set[str]()
2727
for key_node, _ in node.value:
28-
key = self.construct_object(key_node, deep=deep)
28+
key: str = str(self.construct_object(key_node, deep=deep)) # pyright: ignore[reportUnknownMemberType, reportUnknownArgumentType]
2929
if key in mapping:
3030
raise yaml.MarkedYAMLError(f"Duplicate key {key!r} found.", key_node.start_mark)
3131
mapping.add(key)
@@ -47,10 +47,12 @@ def __init__(
4747
working_groups: list[str] | None = None,
4848
branch_protection: str | None = None,
4949
):
50-
self.org_cfg = OrgGenerator._validate_github_org_cfg(OrgGenerator._yaml_load(static_org_cfg)) if static_org_cfg else {"orgs": {}}
50+
self.org_cfg: dict[str, Any] = (
51+
OrgGenerator._validate_github_org_cfg(OrgGenerator._yaml_load(static_org_cfg)) if static_org_cfg else {"orgs": {}}
52+
)
5153
self.contributors = dict[str, set[str]]()
52-
self.working_groups = {}
53-
self.branch_protection = (
54+
self.working_groups: dict[str, Any] = {}
55+
self.branch_protection: dict[str, Any] = (
5456
OrgGenerator._validate_branch_protection(OrgGenerator._yaml_load(branch_protection))
5557
if branch_protection
5658
else {"branch-protection": {"orgs": {}}}
@@ -218,7 +220,7 @@ def write_branch_protection(self, path: str):
218220
return yaml.safe_dump(self.branch_protection, stream)
219221

220222
@staticmethod
221-
def _yaml_load(stream) -> dict[str, Any]:
223+
def _yaml_load(stream: TextIO | str) -> dict[str, Any]:
222224
# safe_load + reject unique keys
223225
return yaml.load(stream, UniqueKeyLoader)
224226

@@ -247,7 +249,7 @@ def _extract_wg_config(wg_charter: str):
247249
return OrgGenerator._validate_wg(OrgGenerator._yaml_load(match.group(1))) if match else None
248250

249251
@staticmethod
250-
def _empty_wg_config(name: str):
252+
def _empty_wg_config(name: str) -> dict[str, Any]:
251253
return {
252254
"name": name,
253255
"org": OrgGenerator._DEFAULT_ORG,
@@ -258,7 +260,7 @@ def _empty_wg_config(name: str):
258260
}
259261

260262
@staticmethod
261-
def _wg_github_users(wg) -> set[str]:
263+
def _wg_github_users(wg: dict[str, Any]) -> set[str]:
262264
users = {u["github"] for u in wg["execution_leads"]}
263265
users |= {u["github"] for u in wg["technical_leads"]}
264266
users |= {u["github"] for u in wg["bots"]}
@@ -271,7 +273,7 @@ def _wg_github_users(wg) -> set[str]:
271273
return users
272274

273275
@staticmethod
274-
def _wg_github_users_leads(wg) -> set[str]:
276+
def _wg_github_users_leads(wg: dict[str, Any]) -> set[str]:
275277
users = {u["github"] for u in wg["execution_leads"]}
276278
users |= {u["github"] for u in wg["technical_leads"]}
277279
return users
@@ -297,7 +299,7 @@ def _wg_github_users_leads(wg) -> set[str]:
297299
}
298300

299301
@staticmethod
300-
def _validate_contributors(contributors) -> dict[str, Any]:
302+
def _validate_contributors(contributors: dict[str, Any]) -> dict[str, Any]:
301303
jsonschema.validate(contributors, OrgGenerator._CONTRIBUTORS_SCHEMA)
302304
# check that orgs are in _ORGS
303305
for org in contributors["orgs"]:
@@ -343,7 +345,7 @@ def _validate_contributors(contributors) -> dict[str, Any]:
343345
}
344346

345347
@staticmethod
346-
def _validate_wg(wg) -> dict[str, Any]:
348+
def _validate_wg(wg: dict[str, Any]) -> dict[str, Any]:
347349
jsonschema.validate(wg, OrgGenerator._WG_SCHEMA)
348350
# validate org and use 'cloudfoundry' if missing
349351
if "org" not in wg:
@@ -375,7 +377,7 @@ def _validate_wg(wg) -> dict[str, Any]:
375377
}
376378

377379
@staticmethod
378-
def _validate_github_org_cfg(cfg):
380+
def _validate_github_org_cfg(cfg: dict[str, Any]) -> dict[str, Any]:
379381
jsonschema.validate(cfg, OrgGenerator._GITHUB_ORG_CFG_SCHEMA)
380382
# check that orgs are in _ORGS
381383
for org in cfg["orgs"]:
@@ -410,7 +412,7 @@ def _validate_github_org_cfg(cfg):
410412
}
411413

412414
@staticmethod
413-
def _validate_branch_protection(cfg):
415+
def _validate_branch_protection(cfg: dict[str, Any]) -> dict[str, Any]:
414416
jsonschema.validate(cfg, OrgGenerator._BRANCH_PROTECTION_SCHEMA)
415417
# check that orgs are in _ORGS
416418
for org in cfg["branch-protection"]["orgs"]:
@@ -420,7 +422,7 @@ def _validate_branch_protection(cfg):
420422

421423
# https://github.com/cloudfoundry/community/blob/main/toc/rfc/rfc-0005-github-teams-and-access.md
422424
@staticmethod
423-
def _generate_wg_teams(wg) -> tuple[str, dict[str, Any]]:
425+
def _generate_wg_teams(wg: dict[str, Any]) -> tuple[str, dict[str, Any]]:
424426
org = wg["org"]
425427
org_prefix = org + "/"
426428
org_prefix_len = len(org_prefix)
@@ -489,7 +491,7 @@ def _generate_wg_teams(wg) -> tuple[str, dict[str, Any]]:
489491
return (name, team)
490492

491493
@staticmethod
492-
def _generate_toc_team(wg) -> tuple[str, dict[str, Any]]:
494+
def _generate_toc_team(wg: dict[str, Any]) -> tuple[str, dict[str, Any]]:
493495
org = wg["org"]
494496
org_prefix = org + "/"
495497
org_prefix_len = len(org_prefix)
@@ -504,7 +506,7 @@ def _generate_toc_team(wg) -> tuple[str, dict[str, Any]]:
504506
return ("toc", team)
505507

506508
@staticmethod
507-
def _generate_wg_leads_team(wgs: list[Any]) -> tuple[str, dict[str, Any]]:
509+
def _generate_wg_leads_team(wgs: list[dict[str, Any]]) -> tuple[str, dict[str, Any]]:
508510
members = {u for wg in wgs for u in OrgGenerator._wg_github_users_leads(wg)}
509511
team = {
510512
"description": "Technical and Execution Leads for all WGs",
@@ -515,7 +517,7 @@ def _generate_wg_leads_team(wgs: list[Any]) -> tuple[str, dict[str, Any]]:
515517

516518
# https://github.com/cloudfoundry/community/blob/main/toc/rfc/rfc-0015-branch-protection.md
517519
# returns hash with branch protection rules per repo
518-
def _generate_wg_branch_protection(self, wg) -> dict[str, Any]:
520+
def _generate_wg_branch_protection(self, wg: dict[str, Any]) -> dict[str, Any]:
519521
org = wg["org"]
520522
org_prefix = org + "/"
521523
org_prefix_len = len(org_prefix)

orgs/org_management/org_user_management.py

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import os
44
import uuid
55
from pathlib import Path
6-
from typing import final
6+
from typing import Any, final
77

88
import requests
99
import yaml
@@ -30,17 +30,17 @@ def __init__(
3030
def _get_request_headrs(self):
3131
return {"Authorization": f"Bearer {self.github_token}"}
3232

33-
def _process_request_result(self, request):
33+
def _process_request_result(self, request: requests.Response):
3434
if request.status_code == 200 or request.status_code == 201:
3535
return request.json()
3636
else:
3737
raise Exception(f"Request execution failed with status code of {request.status_code}. {request.status_code}")
3838

39-
def _execute_query(self, query):
39+
def _execute_query(self, query: str):
4040
request = requests.post("https://api.github.com/graphql", json={"query": query}, headers=self._get_request_headrs())
4141
return self._process_request_result(request)
4242

43-
def _build_query(self, after_cursor_value=None):
43+
def _build_query(self, after_cursor_value: Any):
4444
after_cursor = f'"{after_cursor_value}"' if after_cursor_value else "null"
4545
query = (
4646
"""
@@ -70,10 +70,10 @@ def _build_query(self, after_cursor_value=None):
7070
)
7171
return query
7272

73-
def get_inactive_users(self):
74-
inactive_users = set()
73+
def get_inactive_users(self) -> set[str]:
74+
inactive_users = set[str]()
7575
has_next_page = True
76-
after_cursor_value = None
76+
after_cursor_value: Any = None
7777
while has_next_page:
7878
result = self._execute_query(self._build_query(after_cursor_value))
7979
for user_node in result["data"]["organization"]["membersWithRole"]["nodes"]:
@@ -89,31 +89,31 @@ def get_inactive_users(self):
8989

9090
return inactive_users
9191

92-
def _load_yaml_file(self, path):
92+
def _load_yaml_file(self, path: Path) -> dict[str, Any]:
9393
with open(path) as stream:
9494
return yaml.safe_load(stream)
9595

96-
def _write_yaml_file(self, path, data):
96+
def _write_yaml_file(self, path: Path, data: dict[str, Any]):
9797
with open(path, "w") as f:
9898
yaml.dump(data, f)
9999

100-
def _get_inactive_users_msg_for_wgs(self, inactive_users_by_wg, user_tagging_prefix):
100+
def _get_inactive_users_msg_for_wgs(self, inactive_users_by_wg: dict[str, set[str]], user_tagging_prefix: str) -> str:
101101
result = "\n\nWarning:\n" if inactive_users_by_wg else ""
102102
for wg, users in inactive_users_by_wg.items():
103103
wg_users_as_list = "\n".join(str(user_tagging_prefix + s) for s in users)
104104
result += f'Inactive users of Working Group "{wg}" are: \n{wg_users_as_list}\n'
105105
return result
106106

107-
def delete_inactive_contributors(self, users_to_delete):
108-
path = f"{_SCRIPT_PATH}/contributors.yml"
107+
def delete_inactive_contributors(self, users_to_delete: set[str]):
108+
path = _SCRIPT_PATH / "contributors.yml"
109109
contributors_yaml = self._load_yaml_file(path)
110-
users_to_delete_lower = [user.lower() for user in users_to_delete]
110+
users_to_delete_lower = {user.lower() for user in users_to_delete}
111111
contributors_yaml["orgs"][self.github_org]["contributors"] = [
112112
c for c in contributors_yaml["orgs"][self.github_org]["contributors"] if c.lower() not in users_to_delete_lower
113113
]
114114
self._write_yaml_file(path, contributors_yaml)
115115

116-
def get_inactive_users_msg(self, users_to_delete, inactive_users_by_wg, tagusers):
116+
def get_inactive_users_msg(self, users_to_delete: set[str], inactive_users_by_wg: dict[str, set[str]], tagusers: bool) -> str:
117117
rfc = (
118118
"https://github.com/cloudfoundry/community/blob/main/toc/rfc/"
119119
"rfc-0025-define-criteria-and-removal-process-for-inactive-members.md"
@@ -137,17 +137,19 @@ def get_inactive_users_msg(self, users_to_delete, inactive_users_by_wg, tagusers
137137
f"{self._get_inactive_users_msg_for_wgs(inactive_users_by_wg, user_tagging_prefix)}"
138138
)
139139

140-
def get_inactive_users_by_wg(self, inactive_users, community_members_with_role_by_wg):
141-
result = dict()
140+
def get_inactive_users_by_wg(
141+
self, inactive_users: set[str], community_members_with_role_by_wg: dict[str, set[str]]
142+
) -> dict[str, set[str]]:
143+
result = dict[str, set[str]]()
142144
for wg, members in community_members_with_role_by_wg.items():
143145
wg_inactive_members = inactive_users.intersection(members)
144146
if len(wg_inactive_members) != 0 and wg != "Admin":
145147
result[wg] = wg_inactive_members
146148
return result
147149

148150
@staticmethod
149-
def _get_bool_env_var(env_var_name, default):
150-
return os.getenv(env_var_name, default).lower() == "true"
151+
def get_bool_env_var(env_var_name: str, default: bool) -> bool:
152+
return os.getenv(env_var_name, str(default)).lower() == "true"
151153

152154

153155
if __name__ == "__main__":
@@ -178,7 +180,7 @@ def _get_bool_env_var(env_var_name, default):
178180
generator = OrgGenerator()
179181
generator.load_from_project()
180182
community_members_with_role_by_wg = generator.get_community_members_with_role_by_wg(args.githuborg)
181-
community_members_with_role = set()
183+
community_members_with_role = set[str]()
182184
for members in community_members_with_role_by_wg.values():
183185
community_members_with_role |= set(members)
184186

@@ -188,11 +190,11 @@ def _get_bool_env_var(env_var_name, default):
188190

189191
print(f"Inactive users length is {len(inactive_users)} and inactive users are {inactive_users}")
190192
users_to_delete = inactive_users - community_members_with_role
191-
tagusers = args.tagusers or InactiveUserHandler._get_bool_env_var("INACTIVE_USER_MANAGEMENT_TAG_USERS", "False")
193+
tagusers = args.tagusers or InactiveUserHandler.get_bool_env_var("INACTIVE_USER_MANAGEMENT_TAG_USERS", False)
192194
inactive_users_by_wg = userHandler.get_inactive_users_by_wg(inactive_users, community_members_with_role_by_wg)
193195
inactive_users_msg = userHandler.get_inactive_users_msg(users_to_delete, inactive_users_by_wg, tagusers)
194196
print(f"Inactive users by wg are {inactive_users_by_wg}")
195-
if args.dryrun or InactiveUserHandler._get_bool_env_var("INACTIVE_USER_MANAGEMENT_DRY_RUN", "False"):
197+
if args.dryrun or InactiveUserHandler.get_bool_env_var("INACTIVE_USER_MANAGEMENT_DRY_RUN", False):
196198
print(f"Dry-run mode.\nInactive_users_msg is: {inactive_users_msg}")
197199
print(f"Following users will be deleted: {inactive_users}")
198200
elif users_to_delete:

orgs/org_management/test_org_management.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import unittest
2+
from typing import final, override
23

34
import jsonschema
45
import yaml
56

67
from .org_management import OrgGenerator
78

9+
# pyright: reportPrivateUsage=false
10+
811
org_cfg = """
912
---
1013
orgs:
@@ -278,7 +281,9 @@
278281
"""
279282

280283

284+
@final
281285
class TestOrgGenerator(unittest.TestCase):
286+
@override
282287
def setUp(self) -> None:
283288
OrgGenerator._MANAGED_ORGS = ["cloudfoundry"]
284289

orgs/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ include = ["org_management"]
7474
# By default BasedPyright is very strict, so you almost certainly want to disable
7575
# some of the rules.
7676
# First, these turn off warnings about (yes) how you ignore warnings:
77-
failOnWarnings = false
77+
# failOnWarnings = false
7878
enableTypeIgnoreComments = true
7979
# reportIgnoreCommentWithoutRule = false
8080
# reportUnnecessaryTypeIgnoreComment = false

0 commit comments

Comments
 (0)