Open ikonst opened 1 year ago
Just a note that perhaps, the current behavior can be patched in another (if worse) way?
https://github.com/python/mypy/issues/7981#issuecomment-557079403 as mentioned here, final typeddict semantics was accepted knowing that you wouldn't be able to consider structural subtyping... as far as I read it?
i.e. this should fail (it doesn't right now):
from typing import TypedDict, final
@final
class A(TypedDict):
x: int
class B(TypedDict):
x: int
y: int
y: B = {"x": 42, "y": 42}
x: A = y
... but at the same time https://github.com/python/mypy/pull/15425 was accepted so this new unsafety is probably ok.
@hauntsaninja Judging by your comment here, let's ship it? :)
It would appear that's also how people expect it to be.
FWIW there are some typos in the example -- mypy doesn't accept it as written. The last lines probably were intended to be:
animal: Mammal | Bird
if 'eggs' in animal:
assert_type(animal, Bird) # WRONG! Could still be a Mammal (a Echidna)
if 'eggs' in animal and 'mammary_glands' in animal:
assert_never(animal) # WRONG! Could still be a Mammal (a Echidna)
Thanks @gvanrossum, edited the PR.
We shouldn't require
@final
decoration for TypedDicts to narrow them based on the 'in' operator.Why?
Basically @erictraut's comment.
In #13838, we've added "key in Union[TypedDict, ...]" narrowing for TypedDicts that are marked
@final
. The reason was to prevent this:However, per @erictraut's comment, due to TypedDict being a structural type, we shouldn't consider the class hierarchy when type-matching.
This will be consistent with pyright and TypeScript (Playground Link).