Skip to content

chore!: drop Python 3.10 support - #1923

Draft
hassiebp wants to merge 3 commits into
mainfrom
hassiebbot/drop-python-310-f754
Draft

hassiebp wants to merge 3 commits into
mainfrom
hassiebbot/drop-python-310-f754

Conversation

@hassiebp

@hassiebp hassiebp commented Oct 3, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

Drops Python 3.10, which reaches end of life in October 2026, and removes the code that only existed for it. It also fixes the one 3.15 deprecation in SDK code. Python 3.15 is not added to CI yet; see below.

  • requires-python is now >=3.11, ruff targets py311, 3.10 is removed from the unit-test matrix, and AGENTS.md is updated.
  • observe.py: the async generator wrapper always uses asyncio.create_task(..., context=...) (3.11+), so the context.run(asyncio.create_task, ...) fallback, the version flag, and the unit test that monkeypatched it are gone.
  • types.py: NotRequired comes from typing directly, without the typing_extensions fallback.
  • The skipif(sys.version_info < (3, 11)) markers are removed from unit and e2e tests.
  • uv.lock (regenerated with the CI-pinned uv 0.11.2) only drops exceptiongroup, tomli, and backports-asyncio-runner. No package versions change.
  • Separate commit: inspect.iscoroutinefunction replaces asyncio.iscoroutinefunction, which warns on 3.14+ and is removed in 3.16. I checked that both return identical results on 3.11 through 3.15 for plain functions, partials, bound methods, static methods, and AsyncMock.
  • Separate commit: ruff format fix for pre-existing drift in tests/unit/test_media.py (blank lines only).

Impact: about 10.6% of monthly PyPI downloads still come from 3.10 (pypistats). Those users will stay on 4.16.x. This should probably go out as a clearly noted minor release.

Why 3.15 is not in the matrix yet

uv sync --locked fails on 3.15 (only 3.15.0rc2 is available; setup-python doesn't have a final yet):

  • Runtime: the latest stable pydantic, 2.13.5, pins pydantic-core==2.46.5, which has no cp315 wheels. Only the pydantic 2.14 betas use a 3.15-ready core. Until 2.14 ships, pip install langfuse on 3.15 has to compile pydantic-core with Rust, whatever this SDK declares.
  • Dev: the locked tiktoken and ormsgpack (pulled in by langchain-openai and langgraph) have no cp315 wheels.

With 3.15.0rc2 and pydantic==2.14.0b2, the unit suite passes, apart from the LangChain tests, which couldn't be installed: 633 passed, 2 skipped. Adding "3.15" to the matrix (plus a lock upgrade) should be a one-line follow-up once pydantic 2.14 is released.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Refactor
  • Documentation update
  • Tooling, CI, or repo maintenance

Verification

uv run --frozen ruff check .                       # All checks passed!
uv run --frozen ruff format --check .              # 649 files already formatted
uv run --frozen mypy langfuse --no-error-summary   # clean
uv run --frozen --python 3.11 pytest -n auto tests/unit   # 708 passed, 2 skipped
uv run --frozen --python 3.14 pytest -n auto tests/unit   # 708 passed, 2 skipped
# 3.15.0rc2 + pydantic 2.14.0b2, without the langchain test files:
pytest -n auto tests/unit   # 633 passed, 2 skipped; no SDK-originated DeprecationWarnings remain

I didn't run the e2e tests locally because they need a Langfuse server. The only e2e change is removing the 3.11 skip markers.

Checklist

  • I self-reviewed the diff using code_review.md.
  • I added or updated tests for behavior changes.
  • I updated docs, examples, or .env.template if needed.
  • I did not hand-edit generated files; if generated files changed, I used the upstream regeneration path.
  • I did not commit secrets or credentials.
Open in Web Open in Cursor 

cursoragent and others added 3 commits October 3, 2026 02:33
…syncio variant

asyncio.iscoroutinefunction emits a DeprecationWarning on Python 3.14+
and is slated for removal in Python 3.16.

Co-authored-by: Hassieb Pakzad <hassiebp@users.noreply.github.com>
Co-authored-by: Hassieb Pakzad <hassiebp@users.noreply.github.com>
Python 3.10 reaches end of life in October 2026. Raise requires-python
to >=3.11, remove 3.10 from the CI matrix, and drop code paths that only
existed for 3.10: the asyncio.create_task(context=...) fallback in the
async generator wrapper, the typing_extensions NotRequired fallback, and
the 3.11 test skips.

Co-authored-by: Hassieb Pakzad <hassiebp@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

2 participants