Skip to content

Commit 39bada9

Browse files
tcoratgerfselmo
andauthored
python: replace mypy by ty (#235)
* python: replace mypy by ty * fmt * fix strange ignore * bitfield fix * element property method simplification * rm useless ty rule * bump ty * fix conflicts * small simplifications * remove useless thing * minor cleanup related to adding ty * refactor: avoid cast(Any, ...), be more explicit with test models + ignores --------- Co-authored-by: fselmo <[email protected]>
1 parent 87d2b11 commit 39bada9

File tree

34 files changed

+520
-451
lines changed

34 files changed

+520
-451
lines changed

CLAUDE.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ uv run fill --fork=devnet --clean -n auto # Generate test vectors
2828
### Code Quality
2929

3030
```bash
31-
uv run ruff format src tests packages # Format code
32-
uv run ruff check --fix src tests packages # Lint and fix
33-
uvx tox -e typecheck # Type check
34-
uvx tox -e all-checks # All quality checks
35-
uvx tox # Everything (checks + tests + docs)
31+
uv run ruff format # Format code
32+
uv run ruff check --fix # Lint and fix
33+
uvx tox -e typecheck # Type check
34+
uvx tox -e all-checks # All quality checks
35+
uvx tox # Everything (checks + tests + docs)
3636
```
3737

3838
### Common Tasks

README.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -97,16 +97,16 @@ uv run fill --clean --fork=devnet
9797

9898
```bash
9999
# Check code style and errors
100-
uv run ruff check src tests packages
100+
uv run ruff check
101101

102102
# Auto-fix issues
103-
uv run ruff check --fix src tests packages
103+
uv run ruff check --fix
104104

105105
# Format code
106-
uv run ruff format src tests packages
106+
uv run ruff format
107107

108108
# Type checking
109-
uv run mypy src tests packages
109+
uv run ty check
110110
```
111111

112112
### Using Tox for Comprehensive Checks
@@ -179,24 +179,24 @@ def test_withdrawal_amount_above_uint64_max():
179179
- **pytest**: Testing framework - just name test files `test_*.py` and functions `test_*`
180180
- **uv**: Fast Python package manager - like npm/yarn but for Python
181181
- **ruff**: Linter and formatter
182-
- **mypy**: Type checker that works with Pydantic models
182+
- **ty**: Type checker
183183
- **tox**: Automation tool for running tests across multiple environments (used via `uvx`)
184184
- **mkdocs**: Documentation generator - write docs in Markdown, serve them locally
185185

186186
## Common Commands Reference
187187

188-
| Task | Command |
189-
|-----------------------------------------------|----------------------------------------------|
190-
| Install and sync project and dev dependencies | `uv sync` |
191-
| Run tests | `uv run pytest ...` |
192-
| Format code | `uv run ruff format src tests packages` |
193-
| Lint code | `uv run ruff check src tests packages` |
194-
| Fix lint errors | `uv run ruff check --fix src tests packages` |
195-
| Type check | `uv run mypy src tests packages` |
196-
| Build docs | `uv run mkdocs build` |
197-
| Serve docs | `uv run mkdocs serve` |
198-
| Run everything (checks + tests + docs) | `uvx tox` |
199-
| Run all quality checks (no tests/docs) | `uvx tox -e all-checks` |
188+
| Task | Command |
189+
|-----------------------------------------------|---------------------------|
190+
| Install and sync project and dev dependencies | `uv sync` |
191+
| Run tests | `uv run pytest ...` |
192+
| Format code | `uv run ruff format` |
193+
| Lint code | `uv run ruff check` |
194+
| Fix lint errors | `uv run ruff check --fix` |
195+
| Type check | `uv run ty check` |
196+
| Build docs | `uv run mkdocs build` |
197+
| Serve docs | `uv run mkdocs serve` |
198+
| Run everything (checks + tests + docs) | `uvx tox` |
199+
| Run all quality checks (no tests/docs) | `uvx tox -e all-checks` |
200200

201201
## Contributing
202202

packages/testing/src/framework/forks/base.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ def __init_subclass__(
9797
cls._children = set()
9898

9999
# Track parent-child relationships
100-
base_class = cls.__bases__[0]
101-
if base_class != BaseFork and hasattr(base_class, "_children"):
102-
base_class._children.add(cls)
100+
for base in cls.__bases__:
101+
if base is not BaseFork and issubclass(base, BaseFork):
102+
base._children.add(cls)
103103

104104
@classmethod
105105
@abstractmethod

pyproject.toml

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -66,16 +66,11 @@ known-first-party = ["lean_spec"]
6666
[tool.ruff.lint.per-file-ignores]
6767
"tests/**" = ["D", "F401", "F403"]
6868

69-
[tool.mypy]
70-
python_version = "3.12"
71-
plugins = ["pydantic.mypy"]
72-
strict = true
73-
warn_return_any = true
74-
warn_unused_configs = true
75-
warn_unused_ignores = true
76-
no_implicit_reexport = true
77-
namespace_packages = false
78-
explicit_package_bases = false
69+
[tool.ty.environment]
70+
python-version = "3.12"
71+
72+
[tool.ty.terminal]
73+
error-on-warning = true
7974

8075
[tool.pytest.ini_options]
8176
minversion = "8.3.3"
@@ -125,7 +120,7 @@ test = [
125120
"lean-ethereum-testing",
126121
]
127122
lint = [
128-
"mypy>=1.17.0,<2",
123+
"ty>=0.0.1a34",
129124
"ruff>=0.13.2,<1",
130125
"codespell>=2.4.1,<3",
131126
]

src/lean_spec/subspecs/containers/attestation/types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def to_validator_indices(self) -> list[Uint64]:
5959
return indices
6060

6161

62-
class NaiveAggregatedSignature(SSZList):
62+
class NaiveAggregatedSignature(SSZList[Signature]):
6363
"""Naive list of validator signatures used for aggregation placeholders."""
6464

6565
ELEMENT_TYPE = Signature

src/lean_spec/subspecs/containers/block/types.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,12 @@
66
from ..attestation import AggregatedAttestation, AttestationData, NaiveAggregatedSignature
77

88

9-
class AggregatedAttestations(SSZList):
9+
class AggregatedAttestations(SSZList[AggregatedAttestation]):
1010
"""List of aggregated attestations included in a block."""
1111

1212
ELEMENT_TYPE = AggregatedAttestation
1313
LIMIT = int(VALIDATOR_REGISTRY_LIMIT)
1414

15-
def __getitem__(self, index: int) -> AggregatedAttestation:
16-
"""Access an aggregated attestation by index with proper typing."""
17-
item = self.data[index]
18-
assert isinstance(item, AggregatedAttestation)
19-
return item
20-
2115
def has_duplicate_data(self) -> bool:
2216
"""Check if any two attestations share the same AttestationData."""
2317
seen: set[AttestationData] = set()
@@ -28,7 +22,7 @@ def has_duplicate_data(self) -> bool:
2822
return False
2923

3024

31-
class AttestationSignatures(SSZList):
25+
class AttestationSignatures(SSZList[NaiveAggregatedSignature]):
3226
"""List of per-attestation naive signature lists aligned with block body attestations."""
3327

3428
ELEMENT_TYPE = NaiveAggregatedSignature

src/lean_spec/subspecs/containers/state/state.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,8 @@ def process_block_header(self, block: Block) -> "State":
333333
update={
334334
"latest_justified": new_latest_justified,
335335
"latest_finalized": new_latest_finalized,
336-
"historical_block_hashes": HistoricalBlockHashes(data=new_historical_hashes_data),
337-
"justified_slots": JustifiedSlots(data=new_justified_slots_data),
336+
"historical_block_hashes": new_historical_hashes_data,
337+
"justified_slots": new_justified_slots_data,
338338
"latest_block_header": new_header,
339339
}
340340
)
@@ -570,7 +570,7 @@ def process_attestations(
570570
"justifications_validators": JustificationValidators(
571571
data=[vote for root in sorted_roots for vote in justifications[root]]
572572
),
573-
"justified_slots": JustifiedSlots(data=justified_slots),
573+
"justified_slots": justified_slots,
574574
"latest_justified": latest_justified,
575575
"latest_finalized": latest_finalized,
576576
}

src/lean_spec/subspecs/containers/state/types.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
from ..validator import Validator
88

99

10-
class HistoricalBlockHashes(SSZList):
10+
class HistoricalBlockHashes(SSZList[Bytes32]):
1111
"""List of historical block root hashes up to historical_roots_limit."""
1212

1313
ELEMENT_TYPE = Bytes32
1414
LIMIT = int(DEVNET_CONFIG.historical_roots_limit)
1515

1616

17-
class JustificationRoots(SSZList):
17+
class JustificationRoots(SSZList[Bytes32]):
1818
"""List of justified block roots up to historical_roots_limit."""
1919

2020
ELEMENT_TYPE = Bytes32
@@ -33,14 +33,8 @@ class JustificationValidators(BaseBitlist):
3333
LIMIT = int(DEVNET_CONFIG.historical_roots_limit) * int(DEVNET_CONFIG.validator_registry_limit)
3434

3535

36-
class Validators(SSZList):
36+
class Validators(SSZList[Validator]):
3737
"""Validator registry tracked in the state."""
3838

3939
ELEMENT_TYPE = Validator
4040
LIMIT = int(DEVNET_CONFIG.validator_registry_limit)
41-
42-
def __getitem__(self, index: int) -> Validator:
43-
"""Access a validator by index with proper typing."""
44-
item = self.data[index]
45-
assert isinstance(item, Validator)
46-
return item

src/lean_spec/subspecs/networking/config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
MAX_REQUEST_BLOCKS: Final = 2**10
88
"""Maximum number of blocks in a single request."""
99

10-
MESSAGE_DOMAIN_INVALID_SNAPPY: Final = DomainType(b"\x00\x00\x00\x00")
10+
MESSAGE_DOMAIN_INVALID_SNAPPY: Final[DomainType] = b"\x00\x00\x00\x00"
1111
"""4-byte domain for gossip message-id isolation of invalid snappy messages."""
1212

13-
MESSAGE_DOMAIN_VALID_SNAPPY: Final = DomainType(b"\x01\x00\x00\x00")
13+
MESSAGE_DOMAIN_VALID_SNAPPY: Final[DomainType] = b"\x01\x00\x00\x00"
1414
"""4-byte domain for gossip message-id isolation of valid snappy messages."""

src/lean_spec/subspecs/networking/gossipsub/message.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ def id(self) -> MessageId:
8383
self.raw_data,
8484
)
8585

86-
# Compute the raw ID bytes and cast to our strict type before caching
87-
self._id = MessageId(self._compute_raw_id(domain, data_for_hash))
86+
# Compute the raw ID bytes and assign with proper type annotation
87+
self._id: MessageId = self._compute_raw_id(domain, data_for_hash)
8888
return self._id
8989

9090
def _compute_raw_id(self, domain: bytes, message_data: bytes) -> bytes:

0 commit comments

Comments
 (0)