Skip to content

Commit a2ffd5e

Browse files
dreamiurgclaude
andauthored
chore: migrate from mypy to ty type checker (#63)
Replace mypy with Astral's ty, a faster Rust-based type checker. - Update pyproject.toml config and dependencies - Update pre-commit hook to use local ty via uvx - Update CI workflow to run ty instead of mypy - Fix type errors ty detected that mypy missed: - elevation_ft passed as string instead of int - Missing None checks before accessing seasonal_pattern.values() 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 35126c0 commit a2ffd5e

File tree

6 files changed

+20
-21
lines changed

6 files changed

+20
-21
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ jobs:
5454
- name: Run ruff format check
5555
run: uv run ruff format --check peakbagger tests
5656

57-
- name: Run mypy
58-
run: uv run mypy peakbagger --pretty
57+
- name: Run ty
58+
run: uvx ty check peakbagger
5959
continue-on-error: true
6060

6161
test:

.pre-commit-config.yaml

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,15 @@ repos:
5353
additional_dependencies: ["bandit[toml]"]
5454
exclude: ^tests/
5555

56-
# Type checking with mypy
57-
- repo: https://github.com/pre-commit/mirrors-mypy
58-
rev: v1.18.2
56+
# Type checking with ty
57+
- repo: local
5958
hooks:
60-
- id: mypy
61-
additional_dependencies:
62-
- types-requests
63-
args: [--ignore-missing-imports, --python-version=3.12]
59+
- id: ty
60+
name: ty
61+
entry: uvx ty check
62+
language: system
63+
types: [python]
64+
pass_filenames: false
6465

6566
# Markdown linting
6667
- repo: https://github.com/igorshubovych/markdownlint-cli

CLAUDE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ Output changes include:
314314
- pytest + pytest-cov
315315
- ruff
316316
- pre-commit
317-
- mypy
317+
- ty
318318
- python-semantic-release
319319
- commitizen
320320

pyproject.toml

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ dev = [
3737
"pytest-vcr>=1.0.2",
3838
"ruff>=0.8.0",
3939
"pre-commit>=3.0.0",
40-
"mypy>=1.18.2",
41-
"types-beautifulsoup4>=4.12.0.20250516",
40+
"ty>=0.0.8",
4241
"vcrpy>=7.0.0",
4342
]
4443

@@ -94,12 +93,8 @@ python_files = "test_*.py"
9493
python_functions = "test_*"
9594
addopts = "-v --cov=peakbagger --cov-report=term-missing"
9695

97-
[tool.mypy]
98-
python_version = "3.12"
99-
warn_return_any = true
100-
warn_unused_configs = true
101-
disallow_untyped_defs = false
102-
ignore_missing_imports = true
96+
[tool.ty.environment]
97+
python-version = "3.12"
10398

10499
[tool.semantic_release]
105100
version_toml = ["pyproject.toml:project.version"]
@@ -132,12 +127,11 @@ tag_format = "$version"
132127
[dependency-groups]
133128
dev = [
134129
"commitizen>=4.9.1",
135-
"mypy>=1.18.2",
136130
"pre-commit>=4.3.0",
137131
"pytest-cov>=7.0.0",
138132
"pytest-vcr>=1.0.2",
139133
"python-semantic-release>=10.4.1",
140134
"twine>=6.2.0",
141-
"types-beautifulsoup4>=4.12.0.20250516",
135+
"ty>=0.0.8",
142136
"vcrpy>=7.0.0",
143137
]

tests/test_cli_errors.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def test_search_full_flag_with_empty_peaks(self):
134134
name="Test Peak",
135135
url="peak.aspx?pid=1",
136136
pid="1",
137-
elevation_ft="1000",
137+
elevation_ft=1000,
138138
location="USA",
139139
)
140140
]

tests/test_statistics.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,8 @@ def test_calculate_statistics_seasonal_window(self, sample_ascents):
166166
)
167167

168168
# Wide window should capture more ascents in seasonal pattern
169+
assert stats_wide.seasonal_pattern is not None
170+
assert stats_narrow.seasonal_pattern is not None
169171
assert sum(stats_wide.seasonal_pattern.values()) >= sum(
170172
stats_narrow.seasonal_pattern.values()
171173
)
@@ -183,6 +185,7 @@ def test_calculate_statistics_year_wraparound(self):
183185
)
184186

185187
# Both ascents should be within seasonal window due to wraparound handling
188+
assert stats.seasonal_pattern is not None
186189
assert sum(stats.seasonal_pattern.values()) >= 1
187190

188191
def test_calculate_statistics_invalid_date_formats(self):
@@ -465,4 +468,5 @@ def test_large_seasonal_window(self):
465468
)
466469

467470
# With 365-day window, all ascents should be in seasonal pattern
471+
assert stats.seasonal_pattern is not None
468472
assert sum(stats.seasonal_pattern.values()) == 12

0 commit comments

Comments
 (0)