Skip to content

Commit 2278a9f

Browse files
authored
refactor(dev): replace mypy with ty for type checking (#60)
* refactor(dev): replace mypy with ty for type checking - Remove mypy and types-requests from dev dependencies - Update justfile to use ty check command - Update CI workflow to run ty instead of mypy - Update flake.nix pre-commit hook to use ty - Update documentation references in CLAUDE.md, README.md and rules * fix(types): add ty ignore comments for optional dependencies - Add ty: ignore[unresolved-import] for langgraph and mcp imports (these are optional dependencies not always installed) - Add ty: ignore[invalid-argument-type] for bm25s.tokenize stemmer=None (upstream type stub incorrectly requires callable) - Add ty: ignore[invalid-assignment] for dynamic schema_class - Remove unused TYPE_CHECKING import block in langgraph integration
1 parent 1a31baa commit 2278a9f

File tree

12 files changed

+55
-150
lines changed

12 files changed

+55
-150
lines changed

.claude/rules/development-workflow.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ This rule provides code style guidelines and project conventions for the StackOn
1818

1919
- Full type annotations required for all public APIs
2020
- Use Python 3.11+ typing features
21-
- Run `just mypy` to verify type correctness
22-
- Strict mypy configuration is enforced
21+
- Run `just ty` to verify type correctness
22+
- Strict ty configuration is enforced
2323

2424
## Pre-commit Hooks
2525

2626
Pre-commit hooks are configured for:
2727

2828
- ruff linting
29-
- mypy type checking
29+
- ty type checking
3030

3131
Run `just install` to set up hooks.
3232

@@ -36,7 +36,7 @@ Run `just install` to set up hooks.
3636
just install # Install dependencies and pre-commit hooks
3737
just lint # Run ruff linting
3838
just lint-fix # Auto-fix linting issues
39-
just mypy # Run type checking
39+
just ty # Run type checking
4040
just test # Run all tests
4141
just test-tools # Run tool-specific tests
4242
just test-examples # Run example tests

.github/workflows/ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,8 @@ jobs:
7070
- name: Run Lint
7171
run: nix develop --command just lint
7272

73-
- name: Run Mypy
74-
run: nix develop --command just mypy
73+
- name: Run Ty
74+
run: nix develop --command just ty
7575

7676
- name: Run Tests
7777
run: nix develop --command just test

CLAUDE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ just install # Install dependencies and pre-commit hooks
3333
# Code quality
3434
just lint # Run ruff linting
3535
just lint-fix # Auto-fix linting issues
36-
just mypy # Run type checking
36+
just ty # Run type checking
3737

3838
# Testing
3939
just test # Run all tests
@@ -88,7 +88,7 @@ toolset = StackOneToolSet(
8888
### Type Safety
8989

9090
- Full type annotations required (Python 3.11+)
91-
- Strict mypy configuration
91+
- Strict ty configuration
9292
- Use generics for better IDE support
9393

9494
### Testing
@@ -100,7 +100,7 @@ toolset = StackOneToolSet(
100100
## Important Considerations
101101

102102
1. **Dependencies**: See `package-installation` rule for uv dependency management
103-
2. **Pre-commit**: Hooks configured for ruff and mypy - run on all commits
103+
2. **Pre-commit**: Hooks configured for ruff and ty - run on all commits
104104
3. **Python Version**: Requires Python >=3.11
105105
4. **Error Handling**: Custom exceptions (`StackOneError`, `StackOneAPIError`)
106106
5. **File Uploads**: Binary parameters auto-detected from OpenAPI specs

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ The Nix development environment includes:
4848

4949
- Python with uv package manager
5050
- Automatic dependency installation
51-
- Git hooks (treefmt + mypy) auto-configured
51+
- Git hooks (treefmt + ty) auto-configured
5252
- Consistent environment across all platforms
5353

5454
### Using pip/uv

flake.nix

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
# Git hooks configuration
6262
pre-commit = {
63-
check.enable = false; # Skip check in flake (mypy needs Python env)
63+
check.enable = false; # Skip check in flake (ty needs Python env)
6464
settings.hooks = {
6565
gitleaks = {
6666
enable = true;
@@ -73,10 +73,10 @@
7373
enable = true;
7474
package = config.treefmt.build.wrapper;
7575
};
76-
mypy = {
76+
ty = {
7777
enable = true;
78-
name = "mypy";
79-
entry = "${pkgs.uv}/bin/uv run mypy";
78+
name = "ty";
79+
entry = "${pkgs.uv}/bin/uv run ty check";
8080
files = "^stackone_ai/";
8181
language = "system";
8282
types = [ "python" ];

justfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ test-examples:
2727
uv run pytest examples
2828

2929
# Run type checking
30-
mypy:
31-
uv run mypy stackone_ai
30+
ty:
31+
uv run ty check stackone_ai
3232

3333
# Run typos spell checker
3434
typos:

pyproject.toml

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,14 @@ examples = [
5757

5858
[dependency-groups]
5959
dev = [
60-
"mypy>=1.15.0",
6160
"pytest>=8.3.4",
6261
"pytest-asyncio>=0.25.3",
6362
"pytest-cov>=6.0.0",
6463
"pytest-snapshot>=0.9.0",
6564
"responses>=0.25.8",
6665
"ruff>=0.9.6",
6766
"stackone-ai",
68-
"types-requests>=2.31.0.20240311",
67+
"ty>=0.0.3",
6968
]
7069

7170
[tool.pytest.ini_options]
@@ -96,34 +95,6 @@ select = [
9695
"UP", # pyupgrade
9796
]
9897

99-
[tool.mypy]
100-
python_version = "3.10"
101-
disallow_untyped_defs = true
102-
disallow_incomplete_defs = true
103-
check_untyped_defs = true
104-
disallow_untyped_decorators = true
105-
no_implicit_optional = true
106-
warn_redundant_casts = true
107-
warn_unused_ignores = true
108-
warn_return_any = true
109-
warn_unreachable = true
110-
exclude = [
111-
"^.venv/",
112-
]
113-
114-
[[tool.mypy.overrides]]
115-
module = "bm25s"
116-
ignore_missing_imports = true
117-
118-
[[tool.mypy.overrides]]
119-
module = "langgraph.*"
120-
ignore_missing_imports = true
121-
122-
[[tool.mypy.overrides]]
123-
module = "mcp.*"
124-
ignore_missing_imports = true
125-
ignore_errors = true
126-
12798
[tool.coverage.run]
12899
source = ["stackone_ai"]
129100
branch = true

stackone_ai/integrations/langgraph.py

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,16 @@
1414
from __future__ import annotations
1515

1616
from collections.abc import Sequence
17-
from typing import TYPE_CHECKING, Any
17+
from typing import Any
1818

1919
from langchain_core.tools import BaseTool
2020

2121
from stackone_ai.models import Tools
2222

23-
if TYPE_CHECKING: # pragma: no cover - only for typing
24-
try:
25-
from langgraph.prebuilt import ToolNode
26-
except Exception: # pragma: no cover
27-
28-
class ToolNode: # type: ignore[no-redef]
29-
pass
30-
3123

3224
def _ensure_langgraph() -> None:
3325
try:
34-
from langgraph import prebuilt as _ # noqa: F401
26+
from langgraph import prebuilt as _ # noqa: F401 # ty: ignore[unresolved-import]
3527
except Exception as e: # pragma: no cover
3628
raise ImportError(
3729
"LangGraph is not installed. Install with `pip install langgraph` or "
@@ -53,7 +45,7 @@ def to_tool_node(tools: Tools | Sequence[BaseTool], **kwargs: Any) -> Any:
5345
for inclusion in a graph.
5446
"""
5547
_ensure_langgraph()
56-
from langgraph.prebuilt import ToolNode # local import with helpful error
48+
from langgraph.prebuilt import ToolNode # ty: ignore[unresolved-import]
5749

5850
langchain_tools = _to_langchain_tools(tools)
5951
return ToolNode(langchain_tools, **kwargs)
@@ -66,7 +58,7 @@ def to_tool_executor(tools: Tools | Sequence[BaseTool], **kwargs: Any) -> Any:
6658
This function now returns a ToolNode for compatibility.
6759
"""
6860
_ensure_langgraph()
69-
from langgraph.prebuilt import ToolNode # local import with helpful error
61+
from langgraph.prebuilt import ToolNode # ty: ignore[unresolved-import]
7062

7163
langchain_tools = _to_langchain_tools(tools)
7264
return ToolNode(langchain_tools, **kwargs)
@@ -89,6 +81,6 @@ def create_react_agent(llm: Any, tools: Tools | Sequence[BaseTool], **kwargs: An
8981
`Tools` collection from this SDK.
9082
"""
9183
_ensure_langgraph()
92-
from langgraph.prebuilt import create_react_agent as _create
84+
from langgraph.prebuilt import create_react_agent as _create # ty: ignore[unresolved-import]
9385

9486
return _create(llm, _to_langchain_tools(tools), **kwargs)

stackone_ai/meta_tools.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def __init__(self, tools: list[StackOneTool], hybrid_alpha: float | None = None)
8686

8787
# Create BM25 index
8888
self.bm25_retriever = bm25s.BM25()
89-
corpus_tokens = bm25s.tokenize(corpus, stemmer=None, show_progress=False)
89+
corpus_tokens = bm25s.tokenize(corpus, stemmer=None, show_progress=False) # ty: ignore[invalid-argument-type]
9090
self.bm25_retriever.index(corpus_tokens)
9191

9292
# Create TF-IDF index
@@ -108,7 +108,7 @@ def search(self, query: str, limit: int = 5, min_score: float = 0.0) -> list[Met
108108
fetch_limit = max(50, limit)
109109

110110
# Tokenize query for BM25
111-
query_tokens = bm25s.tokenize([query], stemmer=None, show_progress=False)
111+
query_tokens = bm25s.tokenize([query], stemmer=None, show_progress=False) # ty: ignore[invalid-argument-type]
112112

113113
# Search with BM25
114114
bm25_results, bm25_scores = self.bm25_retriever.retrieve(

stackone_ai/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ def to_langchain(self) -> BaseTool:
426426
class StackOneLangChainTool(BaseTool):
427427
name: str = parent_tool.name
428428
description: str = parent_tool.description
429-
args_schema: type[BaseModel] = schema_class
429+
args_schema: type[BaseModel] = schema_class # ty: ignore[invalid-assignment]
430430
func = staticmethod(parent_tool.execute) # Required by CrewAI
431431

432432
def _run(self, **kwargs: Any) -> Any:

0 commit comments

Comments
 (0)