We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Forbid `Optional[Union[A, B]]`, use `Union[A, B, None]` instead
# Rule request

<!-- Thanks for coming up with a proposal! -->

## Thesis

<!-- What exactly do you propose? Please, provide code examples. -->

These two types are equal: `Optional[Union[A, B]] == Union[A, B, None]`

For consistency reasons we need to enforce the second form over the first one.
Related to #792 

--- 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/violations/annotations.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 """
4 These checks help to prevent incorrect usage of Python 3 typing annotations.
5 
6 While they maybe of a great help in writing clear
7 and concise code, they still can be abused.
8 
9 Once again, these rules are highly subjective. But, we love them.
10 
11 .. currentmodule:: wemake_python_styleguide.violations.annotations
12 
13 Summary
14 -------
15 
16 .. autosummary::
17    :nosignatures:
18 
19    LiteralNoneViolation
20    NestedAnnotationsViolation
21 
22 Annotation checks
23 ------------------
24 
25 .. autoclass:: LiteralNoneViolation
26 .. autoclass:: NestedAnnotationsViolation
27 
28 """
29 
30 from typing_extensions import final
31 
32 from wemake_python_styleguide.violations.base import ASTViolation
33 
34 
35 @final
36 class LiteralNoneViolation(ASTViolation):
37     """
38     Forbids to use ``Literal[None]`` typing annotation.
39 
40     Reasoning:
41         Literal[None] is just the same as None.
42         There's no need to use the first version.
43         It is not type related, it is a consistency rule.
44 
45     Solution:
46         Replace ``Literal[None]`` with ``None``.
47 
48     Example::
49 
50         # Correct:
51         def func(empty: None):
52             '''Empty function.'''
53 
54         # Wrong:
55         def func(empty: Literal[None]):
56             '''Empty function.'''
57 
58     .. versionadded:: 0.13.0
59 
60     """
61 
62     code = 701
63     error_template = 'Found useless `Literal[None]` typing annotation'
64 
65 
66 @final
67 class NestedAnnotationsViolation(ASTViolation):
68     """
69     Forbids use of nested Literal and Union Annotation.
70 
71     Reasoning:
72         There is no need to nest certain annotations of the same type.
73         They are exactly equivalent to the flattened version.
74         Use the flattened version for consistency.
75 
76     Solution:
77         Flatten consecutively nested ``typing.Literal`` and ``typing.Union``.
78 
79     Example::
80         # Correct:
81         Literal[1, 2, 3, "foo", 5, None]
82         Union[int, str, float]
83 
84         # Wrong:
85         Literal[Literal[Literal[1, 2, 3], "foo"], 5, None]
86         Union[Union[int, str], float]
87 
88     .. versionadded:: 0.13.0
89 
90     """
91 
92     error_template = 'Found redundant nested typing annotation'
93     code = 702
94
```

Path: `wemake_python_styleguide/visitors/ast/annotations.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 import ast
4 from typing import ClassVar, FrozenSet, Optional
5 
6 from typing_extensions import final
7 
8 from wemake_python_styleguide.logic import source
9 from wemake_python_styleguide.types import AnyFunctionDef
10 from wemake_python_styleguide.violations.annotations import (
11     LiteralNoneViolation,
12     NestedAnnotationsViolation,
13 )
14 from wemake_python_styleguide.violations.consistency import (
15     MultilineFunctionAnnotationViolation,
16 )
17 from wemake_python_styleguide.visitors.base import BaseNodeVisitor
18 from wemake_python_styleguide.visitors.decorators import alias
19 
20 
21 @alias('visit_any_function', (
22     'visit_FunctionDef',
23     'visit_AsyncFunctionDef',
24 ))
25 class _GenericAnnotationVisitor(BaseNodeVisitor):
26     """Base class for all annotations visitors."""
27 
28     _possible_prefixes: ClassVar[FrozenSet[str]] = frozenset((
29         'typing.',
30         'typing_extensions.',
31     ))
32 
33     @final
34     def visit_AnnAssign(self, node: ast.AnnAssign) -> None:
35         """
36         Checks for assigned value annotation.
37 
38         Raises:
39             LiteralNoneAnnotation
40 
41         """
42         self._check_annotation(node.annotation)
43         self.generic_visit(node)
44 
45     @final
46     def visit_any_function(self, node: AnyFunctionDef) -> None:
47         """
48         Checks return type annotations.
49 
50         Raises:
51             LiteralNoneAnnotation
52 
53         """
54         self._check_annotation(node.returns)
55         self.generic_visit(node)
56 
57     @final
58     def visit_arg(self, node: ast.arg) -> None:
59         """
60         Checks arguments annotations.
61 
62         Raises:
63             LiteralNoneAnnotation
64 
65         """
66         self._check_annotation(node.annotation)
67         self.generic_visit(node)
68 
69     @final
70     def _get_annotation(self, node: ast.AST) -> str:
71         """Smartly turns annotation node to string."""
72         full_annotation = source.node_to_string(node)
73         for prefix in self._possible_prefixes:
74             full_annotation = full_annotation.replace(prefix, '')
75         return full_annotation
76 
77     def _check_annotation(self, annotation: Optional[ast.expr]) -> None:
78         """The only method that need to me implemented in child visitors."""
79 
80 
81 @final
82 class SemanticAnnotationVisitor(_GenericAnnotationVisitor):
83     """Ensures that nested annotations are used correctly."""
84 
85     _flat_types: ClassVar[FrozenSet[str]] = frozenset((
86         'Literal',
87         'Union',
88         'Annotated',
89     ))
90 
91     def _check_annotation(self, annotation: Optional[ast.expr]) -> None:
92         if not annotation:
93             return
94 
95         self._check_nested_annotations(annotation)
96         self._check_literal_none(annotation)
97 
98     def _check_nested_annotations(self, annotation: ast.expr) -> None:
99         annotation_string = self._get_annotation(annotation)
100         for flat_type in self._flat_types:
101             if annotation_string.count(flat_type) > 1:
102                 self.add_violation(NestedAnnotationsViolation(annotation))
103 
104     def _check_literal_none(self, annotation: ast.expr) -> None:
105         annotation_string = self._get_annotation(annotation)
106         if 'Literal[None]' in annotation_string:
107             self.add_violation(LiteralNoneViolation(annotation))
108 
109 
110 @final
111 @alias('visit_any_function', (
112     'visit_FunctionDef',
113     'visit_AsyncFunctionDef',
114 ))
115 class WrongAnnotationVisitor(BaseNodeVisitor):
116     """Ensures that annotations are used correctly."""
117 
118     def visit_any_function(self, node: AnyFunctionDef) -> None:
119         """
120         Checks return type annotations.
121 
122         Raises:
123             MultilineFunctionAnnotationViolation
124             LiteralNoneAnnotation
125 
126         """
127         self._check_return_annotation(node)
128         self.generic_visit(node)
129 
130     def visit_arg(self, node: ast.arg) -> None:
131         """
132         Checks arguments annotations.
133 
134         Raises:
135             MultilineFunctionAnnotationViolation
136             LiteralNoneAnnotation
137 
138         """
139         self._check_arg_annotation(node)
140         self.generic_visit(node)
141 
142     def _check_arg_annotation(self, node: ast.arg) -> None:
143         for sub_node in ast.walk(node):
144             lineno = getattr(sub_node, 'lineno', None)
145             if lineno and lineno != node.lineno:
146                 self.add_violation(MultilineFunctionAnnotationViolation(node))
147                 return
148 
149     def _check_return_annotation(self, node: AnyFunctionDef) -> None:
150         if not node.returns:
151             return
152 
153         for sub_node in ast.walk(node.returns):
154             lineno = getattr(sub_node, 'lineno', None)
155             if lineno and lineno != node.returns.lineno:
156                 self.add_violation(MultilineFunctionAnnotationViolation(node))
157                 return
158
```
--- 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/violations/annotations.py b/wemake_python_styleguide/violations/annotations.py
--- a/wemake_python_styleguide/violations/annotations.py
+++ b/wemake_python_styleguide/violations/annotations.py
@@ -18,12 +18,14 @@
 
    LiteralNoneViolation
    NestedAnnotationsViolation
+   UnionNestedInOptionalViolation
 
 Annotation checks
 ------------------
 
 .. autoclass:: LiteralNoneViolation
 .. autoclass:: NestedAnnotationsViolation
+.. autoclass:: UnionNestedInOptionalViolation
 
 """
 
@@ -77,6 +79,7 @@
         Flatten consecutively nested ``typing.Literal`` and ``typing.Union``.
 
     Example::
+
         # Correct:
         Literal[1, 2, 3, "foo", 5, None]
         Union[int, str, float]
@@ -91,3 +94,31 @@
 
     error_template = 'Found redundant nested typing annotation'
     code = 702
+
+
+@final
+class UnionNestedInOptionalViolation(ASTViolation):
+    """
+    Forbids to use ``Optional[Union[int, str]]`` annotation.
+
+    Reasoning:
+        Optional[Union[int, str]] equals to Union[int, str, None].
+        Use Union[int, str, None] version for consistency.
+
+    Solution:
+        Replace ``Optional[Union[int, str]]`` with ``Union[int, str, None]``.
+
+    Example::
+
+        # Correct:
+        Union[int, str, None]
+
+        # Wrong:
+        Optional[Union[int, str]]
+
+    .. versionadded:: 0.13.0
+
+    """
+
+    error_template = 'Found typing annotation with `Union` nested in `Optional`'
+    code = 704
diff --git a/wemake_python_styleguide/visitors/ast/annotations.py b/wemake_python_styleguide/visitors/ast/annotations.py
--- a/wemake_python_styleguide/visitors/ast/annotations.py
+++ b/wemake_python_styleguide/visitors/ast/annotations.py
@@ -10,6 +10,7 @@
 from wemake_python_styleguide.violations.annotations import (
     LiteralNoneViolation,
     NestedAnnotationsViolation,
+    UnionNestedInOptionalViolation,
 )
 from wemake_python_styleguide.violations.consistency import (
     MultilineFunctionAnnotationViolation,
@@ -94,6 +95,7 @@
 
         self._check_nested_annotations(annotation)
         self._check_literal_none(annotation)
+        self._check_union_nested_in_optional(annotation)
 
     def _check_nested_annotations(self, annotation: ast.expr) -> None:
         annotation_string = self._get_annotation(annotation)
@@ -106,6 +108,11 @@
         if 'Literal[None]' in annotation_string:
             self.add_violation(LiteralNoneViolation(annotation))
 
+    def _check_union_nested_in_optional(self, annotation: ast.expr) -> None:
+        annotation_string = self._get_annotation(annotation)
+        if 'Optional[Union[' in annotation_string:
+            self.add_violation(UnionNestedInOptionalViolation(annotation))
+
 
 @final
 @alias('visit_any_function', (

{"golden_diff": "diff --git a/wemake_python_styleguide/violations/annotations.py b/wemake_python_styleguide/violations/annotations.py\n--- a/wemake_python_styleguide/violations/annotations.py\n+++ b/wemake_python_styleguide/violations/annotations.py\n@@ -18,12 +18,14 @@\n \n    LiteralNoneViolation\n    NestedAnnotationsViolation\n+   UnionNestedInOptionalViolation\n \n Annotation checks\n ------------------\n \n .. autoclass:: LiteralNoneViolation\n .. autoclass:: NestedAnnotationsViolation\n+.. autoclass:: UnionNestedInOptionalViolation\n \n \"\"\"\n \n@@ -77,6 +79,7 @@\n         Flatten consecutively nested ``typing.Literal`` and ``typing.Union``.\n \n     Example::\n+\n         # Correct:\n         Literal[1, 2, 3, \"foo\", 5, None]\n         Union[int, str, float]\n@@ -91,3 +94,31 @@\n \n     error_template = 'Found redundant nested typing annotation'\n     code = 702\n+\n+\n+@final\n+class UnionNestedInOptionalViolation(ASTViolation):\n+    \"\"\"\n+    Forbids to use ``Optional[Union[int, str]]`` annotation.\n+\n+    Reasoning:\n+        Optional[Union[int, str]] equals to Union[int, str, None].\n+        Use Union[int, str, None] version for consistency.\n+\n+    Solution:\n+        Replace ``Optional[Union[int, str]]`` with ``Union[int, str, None]``.\n+\n+    Example::\n+\n+        # Correct:\n+        Union[int, str, None]\n+\n+        # Wrong:\n+        Optional[Union[int, str]]\n+\n+    .. versionadded:: 0.13.0\n+\n+    \"\"\"\n+\n+    error_template = 'Found typing annotation with `Union` nested in `Optional`'\n+    code = 704\ndiff --git a/wemake_python_styleguide/visitors/ast/annotations.py b/wemake_python_styleguide/visitors/ast/annotations.py\n--- a/wemake_python_styleguide/visitors/ast/annotations.py\n+++ b/wemake_python_styleguide/visitors/ast/annotations.py\n@@ -10,6 +10,7 @@\n from wemake_python_styleguide.violations.annotations import (\n     LiteralNoneViolation,\n     NestedAnnotationsViolation,\n+    UnionNestedInOptionalViolation,\n )\n from wemake_python_styleguide.violations.consistency import (\n     MultilineFunctionAnnotationViolation,\n@@ -94,6 +95,7 @@\n \n         self._check_nested_annotations(annotation)\n         self._check_literal_none(annotation)\n+        self._check_union_nested_in_optional(annotation)\n \n     def _check_nested_annotations(self, annotation: ast.expr) -> None:\n         annotation_string = self._get_annotation(annotation)\n@@ -106,6 +108,11 @@\n         if 'Literal[None]' in annotation_string:\n             self.add_violation(LiteralNoneViolation(annotation))\n \n+    def _check_union_nested_in_optional(self, annotation: ast.expr) -> None:\n+        annotation_string = self._get_annotation(annotation)\n+        if 'Optional[Union[' in annotation_string:\n+            self.add_violation(UnionNestedInOptionalViolation(annotation))\n+\n \n @final\n @alias('visit_any_function', (\n", "issue": "Forbid `Optional[Union[A, B]]`, use `Union[A, B, None]` instead\n# Rule request\r\n\r\n<!-- Thanks for coming up with a proposal! -->\r\n\r\n## Thesis\r\n\r\n<!-- What exactly do you propose? Please, provide code examples. -->\r\n\r\nThese two types are equal: `Optional[Union[A, B]] == Union[A, B, None]`\r\n\r\nFor consistency reasons we need to enforce the second form over the first one.\r\nRelated to #792 \n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nThese checks help to prevent incorrect usage of Python 3 typing annotations.\n\nWhile they maybe of a great help in writing clear\nand concise code, they still can be abused.\n\nOnce again, these rules are highly subjective. But, we love them.\n\n.. currentmodule:: wemake_python_styleguide.violations.annotations\n\nSummary\n-------\n\n.. autosummary::\n   :nosignatures:\n\n   LiteralNoneViolation\n   NestedAnnotationsViolation\n\nAnnotation checks\n------------------\n\n.. autoclass:: LiteralNoneViolation\n.. autoclass:: NestedAnnotationsViolation\n\n\"\"\"\n\nfrom typing_extensions import final\n\nfrom wemake_python_styleguide.violations.base import ASTViolation\n\n\n@final\nclass LiteralNoneViolation(ASTViolation):\n    \"\"\"\n    Forbids to use ``Literal[None]`` typing annotation.\n\n    Reasoning:\n        Literal[None] is just the same as None.\n        There's no need to use the first version.\n        It is not type related, it is a consistency rule.\n\n    Solution:\n        Replace ``Literal[None]`` with ``None``.\n\n    Example::\n\n        # Correct:\n        def func(empty: None):\n            '''Empty function.'''\n\n        # Wrong:\n        def func(empty: Literal[None]):\n            '''Empty function.'''\n\n    .. versionadded:: 0.13.0\n\n    \"\"\"\n\n    code = 701\n    error_template = 'Found useless `Literal[None]` typing annotation'\n\n\n@final\nclass NestedAnnotationsViolation(ASTViolation):\n    \"\"\"\n    Forbids use of nested Literal and Union Annotation.\n\n    Reasoning:\n        There is no need to nest certain annotations of the same type.\n        They are exactly equivalent to the flattened version.\n        Use the flattened version for consistency.\n\n    Solution:\n        Flatten consecutively nested ``typing.Literal`` and ``typing.Union``.\n\n    Example::\n        # Correct:\n        Literal[1, 2, 3, \"foo\", 5, None]\n        Union[int, str, float]\n\n        # Wrong:\n        Literal[Literal[Literal[1, 2, 3], \"foo\"], 5, None]\n        Union[Union[int, str], float]\n\n    .. versionadded:: 0.13.0\n\n    \"\"\"\n\n    error_template = 'Found redundant nested typing annotation'\n    code = 702\n", "path": "wemake_python_styleguide/violations/annotations.py"}, {"content": "# -*- coding: utf-8 -*-\n\nimport ast\nfrom typing import ClassVar, FrozenSet, Optional\n\nfrom typing_extensions import final\n\nfrom wemake_python_styleguide.logic import source\nfrom wemake_python_styleguide.types import AnyFunctionDef\nfrom wemake_python_styleguide.violations.annotations import (\n    LiteralNoneViolation,\n    NestedAnnotationsViolation,\n)\nfrom wemake_python_styleguide.violations.consistency import (\n    MultilineFunctionAnnotationViolation,\n)\nfrom wemake_python_styleguide.visitors.base import BaseNodeVisitor\nfrom wemake_python_styleguide.visitors.decorators import alias\n\n\n@alias('visit_any_function', (\n    'visit_FunctionDef',\n    'visit_AsyncFunctionDef',\n))\nclass _GenericAnnotationVisitor(BaseNodeVisitor):\n    \"\"\"Base class for all annotations visitors.\"\"\"\n\n    _possible_prefixes: ClassVar[FrozenSet[str]] = frozenset((\n        'typing.',\n        'typing_extensions.',\n    ))\n\n    @final\n    def visit_AnnAssign(self, node: ast.AnnAssign) -> None:\n        \"\"\"\n        Checks for assigned value annotation.\n\n        Raises:\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_annotation(node.annotation)\n        self.generic_visit(node)\n\n    @final\n    def visit_any_function(self, node: AnyFunctionDef) -> None:\n        \"\"\"\n        Checks return type annotations.\n\n        Raises:\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_annotation(node.returns)\n        self.generic_visit(node)\n\n    @final\n    def visit_arg(self, node: ast.arg) -> None:\n        \"\"\"\n        Checks arguments annotations.\n\n        Raises:\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_annotation(node.annotation)\n        self.generic_visit(node)\n\n    @final\n    def _get_annotation(self, node: ast.AST) -> str:\n        \"\"\"Smartly turns annotation node to string.\"\"\"\n        full_annotation = source.node_to_string(node)\n        for prefix in self._possible_prefixes:\n            full_annotation = full_annotation.replace(prefix, '')\n        return full_annotation\n\n    def _check_annotation(self, annotation: Optional[ast.expr]) -> None:\n        \"\"\"The only method that need to me implemented in child visitors.\"\"\"\n\n\n@final\nclass SemanticAnnotationVisitor(_GenericAnnotationVisitor):\n    \"\"\"Ensures that nested annotations are used correctly.\"\"\"\n\n    _flat_types: ClassVar[FrozenSet[str]] = frozenset((\n        'Literal',\n        'Union',\n        'Annotated',\n    ))\n\n    def _check_annotation(self, annotation: Optional[ast.expr]) -> None:\n        if not annotation:\n            return\n\n        self._check_nested_annotations(annotation)\n        self._check_literal_none(annotation)\n\n    def _check_nested_annotations(self, annotation: ast.expr) -> None:\n        annotation_string = self._get_annotation(annotation)\n        for flat_type in self._flat_types:\n            if annotation_string.count(flat_type) > 1:\n                self.add_violation(NestedAnnotationsViolation(annotation))\n\n    def _check_literal_none(self, annotation: ast.expr) -> None:\n        annotation_string = self._get_annotation(annotation)\n        if 'Literal[None]' in annotation_string:\n            self.add_violation(LiteralNoneViolation(annotation))\n\n\n@final\n@alias('visit_any_function', (\n    'visit_FunctionDef',\n    'visit_AsyncFunctionDef',\n))\nclass WrongAnnotationVisitor(BaseNodeVisitor):\n    \"\"\"Ensures that annotations are used correctly.\"\"\"\n\n    def visit_any_function(self, node: AnyFunctionDef) -> None:\n        \"\"\"\n        Checks return type annotations.\n\n        Raises:\n            MultilineFunctionAnnotationViolation\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_return_annotation(node)\n        self.generic_visit(node)\n\n    def visit_arg(self, node: ast.arg) -> None:\n        \"\"\"\n        Checks arguments annotations.\n\n        Raises:\n            MultilineFunctionAnnotationViolation\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_arg_annotation(node)\n        self.generic_visit(node)\n\n    def _check_arg_annotation(self, node: ast.arg) -> None:\n        for sub_node in ast.walk(node):\n            lineno = getattr(sub_node, 'lineno', None)\n            if lineno and lineno != node.lineno:\n                self.add_violation(MultilineFunctionAnnotationViolation(node))\n                return\n\n    def _check_return_annotation(self, node: AnyFunctionDef) -> None:\n        if not node.returns:\n            return\n\n        for sub_node in ast.walk(node.returns):\n            lineno = getattr(sub_node, 'lineno', None)\n            if lineno and lineno != node.returns.lineno:\n                self.add_violation(MultilineFunctionAnnotationViolation(node))\n                return\n", "path": "wemake_python_styleguide/visitors/ast/annotations.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nThese checks help to prevent incorrect usage of Python 3 typing annotations.\n\nWhile they maybe of a great help in writing clear\nand concise code, they still can be abused.\n\nOnce again, these rules are highly subjective. But, we love them.\n\n.. currentmodule:: wemake_python_styleguide.violations.annotations\n\nSummary\n-------\n\n.. autosummary::\n   :nosignatures:\n\n   LiteralNoneViolation\n   NestedAnnotationsViolation\n   UnionNestedInOptionalViolation\n\nAnnotation checks\n------------------\n\n.. autoclass:: LiteralNoneViolation\n.. autoclass:: NestedAnnotationsViolation\n.. autoclass:: UnionNestedInOptionalViolation\n\n\"\"\"\n\nfrom typing_extensions import final\n\nfrom wemake_python_styleguide.violations.base import ASTViolation\n\n\n@final\nclass LiteralNoneViolation(ASTViolation):\n    \"\"\"\n    Forbids to use ``Literal[None]`` typing annotation.\n\n    Reasoning:\n        Literal[None] is just the same as None.\n        There's no need to use the first version.\n        It is not type related, it is a consistency rule.\n\n    Solution:\n        Replace ``Literal[None]`` with ``None``.\n\n    Example::\n\n        # Correct:\n        def func(empty: None):\n            '''Empty function.'''\n\n        # Wrong:\n        def func(empty: Literal[None]):\n            '''Empty function.'''\n\n    .. versionadded:: 0.13.0\n\n    \"\"\"\n\n    code = 701\n    error_template = 'Found useless `Literal[None]` typing annotation'\n\n\n@final\nclass NestedAnnotationsViolation(ASTViolation):\n    \"\"\"\n    Forbids use of nested Literal and Union Annotation.\n\n    Reasoning:\n        There is no need to nest certain annotations of the same type.\n        They are exactly equivalent to the flattened version.\n        Use the flattened version for consistency.\n\n    Solution:\n        Flatten consecutively nested ``typing.Literal`` and ``typing.Union``.\n\n    Example::\n\n        # Correct:\n        Literal[1, 2, 3, \"foo\", 5, None]\n        Union[int, str, float]\n\n        # Wrong:\n        Literal[Literal[Literal[1, 2, 3], \"foo\"], 5, None]\n        Union[Union[int, str], float]\n\n    .. versionadded:: 0.13.0\n\n    \"\"\"\n\n    error_template = 'Found redundant nested typing annotation'\n    code = 702\n\n\n@final\nclass UnionNestedInOptionalViolation(ASTViolation):\n    \"\"\"\n    Forbids to use ``Optional[Union[int, str]]`` annotation.\n\n    Reasoning:\n        Optional[Union[int, str]] equals to Union[int, str, None].\n        Use Union[int, str, None] version for consistency.\n\n    Solution:\n        Replace ``Optional[Union[int, str]]`` with ``Union[int, str, None]``.\n\n    Example::\n\n        # Correct:\n        Union[int, str, None]\n\n        # Wrong:\n        Optional[Union[int, str]]\n\n    .. versionadded:: 0.13.0\n\n    \"\"\"\n\n    error_template = 'Found typing annotation with `Union` nested in `Optional`'\n    code = 704\n", "path": "wemake_python_styleguide/violations/annotations.py"}, {"content": "# -*- coding: utf-8 -*-\n\nimport ast\nfrom typing import ClassVar, FrozenSet, Optional\n\nfrom typing_extensions import final\n\nfrom wemake_python_styleguide.logic import source\nfrom wemake_python_styleguide.types import AnyFunctionDef\nfrom wemake_python_styleguide.violations.annotations import (\n    LiteralNoneViolation,\n    NestedAnnotationsViolation,\n    UnionNestedInOptionalViolation,\n)\nfrom wemake_python_styleguide.violations.consistency import (\n    MultilineFunctionAnnotationViolation,\n)\nfrom wemake_python_styleguide.visitors.base import BaseNodeVisitor\nfrom wemake_python_styleguide.visitors.decorators import alias\n\n\n@alias('visit_any_function', (\n    'visit_FunctionDef',\n    'visit_AsyncFunctionDef',\n))\nclass _GenericAnnotationVisitor(BaseNodeVisitor):\n    \"\"\"Base class for all annotations visitors.\"\"\"\n\n    _possible_prefixes: ClassVar[FrozenSet[str]] = frozenset((\n        'typing.',\n        'typing_extensions.',\n    ))\n\n    @final\n    def visit_AnnAssign(self, node: ast.AnnAssign) -> None:\n        \"\"\"\n        Checks for assigned value annotation.\n\n        Raises:\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_annotation(node.annotation)\n        self.generic_visit(node)\n\n    @final\n    def visit_any_function(self, node: AnyFunctionDef) -> None:\n        \"\"\"\n        Checks return type annotations.\n\n        Raises:\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_annotation(node.returns)\n        self.generic_visit(node)\n\n    @final\n    def visit_arg(self, node: ast.arg) -> None:\n        \"\"\"\n        Checks arguments annotations.\n\n        Raises:\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_annotation(node.annotation)\n        self.generic_visit(node)\n\n    @final\n    def _get_annotation(self, node: ast.AST) -> str:\n        \"\"\"Smartly turns annotation node to string.\"\"\"\n        full_annotation = source.node_to_string(node)\n        for prefix in self._possible_prefixes:\n            full_annotation = full_annotation.replace(prefix, '')\n        return full_annotation\n\n    def _check_annotation(self, annotation: Optional[ast.expr]) -> None:\n        \"\"\"The only method that need to me implemented in child visitors.\"\"\"\n\n\n@final\nclass SemanticAnnotationVisitor(_GenericAnnotationVisitor):\n    \"\"\"Ensures that nested annotations are used correctly.\"\"\"\n\n    _flat_types: ClassVar[FrozenSet[str]] = frozenset((\n        'Literal',\n        'Union',\n        'Annotated',\n    ))\n\n    def _check_annotation(self, annotation: Optional[ast.expr]) -> None:\n        if not annotation:\n            return\n\n        self._check_nested_annotations(annotation)\n        self._check_literal_none(annotation)\n        self._check_union_nested_in_optional(annotation)\n\n    def _check_nested_annotations(self, annotation: ast.expr) -> None:\n        annotation_string = self._get_annotation(annotation)\n        for flat_type in self._flat_types:\n            if annotation_string.count(flat_type) > 1:\n                self.add_violation(NestedAnnotationsViolation(annotation))\n\n    def _check_literal_none(self, annotation: ast.expr) -> None:\n        annotation_string = self._get_annotation(annotation)\n        if 'Literal[None]' in annotation_string:\n            self.add_violation(LiteralNoneViolation(annotation))\n\n    def _check_union_nested_in_optional(self, annotation: ast.expr) -> None:\n        annotation_string = self._get_annotation(annotation)\n        if 'Optional[Union[' in annotation_string:\n            self.add_violation(UnionNestedInOptionalViolation(annotation))\n\n\n@final\n@alias('visit_any_function', (\n    'visit_FunctionDef',\n    'visit_AsyncFunctionDef',\n))\nclass WrongAnnotationVisitor(BaseNodeVisitor):\n    \"\"\"Ensures that annotations are used correctly.\"\"\"\n\n    def visit_any_function(self, node: AnyFunctionDef) -> None:\n        \"\"\"\n        Checks return type annotations.\n\n        Raises:\n            MultilineFunctionAnnotationViolation\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_return_annotation(node)\n        self.generic_visit(node)\n\n    def visit_arg(self, node: ast.arg) -> None:\n        \"\"\"\n        Checks arguments annotations.\n\n        Raises:\n            MultilineFunctionAnnotationViolation\n            LiteralNoneAnnotation\n\n        \"\"\"\n        self._check_arg_annotation(node)\n        self.generic_visit(node)\n\n    def _check_arg_annotation(self, node: ast.arg) -> None:\n        for sub_node in ast.walk(node):\n            lineno = getattr(sub_node, 'lineno', None)\n            if lineno and lineno != node.lineno:\n                self.add_violation(MultilineFunctionAnnotationViolation(node))\n                return\n\n    def _check_return_annotation(self, node: AnyFunctionDef) -> None:\n        if not node.returns:\n            return\n\n        for sub_node in ast.walk(node.returns):\n            lineno = getattr(sub_node, 'lineno', None)\n            if lineno and lineno != node.returns.lineno:\n                self.add_violation(MultilineFunctionAnnotationViolation(node))\n                return\n", "path": "wemake_python_styleguide/visitors/ast/annotations.py"}]}