[PATCH ezgb 4/6] Add pyright checks
Tamir Duberstein <[email protected]>
| Newsgroups | org.kernel.linux.tools |
|---|---|
| Message-ID | <[email protected]> |
Add pyright to local CI with strict source checking. Signed-off-by: Tamir Duberstein <[email protected]> --- ci.sh | 1 + pyproject.toml | 7 +++++++ src/ezgb/__init__.py | 8 +++----- src/ezgb/_git.py | 2 +- src/ezgb/_models.py | 4 ++-- src/ezgb/_reader.py | 38 +++++++++++++++++++++----------------- src/ezgb/_writer.py | 14 +++++++------- 7 files changed, 42 insertions(+), 32 deletions(-) diff --git a/ci.sh b/ci.sh index db7914f..fbc433d 100755 --- a/ci.sh +++ b/ci.sh @@ -5,4 +5,5 @@ set -eu uv run ruff check uv run ruff format --check uv run mypy . +uv run pyright uv run pytest --durations=0 diff --git a/pyproject.toml b/pyproject.toml index c043817..452bd6a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ classifiers = [ [dependency-groups] dev = [ "mypy", + "pyright", "pytest", "ruff", ] @@ -50,3 +51,9 @@ select = ["E", "F", "W", "I"] [tool.ruff.format] quote-style = "single" + +[tool.pyright] +typeCheckingMode = "strict" +executionEnvironments = [ + { root = "tests", reportPrivateUsage = false }, +] diff --git a/src/ezgb/__init__.py b/src/ezgb/__init__.py index 5cb23ae..f2f5d3d 100644 --- a/src/ezgb/__init__.py +++ b/src/ezgb/__init__.py @@ -23,7 +23,7 @@ from ezgb._models import ( Status, UnsupportedFormatError, ) -from ezgb._reader import BugReader +from ezgb._reader import BugReader, parse_since from ezgb._types import JsonValue from ezgb._writer import BugWriter @@ -77,9 +77,7 @@ class GitBugRepo: since = since.replace(tzinfo=timezone.utc) return int(since.timestamp()) # str -- delegate to the reader's parser - from ezgb._reader import BugReader - - return BugReader._parse_since(since) + return parse_since(since) def list_bugs( self, @@ -206,7 +204,7 @@ class GitBugRepo: author_id = author.get('id', '') if isinstance(author, dict) else '' raw_labels = raw.get('labels') or [] if isinstance(raw_labels, list): - labels = frozenset(str(lb) for lb in raw_labels) + labels: frozenset[str] = frozenset(str(lb) for lb in raw_labels) else: labels = frozenset() comment_count = raw.get('comments', 0) diff --git a/src/ezgb/_git.py b/src/ezgb/_git.py index 4e29646..c1c326b 100644 --- a/src/ezgb/_git.py +++ b/src/ezgb/_git.py @@ -45,7 +45,7 @@ def git_run( def git_lines(repo_path: str, args: list[str]) -> list[str]: """Run a git command and return non-empty output lines.""" - ecode, out = git_run(repo_path, args) + _ecode, out = git_run(repo_path, args) if not isinstance(out, str): out = out.decode(errors='replace') return [line for line in out.split('\n') if line] diff --git a/src/ezgb/_models.py b/src/ezgb/_models.py index b8716f0..22e45a7 100644 --- a/src/ezgb/_models.py +++ b/src/ezgb/_models.py @@ -96,7 +96,7 @@ class Comment: text: str created_at: datetime count: int - attachment_ids: list[str] = field(default_factory=list) + attachment_ids: list[str] = field(default_factory=list[str]) @dataclass @@ -110,7 +110,7 @@ class Bug: created_at: datetime labels: set[str] comments: list[Comment] - metadata: dict[str, str] = field(default_factory=dict) + metadata: dict[str, str] = field(default_factory=dict[str, str]) @dataclass(frozen=True) diff --git a/src/ezgb/_reader.py b/src/ezgb/_reader.py index 735d41d..2d44478 100644 --- a/src/ezgb/_reader.py +++ b/src/ezgb/_reader.py @@ -57,6 +57,26 @@ def _is_dict_values(value: dict[_K, _T], value_ty: type[_U]) -> TypeGuard[dict[_ return all(isinstance(value, value_ty) for value in value.values()) +def parse_since(since: str) -> int: + """Parse a datetime string to a unix timestamp. + + Accepts ISO-8601 variants and ``YYYYMMDDHHMMSS``. + """ + since = since.strip() + for fmt in ( + '%Y-%m-%d %H:%M:%S', + '%Y%m%d%H%M%S', + '%Y-%m-%dT%H:%M:%SZ', + '%Y-%m-%dT%H:%M:%S', + ): + try: + dt = datetime.strptime(since, fmt).replace(tzinfo=timezone.utc) + return int(dt.timestamp()) + except ValueError: + continue + raise ValueError('cannot parse since=%s' % since) + + def _combine_ids(primary: str, secondary: str) -> str: """Interleave primary and secondary IDs into a CombinedId. @@ -415,23 +435,7 @@ class BugReader: @staticmethod def _parse_since(since: str) -> int: - """Parse a datetime string to a unix timestamp. - - Accepts ISO-8601 variants and ``YYYYMMDDHHMMSS``. - """ - since = since.strip() - for fmt in ( - '%Y-%m-%d %H:%M:%S', - '%Y%m%d%H%M%S', - '%Y-%m-%dT%H:%M:%SZ', - '%Y-%m-%dT%H:%M:%S', - ): - try: - dt = datetime.strptime(since, fmt).replace(tzinfo=timezone.utc) - return int(dt.timestamp()) - except ValueError: - continue - raise ValueError('cannot parse since=%s' % since) + return parse_since(since) def build_bug( self, diff --git a/src/ezgb/_writer.py b/src/ezgb/_writer.py index ae1d45f..adacfa1 100644 --- a/src/ezgb/_writer.py +++ b/src/ezgb/_writer.py @@ -77,7 +77,7 @@ class BugWriter: '-', '--non-interactive', ] - ecode, out, err = self._cli(args, stdin=text) + ecode, _out, err = self._cli(args, stdin=text) if ecode != 0: raise CliError('git bug comment new failed: %s' % err) self._reader.invalidate(bid) @@ -100,7 +100,7 @@ class BugWriter: '-', '--non-interactive', ] - ecode, out, err = self._cli(args, stdin=text) + ecode, _out, err = self._cli(args, stdin=text) if ecode != 0: raise CliError('git bug comment edit failed: %s' % err) self._reader.invalidate(bid) @@ -112,7 +112,7 @@ class BugWriter: subcmd = 'close' else: subcmd = 'open' - ecode, out, err = self._cli(['bug', 'status', subcmd, bid]) + ecode, _out, err = self._cli(['bug', 'status', subcmd, bid]) if ecode != 0: raise CliError('git bug status %s failed: %s' % (subcmd, err)) self._reader.invalidate(bid) @@ -121,7 +121,7 @@ class BugWriter: """Edit a bug's title.""" bid = self._reader.resolve_bug_id(bid) args = ['bug', 'title', 'edit', bid, '-t', title] - ecode, out, err = self._cli(args) + ecode, _out, err = self._cli(args) if ecode != 0: raise CliError('git bug title edit failed: %s' % err) self._reader.invalidate(bid) @@ -129,7 +129,7 @@ class BugWriter: def add_label(self, bid: str, label: str) -> None: """Add a label to a bug.""" bid = self._reader.resolve_bug_id(bid) - ecode, out, err = self._cli( + ecode, _out, err = self._cli( ['bug', 'label', 'new', bid, label], ) if ecode != 0: @@ -139,7 +139,7 @@ class BugWriter: def remove_label(self, bid: str, label: str) -> None: """Remove a label from a bug.""" bid = self._reader.resolve_bug_id(bid) - ecode, out, err = self._cli( + ecode, _out, err = self._cli( ['bug', 'label', 'rm', bid, label], ) if ecode != 0: @@ -153,7 +153,7 @@ class BugWriter: remote copies. This is irreversible. """ bid = self._reader.resolve_bug_id(bid) - ecode, out, err = self._cli(['bug', 'rm', bid]) + ecode, _out, err = self._cli(['bug', 'rm', bid]) if ecode != 0: raise CliError('git bug rm failed: %s' % err) # Invalidate everything — the refs list has changed -- 2.53.0