Skip to content

Conversation

@zsol
Copy link

@zsol zsol commented Dec 9, 2025

Description

This PR converts all Python 2-style type annotations (in comments) into Python 3-style annotations (after : tokens, and inside the AST).

There's a large amount of changes in here, apologies for that. I generated these changes using:

  1. A LibCST codemod to do the bulk of the work: uv run --with libcst python -m libcst.tool codemod convert_type_comments.ConvertTypeComments --no-format -j1 sentry_sdk
  2. Some manual fixups here and there (see below)
  3. Run com2ann to fix the rest: uvx com2ann sentry_sdk
  4. Reformat: uvx ruff format sentry_sdk

Manual changes

  • The LibCST command made a bunch of silly mistakes like turning foo = None # type: Foo # noqa into foo: "Foo # noqa" = None, which were trivial to fix
  • When turning foo = None # type: Foo into foo: Foo = None, mypy starts raising an error on the second form - I suppressed these using type: ignore[assignment]

Test plan

mypy should continue being green, as evidenced by running uvx tox -e linters

@zsol zsol marked this pull request as ready for review December 9, 2025 17:49
@zsol zsol requested a review from a team as a code owner December 9, 2025 17:49
@alexander-alderman-webb
Copy link
Contributor

Hi @zsol,

Thank you for the PR. Upgrading the type annotation style is a breaking change because we still support Python 3.6.

We will do this work on the major branch, and can keep you updated.

@charliermarsh
Copy link

My understanding is that PEP 526 is compatible with Python 3.6 (but not Python 3.5), so IIUC this shouldn't break any Python 3.6 users.

@alexander-alderman-webb
Copy link
Contributor

alexander-alderman-webb commented Dec 12, 2025

You're correct that using PEP 526 is possible on Python 3.6.

The reason we didn't do the type transition yet is that we use some newer types, such as typing.Literal and typing.TypedDict.

We currently type check on newer Python versions, while supporting 3.6 at runtime for users. This is possible because old-style type annotations together with typing.TYPE_CHECKING prevent user runtimes from having to import types.

You can achieve an analogous result on Python 3.7 with new-style type annotations, but I believe you require __future__.annotations, which is unfortunately only available in Python 3.7. See https://peps.python.org/pep-0563/.

@sl0thentr0py
Copy link
Member

if only Literal and TypedDict are the blockers, I'm fine with removing those since I massively dislike TypedDict anyway

@alexander-alderman-webb
Copy link
Contributor

It's mainly those two. There's a few instances of other new types like typing.NotRequired and typing_extensions.Unpack.

@AlexWaygood
Copy link

You can achieve an analogous result on Python 3.7 with new-style type annotations, but I believe you require __future__.annotations, which is unfortunately only available in Python 3.7. See peps.python.org/pep-0563.

You can do the same on Python 3.6 without __future__.annotations if you're happy to use stringized/quoted annotations. Which this PR does.

@alexander-alderman-webb
Copy link
Contributor

Great to know! CI seems to fail because there are some places in which the annotations are not in quotes in this PR.

What is the motivation for the PR? We need to transition regardless, but for us to prioritize bringing this over the line it would be helpful to understand if there are limitations beyond comment-based types becoming less idiomatic.
Are there new tools for which the comment-based annotations do not work?

@AlexWaygood
Copy link

AlexWaygood commented Dec 12, 2025

Great to know! CI seems to fail because there are some places in which the annotations are not in quotes in this PR.

Ah, cool, that's a bug in the PR! Thanks for the heads-up (cc. @zsol)

What is the motivation for the PR? We need to transition regardless, but for us to prioritize bringing this over the line it would be helpful to understand if there are limitations beyond comment-based types becoming less idiomatic. Are there new tools for which the comment-based annotations do not work?

Yes. The main motivation is that newer type checkers such as ty do not support the legacy syntax. (Full disclosure: I'm a ty developer and Zsolt's a colleague, though he doesn't work on ty.) It would be quite a bit of work for us to add support for the legacy syntax to ty, so we're reluctant to do so given that it's only required for compatibility with Python <=3.5. Meanwhile, we're big fans of Sentry, and have other code elsewhere that uses Sentry. We'd love to type-check that code with ty, but doing so currently produces poor results, because ty can't understand any of Sentry's legacy type hints.

Note that there have also been discussions about deprecating the legacy syntax from the type system altogether, albeit those discussions have been dormant for a while now:

Other tools such as pyflakes/flake8 dropped support for type comments a while back, and Ruff has never supported them.

@alexander-alderman-webb
Copy link
Contributor

Thank you for the detailed explanation, and thank you for using Sentry!

We didn't transition yet because of internal misunderstanding that we need __future__.annotations. We are happy to support your efforts so that others can use ty with sentry-python.

The steps already in the PR descriptions are great since we'll verify the manual fixes. If you have a systematic way of putting all annotations in quotes keep us updated. Otherwise, I'll pick up from here next week.

@zsol
Copy link
Author

zsol commented Dec 12, 2025

I'm happy to get this PR green for you!

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.

5 participants