Skip to content

Commit 737ce9e

Browse files
ilevkivskyiJukkaL
authored andcommitted
Allow TypedDict field names starting with underscore (#2839)
As proposed by @JukkaL in discussion of #2808
1 parent e2d42f8 commit 737ce9e

File tree

3 files changed

+7
-14
lines changed

3 files changed

+7
-14
lines changed

mypy/semanal.py

-7
Original file line numberDiff line numberDiff line change
@@ -1143,9 +1143,6 @@ def check_typeddict_classdef(self, defn: ClassDef,
11431143
fields.append(name)
11441144
types.append(AnyType() if stmt.type is None else self.anal_type(stmt.type))
11451145
# ...despite possible minor failures that allow further analyzis.
1146-
if name.startswith('_'):
1147-
self.fail('TypedDict field name cannot start with an underscore: {}'
1148-
.format(name), stmt)
11491146
if stmt.type is None or hasattr(stmt, 'new_syntax') and not stmt.new_syntax:
11501147
self.fail(TPDICT_CLASS_ERROR, stmt)
11511148
elif not isinstance(stmt.rvalue, TempNode):
@@ -2162,10 +2159,6 @@ def parse_typeddict_args(self, call: CallExpr,
21622159
"TypedDict() expects a dictionary literal as the second argument", call)
21632160
dictexpr = args[1]
21642161
items, types, ok = self.parse_typeddict_fields_with_types(dictexpr.items, call)
2165-
underscore = [item for item in items if item.startswith('_')]
2166-
if underscore:
2167-
self.fail("TypedDict() item names cannot start with an underscore: "
2168-
+ ', '.join(underscore), call)
21692162
return items, types, ok
21702163

21712164
def parse_typeddict_fields_with_types(self, dict_items: List[Tuple[Expression, Expression]],

test-data/unit/check-typeddict.test

+7-2
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,18 @@ p = Point(x=42, y=1337, z='whatever')
155155
reveal_type(p) # E: Revealed type is 'TypedDict(x=builtins.int, y=builtins.int, z=builtins.str, _fallback=typing.Mapping[builtins.str, builtins.object])'
156156
[builtins fixtures/dict.pyi]
157157

158-
[case testCannotCreateTypedDictWithClassUnderscores]
158+
[case testCanCreateTypedDictTypeWithUnderscoreItemName]
159+
from mypy_extensions import TypedDict
160+
Point = TypedDict('Point', {'x': int, 'y': int, '_fallback': object})
161+
[builtins fixtures/dict.pyi]
162+
163+
[case testCanCreateTypedDictWithClassUnderscores]
159164
# flags: --python-version 3.6
160165
from mypy_extensions import TypedDict
161166

162167
class Point(TypedDict):
163168
x: int
164-
_y: int # E: TypedDict field name cannot start with an underscore: _y
169+
_y: int
165170

166171
p: Point
167172
reveal_type(p) # E: Revealed type is 'TypedDict(x=builtins.int, _y=builtins.int, _fallback=__main__.Point)'

test-data/unit/semanal-typeddict.test

-5
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,6 @@ from mypy_extensions import TypedDict
5858
Point = TypedDict('Point', {'x'}) # E: TypedDict() expects a dictionary literal as the second argument
5959
[builtins fixtures/dict.pyi]
6060

61-
[case testCannotCreateTypedDictTypeWithUnderscoreItemName]
62-
from mypy_extensions import TypedDict
63-
Point = TypedDict('Point', {'x': int, 'y': int, '_fallback': object}) # E: TypedDict() item names cannot start with an underscore: _fallback
64-
[builtins fixtures/dict.pyi]
65-
6661
-- NOTE: The following code works at runtime but is not yet supported by mypy.
6762
-- Keyword arguments may potentially be supported in the future.
6863
[case testCannotCreateTypedDictTypeWithNonpositionalArgs]

0 commit comments

Comments
 (0)