From a4289ecfa394da2a31dd840024046dafd52e2dd5 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Tue, 12 Nov 2024 21:18:40 -0800 Subject: [PATCH 1/2] special case types.DynamicClassAttribute as property-like This enables typeshed to define types.DynamicClassAttribute as a different class from builtins.property without breakage. --- mypy/semanal.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mypy/semanal.py b/mypy/semanal.py index 59e4594353f0f..9d2d6f5fa4849 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -1684,6 +1684,7 @@ def visit_decorator(self, dec: Decorator) -> None: "abc.abstractproperty", "functools.cached_property", "enum.property", + "types.DynamicClassAttribute", ), ): removed.append(i) From 72f37db8aabd28bbd435a465cb7a3c3e993695ef Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Fri, 15 Nov 2024 22:16:38 -0800 Subject: [PATCH 2/2] add test case --- test-data/unit/pythoneval.test | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test-data/unit/pythoneval.test b/test-data/unit/pythoneval.test index 4942a5fd5f2ff..70003545754cf 100644 --- a/test-data/unit/pythoneval.test +++ b/test-data/unit/pythoneval.test @@ -2163,3 +2163,21 @@ class C3[T1, T2](tuple[T1, ...]): def func3(p: C3[int, object]): x: C3[int, int] = p + + +[case testDynamicClassAttribute] +# Some things that can break if DynamicClassAttribute isn't handled properly +from types import DynamicClassAttribute +from enum import Enum + +class TestClass: + @DynamicClassAttribute + def name(self) -> str: ... + +class TestClass2(TestClass, Enum): ... + +class Status(Enum): + ABORTED = -1 + +def imperfect(status: Status) -> str: + return status.name.lower()