Skip to content

Commit 3f2cf8e

Browse files
[Internal] Use ty type checker (#3294)
* switch to ty type checker * fix quality workflow * re-add mypy in CI * fix quality
1 parent 61dce66 commit 3f2cf8e

File tree

16 files changed

+61
-39
lines changed

16 files changed

+61
-39
lines changed

.github/workflows/python-quality.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ jobs:
4444
- run: .venv/bin/python utils/generate_async_inference_client.py
4545
- run: .venv/bin/python utils/generate_inference_types.py
4646
- run: .venv/bin/python utils/check_task_parameters.py
47-
47+
- run: uvx ty check src
4848
# Run type checking at least on huggingface_hub root file to check all modules
4949
# that can be lazy-loaded actually exist.
5050
- run: .venv/bin/mypy src/huggingface_hub/__init__.py --follow-imports=silent --show-traceback
5151

5252
# Run mypy on full package
53-
- run: .venv/bin/mypy src
53+
- run: .venv/bin/mypy src

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ Follow these steps to start contributing:
164164
```
165165

166166
Compared to `make style`, `make quality` will never update your code. In addition to the previous code formatter, it
167-
also runs [`mypy`](https://github.com/python/mypy) to check for static typing issues. All those tests will also run
167+
also runs [`ty`](https://docs.astral.sh/ty/) type checker to check for static typing issues. All those tests will also run
168168
in the CI once you open your PR but it is recommended to run them locally in order to iterate faster.
169169

170170
> For the commands leveraging the `make` utility, we recommend using the WSL system when running on

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ quality:
1313
python utils/check_all_variable.py
1414
python utils/generate_async_inference_client.py
1515

16-
mypy src
16+
ty check src
1717

1818
style:
1919
ruff format $(check_dirs) # formatter

pyproject.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,28 @@
11
[tool.mypy]
22
ignore_missing_imports = true
33

4+
[tool.ty]
5+
[tool.ty.terminal]
6+
# Do not fail CI on warnings; keep output readable
7+
error-on-warning = false
8+
output-format = "concise"
9+
10+
[tool.ty.rules]
11+
# Minimize noise from optional/extra dependencies not installed in CI or local
12+
unresolved-import = "ignore"
13+
unresolved-attribute = "ignore"
14+
15+
# Be tolerant with framework/typing edge-cases and runtime-validated code paths
16+
unsupported-base = "ignore"
17+
possibly-unbound-attribute = "ignore"
18+
unsupported-operator = "ignore"
19+
non-subscriptable = "ignore"
20+
call-non-callable = "ignore"
21+
22+
# Loosen strictness a bit on type matching
23+
missing-argument = "ignore"
24+
deprecated = "ignore"
25+
426
[tool.pytest.ini_options]
527
# Add the specified `OPTS` to the set of command line arguments as if they had
628
# been specified by the user.

setup.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ def get_version() -> str:
111111
"mypy>=1.14.1,<1.15.0; python_version=='3.8'",
112112
"mypy==1.15.0; python_version>='3.9'",
113113
"libcst>=1.4.0",
114+
"ty",
114115
]
115116

116117
extras["all"] = extras["testing"] + extras["quality"] + extras["typing"]

src/huggingface_hub/_tensorboard_logger.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"""Contains a logger to push training logs to the Hub, using Tensorboard."""
1515

1616
from pathlib import Path
17-
from typing import TYPE_CHECKING, List, Optional, Union
17+
from typing import List, Optional, Union
1818

1919
from ._commit_scheduler import CommitScheduler
2020
from .errors import EntryNotFoundError
@@ -26,25 +26,24 @@
2626
# or from 'torch.utils.tensorboard'. Both are compatible so let's try to load
2727
# from either of them.
2828
try:
29-
from tensorboardX import SummaryWriter
29+
from tensorboardX import SummaryWriter as _RuntimeSummaryWriter
3030

3131
is_summary_writer_available = True
32-
3332
except ImportError:
3433
try:
35-
from torch.utils.tensorboard import SummaryWriter
34+
from torch.utils.tensorboard import SummaryWriter as _RuntimeSummaryWriter
3635

37-
is_summary_writer_available = False
36+
is_summary_writer_available = True
3837
except ImportError:
3938
# Dummy class to avoid failing at import. Will raise on instance creation.
40-
SummaryWriter = object
41-
is_summary_writer_available = False
39+
class _DummySummaryWriter:
40+
pass
4241

43-
if TYPE_CHECKING:
44-
from tensorboardX import SummaryWriter
42+
_RuntimeSummaryWriter = _DummySummaryWriter # type: ignore[assignment]
43+
is_summary_writer_available = False
4544

4645

47-
class HFSummaryWriter(SummaryWriter):
46+
class HFSummaryWriter(_RuntimeSummaryWriter):
4847
"""
4948
Wrapper around the tensorboard's `SummaryWriter` to push training logs to the Hub.
5049

src/huggingface_hub/cli/cache.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,7 @@
2121
from tempfile import mkstemp
2222
from typing import Any, Callable, Iterable, List, Literal, Optional, Union
2323

24-
from ..utils import (
25-
CachedRepoInfo,
26-
CachedRevisionInfo,
27-
CacheNotFound,
28-
HFCacheInfo,
29-
scan_cache_dir,
30-
)
24+
from ..utils import CachedRepoInfo, CachedRevisionInfo, CacheNotFound, HFCacheInfo, scan_cache_dir
3125
from . import BaseHuggingfaceCLICommand
3226
from ._cli_utils import ANSI, tabulate
3327

@@ -149,7 +143,7 @@ def _run_scan(self):
149143
if self.verbosity >= 3:
150144
print(ANSI.gray(message))
151145
for warning in hf_cache_info.warnings:
152-
print(ANSI.gray(warning))
146+
print(ANSI.gray(str(warning)))
153147
else:
154148
print(ANSI.gray(message + " Use -vvv to print details."))
155149

src/huggingface_hub/cli/repo.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,9 @@ def __init__(self, args):
183183

184184
class RepoTagCreateCommand(RepoTagCommand):
185185
def run(self):
186-
print(f"You are about to create tag {ANSI.bold(self.args.tag)} on {self.repo_type} {ANSI.bold(self.repo_id)}")
186+
print(
187+
f"You are about to create tag {ANSI.bold(str(self.args.tag))} on {self.repo_type} {ANSI.bold(self.repo_id)}"
188+
)
187189
try:
188190
self.api.create_tag(
189191
repo_id=self.repo_id,
@@ -196,14 +198,14 @@ def run(self):
196198
print(f"{self.repo_type.capitalize()} {ANSI.bold(self.repo_id)} not found.")
197199
exit(1)
198200
except RevisionNotFoundError:
199-
print(f"Revision {ANSI.bold(getattr(self.args, 'revision', None))} not found.")
201+
print(f"Revision {ANSI.bold(str(getattr(self.args, 'revision', None)))} not found.")
200202
exit(1)
201203
except HfHubHTTPError as e:
202204
if e.response.status_code == 409:
203-
print(f"Tag {ANSI.bold(self.args.tag)} already exists on {ANSI.bold(self.repo_id)}")
205+
print(f"Tag {ANSI.bold(str(self.args.tag))} already exists on {ANSI.bold(self.repo_id)}")
204206
exit(1)
205207
raise e
206-
print(f"Tag {ANSI.bold(self.args.tag)} created on {ANSI.bold(self.repo_id)}")
208+
print(f"Tag {ANSI.bold(str(self.args.tag))} created on {ANSI.bold(self.repo_id)}")
207209

208210

209211
class RepoTagListCommand(RepoTagCommand):

src/huggingface_hub/commands/scan_cache.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def run(self):
7777
if self.verbosity >= 3:
7878
print(ANSI.gray(message))
7979
for warning in hf_cache_info.warnings:
80-
print(ANSI.gray(warning))
80+
print(ANSI.gray(str(warning)))
8181
else:
8282
print(ANSI.gray(message + " Use -vvv to print details."))
8383

src/huggingface_hub/hf_file_system.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -896,7 +896,7 @@ def get_file(self, rpath, lpath, callback=_DEFAULT_CALLBACK, outfile=None, **kwa
896896
repo_type=resolve_remote_path.repo_type,
897897
endpoint=self.endpoint,
898898
),
899-
temp_file=outfile,
899+
temp_file=outfile, # type: ignore[arg-type]
900900
displayed_filename=rpath,
901901
expected_size=expected_size,
902902
resume_size=0,

0 commit comments

Comments
 (0)