envoy.code.check 0.5.13__tar.gz → 0.5.14__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/PKG-INFO +1 -1
  2. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/backend_shim.py +9 -2
  3. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/base.py +9 -8
  4. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/changelog.py +14 -14
  5. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/checker.py +46 -22
  6. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/extensions.py +20 -22
  7. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/flake8.py +16 -17
  8. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/glint.py +22 -17
  9. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/gofmt.py +6 -6
  10. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/rst.py +5 -5
  11. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/runtime_guards.py +8 -8
  12. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/shellcheck.py +18 -14
  13. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/yamllint.py +12 -15
  14. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/yapf.py +8 -8
  15. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/checker.py +4 -5
  16. envoy.code.check-0.5.14/envoy/code/check/exceptions.py +12 -0
  17. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/interface.py +28 -28
  18. envoy.code.check-0.5.14/envoy/code/check/typing.py +55 -0
  19. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy.code.check.egg-info/PKG-INFO +1 -1
  20. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy.code.check.egg-info/requires.txt +3 -2
  21. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/setup.py +4 -3
  22. envoy.code.check-0.5.13/envoy/code/check/exceptions.py +0 -8
  23. envoy.code.check-0.5.13/envoy/code/check/typing.py +0 -54
  24. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/MANIFEST.in +0 -0
  25. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/__init__.py +0 -0
  26. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/abstract/__init__.py +0 -0
  27. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/cmd.py +0 -0
  28. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy/code/check/py.typed +0 -0
  29. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy.code.check.egg-info/SOURCES.txt +0 -0
  30. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy.code.check.egg-info/dependency_links.txt +0 -0
  31. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy.code.check.egg-info/entry_points.txt +0 -0
  32. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy.code.check.egg-info/namespace_packages.txt +0 -0
  33. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/envoy.code.check.egg-info/top_level.txt +0 -0
  34. {envoy.code.check-0.5.13 → envoy.code.check-0.5.14}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: envoy.code.check
3
- Version: 0.5.13
3
+ Version: 0.5.14
4
4
  Summary: "Code checker used in Envoy proxy's CI"
5
5
  Home-page: https://github.com/envoyproxy/toolshed/tree/main/envoy.code.check
6
6
  Author: Ryan Northey
@@ -1,12 +1,13 @@
1
1
 
2
2
  # DO NOT EDIT THIS FILE -- AUTOGENERATED BY PANTS
3
3
 
4
+ import errno
4
5
  import os
5
6
  import setuptools.build_meta
6
7
 
7
8
  backend = setuptools.build_meta.__legacy__
8
9
 
9
- dist_dir = "dist"
10
+ dist_dir = "dist/"
10
11
  build_wheel = True
11
12
  build_sdist = True
12
13
  wheel_config_settings = {
@@ -14,7 +15,13 @@ wheel_config_settings = {
14
15
  sdist_config_settings = {
15
16
  }
16
17
 
17
- os.makedirs(dist_dir, exist_ok=True)
18
+ # Python 2.7 doesn't have the exist_ok arg on os.makedirs().
19
+ try:
20
+ os.makedirs(dist_dir)
21
+ except OSError as e:
22
+ if e.errno != errno.EEXIST:
23
+ raise
24
+
18
25
  wheel_path = backend.build_wheel(dist_dir, wheel_config_settings) if build_wheel else None
19
26
  sdist_path = backend.build_sdist(dist_dir, sdist_config_settings) if build_sdist else None
20
27
 
@@ -1,7 +1,6 @@
1
1
 
2
2
  import asyncio
3
3
  from concurrent import futures
4
- from typing import Dict, List, Optional, Set
5
4
 
6
5
  import abstracts
7
6
 
@@ -10,7 +9,7 @@ from aio.core.directory import ADirectory
10
9
  from aio.core.functional import async_property
11
10
 
12
11
  from envoy.base import utils
13
- from envoy.code.check import interface
12
+ from envoy.code.check import interface, typing
14
13
 
15
14
 
16
15
  @abstracts.implementer(event.IExecutive)
@@ -20,10 +19,12 @@ class ACodeCheck(event.AExecutive, metaclass=abstracts.Abstraction):
20
19
  self,
21
20
  directory: ADirectory,
22
21
  fix: bool = False,
23
- binaries: Optional[Dict[str, str]] = None,
24
- loop: Optional[asyncio.AbstractEventLoop] = None,
25
- pool: Optional[futures.Executor] = None) -> None:
22
+ binaries: dict[str, str] | None = None,
23
+ config: typing.YAMLConfigDict | None = None,
24
+ loop: asyncio.AbstractEventLoop | None = None,
25
+ pool: futures.Executor | None = None) -> None:
26
26
  self.directory = directory
27
+ self.config = config
27
28
  self._fix = fix
28
29
  self._loop = loop
29
30
  self._pool = pool
@@ -39,11 +40,11 @@ class AFileCodeCheck(ACodeCheck, metaclass=abstracts.Abstraction):
39
40
 
40
41
  @async_property
41
42
  @abstracts.interfacemethod
42
- async def checker_files(self) -> Set[str]:
43
+ async def checker_files(self) -> set[str]:
43
44
  raise NotImplementedError
44
45
 
45
46
  @async_property(cache=True)
46
- async def files(self) -> Set[str]:
47
+ async def files(self) -> set[str]:
47
48
  files = await self.directory.files
48
49
  return (
49
50
  files & await self.checker_files
@@ -56,7 +57,7 @@ class AFileCodeCheck(ACodeCheck, metaclass=abstracts.Abstraction):
56
57
 
57
58
  @async_property
58
59
  @abstracts.interfacemethod
59
- async def problem_files(self) -> Dict[str, List[str]]:
60
+ async def problem_files(self) -> dict[str, list[str]]:
60
61
  """Discovered files with flake8 errors."""
61
62
  raise NotImplementedError
62
63
 
@@ -2,7 +2,7 @@
2
2
  import itertools
3
3
  from datetime import datetime
4
4
  from functools import cached_property
5
- from typing import Iterator, Optional, Tuple, Type
5
+ from typing import Iterator
6
6
 
7
7
  from packaging import version as _version
8
8
 
@@ -30,7 +30,7 @@ class AChangelogChangesChecker(metaclass=abstracts.Abstraction):
30
30
 
31
31
  @property # type:ignore
32
32
  @abstracts.interfacemethod
33
- def change_checkers(self) -> Tuple[interface.IRSTCheck, ...]:
33
+ def change_checkers(self) -> tuple[interface.IRSTCheck, ...]:
34
34
  raise NotImplementedError
35
35
 
36
36
  @cached_property
@@ -41,7 +41,7 @@ class AChangelogChangesChecker(metaclass=abstracts.Abstraction):
41
41
  self,
42
42
  version: _version.Version,
43
43
  section: str,
44
- entry: utils.typing.ChangeDict) -> Tuple[str, ...]:
44
+ entry: utils.typing.ChangeDict) -> tuple[str, ...]:
45
45
  change = entry["change"].strip()
46
46
  errors = [
47
47
  checker(change)
@@ -61,7 +61,7 @@ class AChangelogChangesChecker(metaclass=abstracts.Abstraction):
61
61
  self,
62
62
  version: _version.Version,
63
63
  section: str,
64
- data: Optional[utils.typing.ChangeList]) -> Tuple[str, ...]:
64
+ data: utils.typing.ChangeList | None) -> tuple[str, ...]:
65
65
  name_error = self.check_section_name(version, section)
66
66
  return (
67
67
  *((name_error, )
@@ -76,7 +76,7 @@ class AChangelogChangesChecker(metaclass=abstracts.Abstraction):
76
76
  self,
77
77
  version: _version.Version,
78
78
  sections: utils.typing.ChangelogChangeSectionsDict) -> (
79
- Tuple[str, ...]):
79
+ tuple[str, ...]):
80
80
  return tuple(
81
81
  itertools.chain.from_iterable(
82
82
  self.check_section(version, section, data) # type:ignore
@@ -86,7 +86,7 @@ class AChangelogChangesChecker(metaclass=abstracts.Abstraction):
86
86
  def check_section_name(
87
87
  self,
88
88
  version: _version.Version,
89
- section: str) -> Optional[str]:
89
+ section: str) -> str | None:
90
90
  invalid_changes = (
91
91
  section == "changes"
92
92
  and version > self.max_version_for_changes_section)
@@ -137,7 +137,7 @@ class AChangelogStatus(metaclass=abstracts.Abstraction):
137
137
  self.version).exists())
138
138
 
139
139
  @async_property(cache=True)
140
- async def errors(self) -> Tuple[str, ...]:
140
+ async def errors(self) -> tuple[str, ...]:
141
141
  try:
142
142
  return (
143
143
  *self.check_version(),
@@ -147,7 +147,7 @@ class AChangelogStatus(metaclass=abstracts.Abstraction):
147
147
  return (f"{self.version}: {e}", )
148
148
 
149
149
  @async_property
150
- async def invalid_date(self) -> Optional[str]:
150
+ async def invalid_date(self) -> str | None:
151
151
  if await self.is_pending:
152
152
  return None
153
153
  date = await self.date
@@ -194,7 +194,7 @@ class AChangelogStatus(metaclass=abstracts.Abstraction):
194
194
  self.version
195
195
  > _version.Version(self.project.version.base_version))
196
196
 
197
- async def check_date(self) -> Tuple[str, ...]:
197
+ async def check_date(self) -> tuple[str, ...]:
198
198
  errors = []
199
199
  if invalid_date := await self.invalid_date:
200
200
  errors.append(f"Format not recognized \"{invalid_date}\"")
@@ -207,7 +207,7 @@ class AChangelogStatus(metaclass=abstracts.Abstraction):
207
207
  for e
208
208
  in errors)
209
209
 
210
- async def check_sections(self) -> Tuple[str, ...]:
210
+ async def check_sections(self) -> tuple[str, ...]:
211
211
  # Runs checker in executor, uncomment following line for debugging
212
212
  # return self.checker.check_sections(self.version, await self.sections)
213
213
  return await self.project.execute(
@@ -215,7 +215,7 @@ class AChangelogStatus(metaclass=abstracts.Abstraction):
215
215
  self.version,
216
216
  await self.sections)
217
217
 
218
- def check_version(self) -> Tuple[str, ...]:
218
+ def check_version(self) -> tuple[str, ...]:
219
219
  errors = []
220
220
  if self.duplicate_current:
221
221
  errors.append(
@@ -245,7 +245,7 @@ class AChangelogCheck(
245
245
  @property # type:ignore
246
246
  @abstracts.interfacemethod
247
247
  def changes_checker_class(
248
- self) -> Type[interface.IChangelogChangesChecker]:
248
+ self) -> type[interface.IChangelogChangesChecker]:
249
249
  raise NotImplementedError
250
250
 
251
251
  @cached_property
@@ -255,11 +255,11 @@ class AChangelogCheck(
255
255
 
256
256
  @property # type:ignore
257
257
  @abstracts.interfacemethod
258
- def changelog_status_class(self) -> Type[interface.IChangelogStatus]:
258
+ def changelog_status_class(self) -> type[interface.IChangelogStatus]:
259
259
  raise NotImplementedError
260
260
 
261
261
  @cached_property
262
- def changelogs(self) -> Tuple[interface.IChangelogStatus, ...]:
262
+ def changelogs(self) -> tuple[interface.IChangelogStatus, ...]:
263
263
  return tuple(
264
264
  self.changelog_status_class(self, changelog)
265
265
  for changelog
@@ -5,7 +5,9 @@ import argparse
5
5
  import pathlib
6
6
  import re
7
7
  from functools import cached_property
8
- from typing import Dict, Mapping, Optional, Pattern, Set, Type
8
+ from typing import Mapping, Pattern
9
+
10
+ import yaml
9
11
 
10
12
  from yamllint.config import YamlLintConfigError # type:ignore
11
13
 
@@ -73,7 +75,7 @@ class ACodeChecker(
73
75
  return self.args.all_files
74
76
 
75
77
  @cached_property
76
- def binaries(self) -> Dict[str, str]:
78
+ def binaries(self) -> dict[str, str]:
77
79
  return dict(
78
80
  binary.split(":")
79
81
  for binary
@@ -91,7 +93,7 @@ class ACodeChecker(
91
93
  return disabled
92
94
 
93
95
  @property
94
- def changed_since(self) -> Optional[str]:
96
+ def changed_since(self) -> str | None:
95
97
  return self.args.since
96
98
 
97
99
  @cached_property
@@ -103,7 +105,7 @@ class ACodeChecker(
103
105
 
104
106
  @property # type:ignore
105
107
  @abstracts.interfacemethod
106
- def changelog_class(self) -> Type["interface.IChangelogCheck"]:
108
+ def changelog_class(self) -> type["interface.IChangelogCheck"]:
107
109
  raise NotImplementedError
108
110
 
109
111
  @cached_property
@@ -114,6 +116,23 @@ class ACodeChecker(
114
116
  loop=self.loop,
115
117
  pool=self.pool)
116
118
 
119
+ @cached_property
120
+ def config(self) -> typing.YAMLConfigDict:
121
+ return (
122
+ yaml.safe_load(self.config_path.read_text())
123
+ if self.config_path
124
+ else {})
125
+
126
+ @property
127
+ def config_path(self) -> pathlib.Path | None:
128
+ if not self.args.config:
129
+ return None
130
+ path = pathlib.Path(self.args.config)
131
+ if not path.exists():
132
+ raise exceptions.ConfigurationError(
133
+ f"Config specified but not found: {path}")
134
+ return path
135
+
117
136
  @cached_property
118
137
  def directory(self) -> "_directory.ADirectory":
119
138
  """Greppable directory - optionally in a git repo, depending on whether
@@ -122,8 +141,8 @@ class ACodeChecker(
122
141
  return self.project.directory.filtered(**self.directory_kwargs)
123
142
 
124
143
  @property
125
- def directory_kwargs(self) -> Dict:
126
- kwargs: Dict = dict(
144
+ def directory_kwargs(self) -> dict:
145
+ kwargs: dict = dict(
127
146
  exclude_matcher=self.grep_excluding_re,
128
147
  path_matcher=self.grep_matching_re,
129
148
  untracked=self.all_files)
@@ -144,7 +163,7 @@ class ACodeChecker(
144
163
 
145
164
  @property # type:ignore
146
165
  @abstracts.interfacemethod
147
- def extensions_class(self) -> Type["interface.IExtensionsCheck"]:
166
+ def extensions_class(self) -> type["interface.IExtensionsCheck"]:
148
167
  raise NotImplementedError
149
168
 
150
169
  @cached_property
@@ -154,17 +173,17 @@ class ACodeChecker(
154
173
 
155
174
  @property # type:ignore
156
175
  @abstracts.interfacemethod
157
- def flake8_class(self) -> Type["interface.IFlake8Check"]:
176
+ def flake8_class(self) -> type["interface.IFlake8Check"]:
158
177
  raise NotImplementedError
159
178
 
160
179
  @property # type:ignore
161
180
  @abstracts.interfacemethod
162
- def fs_directory_class(self) -> Type["_directory.ADirectory"]:
181
+ def fs_directory_class(self) -> type["_directory.ADirectory"]:
163
182
  raise NotImplementedError
164
183
 
165
184
  @property # type:ignore
166
185
  @abstracts.interfacemethod
167
- def git_directory_class(self) -> Type["_directory.AGitDirectory"]:
186
+ def git_directory_class(self) -> type["_directory.AGitDirectory"]:
168
187
  raise NotImplementedError
169
188
 
170
189
  @cached_property
@@ -174,7 +193,7 @@ class ACodeChecker(
174
193
 
175
194
  @property # type:ignore
176
195
  @abstracts.interfacemethod
177
- def glint_class(self) -> Type["interface.IGlintCheck"]:
196
+ def glint_class(self) -> type["interface.IGlintCheck"]:
178
197
  raise NotImplementedError
179
198
 
180
199
  @cached_property
@@ -184,15 +203,15 @@ class ACodeChecker(
184
203
 
185
204
  @property # type:ignore
186
205
  @abstracts.interfacemethod
187
- def gofmt_class(self) -> Type["interface.IGofmtCheck"]:
206
+ def gofmt_class(self) -> type["interface.IGofmtCheck"]:
188
207
  raise NotImplementedError
189
208
 
190
209
  @property
191
- def grep_excluding_re(self) -> Optional[Pattern[str]]:
210
+ def grep_excluding_re(self) -> Pattern[str] | None:
192
211
  return self._grep_re(self.args.excluding)
193
212
 
194
213
  @property
195
- def grep_matching_re(self) -> Optional[Pattern[str]]:
214
+ def grep_matching_re(self) -> Pattern[str] | None:
196
215
  return self._grep_re(self.args.matching)
197
216
 
198
217
  @property
@@ -206,7 +225,7 @@ class ACodeChecker(
206
225
 
207
226
  @property # type:ignore
208
227
  @abstracts.interfacemethod
209
- def project_class(self) -> Type[IProject]:
228
+ def project_class(self) -> type[IProject]:
210
229
  raise NotImplementedError
211
230
 
212
231
  @cached_property
@@ -218,7 +237,7 @@ class ACodeChecker(
218
237
 
219
238
  @property # type:ignore
220
239
  @abstracts.interfacemethod
221
- def runtime_guards_class(self) -> Type["interface.IRuntimeGuardsCheck"]:
240
+ def runtime_guards_class(self) -> type["interface.IRuntimeGuardsCheck"]:
222
241
  raise NotImplementedError
223
242
 
224
243
  @cached_property
@@ -228,11 +247,11 @@ class ACodeChecker(
228
247
 
229
248
  @property # type:ignore
230
249
  @abstracts.interfacemethod
231
- def shellcheck_class(self) -> Type["interface.IShellcheckCheck"]:
250
+ def shellcheck_class(self) -> type["interface.IShellcheckCheck"]:
232
251
  raise NotImplementedError
233
252
 
234
253
  @property
235
- def summary_class(self) -> Type[CodeCheckerSummary]:
254
+ def summary_class(self) -> type[CodeCheckerSummary]:
236
255
  """CodeChecker's summary class."""
237
256
  return CodeCheckerSummary
238
257
 
@@ -243,7 +262,7 @@ class ACodeChecker(
243
262
 
244
263
  @property # type:ignore
245
264
  @abstracts.interfacemethod
246
- def yamllint_class(self) -> Type[interface.IYamllintCheck]:
265
+ def yamllint_class(self) -> type[interface.IYamllintCheck]:
247
266
  raise NotImplementedError
248
267
 
249
268
  @cached_property
@@ -253,7 +272,7 @@ class ACodeChecker(
253
272
 
254
273
  @property # type:ignore
255
274
  @abstracts.interfacemethod
256
- def yapf_class(self) -> Type[interface.IYapfCheck]:
275
+ def yapf_class(self) -> type[interface.IYapfCheck]:
257
276
  raise NotImplementedError
258
277
 
259
278
  def add_arguments(self, parser: argparse.ArgumentParser) -> None:
@@ -263,6 +282,11 @@ class ACodeChecker(
263
282
  parser.add_argument("-x", "--excluding", action="append")
264
283
  parser.add_argument("-b", "--binary", action="append")
265
284
  parser.add_argument("-s", "--since")
285
+ parser.add_argument(
286
+ "--config",
287
+ default="./tools/code/config.yaml",
288
+ help=("specify the config path. "
289
+ "Default './tools/code/config.yaml'."))
266
290
  parser.add_argument("--codeowners")
267
291
  parser.add_argument("--owners")
268
292
  parser.add_argument("--extensions_build_config")
@@ -427,7 +451,7 @@ class ACodeChecker(
427
451
 
428
452
  def _check_output(
429
453
  self,
430
- check_files: Set[str],
454
+ check_files: set[str],
431
455
  problem_files: typing.ProblemDict) -> None:
432
456
  # This can be slow/blocking for large result sets, run
433
457
  # in a separate thread
@@ -453,7 +477,7 @@ class ACodeChecker(
453
477
  await check.files,
454
478
  await check.problem_files)
455
479
 
456
- def _grep_re(self, arg: Optional[str]) -> Optional[Pattern[str]]:
480
+ def _grep_re(self, arg: str | None) -> Pattern[str] | None:
457
481
  # When using system `grep` we want to filter out at least some
458
482
  # of the files that .gitignore would.
459
483
  # TODO: use globs on cli and covert to re here
@@ -6,9 +6,7 @@ import logging
6
6
  import pathlib
7
7
  import re
8
8
  from functools import cached_property
9
- from typing import (
10
- Any, cast, Dict, List,
11
- Optional, Pattern, Set, Tuple, Type, Union)
9
+ from typing import Any, cast, Pattern
12
10
 
13
11
  import yaml as _yaml
14
12
 
@@ -60,7 +58,7 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
60
58
  super().__init__(*args, **kwargs)
61
59
 
62
60
  @cached_property
63
- def all_extensions(self) -> Set[str]:
61
+ def all_extensions(self) -> set[str]:
64
62
  return (
65
63
  set(self.configured_extensions)
66
64
  | set(self.builtin_extensions))
@@ -143,7 +141,7 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
143
141
  return self.directory.path.joinpath(FUZZ_TEST_PATH)
144
142
 
145
143
  @property
146
- def fuzzed_count(self) -> Optional[int]:
144
+ def fuzzed_count(self) -> int | None:
147
145
  # TODO: shift this to the arg parse
148
146
  return (
149
147
  int(self._fuzzed_count)
@@ -186,27 +184,27 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
186
184
  return self.directory.path.joinpath(METADATA_PATH)
187
185
 
188
186
  @async_property
189
- async def metadata_errors(self) -> Dict[str, Tuple[str, ...]]:
187
+ async def metadata_errors(self) -> dict[str, tuple[str, ...]]:
190
188
  return {
191
189
  extension: await self.check_metadata(extension)
192
190
  for extension
193
191
  in await self.metadata}
194
192
 
195
193
  @async_property
196
- async def metadata_missing(self) -> Set[str]:
194
+ async def metadata_missing(self) -> set[str]:
197
195
  return (
198
196
  self.all_extensions
199
197
  - set(await self.metadata))
200
198
 
201
199
  @async_property
202
- async def metadata_only(self) -> Set[str]:
200
+ async def metadata_only(self) -> set[str]:
203
201
  return (
204
202
  set(await self.metadata)
205
203
  - self.metadata_only_extensions
206
204
  - self.all_extensions)
207
205
 
208
206
  @property
209
- def metadata_only_extensions(self) -> Set[str]:
207
+ def metadata_only_extensions(self) -> set[str]:
210
208
  return set(METADATA_ONLY_EXTENSIONS)
211
209
 
212
210
  @cached_property
@@ -223,7 +221,7 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
223
221
  return owned
224
222
 
225
223
  @async_property(cache=True)
226
- async def owners_errors(self) -> Dict[str, Tuple[str, ...]]:
224
+ async def owners_errors(self) -> dict[str, tuple[str, ...]]:
227
225
  return (
228
226
  await self._owners_tracked
229
227
  | await self._owners_found)
@@ -243,7 +241,7 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
243
241
  "contrib/language/": dict(owners=1)}
244
242
 
245
243
  @async_property
246
- async def registration_errors(self) -> List[str]:
244
+ async def registration_errors(self) -> list[str]:
247
245
  return [
248
246
  *[f"Metadata for unused extension found: {extension}"
249
247
  for extension
@@ -281,7 +279,7 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
281
279
  def tracked_ownership_re(self) -> Pattern[str]:
282
280
  return re.compile(TRACKED_OWNERSHIP_RE)
283
281
 
284
- async def check_metadata(self, extension: str) -> Tuple[str, ...]:
282
+ async def check_metadata(self, extension: str) -> tuple[str, ...]:
285
283
  return tuple(
286
284
  itertools.chain.from_iterable(
287
285
  await asyncio.gather(
@@ -317,7 +315,7 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
317
315
  for extension, data in extensions.items()}
318
316
 
319
317
  async def _check_metadata_categories(
320
- self, extension: str) -> Tuple[str, ...]:
318
+ self, extension: str) -> tuple[str, ...]:
321
319
  categories = (await self.metadata)[extension].get("categories", ())
322
320
  if not categories:
323
321
  return (
@@ -332,7 +330,7 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
332
330
  if cat not in self.extension_categories)
333
331
 
334
332
  async def _check_metadata_security_posture(
335
- self, extension: str) -> Tuple[str, ...]:
333
+ self, extension: str) -> tuple[str, ...]:
336
334
  security_posture = (await self.metadata)[extension]["security_posture"]
337
335
  if not security_posture:
338
336
  return (
@@ -346,14 +344,14 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
346
344
  return ()
347
345
 
348
346
  async def _check_metadata_status(
349
- self, extension: str) -> Tuple[str, ...]:
347
+ self, extension: str) -> tuple[str, ...]:
350
348
  status = (await self.metadata)[extension]["status"]
351
349
  if status not in self.extension_status_values:
352
350
  return (f"Unknown status for {extension}: {status}", )
353
351
  return ()
354
352
 
355
353
  async def _check_metadata_status_upstream(
356
- self, extension: str) -> Tuple[str, ...]:
354
+ self, extension: str) -> tuple[str, ...]:
357
355
  metadata = (await self.metadata)[extension]
358
356
  status = metadata.get("status_upstream")
359
357
  categories = metadata.get("categories", ())
@@ -371,8 +369,8 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
371
369
 
372
370
  def _from_json(
373
371
  self,
374
- path: Union[str, pathlib.Path],
375
- type: Type,
372
+ path: str | pathlib.Path,
373
+ type: type,
376
374
  err_message: str,
377
375
  warn_message: str) -> Any:
378
376
  # Parse JSON, handling errors
@@ -387,8 +385,8 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
387
385
 
388
386
  def _from_yaml(
389
387
  self,
390
- path: Union[str, pathlib.Path],
391
- type: Type,
388
+ path: str | pathlib.Path,
389
+ type: type,
392
390
  err_message: str,
393
391
  warn_message: str) -> Any:
394
392
  # Parse YAML, handling errors
@@ -457,8 +455,8 @@ class AExtensionsCheck(abstract.ACodeCheck, metaclass=abstracts.Abstraction):
457
455
  def _owners_extension_match_line(
458
456
  self,
459
457
  line: str,
460
- matcher: Optional[
461
- Pattern[str]] = None) -> dict[str, dict[str, set]]:
458
+ matcher: (
459
+ Pattern[str] | None) = None) -> dict[str, dict[str, set]]:
462
460
  if line.startswith('#'):
463
461
  return {}
464
462
  m = (matcher or self.codeowners_extensions_re).search(line)