We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Knowing the violation code it is quite hard to find the violation description
**Use Case.** I am testing wemake-python-styleguide on my project.

```
...
  22:5     WPS337 Found multiline conditions
  if (
  ^

Full list of violations and explanations:
https://wemake-python-stylegui.de/en/0.13.4/pages/usage/violations/
make: *** [infra/make/lint.mk:3: lint] Error 1
```

To get more information on what `WPS337` is for, I have to do several steps:

* Open https://wemake-python-stylegui.de/en/0.13.4/pages/usage/violations/
* Realize that WPS337 is probably behind the link titled `WPS300 - WPS399`
* And now I am stuck; I can `Ctrl + F` → `337`, but that won't help; so I try to find the word `multiline`
* and finally I reach the description I wanted: https://wemake-python-stylegui.de/en/0.13.4/pages/usage/violations/consistency.html#wemake_python_styleguide.violations.consistency.MultilineConditionsViolation

This takes time, especially when the title of the violation on this page does not exactly correspond to the name the tool prints on command line.

**Ideally,** I would see a link to the violation description right in the console, like this:

```
...
  22:5     WPS337 Found multiline conditions https://wps.it/0.13.4/WPS337/
  if (
  ^
...
```

Regrettably, wps.to domain is registered already, but wps.it is there.

**If that is not possible,** it would help if the docs pages at least included the violation codes, to make the page searchable via `Ctrl + F`.

--- 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/base.py`
Content:
```
1 """
2 Contains detailed technical information about :term:`violation` internals.
3 
4 .. _violations:
5 
6 Violations API
7 --------------
8 
9 .. currentmodule:: wemake_python_styleguide.violations.base
10 
11 .. autoclasstree:: wemake_python_styleguide.violations.base
12 
13 .. autosummary::
14    :nosignatures:
15 
16    ASTViolation
17    MaybeASTViolation
18    TokenizeViolation
19    SimpleViolation
20 
21 Violation cannot have more than one base class.
22 See :ref:`tutorial` for more information about choosing a correct base class.
23 
24 Conventions
25 ~~~~~~~~~~~
26 
27 - Each violation class name should end with "Violation"
28 - Each violation must have a long docstring with full description
29 - Each violation must have "Reasoning" and "Solution" sections
30 - Each violation must have "versionadded" policy
31 - Each violation should have an example with correct and wrong usages
32 - If violation error template should have a parameter
33   it should be the last part of the text: ``: {0}``
34 
35 Deprecating a violation
36 ~~~~~~~~~~~~~~~~~~~~~~~
37 
38 When you want to mark some violation as deprecated,
39 then assign ``deprecated`` boolean flag to it:
40 
41 .. code:: python
42 
43   @final
44   class SomeViolation(ASTViolation):
45       deprecated = True
46 
47 Reference
48 ~~~~~~~~~
49 
50 """
51 
52 import abc
53 import ast
54 import enum
55 import tokenize
56 from typing import Callable, ClassVar, Optional, Set, Tuple, Union
57 
58 from typing_extensions import final
59 
60 #: General type for all possible nodes where error happens.
61 ErrorNode = Union[
62     ast.AST,
63     tokenize.TokenInfo,
64     None,
65 ]
66 
67 #: We use this type to define helper classes with callbacks to add violations.
68 ErrorCallback = Callable[['BaseViolation'], None]
69 
70 
71 @enum.unique
72 class ViolationPostfixes(enum.Enum):
73     """String values of postfixes used for violation baselines."""
74 
75     bigger_than = ' > {0}'
76     less_than = ' < {0}'
77 
78 
79 class BaseViolation(object, metaclass=abc.ABCMeta):
80     """
81     Abstract base class for all style violations.
82 
83     It basically just defines how to create any error and how to format
84     this error later on.
85 
86     Each subclass must define ``error_template`` and ``code`` fields.
87 
88     Attributes:
89         error_template: message that will be shown to user after formatting.
90         code: unique violation number. Used to identify the violation.
91         previous_codes: just a documentation thing to track changes in time.
92         deprecated: indicates that this violation will be removed soon.
93         postfix_template: indicates message that we show at the very end.
94 
95     """
96 
97     error_template: ClassVar[str]
98     code: ClassVar[int]
99     previous_codes: ClassVar[Set[int]]
100     deprecated: ClassVar[bool] = False
101 
102     # We use this code to show base metrics and thresholds mostly:
103     postfix_template: ClassVar[ViolationPostfixes] = (
104         ViolationPostfixes.bigger_than
105     )
106 
107     def __init__(
108         self,
109         node: ErrorNode,
110         text: Optional[str] = None,
111         baseline: Optional[int] = None,
112     ) -> None:
113         """
114         Creates a new instance of an abstract violation.
115 
116         Arguments:
117             node: violation was raised by this node. If applicable.
118             text: extra text to format the final message. If applicable.
119             baseline: some complexity violations show the logic threshold here.
120 
121         """
122         self._node = node
123         self._text = text
124         self._baseline = baseline
125 
126     @final
127     def message(self) -> str:
128         """
129         Returns error's formatted message with code and reason.
130 
131         Conditionally formats the ``error_template`` if it is required.
132         """
133         return '{0} {1}{2}'.format(
134             self._full_code(),
135             self.error_template.format(self._text),
136             self._postfix_information(),
137         )
138 
139     @final
140     def node_items(self) -> Tuple[int, int, str]:
141         """Returns tuple to match ``flake8`` API format."""
142         return (*self._location(), self.message())
143 
144     @final
145     def _full_code(self) -> str:
146         """
147         Returns fully formatted code.
148 
149         Adds violation letter to the numbers.
150         Also ensures that codes like ``3`` will be represented as ``WPS003``.
151         """
152         return 'WPS{0}'.format(str(self.code).zfill(3))
153 
154     @final
155     def _postfix_information(self) -> str:
156         """
157         Adds useful information to the end of the violation message.
158 
159         Useful for complexity baselines and other thresholds.
160         """
161         if self._baseline is None:
162             return ''
163         return self.postfix_template.value.format(self._baseline)
164 
165     @abc.abstractmethod
166     def _location(self) -> Tuple[int, int]:
167         """Base method for showing error location."""
168 
169 
170 class _BaseASTViolation(BaseViolation, metaclass=abc.ABCMeta):
171     """Used as a based type for all ``ast`` violations."""
172 
173     _node: Optional[ast.AST]
174 
175     @final
176     def _location(self) -> Tuple[int, int]:
177         line_number = getattr(self._node, 'lineno', 0)
178         column_offset = getattr(self._node, 'col_offset', 0)
179         return line_number, column_offset
180 
181 
182 class ASTViolation(_BaseASTViolation, metaclass=abc.ABCMeta):
183     """Violation for ``ast`` based style visitors."""
184 
185     _node: ast.AST
186 
187 
188 class MaybeASTViolation(_BaseASTViolation, metaclass=abc.ABCMeta):
189     """
190     Violation for ``ast`` and modules visitors.
191 
192     Is used for violations that share the same rule for nodes and module names.
193     Is wildly used for naming rules.
194     """
195 
196     def __init__(
197         self,
198         node: Optional[ast.AST] = None,
199         text: Optional[str] = None,
200         baseline: Optional[int] = None,
201     ) -> None:
202         """Creates new instance of module violation without explicit node."""
203         super().__init__(node, text=text, baseline=baseline)
204 
205 
206 class TokenizeViolation(BaseViolation, metaclass=abc.ABCMeta):
207     """Violation for ``tokenize`` based visitors."""
208 
209     _node: tokenize.TokenInfo
210 
211     @final
212     def _location(self) -> Tuple[int, int]:
213         return self._node.start
214 
215 
216 class SimpleViolation(BaseViolation, metaclass=abc.ABCMeta):
217     """Violation for cases where there's no associated nodes."""
218 
219     _node: None
220 
221     def __init__(
222         self,
223         node=None,
224         text: Optional[str] = None,
225         baseline: Optional[int] = None,
226     ) -> None:
227         """Creates new instance of simple style violation."""
228         super().__init__(node, text=text, baseline=baseline)
229 
230     @final
231     def _location(self) -> Tuple[int, int]:
232         """
233         Return violation location inside the file.
234 
235         Default location is in the so-called "file beginning".
236         Cannot be ignored by inline ``noqa`` comments.
237         """
238         return 0, 0
239
```
--- 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/base.py b/wemake_python_styleguide/violations/base.py
--- a/wemake_python_styleguide/violations/base.py
+++ b/wemake_python_styleguide/violations/base.py
@@ -76,7 +76,8 @@
     less_than = ' < {0}'
 
 
-class BaseViolation(object, metaclass=abc.ABCMeta):
+# TODO: remove `noqa` after a new release:
+class BaseViolation(object, metaclass=abc.ABCMeta):  # noqa: WPS338
     """
     Abstract base class for all style violations.
 
@@ -99,11 +100,34 @@
     previous_codes: ClassVar[Set[int]]
     deprecated: ClassVar[bool] = False
 
+    # assigned in __init_subclass__
+    full_code: ClassVar[str]
+    summary: ClassVar[str]
+
     # We use this code to show base metrics and thresholds mostly:
     postfix_template: ClassVar[ViolationPostfixes] = (
         ViolationPostfixes.bigger_than
     )
 
+    def __init_subclass__(cls, **kwargs) -> None:
+        """Sets additional values for subclasses."""
+        super().__init_subclass__(**kwargs)
+        violation_code = getattr(cls, 'code', None)
+        if violation_code is None:
+            return
+        if cls.__doc__ is None:
+            raise TypeError(
+                'Please include a docstring documenting {0}'.format(cls),
+            )
+        # this is mostly done for docs to display the full code,
+        # allowing its indexing in search engines and better discoverability
+        cls.full_code = cls._full_code()
+        cls.summary = cls.__doc__.lstrip().split('\n', maxsplit=1)[0]
+        # this hack adds full code to summary table in the docs
+        cls.__doc__ = _prepend_skipping_whitespaces(
+            '{0} — '.format(cls.full_code), cls.__doc__,
+        )
+
     def __init__(
         self,
         node: ErrorNode,
@@ -131,7 +155,7 @@
         Conditionally formats the ``error_template`` if it is required.
         """
         return '{0} {1}{2}'.format(
-            self._full_code(),
+            self.full_code,
             self.error_template.format(self._text),
             self._postfix_information(),
         )
@@ -142,14 +166,15 @@
         return (*self._location(), self.message())
 
     @final
-    def _full_code(self) -> str:
+    @classmethod
+    def _full_code(cls) -> str:
         """
         Returns fully formatted code.
 
         Adds violation letter to the numbers.
         Also ensures that codes like ``3`` will be represented as ``WPS003``.
         """
-        return 'WPS{0}'.format(str(self.code).zfill(3))
+        return 'WPS{0}'.format(str(cls.code).zfill(3))
 
     @final
     def _postfix_information(self) -> str:
@@ -236,3 +261,9 @@
         Cannot be ignored by inline ``noqa`` comments.
         """
         return 0, 0
+
+
+def _prepend_skipping_whitespaces(prefix: str, text: str) -> str:
+    lstripped_text = text.lstrip()
+    leading_whitespaces = text[:len(text) - len(lstripped_text)]
+    return leading_whitespaces + prefix + lstripped_text

{"golden_diff": "diff --git a/wemake_python_styleguide/violations/base.py b/wemake_python_styleguide/violations/base.py\n--- a/wemake_python_styleguide/violations/base.py\n+++ b/wemake_python_styleguide/violations/base.py\n@@ -76,7 +76,8 @@\n     less_than = ' < {0}'\n \n \n-class BaseViolation(object, metaclass=abc.ABCMeta):\n+# TODO: remove `noqa` after a new release:\n+class BaseViolation(object, metaclass=abc.ABCMeta):  # noqa: WPS338\n     \"\"\"\n     Abstract base class for all style violations.\n \n@@ -99,11 +100,34 @@\n     previous_codes: ClassVar[Set[int]]\n     deprecated: ClassVar[bool] = False\n \n+    # assigned in __init_subclass__\n+    full_code: ClassVar[str]\n+    summary: ClassVar[str]\n+\n     # We use this code to show base metrics and thresholds mostly:\n     postfix_template: ClassVar[ViolationPostfixes] = (\n         ViolationPostfixes.bigger_than\n     )\n \n+    def __init_subclass__(cls, **kwargs) -> None:\n+        \"\"\"Sets additional values for subclasses.\"\"\"\n+        super().__init_subclass__(**kwargs)\n+        violation_code = getattr(cls, 'code', None)\n+        if violation_code is None:\n+            return\n+        if cls.__doc__ is None:\n+            raise TypeError(\n+                'Please include a docstring documenting {0}'.format(cls),\n+            )\n+        # this is mostly done for docs to display the full code,\n+        # allowing its indexing in search engines and better discoverability\n+        cls.full_code = cls._full_code()\n+        cls.summary = cls.__doc__.lstrip().split('\\n', maxsplit=1)[0]\n+        # this hack adds full code to summary table in the docs\n+        cls.__doc__ = _prepend_skipping_whitespaces(\n+            '{0} \u2014 '.format(cls.full_code), cls.__doc__,\n+        )\n+\n     def __init__(\n         self,\n         node: ErrorNode,\n@@ -131,7 +155,7 @@\n         Conditionally formats the ``error_template`` if it is required.\n         \"\"\"\n         return '{0} {1}{2}'.format(\n-            self._full_code(),\n+            self.full_code,\n             self.error_template.format(self._text),\n             self._postfix_information(),\n         )\n@@ -142,14 +166,15 @@\n         return (*self._location(), self.message())\n \n     @final\n-    def _full_code(self) -> str:\n+    @classmethod\n+    def _full_code(cls) -> str:\n         \"\"\"\n         Returns fully formatted code.\n \n         Adds violation letter to the numbers.\n         Also ensures that codes like ``3`` will be represented as ``WPS003``.\n         \"\"\"\n-        return 'WPS{0}'.format(str(self.code).zfill(3))\n+        return 'WPS{0}'.format(str(cls.code).zfill(3))\n \n     @final\n     def _postfix_information(self) -> str:\n@@ -236,3 +261,9 @@\n         Cannot be ignored by inline ``noqa`` comments.\n         \"\"\"\n         return 0, 0\n+\n+\n+def _prepend_skipping_whitespaces(prefix: str, text: str) -> str:\n+    lstripped_text = text.lstrip()\n+    leading_whitespaces = text[:len(text) - len(lstripped_text)]\n+    return leading_whitespaces + prefix + lstripped_text\n", "issue": "Knowing the violation code it is quite hard to find the violation description\n**Use Case.** I am testing wemake-python-styleguide on my project.\r\n\r\n```\r\n...\r\n  22:5     WPS337 Found multiline conditions\r\n  if (\r\n  ^\r\n\r\nFull list of violations and explanations:\r\nhttps://wemake-python-stylegui.de/en/0.13.4/pages/usage/violations/\r\nmake: *** [infra/make/lint.mk:3: lint] Error 1\r\n```\r\n\r\nTo get more information on what `WPS337` is for, I have to do several steps:\r\n\r\n* Open https://wemake-python-stylegui.de/en/0.13.4/pages/usage/violations/\r\n* Realize that WPS337 is probably behind the link titled `WPS300 - WPS399`\r\n* And now I am stuck; I can `Ctrl + F` \u2192 `337`, but that won't help; so I try to find the word `multiline`\r\n* and finally I reach the description I wanted: https://wemake-python-stylegui.de/en/0.13.4/pages/usage/violations/consistency.html#wemake_python_styleguide.violations.consistency.MultilineConditionsViolation\r\n\r\nThis takes time, especially when the title of the violation on this page does not exactly correspond to the name the tool prints on command line.\r\n\r\n**Ideally,** I would see a link to the violation description right in the console, like this:\r\n\r\n```\r\n...\r\n  22:5     WPS337 Found multiline conditions https://wps.it/0.13.4/WPS337/\r\n  if (\r\n  ^\r\n...\r\n```\r\n\r\nRegrettably, wps.to domain is registered already, but wps.it is there.\r\n\r\n**If that is not possible,** it would help if the docs pages at least included the violation codes, to make the page searchable via `Ctrl + F`.\n", "before_files": [{"content": "\"\"\"\nContains detailed technical information about :term:`violation` internals.\n\n.. _violations:\n\nViolations API\n--------------\n\n.. currentmodule:: wemake_python_styleguide.violations.base\n\n.. autoclasstree:: wemake_python_styleguide.violations.base\n\n.. autosummary::\n   :nosignatures:\n\n   ASTViolation\n   MaybeASTViolation\n   TokenizeViolation\n   SimpleViolation\n\nViolation cannot have more than one base class.\nSee :ref:`tutorial` for more information about choosing a correct base class.\n\nConventions\n~~~~~~~~~~~\n\n- Each violation class name should end with \"Violation\"\n- Each violation must have a long docstring with full description\n- Each violation must have \"Reasoning\" and \"Solution\" sections\n- Each violation must have \"versionadded\" policy\n- Each violation should have an example with correct and wrong usages\n- If violation error template should have a parameter\n  it should be the last part of the text: ``: {0}``\n\nDeprecating a violation\n~~~~~~~~~~~~~~~~~~~~~~~\n\nWhen you want to mark some violation as deprecated,\nthen assign ``deprecated`` boolean flag to it:\n\n.. code:: python\n\n  @final\n  class SomeViolation(ASTViolation):\n      deprecated = True\n\nReference\n~~~~~~~~~\n\n\"\"\"\n\nimport abc\nimport ast\nimport enum\nimport tokenize\nfrom typing import Callable, ClassVar, Optional, Set, Tuple, Union\n\nfrom typing_extensions import final\n\n#: General type for all possible nodes where error happens.\nErrorNode = Union[\n    ast.AST,\n    tokenize.TokenInfo,\n    None,\n]\n\n#: We use this type to define helper classes with callbacks to add violations.\nErrorCallback = Callable[['BaseViolation'], None]\n\n\n@enum.unique\nclass ViolationPostfixes(enum.Enum):\n    \"\"\"String values of postfixes used for violation baselines.\"\"\"\n\n    bigger_than = ' > {0}'\n    less_than = ' < {0}'\n\n\nclass BaseViolation(object, metaclass=abc.ABCMeta):\n    \"\"\"\n    Abstract base class for all style violations.\n\n    It basically just defines how to create any error and how to format\n    this error later on.\n\n    Each subclass must define ``error_template`` and ``code`` fields.\n\n    Attributes:\n        error_template: message that will be shown to user after formatting.\n        code: unique violation number. Used to identify the violation.\n        previous_codes: just a documentation thing to track changes in time.\n        deprecated: indicates that this violation will be removed soon.\n        postfix_template: indicates message that we show at the very end.\n\n    \"\"\"\n\n    error_template: ClassVar[str]\n    code: ClassVar[int]\n    previous_codes: ClassVar[Set[int]]\n    deprecated: ClassVar[bool] = False\n\n    # We use this code to show base metrics and thresholds mostly:\n    postfix_template: ClassVar[ViolationPostfixes] = (\n        ViolationPostfixes.bigger_than\n    )\n\n    def __init__(\n        self,\n        node: ErrorNode,\n        text: Optional[str] = None,\n        baseline: Optional[int] = None,\n    ) -> None:\n        \"\"\"\n        Creates a new instance of an abstract violation.\n\n        Arguments:\n            node: violation was raised by this node. If applicable.\n            text: extra text to format the final message. If applicable.\n            baseline: some complexity violations show the logic threshold here.\n\n        \"\"\"\n        self._node = node\n        self._text = text\n        self._baseline = baseline\n\n    @final\n    def message(self) -> str:\n        \"\"\"\n        Returns error's formatted message with code and reason.\n\n        Conditionally formats the ``error_template`` if it is required.\n        \"\"\"\n        return '{0} {1}{2}'.format(\n            self._full_code(),\n            self.error_template.format(self._text),\n            self._postfix_information(),\n        )\n\n    @final\n    def node_items(self) -> Tuple[int, int, str]:\n        \"\"\"Returns tuple to match ``flake8`` API format.\"\"\"\n        return (*self._location(), self.message())\n\n    @final\n    def _full_code(self) -> str:\n        \"\"\"\n        Returns fully formatted code.\n\n        Adds violation letter to the numbers.\n        Also ensures that codes like ``3`` will be represented as ``WPS003``.\n        \"\"\"\n        return 'WPS{0}'.format(str(self.code).zfill(3))\n\n    @final\n    def _postfix_information(self) -> str:\n        \"\"\"\n        Adds useful information to the end of the violation message.\n\n        Useful for complexity baselines and other thresholds.\n        \"\"\"\n        if self._baseline is None:\n            return ''\n        return self.postfix_template.value.format(self._baseline)\n\n    @abc.abstractmethod\n    def _location(self) -> Tuple[int, int]:\n        \"\"\"Base method for showing error location.\"\"\"\n\n\nclass _BaseASTViolation(BaseViolation, metaclass=abc.ABCMeta):\n    \"\"\"Used as a based type for all ``ast`` violations.\"\"\"\n\n    _node: Optional[ast.AST]\n\n    @final\n    def _location(self) -> Tuple[int, int]:\n        line_number = getattr(self._node, 'lineno', 0)\n        column_offset = getattr(self._node, 'col_offset', 0)\n        return line_number, column_offset\n\n\nclass ASTViolation(_BaseASTViolation, metaclass=abc.ABCMeta):\n    \"\"\"Violation for ``ast`` based style visitors.\"\"\"\n\n    _node: ast.AST\n\n\nclass MaybeASTViolation(_BaseASTViolation, metaclass=abc.ABCMeta):\n    \"\"\"\n    Violation for ``ast`` and modules visitors.\n\n    Is used for violations that share the same rule for nodes and module names.\n    Is wildly used for naming rules.\n    \"\"\"\n\n    def __init__(\n        self,\n        node: Optional[ast.AST] = None,\n        text: Optional[str] = None,\n        baseline: Optional[int] = None,\n    ) -> None:\n        \"\"\"Creates new instance of module violation without explicit node.\"\"\"\n        super().__init__(node, text=text, baseline=baseline)\n\n\nclass TokenizeViolation(BaseViolation, metaclass=abc.ABCMeta):\n    \"\"\"Violation for ``tokenize`` based visitors.\"\"\"\n\n    _node: tokenize.TokenInfo\n\n    @final\n    def _location(self) -> Tuple[int, int]:\n        return self._node.start\n\n\nclass SimpleViolation(BaseViolation, metaclass=abc.ABCMeta):\n    \"\"\"Violation for cases where there's no associated nodes.\"\"\"\n\n    _node: None\n\n    def __init__(\n        self,\n        node=None,\n        text: Optional[str] = None,\n        baseline: Optional[int] = None,\n    ) -> None:\n        \"\"\"Creates new instance of simple style violation.\"\"\"\n        super().__init__(node, text=text, baseline=baseline)\n\n    @final\n    def _location(self) -> Tuple[int, int]:\n        \"\"\"\n        Return violation location inside the file.\n\n        Default location is in the so-called \"file beginning\".\n        Cannot be ignored by inline ``noqa`` comments.\n        \"\"\"\n        return 0, 0\n", "path": "wemake_python_styleguide/violations/base.py"}], "after_files": [{"content": "\"\"\"\nContains detailed technical information about :term:`violation` internals.\n\n.. _violations:\n\nViolations API\n--------------\n\n.. currentmodule:: wemake_python_styleguide.violations.base\n\n.. autoclasstree:: wemake_python_styleguide.violations.base\n\n.. autosummary::\n   :nosignatures:\n\n   ASTViolation\n   MaybeASTViolation\n   TokenizeViolation\n   SimpleViolation\n\nViolation cannot have more than one base class.\nSee :ref:`tutorial` for more information about choosing a correct base class.\n\nConventions\n~~~~~~~~~~~\n\n- Each violation class name should end with \"Violation\"\n- Each violation must have a long docstring with full description\n- Each violation must have \"Reasoning\" and \"Solution\" sections\n- Each violation must have \"versionadded\" policy\n- Each violation should have an example with correct and wrong usages\n- If violation error template should have a parameter\n  it should be the last part of the text: ``: {0}``\n\nDeprecating a violation\n~~~~~~~~~~~~~~~~~~~~~~~\n\nWhen you want to mark some violation as deprecated,\nthen assign ``deprecated`` boolean flag to it:\n\n.. code:: python\n\n  @final\n  class SomeViolation(ASTViolation):\n      deprecated = True\n\nReference\n~~~~~~~~~\n\n\"\"\"\n\nimport abc\nimport ast\nimport enum\nimport tokenize\nfrom typing import Callable, ClassVar, Optional, Set, Tuple, Union\n\nfrom typing_extensions import final\n\n#: General type for all possible nodes where error happens.\nErrorNode = Union[\n    ast.AST,\n    tokenize.TokenInfo,\n    None,\n]\n\n#: We use this type to define helper classes with callbacks to add violations.\nErrorCallback = Callable[['BaseViolation'], None]\n\n\n@enum.unique\nclass ViolationPostfixes(enum.Enum):\n    \"\"\"String values of postfixes used for violation baselines.\"\"\"\n\n    bigger_than = ' > {0}'\n    less_than = ' < {0}'\n\n\n# TODO: remove `noqa` after a new release:\nclass BaseViolation(object, metaclass=abc.ABCMeta):  # noqa: WPS338\n    \"\"\"\n    Abstract base class for all style violations.\n\n    It basically just defines how to create any error and how to format\n    this error later on.\n\n    Each subclass must define ``error_template`` and ``code`` fields.\n\n    Attributes:\n        error_template: message that will be shown to user after formatting.\n        code: unique violation number. Used to identify the violation.\n        previous_codes: just a documentation thing to track changes in time.\n        deprecated: indicates that this violation will be removed soon.\n        postfix_template: indicates message that we show at the very end.\n\n    \"\"\"\n\n    error_template: ClassVar[str]\n    code: ClassVar[int]\n    previous_codes: ClassVar[Set[int]]\n    deprecated: ClassVar[bool] = False\n\n    # assigned in __init_subclass__\n    full_code: ClassVar[str]\n    summary: ClassVar[str]\n\n    # We use this code to show base metrics and thresholds mostly:\n    postfix_template: ClassVar[ViolationPostfixes] = (\n        ViolationPostfixes.bigger_than\n    )\n\n    def __init_subclass__(cls, **kwargs) -> None:\n        \"\"\"Sets additional values for subclasses.\"\"\"\n        super().__init_subclass__(**kwargs)\n        violation_code = getattr(cls, 'code', None)\n        if violation_code is None:\n            return\n        if cls.__doc__ is None:\n            raise TypeError(\n                'Please include a docstring documenting {0}'.format(cls),\n            )\n        # this is mostly done for docs to display the full code,\n        # allowing its indexing in search engines and better discoverability\n        cls.full_code = cls._full_code()\n        cls.summary = cls.__doc__.lstrip().split('\\n', maxsplit=1)[0]\n        # this hack adds full code to summary table in the docs\n        cls.__doc__ = _prepend_skipping_whitespaces(\n            '{0} \u2014 '.format(cls.full_code), cls.__doc__,\n        )\n\n    def __init__(\n        self,\n        node: ErrorNode,\n        text: Optional[str] = None,\n        baseline: Optional[int] = None,\n    ) -> None:\n        \"\"\"\n        Creates a new instance of an abstract violation.\n\n        Arguments:\n            node: violation was raised by this node. If applicable.\n            text: extra text to format the final message. If applicable.\n            baseline: some complexity violations show the logic threshold here.\n\n        \"\"\"\n        self._node = node\n        self._text = text\n        self._baseline = baseline\n\n    @final\n    def message(self) -> str:\n        \"\"\"\n        Returns error's formatted message with code and reason.\n\n        Conditionally formats the ``error_template`` if it is required.\n        \"\"\"\n        return '{0} {1}{2}'.format(\n            self.full_code,\n            self.error_template.format(self._text),\n            self._postfix_information(),\n        )\n\n    @final\n    def node_items(self) -> Tuple[int, int, str]:\n        \"\"\"Returns tuple to match ``flake8`` API format.\"\"\"\n        return (*self._location(), self.message())\n\n    @final\n    @classmethod\n    def _full_code(cls) -> str:\n        \"\"\"\n        Returns fully formatted code.\n\n        Adds violation letter to the numbers.\n        Also ensures that codes like ``3`` will be represented as ``WPS003``.\n        \"\"\"\n        return 'WPS{0}'.format(str(cls.code).zfill(3))\n\n    @final\n    def _postfix_information(self) -> str:\n        \"\"\"\n        Adds useful information to the end of the violation message.\n\n        Useful for complexity baselines and other thresholds.\n        \"\"\"\n        if self._baseline is None:\n            return ''\n        return self.postfix_template.value.format(self._baseline)\n\n    @abc.abstractmethod\n    def _location(self) -> Tuple[int, int]:\n        \"\"\"Base method for showing error location.\"\"\"\n\n\nclass _BaseASTViolation(BaseViolation, metaclass=abc.ABCMeta):\n    \"\"\"Used as a based type for all ``ast`` violations.\"\"\"\n\n    _node: Optional[ast.AST]\n\n    @final\n    def _location(self) -> Tuple[int, int]:\n        line_number = getattr(self._node, 'lineno', 0)\n        column_offset = getattr(self._node, 'col_offset', 0)\n        return line_number, column_offset\n\n\nclass ASTViolation(_BaseASTViolation, metaclass=abc.ABCMeta):\n    \"\"\"Violation for ``ast`` based style visitors.\"\"\"\n\n    _node: ast.AST\n\n\nclass MaybeASTViolation(_BaseASTViolation, metaclass=abc.ABCMeta):\n    \"\"\"\n    Violation for ``ast`` and modules visitors.\n\n    Is used for violations that share the same rule for nodes and module names.\n    Is wildly used for naming rules.\n    \"\"\"\n\n    def __init__(\n        self,\n        node: Optional[ast.AST] = None,\n        text: Optional[str] = None,\n        baseline: Optional[int] = None,\n    ) -> None:\n        \"\"\"Creates new instance of module violation without explicit node.\"\"\"\n        super().__init__(node, text=text, baseline=baseline)\n\n\nclass TokenizeViolation(BaseViolation, metaclass=abc.ABCMeta):\n    \"\"\"Violation for ``tokenize`` based visitors.\"\"\"\n\n    _node: tokenize.TokenInfo\n\n    @final\n    def _location(self) -> Tuple[int, int]:\n        return self._node.start\n\n\nclass SimpleViolation(BaseViolation, metaclass=abc.ABCMeta):\n    \"\"\"Violation for cases where there's no associated nodes.\"\"\"\n\n    _node: None\n\n    def __init__(\n        self,\n        node=None,\n        text: Optional[str] = None,\n        baseline: Optional[int] = None,\n    ) -> None:\n        \"\"\"Creates new instance of simple style violation.\"\"\"\n        super().__init__(node, text=text, baseline=baseline)\n\n    @final\n    def _location(self) -> Tuple[int, int]:\n        \"\"\"\n        Return violation location inside the file.\n\n        Default location is in the so-called \"file beginning\".\n        Cannot be ignored by inline ``noqa`` comments.\n        \"\"\"\n        return 0, 0\n\n\ndef _prepend_skipping_whitespaces(prefix: str, text: str) -> str:\n    lstripped_text = text.lstrip()\n    leading_whitespaces = text[:len(text) - len(lstripped_text)]\n    return leading_whitespaces + prefix + lstripped_text\n", "path": "wemake_python_styleguide/violations/base.py"}]}