Repository: pylint-dev/pylint (Python)

Issue:
Regressions with `used-before-assignment`
### Bug description

These regressions seem to have been introduced by #6677.
The first one was partially addressed in #7847.

/CC: @jacobtylerwalls

```py
def turn_on(default, **kwargs):
    if "brightness" in kwargs:
        brightness = kwargs["brightness"]
    else:
        if (brightness := default) == 0:  # some condition
            brightness = 255

    print(brightness)  # used-before-assignment
```

```py
def turn_on2(**kwargs):
    if "brightness" in kwargs:
        brightness = kwargs["brightness"]
        var, *args = (1, "set_dimmer_state", brightness)
    else:
        var, *args = (1, "restore_dimmer_state")

    print(*args)  # used-before-assignment
```

### Configuration

_No response_

### Command used

```shell
pylint test.py
```


### Pylint output

```shell
test.py:8:10: E0601: Using variable 'brightness' before assignment (used-before-assignment)
test.py:18:11: E0601: Using variable 'args' before assignment (used-before-assignment)
```


### Expected behavior

_No error_

### Pylint version

```shell
pylint 2.16.0-dev
astroid 2.13.0-dev0
Python 3.11.0
```


### OS / Environment

_No response_

### Additional dependencies

_No response_


Discussion:

Patch:
diff --git a/pylint/checkers/variables.py b/pylint/checkers/variables.py
index 58a2216c0b..1360bae5bf 100644
--- a/pylint/checkers/variables.py
+++ b/pylint/checkers/variables.py
@@ -900,21 +900,16 @@ def _defines_name_raises_or_returns(name: str, node: nodes.NodeNG) -> bool:
         if isinstance(node, nodes.Assign):
             for target in node.targets:
                 for elt in utils.get_all_elements(target):
+                    if isinstance(elt, nodes.Starred):
+                        elt = elt.value
                     if isinstance(elt, nodes.AssignName) and elt.name == name:
                         return True
         if isinstance(node, nodes.If):
-            # Check for assignments inside the test
-            if isinstance(node.test, nodes.NamedExpr) and node.test.target.name == name:
+            if any(
+                child_named_expr.target.name == name
+                for child_named_expr in node.nodes_of_class(nodes.NamedExpr)
+            ):
                 return True
-            if isinstance(node.test, nodes.Call):
-                for arg_or_kwarg in node.test.args + [
-                    kw.value for kw in node.test.keywords
-                ]:
-                    if (
-                        isinstance(arg_or_kwarg, nodes.NamedExpr)
-                        and arg_or_kwarg.target.name == name
-                    ):
-                        return True
         return False
 
     @staticmethod


Test patch:
diff --git a/tests/functional/u/undefined/undefined_variable_py38.py b/tests/functional/u/undefined/undefined_variable_py38.py
index 8afb5eaf9e..2612e535f9 100644
--- a/tests/functional/u/undefined/undefined_variable_py38.py
+++ b/tests/functional/u/undefined/undefined_variable_py38.py
@@ -186,3 +186,7 @@ def expression_in_ternary_operator_inside_container_wrong_position():
     NEVER_DEFINED = 1
 print(defined)
 print(NEVER_DEFINED)  # [used-before-assignment]
+
+if (still_defined := False) == 1:
+    NEVER_DEFINED_EITHER = 1
+print(still_defined)
diff --git a/tests/functional/u/used/used_before_assignment.py b/tests/functional/u/used/used_before_assignment.py
index f8ed651b51..d36b2fd8d5 100644
--- a/tests/functional/u/used/used_before_assignment.py
+++ b/tests/functional/u/used/used_before_assignment.py
@@ -106,3 +106,13 @@ def redefine_time_import_with_global():
     if VAR11:
         VAR12 = False
 print(VAR12)
+
+def turn_on2(**kwargs):
+    """https://github.com/PyCQA/pylint/issues/7873"""
+    if "brightness" in kwargs:
+        brightness = kwargs["brightness"]
+        var, *args = (1, "set_dimmer_state", brightness)
+    else:
+        var, *args = (1, "restore_dimmer_state")
+
+    print(var, *args)