fix(mypy): resolve OpenTelemetry typing issues in telemetry.py (#3931)

## Summary

Fix all 11 mypy type checking errors in `telemetry.py` without using any
type suppressions.

**Changes:**
- Add type aliases for OpenTelemetry attribute types (`AttributeValue`,
`Attributes`)
- Create `_clean_attributes()` helper to filter None values from
attribute dicts
- Use `cast()` for TracerProvider methods (`add_span_processor`,
`force_flush`)
- Use `cast()` for metric creation methods returning from global storage
- Fix variable reuse by renaming `span` to `end_span` in SpanEndPayload
branch
- Add None check for `parent_span` before `set_span_in_context`

**Errors Fixed:**
- TracerProvider attribute access: 2 errors
- Counter/UpDownCounter/ObservableGauge return types: 3 errors
- Attribute dict type mismatches: 4 errors
- Span assignment type conflicts: 2 errors

**Testing:**
```bash
uv run mypy src/llama_stack/core/telemetry/telemetry.py
# Success: no issues found
```

**Part of:** Mypy suppression removal plan (Phase 2a/4)

**Stack:**
- [Phase 1] Add type stubs (#3930)
- [Phase 2a] Fix OpenTelemetry types (this PR)
- [Phase 2b+] Fix remaining errors (upcoming)
- [Phase 3] Remove inline suppressions (upcoming)
- [Phase 4] Un-exclude files from mypy (upcoming)
This commit is contained in:
Ashwin Bharambe 2025-10-28 09:47:20 -07:00 committed by GitHub
parent 5598f61e12
commit 9afc52a36a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 49 additions and 423 deletions

View file

@ -4,7 +4,7 @@
# This source code is licensed under the terms described in the LICENSE file in
# the root directory of this source tree.
from collections.abc import Mapping, Sequence
from typing import Any, Literal
from typing import Any, Literal, cast
from sqlalchemy import (
JSON,
@ -55,17 +55,17 @@ def _build_where_expr(column: ColumnElement, value: Any) -> ColumnElement:
raise ValueError(f"Operator mapping must have a single operator, got: {value}")
op, operand = next(iter(value.items()))
if op == "==" or op == "=":
return column == operand
return cast(ColumnElement[Any], column == operand)
if op == ">":
return column > operand
return cast(ColumnElement[Any], column > operand)
if op == "<":
return column < operand
return cast(ColumnElement[Any], column < operand)
if op == ">=":
return column >= operand
return cast(ColumnElement[Any], column >= operand)
if op == "<=":
return column <= operand
return cast(ColumnElement[Any], column <= operand)
raise ValueError(f"Unsupported operator '{op}' in where mapping")
return column == value
return cast(ColumnElement[Any], column == value)
class SqlAlchemySqlStoreImpl(SqlStore):
@ -210,10 +210,8 @@ class SqlAlchemySqlStoreImpl(SqlStore):
query = query.limit(fetch_limit)
result = await session.execute(query)
if result.rowcount == 0:
rows = []
else:
rows = [dict(row._mapping) for row in result]
# Iterate directly - if no rows, list comprehension yields empty list
rows = [dict(row._mapping) for row in result]
# Always return pagination result
has_more = False