@@ -146,22 +146,6 @@ def _ast_node_for(string: str) -> ast.AST:
146146 return expr .value
147147
148148
149- def _flatten_name (node : ast .expr ) -> str | None :
150- """Return the flattened name of an expression, or None.
151-
152- E.g.:
153- * ast.Name(id="Any") -> "Any"
154- * ast.Attribute(value=ast.Name(id="typing"), attr="Any") -> "typing.Any"
155- """
156-
157- if isinstance (node , ast .Name ):
158- return node .id
159- elif isinstance (node , ast .Attribute ):
160- parent = _flatten_name (node .value )
161- return f"{ parent } .{ node .attr } " if parent else None
162- return None
163-
164-
165149def _is_name (node : ast .AST | None , name : str ) -> bool :
166150 """Return True if `node` is an `ast.Name` node with id `name`.
167151
@@ -242,6 +226,7 @@ def _is_object(node: ast.AST | None, name: str, *, from_: Container[str]) -> boo
242226)
243227_is_Generic = partial (_is_object , name = "Generic" , from_ = _TYPING_MODULES )
244228_is_Unpack = partial (_is_object , name = "Unpack" , from_ = _TYPING_MODULES )
229+ _is_override = partial (_is_object , name = "override" , from_ = _TYPING_MODULES )
245230
246231
247232def _is_union (node : ast .expr | None ) -> TypeIs [ast .BinOp ]:
@@ -2050,11 +2035,12 @@ def check_protocol_param_kinds(
20502035
20512036 def check_for_override (
20522037 self ,
2053- node : ast .FunctionDef | ast .AsyncFunctionDef ,
2054- decorator_names : Container [str ],
2038+ node : ast .FunctionDef | ast .AsyncFunctionDef
20552039 ) -> None :
2056- if "override" in decorator_names or "typing.override" in decorator_names :
2057- self .error (node , errors .Y068 )
2040+ for deco in node .decorator_list :
2041+ if _is_override (deco ):
2042+ self .error (deco , errors .Y068 )
2043+ return
20582044
20592045 @staticmethod
20602046 def _is_positional_pre_570_argname (name : str ) -> bool :
@@ -2110,26 +2096,15 @@ def _visit_function(self, node: ast.FunctionDef | ast.AsyncFunctionDef) -> None:
21102096
21112097 self ._check_pep570_syntax_used_where_applicable (node )
21122098 if self .enclosing_class_ctx is not None :
2113- decorator_names = self ._decorator_names (node )
2099+ decorator_names = {
2100+ decorator .id
2101+ for decorator in node .decorator_list
2102+ if isinstance (decorator , ast .Name )
2103+ }
21142104 self .check_self_typevars (node , decorator_names )
21152105 if self .enclosing_class_ctx .is_protocol_class :
21162106 self .check_protocol_param_kinds (node , decorator_names )
2117- self .check_for_override (node , decorator_names )
2118-
2119- @staticmethod
2120- def _decorator_names (node : ast .FunctionDef | ast .AsyncFunctionDef ) -> list [str ]:
2121- """Return the decorator names applied to this function.
2122-
2123- No normalization will be done.
2124-
2125- E.g. "staticmethod", "override", or "typing.override"
2126- """
2127- names = []
2128- for decorator in node .decorator_list :
2129- name = _flatten_name (decorator )
2130- if name is not None :
2131- names .append (name )
2132- return names
2107+ self .check_for_override (node )
21332108
21342109 def visit_arg (self , node : ast .arg ) -> None :
21352110 if _is_NoReturn (node .annotation ):
0 commit comments