Skip to content

Conversation

@zzstoatzz
Copy link
Collaborator

@zzstoatzz zzstoatzz commented Dec 17, 2025

summary

  • switches from mypy to ty for type checking in pre-commit
  • ty is astral's new extremely fast python type checker written in rust (10-60x faster than mypy/pyright)
  • keeps mypy for pytest-mypy-plugins typesafety tests in tests/typesafety/

approach

starting with permissive rules - all ~1100 existing errors are ignored for now and can be gradually enabled as we fix them.

fast-follow PRs

here's a breakdown of the error categories, roughly in order of ease/impact:

1. invalid-parameter-default (71 errors) - easy wins

mostly fastapi endpoints with param: SomeFilter = None that should be param: SomeFilter | None = None:

# before
artifacts: filters.ArtifactFilter = None

# after  
artifacts: filters.ArtifactFilter | None = None

2. unresolved-import (18 errors) - conditional imports

imports inside try/except blocks for optional dependencies (pendulum, logfire, apprise plugins). ty doesn't understand these are guarded - may need # ty: ignore comments or restructuring.

3. invalid-assignment (95 errors) - mixed bag

  • monkey-patching __init__ in deprecation decorators (~10 errors)
  • dict subscript assignments where ty infers wrong types
  • implicit shadowing of class attributes

4. invalid-return-type (134 errors) - generic type issues

many in _internal/concurrency/ where Call[T].result() returns T but ty infers Unknown. likely needs better type annotations on the Call class.

5. invalid-argument-type (370 errors) - largest category

  • callable/generics confusion in concurrency code (cast_to_call, call_soon_in_*)
  • httpx client method signatures
  • pydantic model validation where ty doesn't understand validators

6. unresolved-attribute (134 errors) - dynamic attributes

  • __name__ on wrapped functions - ty doesn't understand @wraps
  • private methods on type objects - Block class introspection
  • sys.maxint in vendored croniter (py2 compat)
  • module-level private attrs (threading._register_atexit)

7. possibly-missing-attribute (139 warnings) - optional checks

Optional[X] used without None checks. mostly in task/flow engine code where we know the attribute exists at runtime.

8. invalid-method-override (23 errors) - inheritance issues

subclasses with incompatible method signatures. needs investigation.

9. other smaller categories

  • non-subscriptable (27) - likely type annotation issues
  • invalid-await (25) - async/sync confusion in type stubs
  • no-matching-overload (18) - overload resolution failures

changes

  • adds ty>=0.0.2 to dev dependencies
  • adds [tool.ty] config to pyproject.toml with permissive rules
  • replaces mypy pre-commit hook with ty local hook
  • updates mypy config comment to clarify it's kept for typesafety tests

testing

# verify ty passes
uv run ty check

# verify typesafety tests still work  
uv run pytest tests/typesafety/ -v

references

🤖 Generated with Claude Code

ty is astral's new extremely fast python type checker written in rust.
this replaces mypy in pre-commit with ty while keeping mypy for the
pytest-mypy-plugins typesafety tests.

starting with permissive rules - all existing errors are ignored for now
and can be gradually enabled as we fix them.

see https://astral.sh/blog/ty

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@codspeed-hq
Copy link

codspeed-hq bot commented Dec 17, 2025

Merging this PR will not alter performance

Summary

✅ 2 untouched benchmarks


Comparing chore/switch-to-ty (5015e20) with main (600a6a7)

Open in CodSpeed

@github-actions
Copy link
Contributor

This pull request is stale because it has been open 14 days with no activity. To keep this pull request open remove stale label or comment.

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