Repository: PyCQA/pep8-naming (language: python)

Issue:
Feature request: ignore `N802` for methods marked with `@override`
Python 3.12 will introduce the `override` decorator. It is already backported by `typing_extensions`.

Overridden method names are out of the dev's control when subclassing an external library. A strong example of this is PyQt6/PySide6, where I have to keep adding to `ignore-names` as I use more and more features. pep8-naming could understand that there's nothing the dev can do about the names if a method is marked with `@override` (and it'll still raise anyway on the base class if it's internal).

```
; PyQt methods
ignore-names=closeEvent,paintEvent,keyPressEvent,mousePressEvent,mouseMoveEvent,mouseReleaseEvent
```


Discussion / hints:

Fix patch:
diff --git a/src/pep8ext_naming.py b/src/pep8ext_naming.py
index 05b24c8..87a6514 100644
--- a/src/pep8ext_naming.py
+++ b/src/pep8ext_naming.py
@@ -317,6 +317,16 @@ class FunctionNameCheck(BaseASTCheck):
     N802 = "function name '{name}' should be lowercase"
     N807 = "function name '{name}' should not start and end with '__'"
 
+    @staticmethod
+    def has_override_decorator(node):
+        for d in node.decorator_list:
+            if isinstance(d, ast.Name) and d.id == 'override':
+                return True
+            if (isinstance(d, ast.Attribute) and isinstance(d.value, ast.Name)
+                    and d.value.id == 'typing' and d.attr == 'override'):
+                return True
+        return False
+
     def visit_functiondef(self, node, parents, ignore=None):
         function_type = getattr(node, 'function_type', _FunctionType.FUNCTION)
         name = node.name
@@ -324,6 +334,9 @@ def visit_functiondef(self, node, parents, ignore=None):
             return
         if name in ('__dir__', '__getattr__'):
             return
+        if (function_type != _FunctionType.FUNCTION
+                and self.has_override_decorator(node)):
+            return
         if name.lower() != name:
             yield self.err(node, 'N802', name=name)
         if (function_type == _FunctionType.FUNCTION


Test patch:
diff --git a/testsuite/N802.py b/testsuite/N802.py
index c36ef65..cd9028a 100644
--- a/testsuite/N802.py
+++ b/testsuite/N802.py
@@ -53,6 +53,14 @@ class ClassName:
     def notOk(self):
         pass
 #: Okay
+class ClassName:
+    @override
+    def notOk(self):
+        pass
+    @typing.override
+    def alsoNotOk(self):
+        pass
+#: Okay
 def setUp():
     pass