Skip to content

Commit dbca5a5

Browse files
authored
TypedDict: Fix casefolding of 'missing keys' error message (#9757)
Previously the message accidentally converted all identifiers to lowercase. By rephrasing the message, I avoided complicating the `format_key_list()` function.
1 parent 705f881 commit dbca5a5

File tree

2 files changed

+16
-9
lines changed

2 files changed

+16
-9
lines changed

mypy/messages.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,8 +1118,8 @@ def unexpected_typeddict_keys(
11181118
if actual_set < expected_set:
11191119
# Use list comprehension instead of set operations to preserve order.
11201120
missing = [key for key in expected_keys if key not in actual_set]
1121-
self.fail('{} missing for TypedDict {}'.format(
1122-
format_key_list(missing, short=True).capitalize(), format_type(typ)),
1121+
self.fail('Missing {} for TypedDict {}'.format(
1122+
format_key_list(missing, short=True), format_type(typ)),
11231123
context, code=codes.TYPEDDICT_ITEM)
11241124
return
11251125
else:

test-data/unit/check-typeddict.test

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ p = Point(x=42, y=1337, z=666) # E: Extra key 'z' for TypedDict "Point"
6666
[case testCannotCreateTypedDictInstanceWithMissingItems]
6767
from mypy_extensions import TypedDict
6868
Point = TypedDict('Point', {'x': int, 'y': int})
69-
p = Point(x=42) # E: Key 'y' missing for TypedDict "Point"
69+
p = Point(x=42) # E: Missing key 'y' for TypedDict "Point"
7070
[builtins fixtures/dict.pyi]
7171

7272
[case testCannotCreateTypedDictInstanceWithIncompatibleItemType]
@@ -149,7 +149,7 @@ def foo(x):
149149
# type: (Movie) -> None
150150
pass
151151

152-
foo({}) # E: Keys ('name', 'year') missing for TypedDict "Movie"
152+
foo({}) # E: Missing keys ('name', 'year') for TypedDict "Movie"
153153
foo({'name': 'lol', 'year': 2009, 'based_on': 0}) # E: Incompatible types (expression has type "int", TypedDict item "based_on" has type "str")
154154

155155
[builtins fixtures/dict.pyi]
@@ -871,7 +871,7 @@ Point = TypedDict('Point', {'x': int, 'y': int})
871871
def f(p: Point) -> None:
872872
if int():
873873
p = {'x': 2, 'y': 3}
874-
p = {'x': 2} # E: Key 'y' missing for TypedDict "Point"
874+
p = {'x': 2} # E: Missing key 'y' for TypedDict "Point"
875875
p = dict(x=2, y=3)
876876

877877
f({'x': 1, 'y': 3})
@@ -888,15 +888,15 @@ from mypy_extensions import TypedDict
888888

889889
Point = TypedDict('Point', {'x': int, 'y': int})
890890

891-
p1a: Point = {'x': 'hi'} # E: Key 'y' missing for TypedDict "Point"
892-
p1b: Point = {} # E: Keys ('x', 'y') missing for TypedDict "Point"
891+
p1a: Point = {'x': 'hi'} # E: Missing key 'y' for TypedDict "Point"
892+
p1b: Point = {} # E: Missing keys ('x', 'y') for TypedDict "Point"
893893

894894
p2: Point
895-
p2 = dict(x='bye') # E: Key 'y' missing for TypedDict "Point"
895+
p2 = dict(x='bye') # E: Missing key 'y' for TypedDict "Point"
896896

897897
p3 = Point(x=1, y=2)
898898
if int():
899-
p3 = {'x': 'hi'} # E: Key 'y' missing for TypedDict "Point"
899+
p3 = {'x': 'hi'} # E: Missing key 'y' for TypedDict "Point"
900900

901901
p4: Point = {'x': 1, 'y': 2}
902902

@@ -2103,3 +2103,10 @@ d[3] # E: TypedDict key must be a string literal; expected one of ('foo')
21032103
d[True] # E: TypedDict key must be a string literal; expected one of ('foo')
21042104
[builtins fixtures/dict.pyi]
21052105
[typing fixtures/typing-typeddict.pyi]
2106+
2107+
[case testTypedDictUppercaseKey]
2108+
from mypy_extensions import TypedDict
2109+
2110+
Foo = TypedDict('Foo', {'camelCaseKey': str})
2111+
value: Foo = {} # E: Missing key 'camelCaseKey' for TypedDict "Foo"
2112+
[builtins fixtures/dict.pyi]

0 commit comments

Comments
 (0)