Skip to content

Consistency of reveal_type results with other type checkers #113255

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
gkirchou opened this issue Dec 18, 2023 · 5 comments · Fixed by #113326
Closed

Consistency of reveal_type results with other type checkers #113255

gkirchou opened this issue Dec 18, 2023 · 5 comments · Fixed by #113326
Labels
docs Documentation in the Doc dir topic-typing

Comments

@gkirchou
Copy link

gkirchou commented Dec 18, 2023

Bug report

Bug description:

Not sure if this bug is reported before.

FWIK, CPython's reveal_type was introduced based on the motivation of the same features in type checkers. But I found out the behavior is inconsistent, at least between CPython, mypy, and pytype based on the cases in Python 3 Types in the Wild: A Tale of Two Type Systems.

Case 1:

a = 1
reveal_type(a)
a = 's'
reveal_type(a)

Case 2

a = [1]
reveal_type(a)
a.append('s')
reveal_type(a)

Case 3

class A:
    attr = 1
a = A()
reveal_type(a.attr)
a.attr = 's'
reveal_type(a.attr)
reveal_type Case1 Case2 Case3
CPython int, str list, list int, str
mypy int, assignment error list[int], arg-type error int, assignment error
pytype int, str List[int], List[Union[int,str] int, str

For code without type annotations, the current behavior is closer to pytype. Case 2 is unclear, because CPython's reveal_type doesn't show the types for the elements.

And even if I add type to the code to address mypy errors, the result is still inconsistent:

Case 1:

a: int|str = 1
reveal_type(a)
a = 's'
reveal_type(a)

Case 2

a: list[int|str] = [1]
reveal_type(a)
a.append('s')
reveal_type(a)

Case 3

class A:
    attr: int|str = 1
a = A()
reveal_type(a.attr)
a.attr = 's'
reveal_type(a.attr)
reveal_type Case1 Case2 Case3
CPython int, str list, list int, str
mypy Union[int,str], str List[Union[int, str]], List[Union[int, str]] Union[int,str], str
pytype Union[int,str], str List[Union[int, str]], List[Union[int, str]] int, str

I don't know what's the best behavior, while reveal_type in CPython may not be fully aligned with any type checker's type systems. Based on the motivation, will it make sense to align the behavior with at least mypy's reveal_type?

CPython versions tested on:

3.11, 3.12

Operating systems tested on:

Linux, macOS

Linked PRs

@gkirchou gkirchou added the type-bug An unexpected behavior, bug, or error label Dec 18, 2023
@kandeldeepak46
Copy link

Without type hints:
reveal_type results may differ from other checkers due to varying inference capabilities.
Adding type hints generally improves consistency.
With type hints:
Mostly, results should be consistent, but may still differ for edge cases or complex scenarios.
Current behavior:
Closer to pytype for untyped code.
Shows element types for lists in contrast to CPython's reveal_type.

@carljm
Copy link
Member

carljm commented Dec 18, 2023

Thanks for the report and the careful analysis! But I don't think that full consistency between what CPython shows at runtime for reveal_type and what static type checkers show is a valuable (or achievable) goal. Static type checkers in some cases will know more (e.g. they track generic types, like the element types of a list, which are intentionally erased at runtime), and in some cases will know less (for example, a runtime value will never be a union, it will always be one concrete type or the other, but static type systems use union types to represent that at runtime the value may be any of several types.) These differences are unavoidable and inherent to the difference between runtime execution and static analysis.

It should be a goal for the statically-known types and the runtime types to be compatible, but this is a very different (and much weaker) goal than identical output from reveal_type. For example, it is perfectly compatible for the runtime to report list and a static type checker list[int], or for the runtime to report int and a static checker to report Union[int, str].

In general, cases where type checkers report types that are not even compatible with the runtime types are bugs in type checkers, not bugs in CPython, and should be reported to the relevant type checker. (Unless of course it's a bug in CPython for another reason, such as violating CPython's own documented intended behavior; but mismatch with a static type checker is not in itself an indication of a bug in CPython.)

So I don't believe there is anything actionable for CPython in this report, and I think it should be closed. Will mark it pending for now to allow for some discussion if others don't agree.

@carljm carljm added the pending The issue will be closed if no feedback is provided label Dec 18, 2023
@AlexWaygood
Copy link
Member

I agree with everything @carljm says above. The only thing I can think of that might be actionable here would be to improve the docs around this function: perhaps it could be articulated more clearly that it's not necessarily a bug for the runtime output of this function to differ from the output a type checker emits on encountering this function https://docs.python.org/3/library/typing.html#typing.reveal_type

@gkirchou
Copy link
Author

Thanks for the comment @carljm! It's very clear and helpful, my confusion is fully resolved.

As @AlexWaygood suggested, I used my personal account @note35 to send a PR to improve the doc based on your comment. PTaL!

@AlexWaygood AlexWaygood added docs Documentation in the Doc dir and removed pending The issue will be closed if no feedback is provided type-bug An unexpected behavior, bug, or error labels Dec 19, 2023
AlexWaygood added a commit that referenced this issue Dec 20, 2023
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Dec 20, 2023
(cherry picked from commit 11ee912)

Co-authored-by: Kir <[email protected]>
Co-authored-by: AlexWaygood <[email protected]>
AlexWaygood added a commit that referenced this issue Dec 20, 2023
…113323)

gh-113255: Clarify docs for `typing.reveal_type` (GH-113286)
(cherry picked from commit 11ee912)

Co-authored-by: Kir <[email protected]>
Co-authored-by: AlexWaygood <[email protected]>
AlexWaygood added a commit to AlexWaygood/cpython that referenced this issue Dec 20, 2023
AlexWaygood added a commit that referenced this issue Dec 20, 2023
@AlexWaygood
Copy link
Member

Thanks for the PR, @gkirchou!

ryan-duve pushed a commit to ryan-duve/cpython that referenced this issue Dec 26, 2023
kulikjak pushed a commit to kulikjak/cpython that referenced this issue Jan 22, 2024
aisk pushed a commit to aisk/cpython that referenced this issue Feb 11, 2024
Glyphack pushed a commit to Glyphack/cpython that referenced this issue Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir topic-typing
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants
@carljm @kandeldeepak46 @AlexWaygood @gkirchou and others