8000 Allow class-based TypedDicts in all python versions by msullivan · Pull Request #6971 · python/mypy · GitHub
[go: up one dir, main page]

Skip to content

Allow class-based TypedDicts in all python versions #6971

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Allow class-based TypedDicts in all python versions
Entries can't be *declared* in versions that don't support type
annotations, of course, but class-based TypedDict still serves a
valuable purpose in merging TypedDicts together.

This error *only* triggers on empty TypedDicts, since any non-empty
ones would have failed earlier with a syntax error. So there is no
reason to prohibit it because we can handle that case totally fine.
  • Loading branch information
msullivan committed Jun 11, 2019
commit 38ca59935b167089eb06e812c9a3ace2e5ee09fc
3 changes: 0 additions & 3 deletions mypy/newsemanal/semanal_typeddict.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,6 @@ def analyze_typeddict_classdef_fields(
* List of types for each key
* Set of required keys
"""
if self.options.python_version < (3, 6):
self.fail('TypedDict class syntax is only supported in Python 3.6', defn)
return [], [], set()
fields = [] # type: List[str]
types = [] # type: List[Type]
for stmt in defn.defs.body:
Expand Down
3 changes: 0 additions & 3 deletions mypy/semanal_typeddict.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,6 @@ def check_typeddict_classdef(self, defn: ClassDef,
oldfields: Optional[List[str]] = None) -> Tuple[List[str],
List[Type],
Set[str]]:
if self.options.python_version < (3, 6):
self.fail('TypedDict class syntax is only supported in Python 3.6', defn)
return [], [], set()
fields = [] # type: List[str]
types = [] # type: List[Type]
for stmt in defn.defs.body:
Expand Down
23 changes: 20 additions & 3 deletions test-data/unit/check-typeddict.test
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,33 @@ reveal_type(p) # E: Revealed type is 'TypedDict('__main__.EmptyDict', {})'
[builtins fixtures/dict.pyi]


-- Define TypedDict (Class syntax errors)

[case testCanCreateTypedDictWithClassOldVersion]
# flags: --python-version 3.5

# Test that we can use class-syntax to merge TypedDicts even in
# versions without type annotations

from mypy_extensions import TypedDict

class Point(TypedDict): # E: TypedDict class syntax is only supported in Python 3.6
MovieBase1 = TypedDict(
'MovieBase1', {'name': str, 'year': int})
MovieBase2 = TypedDict(
'MovieBase2', {'based_on': str}, total=False)

class Movie(MovieBase1, MovieBase2):
pass

def foo(x):
# type: (Movie) -> None
pass

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

[builtins fixtures/dict.pyi]

-- Define TypedDict (Class syntax errors)

[case testCannotCreateTypedDictWithClassOtherBases]
# flags: --python-version 3.6
from mypy_extensions import TypedDict
Expand Down
0