Skip to content

Commit f550466

Browse files
committed
Implement closed support in TypeAnalyser
Propagate closed when analysing a TypedDictType with a fallback. This ensures subtype checks work correctly for a TypeVar with a closed TypedDict upper bound.
1 parent a8cb4c6 commit f550466

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

mypy/typeanal.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,7 @@ def visit_typeddict_type(self, t: TypedDictType) -> Type:
13471347
" must be enabled with --enable-incomplete-feature=InlineTypedDict",
13481348
t,
13491349
)
1350+
is_closed = False
13501351
required_keys = req_keys
13511352
fallback = self.named_type("typing._TypedDict")
13521353
for typ in t.extra_items_from:
@@ -1369,9 +1370,9 @@ def visit_typeddict_type(self, t: TypedDictType) -> Type:
13691370
readonly_keys = t.readonly_keys
13701371
required_keys = t.required_keys
13711372
fallback = t.fallback
1372-
# TODO: Implement closure analysis
1373+
is_closed = t.is_closed
13731374
return TypedDictType(
1374-
items, required_keys, readonly_keys, False, fallback, t.line, t.column
1375+
items, required_keys, readonly_keys, is_closed, fallback, t.line, t.column
13751376
)
13761377

13771378
def visit_raw_expression_type(self, t: RawExpressionType) -> Type:

test-data/unit/check-typeddict.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5246,6 +5246,23 @@ f_g(h) # E: Argument 1 to "f_g" has incompatible type "H"; expected "G"
52465246
[builtins fixtures/dict.pyi]
52475247
[typing fixtures/typing-typeddict.pyi]
52485248

5249+
[case testTypedDictSubtypingClosedTypeVarBound]
5250+
from typing import TypedDict, TypeVar
5251+
A = TypedDict('A', {'x': int}, closed=True)
5252+
B = TypedDict('B', {'x': int})
5253+
TA = TypeVar('TA', bound=A)
5254+
TB = TypeVar('TB', bound=B)
5255+
def fA(t: TA) -> TA: return t
5256+
def fB(t: TB) -> TB: return t
5257+
a: A
5258+
b: B
5259+
fA(a)
5260+
fA(b) # E: Value of type variable "TA" of "fA" cannot be "B"
5261+
fB(a)
5262+
fB(b)
5263+
[builtins fixtures/dict.pyi]
5264+
[typing fixtures/typing-typeddict.pyi]
5265+
52495266
[case testJoinOfClosedTypedDict]
52505267
from typing import TypedDict, TypeVar
52515268
A = TypedDict('A', {'x': int}, closed=True)

0 commit comments

Comments
 (0)