diff --git a/plare/parser.py b/plare/parser.py index e2ca97f..c30bea5 100644 --- a/plare/parser.py +++ b/plare/parser.py @@ -22,7 +22,7 @@ from collections import deque from itertools import chain -from typing import Any, Iterable, Protocol +from typing import Iterable, Protocol, TypeGuard from plare.exception import ParserError, ParsingError from plare.token import Token @@ -106,10 +106,10 @@ def __init__(self, variable: str) -> None: def __hash__(self) -> int: return super().__hash__() - def __eq__(self, other: Any) -> bool: + def __eq__(self, other: object) -> bool: return isinstance(other, StartVariable) and super().__eq__(other) - def __ne__(self, other: Any) -> bool: + def __ne__(self, other: object) -> bool: return not isinstance(other, StartVariable) or super().__ne__(other) @@ -211,7 +211,7 @@ def __str__(self) -> str: def __hash__(self) -> int: return hash((self.left, tuple(self.right), self.loc)) - def __eq__(self, value: Any) -> bool: + def __eq__(self, value: object) -> bool: return ( isinstance(value, Item) and self.left == value.left @@ -244,8 +244,11 @@ def __init__(self, id: int, items: set[Item[T]]) -> None: def __hash__(self) -> int: return hash(frozenset(self.items)) - def __eq__(self, other: State[T] | Any) -> bool: - return isinstance(other, State) and self.items == other.items + def is_instance(self, obj: object) -> TypeGuard[State[T]]: + return isinstance(obj, State) + + def __eq__(self, other: object) -> bool: + return self.is_instance(other) and self.items == other.items def __str__(self) -> str: return "\n".join(map(str, self.items)) @@ -494,7 +497,7 @@ def calc_follow(self, rules: dict[str, Rule[T]]) -> set[type[Token]]: def __hash__(self) -> int: return hash(self.left) - def __eq__(self, value: Any) -> bool: + def __eq__(self, value: object) -> bool: return isinstance(value, Rule) and self.left == value.left def __repr__(self) -> str: diff --git a/pyproject.toml b/pyproject.toml index 1a201e7..592d1aa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,5 +53,8 @@ markers = [ "slow: marks tests as slow-running (deselect with '-m \"not slow\"')", ] +[tool.pyright] +typeCheckingMode = "strict" + [tool.isort] profile = "black" diff --git a/tests/test_determinism.py b/tests/test_determinism.py index 7a9461f..9005010 100644 --- a/tests/test_determinism.py +++ b/tests/test_determinism.py @@ -19,8 +19,8 @@ type Grammar = dict[ str, list[ - tuple[list[type[Token] | str], type | None, list[int]] - | tuple[list[type[Token] | str], type | None, list[int], type[Token]] + tuple[list[type[Token] | str], type[object] | None, list[int]] + | tuple[list[type[Token] | str], type[object] | None, list[int], type[Token]] ], ] diff --git a/tests/test_hash_semantics.py b/tests/test_hash_semantics.py index d6b7a79..7c7ba2d 100644 --- a/tests/test_hash_semantics.py +++ b/tests/test_hash_semantics.py @@ -18,7 +18,7 @@ def __init__(self, value: str, *, lineno: int, offset: int) -> None: self.offset = offset -def make_item(left: str, right: list, loc: int = 0) -> Item[object]: +def make_item(left: str, right: list[type[Token] | str], loc: int = 0) -> Item[object]: return Item(left, right, IDMaker(0), 0, loc) diff --git a/tests/test_prec_override.py b/tests/test_prec_override.py index 9cd702f..cc115e8 100644 --- a/tests/test_prec_override.py +++ b/tests/test_prec_override.py @@ -8,8 +8,6 @@ from __future__ import annotations -import pytest - from plare.parser import Parser from plare.token import Token @@ -185,7 +183,15 @@ def test_rr_equal_precedence_first_defined_wins() -> None: ParserError. With it, first_val (defined earlier, lower definition_index) wins, so the reduction always produces FirstResult. """ - grammar: dict = { + grammar: dict[ + str, + list[ + tuple[list[type[Token] | str], type[object] | None, list[int]] + | tuple[ + list[type[Token] | str], type[object] | None, list[int], type[Token] + ] + ], + ] = { "result": [ (["first_val"], FirstResult, [0]), (["second_val"], SecondResult, [0]),