From aafc409f87eeb819d387b8eda141ccec44a5f1f0 Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 10 Nov 2023 13:50:42 +0300 Subject: [PATCH] Do not allow other keywords as well --- mypy/semanal.py | 2 -- mypy/semanal_typeddict.py | 6 ++++++ test-data/unit/check-typeddict.test | 15 ++++++--------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 9787c282a600..6f322af816ea 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1745,8 +1745,6 @@ def analyze_typeddict_classdef(self, defn: ClassDef) -> bool: if info is None: self.mark_incomplete(defn.name, defn) else: - if defn.keywords and "metaclass" in defn.keywords: - self.fail('"TypedDict" cannot have a metaclass', defn.keywords["metaclass"]) self.prepare_class_def(defn, info, custom_names=True) return True return False diff --git a/mypy/semanal_typeddict.py b/mypy/semanal_typeddict.py index 5104d31f5c26..914d8a1fa530 100644 --- a/mypy/semanal_typeddict.py +++ b/mypy/semanal_typeddict.py @@ -323,6 +323,12 @@ def analyze_typeddict_classdef_fields( total: bool | None = True if "total" in defn.keywords: total = require_bool_literal_argument(self.api, defn.keywords["total"], "total", True) + if defn.keywords and defn.keywords.keys() != {"total"}: + msg = ( + '"TypedDict" class definition cannot have keywords ' + 'other than "total", got: "{}"' + ) + self.fail(msg.format(", ".join(defn.keywords)), defn) required_keys = { field for (field, t) in zip(fields, types) diff --git a/test-data/unit/check-typeddict.test b/test-data/unit/check-typeddict.test index ea81643ad814..20d9cfff411e 100644 --- a/test-data/unit/check-typeddict.test +++ b/test-data/unit/check-typeddict.test @@ -3404,21 +3404,18 @@ T = TypeVar('T') class Meta(type): ... -class WithMetaKeyword(TypedDict, metaclass=Meta): # E: "TypedDict" cannot have a metaclass +class WithMetaKeyword(TypedDict, metaclass=Meta): # E: "TypedDict" class definition cannot have keywords other than "total", got: "metaclass" ... -class GenericWithMetaKeyword(TypedDict, Generic[T], metaclass=Meta): # E: "TypedDict" cannot have a metaclass - ... - -class PositionOfErrorIsPrecise( - TypedDict, - metaclass=Meta, # E: "TypedDict" cannot have a metaclass -): +class GenericWithMetaKeyword(TypedDict, Generic[T], metaclass=Meta): # E: "TypedDict" class definition cannot have keywords other than "total", got: "metaclass" ... # We still don't allow this, because the implementation is much easier # and it does not make any practical sense to do it: -class WithTypeMeta(TypedDict, metaclass=type): # E: "TypedDict" cannot have a metaclass +class WithTypeMeta(TypedDict, metaclass=type): # E: "TypedDict" class definition cannot have keywords other than "total", got: "metaclass" + ... + +class OtherKeywords(TypedDict, a=1, b=2, c=3, total=True): # E: "TypedDict" class definition cannot have keywords other than "total", got: "a, b, c, total" ... [builtins fixtures/dict.pyi] [typing fixtures/typing-typeddict.pyi]