How do people feel about being able to use reveal_type as a built-in (from the type checker’s point of view, not the runtime), without having to import it from typing?
It has only existed in typing at runtime since Python 3.11; before that it was always just special-cased in type checkers as a pseudo-builtin.
Both mypy and pyright still support use of reveal_type as a built-in, even when checking on Python 3.11+.
The spec is not currently very clear on this behavior. It doesn’t even acknowledge the possibility of importing from typing (probably because that text predates Python 3.11), which suggests that it is specifying reveal_type as a pseudo built-in.
Is there broader appetite for such a deprecation, or should we instead clarify that use of reveal_type as a builtin is and will continue to be supported?
Personally, I think there’s a case to be made in favor of specifying this behavior and keeping it. reveal_type is useful (in a CLI context, where LSP hover isn’t available) for quickly checking the type checker’s understanding of an expression’s type. It can be a major impediment to such use if it can’t just quickly be inserted around an expression of interest, but also requires adding (and then removing) an entire import statement. (If the typing module is already imported, one can just use typing.reveal_type(...) instead; but the typing module isn’t always already imported.)
The other argument against deprecation is just “status quo wins” if there aren’t strong reasons to deprecate.
Thoughts? Anyone have strong feelings in favor of deprecation?
Are you also interested in considering making reveal_type an actual (ordinary) built-in?
The pain of having it as a pseudo-built-in: Sometimes I forget reveal_type in my code while I’m debugging and then because it wasn’t imported, it crashes my code and I have to run the program again.
The pain of deprecating it is having to import it in scripts, CLI, etc.
The pain of having it as a built-in is breaking a very small amount of code?
I wouldn’t be opposed to this (it is annoying that it fails at runtime), but I’m also not that interested in championing it. There tends to be some pushback on proposals to wire typing more deeply into the language, and if I’m going to spend time on that conversation, this wouldn’t be my first priority to push for.
I’m neutral on making it an actual builtin, negative on keeping it as something type checkers recognize without an import unless we add a mandate that when they do so, they loudly announce that it’s missing from an import when not in an if typing.TYPE_CHECKING conditional block to prevent it from being overlooked.
It’s a small negative here and not something I would lead arguing to remove, but as Neil said, it’s relatively easy to miss that it’s been left in without an import when language servers are powered by a type checker (see pyright/pylance relationship, pylance doesn’t catch this is missing an import due to being built off of pyright that recognizes reveal_type without it)
Yeah, basically +1 to mikeshardmind. If I were writing a new type checker, I would default to behaviour similar to mypy’s --enable-error-code unimported-reveal
I’m not aware of any pain caused by the current lack of specification here, so my inclination is to just stick with the status quo and leave this unspecified.
If we were to specify something here, I don’t have a strong opinion on whether it should be treated as a built-in or require an import. I guess I slightly lean toward not requiring an import for the reasons @carljm states. I think it’s typically used for quick experimentation, so the risk of it being left in production code is pretty small.
I am strongly against mandating (or in any way special-casing) type checking behaviors based whether the code is within a TYPE_CHECKING block.
If the above were amended to not have that special case, and that type checkers should additionally note when reveal type is used without importing, would this be an acceptable outcome?
I don’t think it’s a big deal one way or the other, but if we can hit some middle ground that helps avoid the accidentally left in (especially if it ends up in a rarely hit code branch where it might not be noticed right away) while letting people experiment quickly, I see some value in that.
I wouldn’t want to change the behavior based on if TYPE_CHECKING, but I do think mypy’s --enable-error-code unimported-reveal is a reasonable behavior. The extra diagnostic about unimported reveal_type doesn’t really inhibit the quick temporary debugging usage at all, but it does help prevent unintentionally leaving the reveal_type in place.
(I also don’t actually feel strongly about this being specified, I’m really just looking for input on how people prefer their type checkers to behave in this area.)
As an IDE plugin developer, I have chosen to preserve both “missing import” and “reveal type” annotations instead of suppressing the former. The result thus looks like this (please ignore the messages):
That said, I’m with Michael and Shantanu: I think Mypy’s unimported-reveal makes the most sense. A stray reveal_type() might cause the code to fail at runtime; why shouldn’t the user be notified about that?