Skip to content

Commit ac3d455

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 3832630 commit ac3d455

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
@@ -5288,6 +5288,23 @@ f_g(h) # E: Argument 1 to "f_g" has incompatible type "H"; expected "G"
52885288
[builtins fixtures/dict.pyi]
52895289
[typing fixtures/typing-typeddict.pyi]
52905290

5291+
[case testTypedDictSubtypingClosedTypeVarBound]
5292+
from typing import TypedDict, TypeVar
5293+
A = TypedDict('A', {'x': int}, closed=True)
5294+
B = TypedDict('B', {'x': int})
5295+
TA = TypeVar('TA', bound=A)
5296+
TB = TypeVar('TB', bound=B)
5297+
def fA(t: TA) -> TA: return t
5298+
def fB(t: TB) -> TB: return t
5299+
a: A
5300+
b: B
5301+
fA(a)
5302+
fA(b) # E: Value of type variable "TA" of "fA" cannot be "B"
5303+
fB(a)
5304+
fB(b)
5305+
[builtins fixtures/dict.pyi]
5306+
[typing fixtures/typing-typeddict.pyi]
5307+
52915308
[case testJoinOfClosedTypedDict]
52925309
from typing import TypedDict, TypeVar
52935310
A = TypedDict('A', {'x': int}, closed=True)

0 commit comments

Comments
 (0)