Repository: pylint-dev/pylint (Python)

Issue:
Regression `used-before-assignment` with type annotation in conditional
### Bug description

```py
import random

class A:
    def f(self) -> None:
        if random.random() < 0.5:
            _x: A = self  # false-positive: used-before-assignment

    def g(self) -> None:
        _x: A = self  # no warning
```

This is the same issue reported and fixed in #5342 but it still occurs if the assignment is inside a conditional.

### Configuration

_No response_

### Command used

```shell
pylint test.py
```


### Pylint output

```shell
test.py:6:16: E0601: Using variable 'A' before assignment (used-before-assignment)
```


### Expected behavior

No error

### Pylint version

```shell
pylint 2.12.2
astroid 2.9.0
Python 3.9.6 (default, Aug 16 2021, 15:13:47) 
[GCC 9.3.0]
```


### OS / Environment

_No response_

### Additional dependencies

_No response_


Discussion:

Patch:
diff --git a/ChangeLog b/ChangeLog
index 069868d986..8c98f7b442 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -21,6 +21,11 @@ Release date: TBA
 
   Closes #3793
 
+* Fixed false positive for ``used-before-assignment`` with self-referential type
+  annotation in conditional statements within class methods.
+
+  Closes #5499
+
 * ``used-before-assignment`` now assumes that assignments in except blocks
   may not have occurred and warns accordingly.
 
diff --git a/doc/whatsnew/2.13.rst b/doc/whatsnew/2.13.rst
index 31b6d4e367..e725c524b8 100644
--- a/doc/whatsnew/2.13.rst
+++ b/doc/whatsnew/2.13.rst
@@ -56,6 +56,11 @@ Other Changes
 
   Closes #3793
 
+* Fixed false positive for ``used-before-assignment`` with self-referential type
+  annotation in conditional statements within class methods.
+
+  Closes #5499
+
 * ``used-before-assignment`` now assumes that assignments in except blocks
   may not have occurred and warns accordingly.
 
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index 86b7eb6697..41ae16a42c 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -1805,7 +1805,7 @@ def _is_first_level_self_reference(
         """
         if (
             node.frame().parent == defstmt
-            and node.statement(future=True) not in node.frame().body
+            and node.statement(future=True) == node.frame()
         ):
             # Check if used as type annotation
             # Break but don't emit message if postponed evaluation is enabled


Test patch:
diff --git a/tests/functional/u/use/used_before_assignment_typing.py b/tests/functional/u/use/used_before_assignment_typing.py
index a9961c8906..33d81356e6 100644
--- a/tests/functional/u/use/used_before_assignment_typing.py
+++ b/tests/functional/u/use/used_before_assignment_typing.py
@@ -61,3 +61,16 @@ def inner_method(self, other: MyOtherClass) -> bool:
     def self_referential_optional_within_method(self) -> None:
         variable: Optional[MyOtherClass] = self
         print(variable)
+
+
+class MyThirdClass:
+    """Class to test self referential variable typing within conditionals.
+    This regressed, reported in: https://github.com/PyCQA/pylint/issues/5499
+    """
+
+    def function(self, var: int) -> None:
+        if var < 0.5:
+            _x: MyThirdClass = self
+
+    def other_function(self) -> None:
+        _x: MyThirdClass = self