Closed CarliJoy closed 11 months ago
isinstance does not produce an intersection. This isn't needed, and any language that caused isinstance to create a virtual intersection could negatively impact more complex heuristics that type checkers already implement.
See eric's comment here, and specifically this section:
There has been some confusion about whether an isinstance type guard could make use of intersections. The behavior of type narrowing by type guards is not part of the typing spec, so type checkers are free to decide which type guard patterns they implement and how to trade off strictness vs pragmatism. I wouldn't want to change that, so any attempt to dictate how type guards work (including the isinstance type guard) is something I will push back on. The isinstance type guard logic in pyright is very complex and involves many tradeoffs and heuristics, and it continues to evolve over time. There are a couple of cases where it produces an intersection — or something akin to an intersection. One case (which I've already mentioned above) is where the type of the first argument is a type variable. Pyright uses "conditional types" for this case. The other case is where the type of the first argument is a type that has no apparent overlap with the type passed as the second argument. In this case, pyright (and mypy) create an intersection of the two types by synthesizing a new class that derives from both of the types. If "real intersections" were added to the type system, this would be a good candidate for their use, but the current solution works well, so "real intersections" wouldn't add any net new value here.
Thanks for finding that @mikeshardmind
I will close this than :-)
There is a long discussion ongoing in how to handle
Any
within intersections in #1 and #31.A form of intersections are already implemented in some type checkers, i.e. MyPy
The solutions discussed in #1 and #31 could change the behaviour of
if isinstance(any, T)
. Therefore I propose to include a sentence like."… Even so isinstance acts similar to an intersection, types of
Any
for that an instanceT
was determined are always treated asT
and never asT&Any
."A second proposal is that we include a sentence like "An
isinstance
of a variable of typeT1
for a typeT2
that isn't a subtype ofT1
should be treated asT1 & T2
by a type checker in type narrowing."Note:
Any
can't be used a type forisinstance
.What do you think?
I would like to prevent surprises no matter what we decide in #1 or #31. Also having only one "kind" of intersection would make things easier IMHO.