Skip to content

Commit ec8b01e

Browse files
feat: add basedpyright type checking
- Add basedpyright as dev dependency - Add typing_extensions as runtime dependency (for @OverRide on py3.10/3.11) - Configure [tool.basedpyright] with appropriate suppressions - Add basedpyright hook to .pre-commit-config.yaml (runs in CI via prek) - Switch to relative imports to break import cycles - Remove redundant Component.key()/Component.index() static factories - Retype _create_at child_keys as tuple[str, ...] with _ensure_str_keys - Make normalize_keys and compute_patches public (with tests) - Add @OverRide decorators and type annotations for class attributes - Enable reportUnusedCallResult, reportUnknownMemberType, reportUnnecessaryIsInstance, reportImplicitStringConcatenation
1 parent 45612d0 commit ec8b01e

12 files changed

Lines changed: 319 additions & 164 deletions

.importlinter

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,3 @@ exhaustive_ignores =
1818
_display
1919
_types
2020
ignore_imports =
21-
yamltrip.document -> yamltrip
22-
yamltrip.sync -> yamltrip

.pre-commit-config.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ repos:
5555
entry: uv run --frozen cargo clippy --all-targets --no-default-features -- -D warnings
5656
language: system
5757
pass_filenames: false
58+
- repo: local
59+
hooks:
60+
- id: basedpyright
61+
name: basedpyright
62+
always_run: true
63+
entry: uv run --frozen --offline basedpyright
64+
language: system
65+
types: [python]
66+
require_serial: true
5867
- repo: https://github.com/jendrikseipp/vulture
5968
rev: v2.16
6069
hooks:

pyproject.toml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ classifiers = [
1818
"Programming Language :: Python :: 3.13",
1919
"Programming Language :: Python :: 3.14",
2020
]
21-
dependencies = []
21+
dependencies = [
22+
"typing-extensions>=4.4.0",
23+
]
2224

2325
[dependency-groups]
2426
dev = [
27+
"basedpyright>=1.39.6",
2528
"codespell>=2.4.2",
2629
"deptry>=0.25.1",
2730
"import-linter>=2.11",
@@ -77,6 +80,26 @@ report.exclude_also = [
7780
]
7881
report.omit = [ "*/pytest-of-*/*" ]
7982

83+
[tool.basedpyright]
84+
reportAny = false
85+
reportExplicitAny = false
86+
reportUnknownArgumentType = false
87+
reportUnknownVariableType = false
88+
89+
[[tool.basedpyright.executionEnvironments]]
90+
root = "tests"
91+
reportMissingParameterType = false
92+
reportPrivateUsage = false
93+
reportUnannotatedClassAttribute = false
94+
reportUnknownLambdaType = false
95+
reportUnknownMemberType = false
96+
reportUnknownParameterType = false
97+
reportUnreachable = false
98+
reportUnusedCallResult = false
99+
reportUnusedExpression = false
100+
reportUnusedFunction = false
101+
reportUnusedParameter = false
102+
80103
[tool.vulture]
81104
paths = [ "src/yamltrip" ]
82105
ignore_names = [

src/types.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -76,22 +76,10 @@ pub enum PyComponent {
7676

7777
#[pymethods]
7878
impl PyComponent {
79-
#[staticmethod]
80-
fn key(name: &str) -> Self {
81-
Self::Key {
82-
name: name.to_string(),
83-
}
84-
}
85-
86-
#[staticmethod]
87-
fn index(index: usize) -> Self {
88-
Self::Index { index }
89-
}
90-
9179
fn __repr__(&self) -> String {
9280
match self {
93-
Self::Key { name } => format!("Component.key('{name}')"),
94-
Self::Index { index } => format!("Component.index({index})"),
81+
Self::Key { name } => format!("Component.Key('{name}')"),
82+
Self::Index { index } => format!("Component.Index({index})"),
9583
}
9684
}
9785
}

src/yamltrip/_core.pyi

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
from typing import Any, ClassVar, final
44

5+
from typing_extensions import override
6+
57
__all__ = [
68
"Component",
79
"Document",
@@ -22,8 +24,11 @@ class Location:
2224
def start(self) -> int: ...
2325
@property
2426
def end(self) -> int: ...
27+
@override
2528
def __eq__(self, value: object, /) -> bool: ...
29+
@override
2630
def __hash__(self) -> int: ...
31+
@override
2732
def __repr__(self) -> str: ...
2833

2934
@final
@@ -33,9 +38,12 @@ class FeatureKind:
3338
FlowMapping: ClassVar[FeatureKind]
3439
BlockSequence: ClassVar[FeatureKind]
3540
FlowSequence: ClassVar[FeatureKind]
41+
@override
3642
def __eq__(self, value: object, /) -> bool: ...
43+
@override
3744
def __hash__(self) -> int: ...
3845
def __int__(self) -> int: ...
46+
@override
3947
def __repr__(self) -> str: ...
4048

4149
class Component:
@@ -51,22 +59,24 @@ class Component:
5159
__match_args__: ClassVar[tuple[str, ...]]
5260
def __new__(cls, index: int) -> Component.Index: ...
5361
@property
54-
def index(self) -> int: ... # type: ignore[override]
62+
def index(self) -> int: ...
5563

56-
@staticmethod
57-
def key(name: str) -> Component: ...
58-
@staticmethod
59-
def index(index: int) -> Component: ...
64+
@override
6065
def __eq__(self, value: object, /) -> bool: ...
66+
@override
6167
def __hash__(self) -> int: ...
68+
@override
6269
def __repr__(self) -> str: ...
6370

6471
@final
6572
class Route:
6673
def __new__(cls, parts: list[str | int]) -> Route: ...
6774
def __len__(self) -> int: ...
75+
@override
6876
def __eq__(self, value: object, /) -> bool: ...
77+
@override
6978
def __hash__(self) -> int: ...
79+
@override
7080
def __repr__(self) -> str: ...
7181

7282
@final
@@ -79,8 +89,11 @@ class Feature:
7989
def kind(self) -> FeatureKind: ...
8090
@property
8191
def is_multiline(self) -> bool: ...
92+
@override
8293
def __eq__(self, value: object, /) -> bool: ...
94+
@override
8395
def __hash__(self) -> int: ...
96+
@override
8497
def __repr__(self) -> str: ...
8598

8699
@final
@@ -111,6 +124,7 @@ class Op:
111124
def insert_at(index: int, value: Any) -> Op: ...
112125
@property
113126
def kind(self) -> str: ...
127+
@override
114128
def __repr__(self) -> str: ...
115129

116130
@final

0 commit comments

Comments
 (0)