Skip to content

Commit 6a1dc55

Browse files
chore: replace mypy with ty type checker (#31)
1 parent dbe1b7e commit 6a1dc55

File tree

31 files changed

+125
-134
lines changed

31 files changed

+125
-134
lines changed

.github/workflows/build.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ jobs:
4444
- name: "Run Ruff Formatter Check"
4545
run: uv run ruff format --check --diff .
4646

47+
- name: "Run ty Type Check"
48+
run: uv run ty check --output-format github --python-version ${{ env.PYTHON_VERSION }} .
49+
4750
- name: "Run Unit Tests with Coverage"
4851
run: uv run pytest -m "not integration" --cov=src/sap_cloud_sdk --cov-report=xml --cov-report=html --cov-report=term-missing
4952

docs/DEVELOPMENT.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Tip:
3232
## Type Check
3333

3434
```bash
35-
uv run mypy src
35+
uv run ty check .
3636
```
3737

3838
## Build Project

docs/GUIDELINES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
- Use type annotations throughout the codebase (functions, methods, class attributes)
2828
- Leverage `typing` module for complex types (Union, Optional, List, Dict, etc.)
2929
- Use Protocol classes for defining interfaces/contracts
30-
- Enable strict mypy checking in development
30+
- Enable strict type checking with ty in development
3131
- Use `py.typed` marker files to indicate typed packages
3232
- Use `TypedDict` for structured dictionaries
3333

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ packages = ["src/sap_cloud_sdk"]
2727

2828
[dependency-groups]
2929
dev = [
30-
"mypy>=1.18.2",
3130
"pytest>=8.4.2",
3231
"pytest-cov>=7.0.0",
3332
"pytest-bdd>=7.2.0",
3433
"python-dotenv>=1.0.0",
34+
"ty>=0.0.21",
3535
"cryptography>=46.0.3",
3636
"ruff>=0.8.0",
3737
]
@@ -80,4 +80,7 @@ ignore = []
8080
quote-style = "double"
8181
indent-style = "space"
8282
skip-magic-trailing-comma = false
83-
line-ending = "auto"
83+
line-ending = "auto"
84+
85+
[tool.ty.environment]
86+
python-version = "3.11"

src/sap_cloud_sdk/aicore/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import json
88
import logging
99
import os
10+
from typing import Optional
1011

1112
from sap_cloud_sdk.core.telemetry.metrics_decorator import record_metrics
1213
from sap_cloud_sdk.core.telemetry.module import Module
@@ -17,7 +18,7 @@
1718

1819
def _get_secret(
1920
env_var_name: str,
20-
file_name: str = None,
21+
file_name: Optional[str] = None,
2122
default: str = "",
2223
instance_name: str = "aicore-instance",
2324
) -> str:

src/sap_cloud_sdk/core/auditlog/_transport.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,11 @@ def send(self, event: AuditMessage) -> None:
3636
TransportError: If the transport operation fails.
3737
"""
3838
pass
39+
40+
def close(self) -> None:
41+
"""Close the transport and release resources.
42+
43+
Default implementation is a no-op. Subclasses may override
44+
to perform cleanup (e.g., closing HTTP sessions).
45+
"""
46+
pass

src/sap_cloud_sdk/core/auditlog/client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ def log_batch(self, events: List[AuditMessage]) -> List[FailedMessage]:
9292

9393
def close(self) -> None:
9494
"""Close the client and cleanup resources."""
95-
if hasattr(self._transport, "close"):
96-
self._transport.close()
95+
self._transport.close()
9796

9897
def __enter__(self):
9998
"""Enter context manager."""

src/sap_cloud_sdk/core/telemetry/metrics_decorator.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Metrics decorator for telemetry with source detection from client instances."""
22

33
from functools import wraps
4-
from typing import Callable, TypeVar, ParamSpec
4+
from typing import Callable, Optional, TypeVar, ParamSpec
55

66
from sap_cloud_sdk.core.telemetry import (
77
Module,
@@ -62,9 +62,9 @@ def decorator(func: Callable[P, R]) -> Callable[P, R]:
6262
@wraps(func)
6363
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
6464
# Extract source from the client instance (self is the first argument)
65-
source = None
66-
if args and hasattr(args[0], "_telemetry_source"):
67-
source = args[0]._telemetry_source
65+
source: Optional[Module] = None
66+
if args:
67+
source = getattr(args[0], "_telemetry_source", None)
6868

6969
try:
7070
result = func(*args, **kwargs)

src/sap_cloud_sdk/core/telemetry/tracer.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"""
88

99
from contextlib import contextmanager
10-
from typing import ContextManager, Optional, Dict, Any
10+
from typing import Optional, Dict, Any
1111

1212
from opentelemetry import trace
1313
from opentelemetry.trace import Status, StatusCode, Span
@@ -130,7 +130,7 @@ def chat_span(
130130
conversation_id: Optional[str] = None,
131131
server_address: Optional[str] = None,
132132
attributes: Optional[Dict[str, Any]] = None,
133-
) -> ContextManager[Span]:
133+
):
134134
"""
135135
Create a span for LLM chat/completion API calls (OpenTelemetry GenAI Inference span).
136136
@@ -209,7 +209,7 @@ def execute_tool_span(
209209
tool_type: Optional[str] = None,
210210
tool_description: Optional[str] = None,
211211
attributes: Optional[Dict[str, Any]] = None,
212-
) -> ContextManager[Span]:
212+
):
213213
"""
214214
Create a span for tool execution in agentic workflows (OpenTelemetry GenAI Execute Tool span).
215215
@@ -277,7 +277,7 @@ def invoke_agent_span(
277277
server_address: Optional[str] = None,
278278
kind: trace.SpanKind = trace.SpanKind.CLIENT,
279279
attributes: Optional[Dict[str, Any]] = None,
280-
) -> ContextManager[Span]:
280+
):
281281
"""
282282
Create a span for GenAI agent invocation (OpenTelemetry GenAI Invoke agent span).
283283

src/sap_cloud_sdk/destination/certificate_client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ def _list_certificates(
330330
level: Level = Level.SUB_ACCOUNT,
331331
tenant_subdomain: Optional[str] = None,
332332
filter: Optional[ListOptions] = None,
333-
) -> Optional[PagedResult[Certificate]]:
333+
) -> PagedResult[Certificate]:
334334
"""Internal helper to list certificates with optional filters.
335335
336336
Args:
@@ -368,7 +368,7 @@ def _list_certificates(
368368
return PagedResult(items=certificates, pagination=pagination_info)
369369
except HttpError as e:
370370
if getattr(e, "status_code", None) == 404:
371-
return None
371+
return PagedResult(items=[])
372372
raise
373373
except DestinationOperationError:
374374
raise
@@ -382,7 +382,7 @@ def _apply_access_strategy(
382382
access_strategy: AccessStrategy,
383383
tenant: Optional[str],
384384
fetch_func: Callable[[Optional[str]], T],
385-
) -> Optional[T]:
385+
) -> T:
386386
"""Apply access strategy pattern for fetching subaccount certificates.
387387
388388
This method handles the access strategy logic (subscriber/provider precedence)
@@ -439,7 +439,7 @@ def is_empty(value) -> bool:
439439
)
440440

441441
@staticmethod
442-
def _sub_path_for_level(level: Level) -> str:
442+
def _sub_path_for_level(level: Optional[Level] = Level.SUB_ACCOUNT) -> str:
443443
"""Return API sub-path for the given level."""
444444
return (
445445
_INSTANCE_COLLECTION

0 commit comments

Comments
 (0)