Repository: PyCQA/pyflakes (python)

Issue:
F811 redefinition: false positive
Hi,

the following MWE
```python
def no_redef(value):
    if value:

        def fun(x, y):
            return x

    else:

        def fun(x, y):
            return y

    return fun


def redef(value):
    match value:
        case True:

            def fun(x, y):
                return x

        case False:

            def fun(x, y):
                return y

    return fun
```
throws the following warning:
```
redef.py:24:13: redefinition of unused 'fun' from line 19
```
i.e. pyflakes complains that the second `def fun` in the `redef` function is a redefinition of the previous definition. In my understanding both functions, `redef` and `no_redef` should be valid.

I use this version of pyflakes:
```
pyflakes --version
3.0.1 Python 3.10.8 on Linux
```

Constantin

Pull request:
allow redefinition of functions across match arms
resolves #771

Patch:
diff --git a/pyflakes/checker.py b/pyflakes/checker.py
index e654afa..db4da49 100644
--- a/pyflakes/checker.py
+++ b/pyflakes/checker.py
@@ -29,8 +29,10 @@ parse_format_string = string.Formatter().parse
 def getAlternatives(n):
     if isinstance(n, ast.If):
         return [n.body]
-    if isinstance(n, ast.Try):
+    elif isinstance(n, ast.Try):
         return [n.body + n.orelse] + [[hdl] for hdl in n.handlers]
+    elif sys.version_info >= (3, 10) and isinstance(n, ast.Match):
+        return [mc.body for mc in n.cases]
 
 
 FOR_TYPES = (ast.For, ast.AsyncFor)


Test patch:
diff --git a/pyflakes/test/test_match.py b/pyflakes/test/test_match.py
index 89826e3..b237523 100644
--- a/pyflakes/test/test_match.py
+++ b/pyflakes/test/test_match.py
@@ -81,3 +81,14 @@ class TestMatch(TestCase):
                 case {'foo': k1, **rest}:
                     print(f'{k1=} {rest=}')
         ''')
+
+    def test_defined_in_different_branches(self):
+        self.flakes('''
+            def f(x):
+                match x:
+                    case 1:
+                        def y(): pass
+                    case _:
+                        def y(): print(1)
+                return y
+        ''')