Skip to content

chore: modernize typing for Python 3.10+ minimum#356

Merged
Abhijeet Prasad (AbhiPrasad) merged 10 commits intomainfrom
chore/modernize-python-310-typing
Apr 27, 2026
Merged

chore: modernize typing for Python 3.10+ minimum#356
Abhijeet Prasad (AbhiPrasad) merged 10 commits intomainfrom
chore/modernize-python-310-typing

Conversation

@starfolkai
Copy link
Copy Markdown
Contributor

@starfolkai starfolkai Bot commented Apr 27, 2026

Summary

  • Removes stale Python 3.8/3.9 compatibility patterns now that requires-python = ">=3.10.0"
  • Replaces Union[X, Y] with X | Y syntax (PEP 604)
  • Replaces Optional[X] with X | None
  • Replaces typing.List, typing.Dict, etc. with builtin list, dict and collections.abc equivalents
  • Moves Protocol and TypedDict from typing_extensions to stdlib typing (where compatible)
  • Adds proper type annotation to prettify_xact() and TracedThreadPoolExecutor.submit()
  • Removes dead sys.version_info < (3, 9) skipif guard
  • Fixes serializable_data_class.from_dict_deep to handle types.UnionType (the runtime type produced by X | Y on Python 3.10–3.12, which differs from typing.Union)

Intentionally kept:

  • Union import in serializable_data_class.py and devserver/schemas.py — used as a runtime sentinel for get_origin() checks
  • TypedDict from typing_extensions in types/_eval.py — stdlib typing.TypedDict on Python 3.10 does not support Generic + TypedDict multiple inheritance
  • NotRequired from typing_extensions — only available in stdlib typing since 3.11
  • _generated_types.py — auto-generated, not hand-edited
  • Optional[str] in docstrings — documentation text, not type annotations

Test plan

  • make test-core passes (442 passed)
  • nox -s test_types passes (pyright + mypy + pytest)
  • make fixup passes (ruff format, ruff check, codespell, stale cassettes)
  • CI green across Python 3.10–3.14 (static_checks, nox shards, smoke tests, integration tests)

🤖 Generated with Claude Code

Nova (SFK) and others added 7 commits April 27, 2026 19:39
The SDK requires Python >=3.10, so the `sys.version_info < (3, 9)`
guard on `test_to_thread_preserves_context` is always False and can
be removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Now that min Python is 3.10, use `int | str` union syntax directly
in the type annotation instead of leaving it untyped with a comment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…r.submit

Future[T] generic typing has been stable since Python 3.9; with min
Python 3.10 we no longer need to return Any as a workaround.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both have been in stdlib typing since Python 3.8. With min Python
3.10, no need for the typing_extensions backport.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
With min Python 3.10, the union pipe syntax is available at runtime.
Migrates type aliases and annotations in framework.py, logger.py,
util.py, prompt.py, functions/stream.py, and langchain/callbacks.py.

Keeps Union imports where used as a runtime sentinel for
get_origin() checks (serializable_data_class.py, devserver/schemas.py).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Modernizes type annotations across merge_row_batch.py, trace.py,
span_cache.py, otel/context.py, langsmith_wrapper.py, and
test_serializable_data_class.py. Removes unused Optional imports.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Migrates legacy typing container imports (List, Dict, AsyncGenerator,
Generator, Callable, Mapping, Sequence, Iterable, Iterator, Awaitable)
to their modern equivalents: lowercase builtins (list, dict) and
collections.abc for abstract types.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Nova (SFK) and others added 2 commits April 27, 2026 20:03
The regex-based Optional→|None replacement incorrectly placed
| None inside Callable's return type instead of outside the whole
Callable, changing the type semantics:

- `Optional[Callable[[], Awaitable[X]]]` (callable is nullable)
  was wrongly converted to
  `Callable[[], Awaitable[X] | None]` (return type is nullable)

Fixed to: `Callable[[], Awaitable[X]] | None`

Also moves Callable from typing to collections.abc in
langsmith_wrapper.py for consistency with other files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On Python 3.10, stdlib typing.TypedDict does not support inheriting
from both Generic and TypedDict simultaneously. The typing_extensions
backport handles this correctly, so TypedDict must stay in
typing_extensions for types/_eval.py.

Also applies ruff format/check fixes (import sorting, line
collapsing).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
On Python 3.10-3.12, the `X | Y` syntax creates a `types.UnionType`
which is distinct from `typing.Union`. The `from_dict_deep` method
in `SerializableDataClass` only checked for `typing.Union` via
`get_origin`, so it failed to deserialize union-typed fields when
the annotation used pipe syntax (e.g. `PromptBlockData`).

Also fixes a missed `cast(List, ...)` → `cast(list, ...)` in
langchain test_callbacks.py that caused a pylint E0602.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AbhiPrasad Abhijeet Prasad (AbhiPrasad) merged commit 0269b68 into main Apr 27, 2026
82 checks passed
@AbhiPrasad Abhijeet Prasad (AbhiPrasad) deleted the chore/modernize-python-310-typing branch April 27, 2026 20:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant