@@ -1743,9 +1743,8 @@ def analyze_typeddict_classdef(self, defn: ClassDef) -> bool:
1743
1743
if is_typeddict :
1744
1744
for decorator in defn .decorators :
1745
1745
decorator .accept (self )
1746
- if isinstance (decorator , RefExpr ):
1747
- if decorator .fullname in FINAL_DECORATOR_NAMES and info is not None :
1748
- info .is_final = True
1746
+ if info is not None :
1747
+ self .analyze_class_decorator_common (defn , info , decorator )
1749
1748
if info is None :
1750
1749
self .mark_incomplete (defn .name , defn )
1751
1750
else :
@@ -1781,8 +1780,7 @@ def analyze_namedtuple_classdef(
1781
1780
with self .scope .class_scope (defn .info ):
1782
1781
for deco in defn .decorators :
1783
1782
deco .accept (self )
1784
- if isinstance (deco , RefExpr ) and deco .fullname in FINAL_DECORATOR_NAMES :
1785
- info .is_final = True
1783
+ self .analyze_class_decorator_common (defn , defn .info , deco )
1786
1784
with self .named_tuple_analyzer .save_namedtuple_body (info ):
1787
1785
self .analyze_class_body_common (defn )
1788
1786
return True
@@ -1864,21 +1862,30 @@ def leave_class(self) -> None:
1864
1862
1865
1863
def analyze_class_decorator (self , defn : ClassDef , decorator : Expression ) -> None :
1866
1864
decorator .accept (self )
1865
+ self .analyze_class_decorator_common (defn , defn .info , decorator )
1867
1866
if isinstance (decorator , RefExpr ):
1868
1867
if decorator .fullname in RUNTIME_PROTOCOL_DECOS :
1869
1868
if defn .info .is_protocol :
1870
1869
defn .info .runtime_protocol = True
1871
1870
else :
1872
1871
self .fail ("@runtime_checkable can only be used with protocol classes" , defn )
1873
- elif decorator .fullname in FINAL_DECORATOR_NAMES :
1874
- defn .info .is_final = True
1875
- elif refers_to_fullname (decorator , TYPE_CHECK_ONLY_NAMES ):
1876
- defn .info .is_type_check_only = True
1877
1872
elif isinstance (decorator , CallExpr ) and refers_to_fullname (
1878
1873
decorator .callee , DATACLASS_TRANSFORM_NAMES
1879
1874
):
1880
1875
defn .info .dataclass_transform_spec = self .parse_dataclass_transform_spec (decorator )
1881
1876
1877
+ def analyze_class_decorator_common (
1878
+ self , defn : ClassDef , info : TypeInfo , decorator : Expression
1879
+ ) -> None :
1880
+ """Common method for applying class decorators.
1881
+
1882
+ Called on regular classes, typeddicts, and namedtuples.
1883
+ """
1884
+ if refers_to_fullname (decorator , FINAL_DECORATOR_NAMES ):
1885
+ info .is_final = True
1886
+ elif refers_to_fullname (decorator , TYPE_CHECK_ONLY_NAMES ):
1887
+ info .is_type_check_only = True
1888
+
1882
1889
def clean_up_bases_and_infer_type_variables (
1883
1890
self , defn : ClassDef , base_type_exprs : list [Expression ], context : Context
1884
1891
) -> tuple [list [Expression ], list [TypeVarLikeType ], bool ]:
0 commit comments