From fd31874a43d0b8d6dc0399b4b4a0a18a05f4c83c Mon Sep 17 00:00:00 2001 From: Ivan Levkivskyi Date: Thu, 9 Feb 2017 21:46:39 +0100 Subject: [PATCH] Allow TypedDict field names starting with underscore --- mypy/semanal.py | 7 ------- test-data/unit/check-typeddict.test | 9 +++++++-- test-data/unit/semanal-typeddict.test | 5 ----- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index dd82975585b8..96fb40edf3c3 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1100,9 +1100,6 @@ def check_typeddict_classdef(self, defn: ClassDef, fields.append(name) types.append(AnyType() if stmt.type is None else self.anal_type(stmt.type)) # ...despite possible minor failures that allow further analyzis. - if name.startswith('_'): - self.fail('TypedDict field name cannot start with an underscore: {}' - .format(name), stmt) if stmt.type is None or hasattr(stmt, 'new_syntax') and not stmt.new_syntax: self.fail(TPDICT_CLASS_ERROR, stmt) elif not isinstance(stmt.rvalue, TempNode): @@ -2118,10 +2115,6 @@ def parse_typeddict_args(self, call: CallExpr, "TypedDict() expects a dictionary literal as the second argument", call) dictexpr = args[1] items, types, ok = self.parse_typeddict_fields_with_types(dictexpr.items, call) - underscore = [item for item in items if item.startswith('_')] - if underscore: - self.fail("TypedDict() item names cannot start with an underscore: " - + ', '.join(underscore), call) return items, types, ok def parse_typeddict_fields_with_types(self, dict_items: List[Tuple[Expression, Expression]], diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index 4f9c66c5b4fc..20e6bf63aee0 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -155,13 +155,18 @@ p = Point(x=42, y=1337, z='whatever') reveal_type(p) # E: Revealed type is 'TypedDict(x=builtins.int, y=builtins.int, z=builtins.str, _fallback=typing.Mapping[builtins.str, builtins.object])' [builtins fixtures/dict.pyi] -[case testCannotCreateTypedDictWithClassUnderscores] +[case testCanCreateTypedDictTypeWithUnderscoreItemName] +from mypy_extensions import TypedDict +Point = TypedDict('Point', {'x': int, 'y': int, '_fallback': object}) +[builtins fixtures/dict.pyi] + +[case testCanCreateTypedDictWithClassUnderscores] # flags: --python-version 3.6 from mypy_extensions import TypedDict class Point(TypedDict): x: int - _y: int # E: TypedDict field name cannot start with an underscore: _y + _y: int p: Point reveal_type(p) # E: Revealed type is 'TypedDict(x=builtins.int, _y=builtins.int, _fallback=__main__.Point)' diff --git a/test-data/unit/semanal-typeddict.test b/test-data/unit/semanal-typeddict.test index a0229d82a9ed..ab6c428752d6 100644 --- a/test-data/unit/semanal-typeddict.test +++ b/test-data/unit/semanal-typeddict.test @@ -58,11 +58,6 @@ from mypy_extensions import TypedDict Point = TypedDict('Point', {'x'}) # E: TypedDict() expects a dictionary literal as the second argument [builtins fixtures/dict.pyi] -[case testCannotCreateTypedDictTypeWithUnderscoreItemName] -from mypy_extensions import TypedDict -Point = TypedDict('Point', {'x': int, 'y': int, '_fallback': object}) # E: TypedDict() item names cannot start with an underscore: _fallback -[builtins fixtures/dict.pyi] - -- NOTE: The following code works at runtime but is not yet supported by mypy. -- Keyword arguments may potentially be supported in the future. [case testCannotCreateTypedDictTypeWithNonpositionalArgs]