We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
False positive for Z121 when using `_` for unused var names
# Bug report

## What's wrong

This code triggers `Z121`:

```python
def logo_and_user():
    user, _ = User.objects.get_or_create(username='sobolevn')
    logo, _ = Logo.objects.get_or_create(username='sobolevn')  # here
```

Log: `test.py:4:11: Z121 Found usage of a variable marked as unused: _`
But it should not, since these variables are unused.

## How is that should be

It should not raise any `Z121` violations here.

## System information

I am using `8.0.1`

False positive Z309 for keys
# Bug report

<!--
Hi, thanks for submitting a bug. We appreciate that.

But, we will need some information about what's wrong to help you.
-->

## What's wrong

```python
def test(office, returned_item):
    assert returned_item['id'] == office.id
```

raises `Z309 Found reversed comparison order` violation

## How is that should be

It should not raise a violation. We use variables on both sides.

## System information

I am using `0.8.1` release.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `wemake_python_styleguide/visitors/ast/functions.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 import ast
4 from typing import ClassVar, Dict, List, Optional, Union
5 
6 from wemake_python_styleguide.constants import (
7     FUNCTIONS_BLACKLIST,
8     UNUSED_VARIABLE,
9 )
10 from wemake_python_styleguide.logics import functions
11 from wemake_python_styleguide.logics.naming import access
12 from wemake_python_styleguide.types import AnyFunctionDef, AnyNodes, final
13 from wemake_python_styleguide.violations.best_practices import (
14     BooleanPositionalArgumentViolation,
15     ComplexDefaultValuesViolation,
16     IncorrectSuperCallViolation,
17     WrongFunctionCallViolation,
18 )
19 from wemake_python_styleguide.violations.naming import (
20     UnusedVariableIsUsedViolation,
21 )
22 from wemake_python_styleguide.visitors.base import BaseNodeVisitor
23 from wemake_python_styleguide.visitors.decorators import alias
24 
25 LocalVariable = Union[ast.Name, ast.ExceptHandler]
26 
27 
28 @final
29 class WrongFunctionCallVisitor(BaseNodeVisitor):
30     """
31     Responsible for restricting some dangerous function calls.
32 
33     All these functions are defined in ``FUNCTIONS_BLACKLIST``.
34     """
35 
36     def _check_wrong_function_called(self, node: ast.Call) -> None:
37         function_name = functions.given_function_called(
38             node, FUNCTIONS_BLACKLIST,
39         )
40         if function_name:
41             self.add_violation(
42                 WrongFunctionCallViolation(node, text=function_name),
43             )
44 
45     def _check_boolean_arguments(self, node: ast.Call) -> None:
46         for arg in node.args:
47             if isinstance(arg, ast.NameConstant):
48                 # We do not check for `None` values here:
49                 if arg.value is True or arg.value is False:
50                     self.add_violation(
51                         BooleanPositionalArgumentViolation(
52                             arg, text=str(arg.value),
53                         ),
54                     )
55 
56     def _ensure_super_context(self, node: ast.Call) -> None:
57         parent_context = getattr(node, 'wps_context', None)
58         if isinstance(parent_context, (ast.FunctionDef, ast.AsyncFunctionDef)):
59             grand_context = getattr(parent_context, 'wps_context', None)
60             if isinstance(grand_context, ast.ClassDef):
61                 return
62         self.add_violation(
63             IncorrectSuperCallViolation(node, text='not inside method'),
64         )
65 
66     def _ensure_super_arguments(self, node: ast.Call) -> None:
67         if len(node.args) > 0 or len(node.keywords) > 0:
68             self.add_violation(
69                 IncorrectSuperCallViolation(node, text='remove arguments'),
70             )
71 
72     def _check_super_call(self, node: ast.Call) -> None:
73         function_name = functions.given_function_called(node, ['super'])
74         if function_name:
75             self._ensure_super_context(node)
76             self._ensure_super_arguments(node)
77 
78     def visit_Call(self, node: ast.Call) -> None:
79         """
80         Used to find ``FUNCTIONS_BLACKLIST`` calls.
81 
82         Raises:
83             BooleanPositionalArgumentViolation
84             WrongFunctionCallViolation
85             IncorrectSuperCallViolation
86 
87         """
88         self._check_wrong_function_called(node)
89         self._check_boolean_arguments(node)
90         self._check_super_call(node)
91         self.generic_visit(node)
92 
93 
94 @final
95 @alias('visit_any_function', (
96     'visit_AsyncFunctionDef',
97     'visit_FunctionDef',
98 ))
99 class FunctionDefinitionVisitor(BaseNodeVisitor):
100     """Responsible for checking function internals."""
101 
102     _allowed_default_value_types: ClassVar[AnyNodes] = (
103         ast.Name,
104         ast.Attribute,
105         ast.Str,
106         ast.NameConstant,
107         ast.Tuple,
108         ast.Bytes,
109         ast.Num,
110     )
111 
112     def _check_used_variables(
113         self,
114         local_variables: Dict[str, List[LocalVariable]],
115     ) -> None:
116         for varname, usages in local_variables.items():
117             for node in usages:
118                 if access.is_protected(varname) or varname == UNUSED_VARIABLE:
119                     self.add_violation(
120                         UnusedVariableIsUsedViolation(node, text=varname),
121                     )
122 
123     def _maybe_update_variable(
124         self,
125         sub_node: LocalVariable,
126         var_name: str,
127         local_variables: Dict[str, List[LocalVariable]],
128     ) -> None:
129         if var_name in local_variables:
130             local_variables[var_name].append(sub_node)
131             return
132 
133         is_name_def = isinstance(
134             sub_node, ast.Name,
135         ) and isinstance(
136             sub_node.ctx, ast.Store,
137         )
138 
139         if is_name_def or isinstance(sub_node, ast.ExceptHandler):
140             local_variables[var_name] = []
141 
142     def _get_variable_name(self, node: LocalVariable) -> Optional[str]:
143         if isinstance(node, ast.Name):
144             return node.id
145         return getattr(node, 'name', None)
146 
147     def _check_unused_variables(self, node: AnyFunctionDef) -> None:
148         local_variables: Dict[str, List[LocalVariable]] = {}
149         for body_item in node.body:
150             for sub_node in ast.walk(body_item):
151                 if not isinstance(sub_node, (ast.Name, ast.ExceptHandler)):
152                     continue
153 
154                 var_name = self._get_variable_name(sub_node)
155                 if not var_name:
156                     continue
157 
158                 self._maybe_update_variable(
159                     sub_node, var_name, local_variables,
160                 )
161         self._check_used_variables(local_variables)
162 
163     def _check_argument_default_values(self, node: AnyFunctionDef) -> None:
164 
165         for arg in node.args.defaults:
166             if not isinstance(arg, self._allowed_default_value_types):
167                 self.add_violation(
168                     ComplexDefaultValuesViolation(node, text='Test text'),
169                 )
170 
171     def visit_any_function(self, node: AnyFunctionDef) -> None:
172         """
173         Checks regular, lambda, and async functions.
174 
175         Raises:
176             UnusedVariableIsUsedViolation
177             ComplexDefaultValuesViolation
178 
179         """
180         self._check_argument_default_values(node)
181         self._check_unused_variables(node)
182         self.generic_visit(node)
183
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/wemake_python_styleguide/visitors/ast/functions.py b/wemake_python_styleguide/visitors/ast/functions.py
--- a/wemake_python_styleguide/visitors/ast/functions.py
+++ b/wemake_python_styleguide/visitors/ast/functions.py
@@ -127,6 +127,9 @@
         local_variables: Dict[str, List[LocalVariable]],
     ) -> None:
         if var_name in local_variables:
+            if var_name == UNUSED_VARIABLE:
+                if isinstance(getattr(sub_node, 'ctx', None), ast.Store):
+                    return
             local_variables[var_name].append(sub_node)
             return

{"golden_diff": "diff --git a/wemake_python_styleguide/visitors/ast/functions.py b/wemake_python_styleguide/visitors/ast/functions.py\n--- a/wemake_python_styleguide/visitors/ast/functions.py\n+++ b/wemake_python_styleguide/visitors/ast/functions.py\n@@ -127,6 +127,9 @@\n         local_variables: Dict[str, List[LocalVariable]],\n     ) -> None:\n         if var_name in local_variables:\n+            if var_name == UNUSED_VARIABLE:\n+                if isinstance(getattr(sub_node, 'ctx', None), ast.Store):\n+                    return\n             local_variables[var_name].append(sub_node)\n             return\n", "issue": "False positive for Z121 when using `_` for unused var names\n# Bug report\r\n\r\n## What's wrong\r\n\r\nThis code triggers `Z121`:\r\n\r\n```python\r\ndef logo_and_user():\r\n    user, _ = User.objects.get_or_create(username='sobolevn')\r\n    logo, _ = Logo.objects.get_or_create(username='sobolevn')  # here\r\n```\r\n\r\nLog: `test.py:4:11: Z121 Found usage of a variable marked as unused: _`\r\nBut it should not, since these variables are unused.\r\n\r\n## How is that should be\r\n\r\nIt should not raise any `Z121` violations here.\r\n\r\n## System information\r\n\r\nI am using `8.0.1`\r\n\nFalse positive Z309 for keys\n# Bug report\r\n\r\n<!--\r\nHi, thanks for submitting a bug. We appreciate that.\r\n\r\nBut, we will need some information about what's wrong to help you.\r\n-->\r\n\r\n## What's wrong\r\n\r\n```python\r\ndef test(office, returned_item):\r\n    assert returned_item['id'] == office.id\r\n```\r\n\r\nraises `Z309 Found reversed comparison order` violation\r\n\r\n## How is that should be\r\n\r\nIt should not raise a violation. We use variables on both sides.\r\n\r\n## System information\r\n\r\nI am using `0.8.1` release.\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\nimport ast\nfrom typing import ClassVar, Dict, List, Optional, Union\n\nfrom wemake_python_styleguide.constants import (\n    FUNCTIONS_BLACKLIST,\n    UNUSED_VARIABLE,\n)\nfrom wemake_python_styleguide.logics import functions\nfrom wemake_python_styleguide.logics.naming import access\nfrom wemake_python_styleguide.types import AnyFunctionDef, AnyNodes, final\nfrom wemake_python_styleguide.violations.best_practices import (\n    BooleanPositionalArgumentViolation,\n    ComplexDefaultValuesViolation,\n    IncorrectSuperCallViolation,\n    WrongFunctionCallViolation,\n)\nfrom wemake_python_styleguide.violations.naming import (\n    UnusedVariableIsUsedViolation,\n)\nfrom wemake_python_styleguide.visitors.base import BaseNodeVisitor\nfrom wemake_python_styleguide.visitors.decorators import alias\n\nLocalVariable = Union[ast.Name, ast.ExceptHandler]\n\n\n@final\nclass WrongFunctionCallVisitor(BaseNodeVisitor):\n    \"\"\"\n    Responsible for restricting some dangerous function calls.\n\n    All these functions are defined in ``FUNCTIONS_BLACKLIST``.\n    \"\"\"\n\n    def _check_wrong_function_called(self, node: ast.Call) -> None:\n        function_name = functions.given_function_called(\n            node, FUNCTIONS_BLACKLIST,\n        )\n        if function_name:\n            self.add_violation(\n                WrongFunctionCallViolation(node, text=function_name),\n            )\n\n    def _check_boolean_arguments(self, node: ast.Call) -> None:\n        for arg in node.args:\n            if isinstance(arg, ast.NameConstant):\n                # We do not check for `None` values here:\n                if arg.value is True or arg.value is False:\n                    self.add_violation(\n                        BooleanPositionalArgumentViolation(\n                            arg, text=str(arg.value),\n                        ),\n                    )\n\n    def _ensure_super_context(self, node: ast.Call) -> None:\n        parent_context = getattr(node, 'wps_context', None)\n        if isinstance(parent_context, (ast.FunctionDef, ast.AsyncFunctionDef)):\n            grand_context = getattr(parent_context, 'wps_context', None)\n            if isinstance(grand_context, ast.ClassDef):\n                return\n        self.add_violation(\n            IncorrectSuperCallViolation(node, text='not inside method'),\n        )\n\n    def _ensure_super_arguments(self, node: ast.Call) -> None:\n        if len(node.args) > 0 or len(node.keywords) > 0:\n            self.add_violation(\n                IncorrectSuperCallViolation(node, text='remove arguments'),\n            )\n\n    def _check_super_call(self, node: ast.Call) -> None:\n        function_name = functions.given_function_called(node, ['super'])\n        if function_name:\n            self._ensure_super_context(node)\n            self._ensure_super_arguments(node)\n\n    def visit_Call(self, node: ast.Call) -> None:\n        \"\"\"\n        Used to find ``FUNCTIONS_BLACKLIST`` calls.\n\n        Raises:\n            BooleanPositionalArgumentViolation\n            WrongFunctionCallViolation\n            IncorrectSuperCallViolation\n\n        \"\"\"\n        self._check_wrong_function_called(node)\n        self._check_boolean_arguments(node)\n        self._check_super_call(node)\n        self.generic_visit(node)\n\n\n@final\n@alias('visit_any_function', (\n    'visit_AsyncFunctionDef',\n    'visit_FunctionDef',\n))\nclass FunctionDefinitionVisitor(BaseNodeVisitor):\n    \"\"\"Responsible for checking function internals.\"\"\"\n\n    _allowed_default_value_types: ClassVar[AnyNodes] = (\n        ast.Name,\n        ast.Attribute,\n        ast.Str,\n        ast.NameConstant,\n        ast.Tuple,\n        ast.Bytes,\n        ast.Num,\n    )\n\n    def _check_used_variables(\n        self,\n        local_variables: Dict[str, List[LocalVariable]],\n    ) -> None:\n        for varname, usages in local_variables.items():\n            for node in usages:\n                if access.is_protected(varname) or varname == UNUSED_VARIABLE:\n                    self.add_violation(\n                        UnusedVariableIsUsedViolation(node, text=varname),\n                    )\n\n    def _maybe_update_variable(\n        self,\n        sub_node: LocalVariable,\n        var_name: str,\n        local_variables: Dict[str, List[LocalVariable]],\n    ) -> None:\n        if var_name in local_variables:\n            local_variables[var_name].append(sub_node)\n            return\n\n        is_name_def = isinstance(\n            sub_node, ast.Name,\n        ) and isinstance(\n            sub_node.ctx, ast.Store,\n        )\n\n        if is_name_def or isinstance(sub_node, ast.ExceptHandler):\n            local_variables[var_name] = []\n\n    def _get_variable_name(self, node: LocalVariable) -> Optional[str]:\n        if isinstance(node, ast.Name):\n            return node.id\n        return getattr(node, 'name', None)\n\n    def _check_unused_variables(self, node: AnyFunctionDef) -> None:\n        local_variables: Dict[str, List[LocalVariable]] = {}\n        for body_item in node.body:\n            for sub_node in ast.walk(body_item):\n                if not isinstance(sub_node, (ast.Name, ast.ExceptHandler)):\n                    continue\n\n                var_name = self._get_variable_name(sub_node)\n                if not var_name:\n                    continue\n\n                self._maybe_update_variable(\n                    sub_node, var_name, local_variables,\n                )\n        self._check_used_variables(local_variables)\n\n    def _check_argument_default_values(self, node: AnyFunctionDef) -> None:\n\n        for arg in node.args.defaults:\n            if not isinstance(arg, self._allowed_default_value_types):\n                self.add_violation(\n                    ComplexDefaultValuesViolation(node, text='Test text'),\n                )\n\n    def visit_any_function(self, node: AnyFunctionDef) -> None:\n        \"\"\"\n        Checks regular, lambda, and async functions.\n\n        Raises:\n            UnusedVariableIsUsedViolation\n            ComplexDefaultValuesViolation\n\n        \"\"\"\n        self._check_argument_default_values(node)\n        self._check_unused_variables(node)\n        self.generic_visit(node)\n", "path": "wemake_python_styleguide/visitors/ast/functions.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\nimport ast\nfrom typing import ClassVar, Dict, List, Optional, Union\n\nfrom wemake_python_styleguide.constants import (\n    FUNCTIONS_BLACKLIST,\n    UNUSED_VARIABLE,\n)\nfrom wemake_python_styleguide.logics import functions\nfrom wemake_python_styleguide.logics.naming import access\nfrom wemake_python_styleguide.types import AnyFunctionDef, AnyNodes, final\nfrom wemake_python_styleguide.violations.best_practices import (\n    BooleanPositionalArgumentViolation,\n    ComplexDefaultValuesViolation,\n    IncorrectSuperCallViolation,\n    WrongFunctionCallViolation,\n)\nfrom wemake_python_styleguide.violations.naming import (\n    UnusedVariableIsUsedViolation,\n)\nfrom wemake_python_styleguide.visitors.base import BaseNodeVisitor\nfrom wemake_python_styleguide.visitors.decorators import alias\n\nLocalVariable = Union[ast.Name, ast.ExceptHandler]\n\n\n@final\nclass WrongFunctionCallVisitor(BaseNodeVisitor):\n    \"\"\"\n    Responsible for restricting some dangerous function calls.\n\n    All these functions are defined in ``FUNCTIONS_BLACKLIST``.\n    \"\"\"\n\n    def _check_wrong_function_called(self, node: ast.Call) -> None:\n        function_name = functions.given_function_called(\n            node, FUNCTIONS_BLACKLIST,\n        )\n        if function_name:\n            self.add_violation(\n                WrongFunctionCallViolation(node, text=function_name),\n            )\n\n    def _check_boolean_arguments(self, node: ast.Call) -> None:\n        for arg in node.args:\n            if isinstance(arg, ast.NameConstant):\n                # We do not check for `None` values here:\n                if arg.value is True or arg.value is False:\n                    self.add_violation(\n                        BooleanPositionalArgumentViolation(\n                            arg, text=str(arg.value),\n                        ),\n                    )\n\n    def _ensure_super_context(self, node: ast.Call) -> None:\n        parent_context = getattr(node, 'wps_context', None)\n        if isinstance(parent_context, (ast.FunctionDef, ast.AsyncFunctionDef)):\n            grand_context = getattr(parent_context, 'wps_context', None)\n            if isinstance(grand_context, ast.ClassDef):\n                return\n        self.add_violation(\n            IncorrectSuperCallViolation(node, text='not inside method'),\n        )\n\n    def _ensure_super_arguments(self, node: ast.Call) -> None:\n        if len(node.args) > 0 or len(node.keywords) > 0:\n            self.add_violation(\n                IncorrectSuperCallViolation(node, text='remove arguments'),\n            )\n\n    def _check_super_call(self, node: ast.Call) -> None:\n        function_name = functions.given_function_called(node, ['super'])\n        if function_name:\n            self._ensure_super_context(node)\n            self._ensure_super_arguments(node)\n\n    def visit_Call(self, node: ast.Call) -> None:\n        \"\"\"\n        Used to find ``FUNCTIONS_BLACKLIST`` calls.\n\n        Raises:\n            BooleanPositionalArgumentViolation\n            WrongFunctionCallViolation\n            IncorrectSuperCallViolation\n\n        \"\"\"\n        self._check_wrong_function_called(node)\n        self._check_boolean_arguments(node)\n        self._check_super_call(node)\n        self.generic_visit(node)\n\n\n@final\n@alias('visit_any_function', (\n    'visit_AsyncFunctionDef',\n    'visit_FunctionDef',\n))\nclass FunctionDefinitionVisitor(BaseNodeVisitor):\n    \"\"\"Responsible for checking function internals.\"\"\"\n\n    _allowed_default_value_types: ClassVar[AnyNodes] = (\n        ast.Name,\n        ast.Attribute,\n        ast.Str,\n        ast.NameConstant,\n        ast.Tuple,\n        ast.Bytes,\n        ast.Num,\n    )\n\n    def _check_used_variables(\n        self,\n        local_variables: Dict[str, List[LocalVariable]],\n    ) -> None:\n        for varname, usages in local_variables.items():\n            for node in usages:\n                if access.is_protected(varname) or varname == UNUSED_VARIABLE:\n                    self.add_violation(\n                        UnusedVariableIsUsedViolation(node, text=varname),\n                    )\n\n    def _maybe_update_variable(\n        self,\n        sub_node: LocalVariable,\n        var_name: str,\n        local_variables: Dict[str, List[LocalVariable]],\n    ) -> None:\n        if var_name in local_variables:\n            if var_name == UNUSED_VARIABLE:\n                if isinstance(getattr(sub_node, 'ctx', None), ast.Store):\n                    return\n            local_variables[var_name].append(sub_node)\n            return\n\n        is_name_def = isinstance(\n            sub_node, ast.Name,\n        ) and isinstance(\n            sub_node.ctx, ast.Store,\n        )\n\n        if is_name_def or isinstance(sub_node, ast.ExceptHandler):\n            local_variables[var_name] = []\n\n    def _get_variable_name(self, node: LocalVariable) -> Optional[str]:\n        if isinstance(node, ast.Name):\n            return node.id\n        return getattr(node, 'name', None)\n\n    def _check_unused_variables(self, node: AnyFunctionDef) -> None:\n        local_variables: Dict[str, List[LocalVariable]] = {}\n        for body_item in node.body:\n            for sub_node in ast.walk(body_item):\n                if not isinstance(sub_node, (ast.Name, ast.ExceptHandler)):\n                    continue\n\n                var_name = self._get_variable_name(sub_node)\n                if not var_name:\n                    continue\n\n                self._maybe_update_variable(\n                    sub_node, var_name, local_variables,\n                )\n        self._check_used_variables(local_variables)\n\n    def _check_argument_default_values(self, node: AnyFunctionDef) -> None:\n\n        for arg in node.args.defaults:\n            if not isinstance(arg, self._allowed_default_value_types):\n                self.add_violation(\n                    ComplexDefaultValuesViolation(node, text='Test text'),\n                )\n\n    def visit_any_function(self, node: AnyFunctionDef) -> None:\n        \"\"\"\n        Checks regular, lambda, and async functions.\n\n        Raises:\n            UnusedVariableIsUsedViolation\n            ComplexDefaultValuesViolation\n\n        \"\"\"\n        self._check_argument_default_values(node)\n        self._check_unused_variables(node)\n        self.generic_visit(node)\n", "path": "wemake_python_styleguide/visitors/ast/functions.py"}]}