We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Feature: count async function as a module member
Currently we count only regular functions and classes as module members: https://github.com/wemake-services/wemake-python-styleguide/blob/master/wemake_python_styleguide/visitors/ast/complexity/counts.py#L40-L60

What needs to be done?
1. We need to count `AsyncFunctionDef` as well
2. We need to improve `ModuleMembers` type to include `AsyncFunctionDef`
3. We need to refactor how handler for each node works: there's no need to duplicate the logic, so it can just be: `visit_AsyncFunctionDef = visit_FunctionDef = visit_ClassDef`
4. We need to improve unit tests to include `async` functions as well: https://github.com/wemake-services/wemake-python-styleguide/blob/master/tests/test_visitors/test_ast/test_complexity/test_counts/test_module_counts.py



--- 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/types.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 """
4 This module contains custom ``mypy`` types that we commonly use.
5 
6 Policy
7 ------
8 
9 If any of the following statements is true, move the type to this file:
10 
11 - if type is used in multiple files
12 - if type is complex enough it has to be documented
13 - if type is very important for the public API
14 
15 """
16 
17 import ast
18 from typing import TYPE_CHECKING, Tuple, Type, Union
19 
20 if TYPE_CHECKING:  # pragma: no cover
21     from typing_extensions import Protocol  # noqa: Z435
22 
23     # This solves cycle imports problem:
24     from .visitors import base  # noqa: F401,Z300,Z435
25 else:
26     # We do not need to do anything if type checker is not working:
27     Protocol = object
28 
29 #: Visitor type definition:
30 VisitorClass = Type['base.BaseVisitor']
31 
32 #: In cases we need to work with both import types:
33 AnyImport = Union[ast.Import, ast.ImportFrom]
34 
35 #: Flake8 API format to return error messages:
36 CheckResult = Tuple[int, int, str, type]
37 
38 #: Code members that we count in a module:
39 ModuleMembers = Union[ast.FunctionDef, ast.ClassDef]
40 
41 
42 class ConfigurationOptions(Protocol):
43     """
44     Provides structure for the options we use in our checker.
45 
46     Then this protocol is passed to each individual visitor and used there.
47     It uses structural sub-typing, and does not represent any kind of a real
48     class or structure.
49 
50     This class actually works only when running type check.
51     At other cases it is just an ``object``.
52 
53     See also:
54         https://mypy.readthedocs.io/en/latest/protocols.html
55 
56     """
57 
58     # General:
59     min_variable_length: int
60     i_control_code: bool
61 
62     # Complexity:
63     max_arguments: int
64     max_local_variables: int
65     max_returns: int
66     max_expressions: int
67     max_offset_blocks: int
68     max_elifs: int
69     max_module_members: int
70     max_methods: int
71     max_line_complexity: int
72     max_jones_score: int
73     max_imports: int
74     max_conditions: int
75 
76     # File names:
77     min_module_name_length: int
78
```

Path: `wemake_python_styleguide/visitors/ast/complexity/counts.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 import ast
4 from collections import defaultdict
5 from typing import DefaultDict, Union
6 
7 from wemake_python_styleguide.logics.functions import is_method
8 from wemake_python_styleguide.types import AnyImport, ModuleMembers
9 from wemake_python_styleguide.violations.complexity import (
10     TooManyConditionsViolation,
11     TooManyImportsViolation,
12     TooManyMethodsViolation,
13     TooManyModuleMembersViolation,
14 )
15 from wemake_python_styleguide.visitors.base import BaseNodeVisitor
16 
17 ConditionNodes = Union[ast.If, ast.While, ast.IfExp]
18 
19 
20 class ModuleMembersVisitor(BaseNodeVisitor):
21     """Counts classes and functions in a module."""
22 
23     def __init__(self, *args, **kwargs) -> None:
24         """Creates a counter for tracked metrics."""
25         super().__init__(*args, **kwargs)
26         self._public_items_count = 0
27 
28     def _check_members_count(self, node: ModuleMembers) -> None:
29         """This method increases the number of module members."""
30         parent = getattr(node, 'parent', None)
31         is_real_method = is_method(getattr(node, 'function_type', None))
32 
33         if isinstance(parent, ast.Module) and not is_real_method:
34             self._public_items_count += 1
35 
36     def _post_visit(self) -> None:
37         if self._public_items_count > self.options.max_module_members:
38             self.add_violation(TooManyModuleMembersViolation())
39 
40     def visit_ClassDef(self, node: ast.ClassDef) -> None:
41         """
42         Counts the number of `class`es in a single module.
43 
44         Raises:
45             TooManyModuleMembersViolation
46 
47         """
48         self._check_members_count(node)
49         self.generic_visit(node)
50 
51     def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
52         """
53         Counts the number of functions in a single module.
54 
55         Raises:
56             TooManyModuleMembersViolation
57 
58         """
59         self._check_members_count(node)
60         self.generic_visit(node)
61 
62 
63 class ImportMembersVisitor(BaseNodeVisitor):
64     """Counts imports in a module."""
65 
66     def __init__(self, *args, **kwargs) -> None:
67         """Creates a counter for tracked metrics."""
68         super().__init__(*args, **kwargs)
69         self._imports_count = 0
70 
71     def _post_visit(self) -> None:
72         if self._imports_count > self.options.max_imports:
73             self.add_violation(
74                 TooManyImportsViolation(text=str(self._imports_count)),
75             )
76 
77     def visit_Import(self, node: AnyImport) -> None:
78         """
79         Counts the number of ``import`` and ``from ... import ...``.
80 
81         Raises:
82             TooManyImportsViolation
83 
84         """
85         self._imports_count += 1
86         self.generic_visit(node)
87 
88     visit_ImportFrom = visit_Import
89 
90 
91 class MethodMembersVisitor(BaseNodeVisitor):
92     """Counts methods in a single class."""
93 
94     def __init__(self, *args, **kwargs) -> None:
95         """Creates a counter for tracked methods in different classes."""
96         super().__init__(*args, **kwargs)
97         self._methods: DefaultDict[ast.ClassDef, int] = defaultdict(int)
98 
99     def _check_method(self, node: ast.FunctionDef) -> None:
100         parent = getattr(node, 'parent', None)
101         if isinstance(parent, ast.ClassDef):
102             self._methods[parent] += 1
103 
104     def _post_visit(self) -> None:
105         for node, count in self._methods.items():
106             if count > self.options.max_methods:
107                 self.add_violation(TooManyMethodsViolation(text=node.name))
108 
109     def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
110         """
111         Counts the number of methods in a single class.
112 
113         Raises:
114             TooManyMethodsViolation
115 
116         """
117         self._check_method(node)
118         self.generic_visit(node)
119 
120 
121 class ConditionsVisitor(BaseNodeVisitor):
122     """Checks ``if`` and ``while`` statements for condition counts."""
123 
124     def __init__(self, *args, **kwargs) -> None:
125         """Creates a counter for tracked conditions."""
126         super().__init__(*args, **kwargs)
127         self._conditions: DefaultDict[ast.AST, int] = defaultdict(int)
128 
129     def _check_conditions(self, node: ast.AST) -> None:
130         for condition in ast.walk(node):
131             if isinstance(condition, (ast.And, ast.Or)):
132                 self._conditions[node] += 1
133 
134     def _post_visit(self) -> None:
135         for node, count in self._conditions.items():
136             if count > self.options.max_conditions - 1:
137                 self.add_violation(
138                     TooManyConditionsViolation(node, text=str(count)),
139                 )
140 
141     def visit_comprehension(self, node: ast.comprehension) -> None:
142         """
143         Counts the number of conditions in list comprehensions.
144 
145         Raises:
146             TooManyConditionsViolation
147 
148         """
149         if node.ifs:
150             # We only check the first `if`, since it is forbidden
151             # to have more than one at a time
152             # by `MultipleIfsInComprehensionViolation`
153             self._check_conditions(node.ifs[0])
154         self.generic_visit(node)
155 
156     def visit_If(self, node: ConditionNodes) -> None:
157         """
158         Counts the number of conditions.
159 
160         Raises:
161             TooManyConditionsViolation
162 
163         """
164         self._check_conditions(node.test)
165         self.generic_visit(node)
166 
167     visit_While = visit_IfExp = visit_If
168
```
--- 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/types.py b/wemake_python_styleguide/types.py
--- a/wemake_python_styleguide/types.py
+++ b/wemake_python_styleguide/types.py
@@ -36,7 +36,7 @@
 CheckResult = Tuple[int, int, str, type]
 
 #: Code members that we count in a module:
-ModuleMembers = Union[ast.FunctionDef, ast.ClassDef]
+ModuleMembers = Union[ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef]
 
 
 class ConfigurationOptions(Protocol):
diff --git a/wemake_python_styleguide/visitors/ast/complexity/counts.py b/wemake_python_styleguide/visitors/ast/complexity/counts.py
--- a/wemake_python_styleguide/visitors/ast/complexity/counts.py
+++ b/wemake_python_styleguide/visitors/ast/complexity/counts.py
@@ -37,9 +37,9 @@
         if self._public_items_count > self.options.max_module_members:
             self.add_violation(TooManyModuleMembersViolation())
 
-    def visit_ClassDef(self, node: ast.ClassDef) -> None:
+    def visit_module_members(self, node: ModuleMembers) -> None:
         """
-        Counts the number of `class`es in a single module.
+        Counts the number of ModuleMembers in a single module.
 
         Raises:
             TooManyModuleMembersViolation
@@ -48,16 +48,8 @@
         self._check_members_count(node)
         self.generic_visit(node)
 
-    def visit_FunctionDef(self, node: ast.FunctionDef) -> None:
-        """
-        Counts the number of functions in a single module.
-
-        Raises:
-            TooManyModuleMembersViolation
-
-        """
-        self._check_members_count(node)
-        self.generic_visit(node)
+    visit_ClassDef = visit_module_members
+    visit_AsyncFunctionDef = visit_FunctionDef = visit_module_members
 
 
 class ImportMembersVisitor(BaseNodeVisitor):

{"golden_diff": "diff --git a/wemake_python_styleguide/types.py b/wemake_python_styleguide/types.py\n--- a/wemake_python_styleguide/types.py\n+++ b/wemake_python_styleguide/types.py\n@@ -36,7 +36,7 @@\n CheckResult = Tuple[int, int, str, type]\n \n #: Code members that we count in a module:\n-ModuleMembers = Union[ast.FunctionDef, ast.ClassDef]\n+ModuleMembers = Union[ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef]\n \n \n class ConfigurationOptions(Protocol):\ndiff --git a/wemake_python_styleguide/visitors/ast/complexity/counts.py b/wemake_python_styleguide/visitors/ast/complexity/counts.py\n--- a/wemake_python_styleguide/visitors/ast/complexity/counts.py\n+++ b/wemake_python_styleguide/visitors/ast/complexity/counts.py\n@@ -37,9 +37,9 @@\n         if self._public_items_count > self.options.max_module_members:\n             self.add_violation(TooManyModuleMembersViolation())\n \n-    def visit_ClassDef(self, node: ast.ClassDef) -> None:\n+    def visit_module_members(self, node: ModuleMembers) -> None:\n         \"\"\"\n-        Counts the number of `class`es in a single module.\n+        Counts the number of ModuleMembers in a single module.\n \n         Raises:\n             TooManyModuleMembersViolation\n@@ -48,16 +48,8 @@\n         self._check_members_count(node)\n         self.generic_visit(node)\n \n-    def visit_FunctionDef(self, node: ast.FunctionDef) -> None:\n-        \"\"\"\n-        Counts the number of functions in a single module.\n-\n-        Raises:\n-            TooManyModuleMembersViolation\n-\n-        \"\"\"\n-        self._check_members_count(node)\n-        self.generic_visit(node)\n+    visit_ClassDef = visit_module_members\n+    visit_AsyncFunctionDef = visit_FunctionDef = visit_module_members\n \n \n class ImportMembersVisitor(BaseNodeVisitor):\n", "issue": "Feature: count async function as a module member\nCurrently we count only regular functions and classes as module members: https://github.com/wemake-services/wemake-python-styleguide/blob/master/wemake_python_styleguide/visitors/ast/complexity/counts.py#L40-L60\r\n\r\nWhat needs to be done?\r\n1. We need to count `AsyncFunctionDef` as well\r\n2. We need to improve `ModuleMembers` type to include `AsyncFunctionDef`\r\n3. We need to refactor how handler for each node works: there's no need to duplicate the logic, so it can just be: `visit_AsyncFunctionDef = visit_FunctionDef = visit_ClassDef`\r\n4. We need to improve unit tests to include `async` functions as well: https://github.com/wemake-services/wemake-python-styleguide/blob/master/tests/test_visitors/test_ast/test_complexity/test_counts/test_module_counts.py\r\n\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nThis module contains custom ``mypy`` types that we commonly use.\n\nPolicy\n------\n\nIf any of the following statements is true, move the type to this file:\n\n- if type is used in multiple files\n- if type is complex enough it has to be documented\n- if type is very important for the public API\n\n\"\"\"\n\nimport ast\nfrom typing import TYPE_CHECKING, Tuple, Type, Union\n\nif TYPE_CHECKING:  # pragma: no cover\n    from typing_extensions import Protocol  # noqa: Z435\n\n    # This solves cycle imports problem:\n    from .visitors import base  # noqa: F401,Z300,Z435\nelse:\n    # We do not need to do anything if type checker is not working:\n    Protocol = object\n\n#: Visitor type definition:\nVisitorClass = Type['base.BaseVisitor']\n\n#: In cases we need to work with both import types:\nAnyImport = Union[ast.Import, ast.ImportFrom]\n\n#: Flake8 API format to return error messages:\nCheckResult = Tuple[int, int, str, type]\n\n#: Code members that we count in a module:\nModuleMembers = Union[ast.FunctionDef, ast.ClassDef]\n\n\nclass ConfigurationOptions(Protocol):\n    \"\"\"\n    Provides structure for the options we use in our checker.\n\n    Then this protocol is passed to each individual visitor and used there.\n    It uses structural sub-typing, and does not represent any kind of a real\n    class or structure.\n\n    This class actually works only when running type check.\n    At other cases it is just an ``object``.\n\n    See also:\n        https://mypy.readthedocs.io/en/latest/protocols.html\n\n    \"\"\"\n\n    # General:\n    min_variable_length: int\n    i_control_code: bool\n\n    # Complexity:\n    max_arguments: int\n    max_local_variables: int\n    max_returns: int\n    max_expressions: int\n    max_offset_blocks: int\n    max_elifs: int\n    max_module_members: int\n    max_methods: int\n    max_line_complexity: int\n    max_jones_score: int\n    max_imports: int\n    max_conditions: int\n\n    # File names:\n    min_module_name_length: int\n", "path": "wemake_python_styleguide/types.py"}, {"content": "# -*- coding: utf-8 -*-\n\nimport ast\nfrom collections import defaultdict\nfrom typing import DefaultDict, Union\n\nfrom wemake_python_styleguide.logics.functions import is_method\nfrom wemake_python_styleguide.types import AnyImport, ModuleMembers\nfrom wemake_python_styleguide.violations.complexity import (\n    TooManyConditionsViolation,\n    TooManyImportsViolation,\n    TooManyMethodsViolation,\n    TooManyModuleMembersViolation,\n)\nfrom wemake_python_styleguide.visitors.base import BaseNodeVisitor\n\nConditionNodes = Union[ast.If, ast.While, ast.IfExp]\n\n\nclass ModuleMembersVisitor(BaseNodeVisitor):\n    \"\"\"Counts classes and functions in a module.\"\"\"\n\n    def __init__(self, *args, **kwargs) -> None:\n        \"\"\"Creates a counter for tracked metrics.\"\"\"\n        super().__init__(*args, **kwargs)\n        self._public_items_count = 0\n\n    def _check_members_count(self, node: ModuleMembers) -> None:\n        \"\"\"This method increases the number of module members.\"\"\"\n        parent = getattr(node, 'parent', None)\n        is_real_method = is_method(getattr(node, 'function_type', None))\n\n        if isinstance(parent, ast.Module) and not is_real_method:\n            self._public_items_count += 1\n\n    def _post_visit(self) -> None:\n        if self._public_items_count > self.options.max_module_members:\n            self.add_violation(TooManyModuleMembersViolation())\n\n    def visit_ClassDef(self, node: ast.ClassDef) -> None:\n        \"\"\"\n        Counts the number of `class`es in a single module.\n\n        Raises:\n            TooManyModuleMembersViolation\n\n        \"\"\"\n        self._check_members_count(node)\n        self.generic_visit(node)\n\n    def visit_FunctionDef(self, node: ast.FunctionDef) -> None:\n        \"\"\"\n        Counts the number of functions in a single module.\n\n        Raises:\n            TooManyModuleMembersViolation\n\n        \"\"\"\n        self._check_members_count(node)\n        self.generic_visit(node)\n\n\nclass ImportMembersVisitor(BaseNodeVisitor):\n    \"\"\"Counts imports in a module.\"\"\"\n\n    def __init__(self, *args, **kwargs) -> None:\n        \"\"\"Creates a counter for tracked metrics.\"\"\"\n        super().__init__(*args, **kwargs)\n        self._imports_count = 0\n\n    def _post_visit(self) -> None:\n        if self._imports_count > self.options.max_imports:\n            self.add_violation(\n                TooManyImportsViolation(text=str(self._imports_count)),\n            )\n\n    def visit_Import(self, node: AnyImport) -> None:\n        \"\"\"\n        Counts the number of ``import`` and ``from ... import ...``.\n\n        Raises:\n            TooManyImportsViolation\n\n        \"\"\"\n        self._imports_count += 1\n        self.generic_visit(node)\n\n    visit_ImportFrom = visit_Import\n\n\nclass MethodMembersVisitor(BaseNodeVisitor):\n    \"\"\"Counts methods in a single class.\"\"\"\n\n    def __init__(self, *args, **kwargs) -> None:\n        \"\"\"Creates a counter for tracked methods in different classes.\"\"\"\n        super().__init__(*args, **kwargs)\n        self._methods: DefaultDict[ast.ClassDef, int] = defaultdict(int)\n\n    def _check_method(self, node: ast.FunctionDef) -> None:\n        parent = getattr(node, 'parent', None)\n        if isinstance(parent, ast.ClassDef):\n            self._methods[parent] += 1\n\n    def _post_visit(self) -> None:\n        for node, count in self._methods.items():\n            if count > self.options.max_methods:\n                self.add_violation(TooManyMethodsViolation(text=node.name))\n\n    def visit_FunctionDef(self, node: ast.FunctionDef) -> None:\n        \"\"\"\n        Counts the number of methods in a single class.\n\n        Raises:\n            TooManyMethodsViolation\n\n        \"\"\"\n        self._check_method(node)\n        self.generic_visit(node)\n\n\nclass ConditionsVisitor(BaseNodeVisitor):\n    \"\"\"Checks ``if`` and ``while`` statements for condition counts.\"\"\"\n\n    def __init__(self, *args, **kwargs) -> None:\n        \"\"\"Creates a counter for tracked conditions.\"\"\"\n        super().__init__(*args, **kwargs)\n        self._conditions: DefaultDict[ast.AST, int] = defaultdict(int)\n\n    def _check_conditions(self, node: ast.AST) -> None:\n        for condition in ast.walk(node):\n            if isinstance(condition, (ast.And, ast.Or)):\n                self._conditions[node] += 1\n\n    def _post_visit(self) -> None:\n        for node, count in self._conditions.items():\n            if count > self.options.max_conditions - 1:\n                self.add_violation(\n                    TooManyConditionsViolation(node, text=str(count)),\n                )\n\n    def visit_comprehension(self, node: ast.comprehension) -> None:\n        \"\"\"\n        Counts the number of conditions in list comprehensions.\n\n        Raises:\n            TooManyConditionsViolation\n\n        \"\"\"\n        if node.ifs:\n            # We only check the first `if`, since it is forbidden\n            # to have more than one at a time\n            # by `MultipleIfsInComprehensionViolation`\n            self._check_conditions(node.ifs[0])\n        self.generic_visit(node)\n\n    def visit_If(self, node: ConditionNodes) -> None:\n        \"\"\"\n        Counts the number of conditions.\n\n        Raises:\n            TooManyConditionsViolation\n\n        \"\"\"\n        self._check_conditions(node.test)\n        self.generic_visit(node)\n\n    visit_While = visit_IfExp = visit_If\n", "path": "wemake_python_styleguide/visitors/ast/complexity/counts.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n\"\"\"\nThis module contains custom ``mypy`` types that we commonly use.\n\nPolicy\n------\n\nIf any of the following statements is true, move the type to this file:\n\n- if type is used in multiple files\n- if type is complex enough it has to be documented\n- if type is very important for the public API\n\n\"\"\"\n\nimport ast\nfrom typing import TYPE_CHECKING, Tuple, Type, Union\n\nif TYPE_CHECKING:  # pragma: no cover\n    from typing_extensions import Protocol  # noqa: Z435\n\n    # This solves cycle imports problem:\n    from .visitors import base  # noqa: F401,Z300,Z435\nelse:\n    # We do not need to do anything if type checker is not working:\n    Protocol = object\n\n#: Visitor type definition:\nVisitorClass = Type['base.BaseVisitor']\n\n#: In cases we need to work with both import types:\nAnyImport = Union[ast.Import, ast.ImportFrom]\n\n#: Flake8 API format to return error messages:\nCheckResult = Tuple[int, int, str, type]\n\n#: Code members that we count in a module:\nModuleMembers = Union[ast.FunctionDef, ast.ClassDef, ast.AsyncFunctionDef]\n\n\nclass ConfigurationOptions(Protocol):\n    \"\"\"\n    Provides structure for the options we use in our checker.\n\n    Then this protocol is passed to each individual visitor and used there.\n    It uses structural sub-typing, and does not represent any kind of a real\n    class or structure.\n\n    This class actually works only when running type check.\n    At other cases it is just an ``object``.\n\n    See also:\n        https://mypy.readthedocs.io/en/latest/protocols.html\n\n    \"\"\"\n\n    # General:\n    min_variable_length: int\n    i_control_code: bool\n\n    # Complexity:\n    max_arguments: int\n    max_local_variables: int\n    max_returns: int\n    max_expressions: int\n    max_offset_blocks: int\n    max_elifs: int\n    max_module_members: int\n    max_methods: int\n    max_line_complexity: int\n    max_jones_score: int\n    max_imports: int\n    max_conditions: int\n\n    # File names:\n    min_module_name_length: int\n", "path": "wemake_python_styleguide/types.py"}, {"content": "# -*- coding: utf-8 -*-\n\nimport ast\nfrom collections import defaultdict\nfrom typing import DefaultDict, Union\n\nfrom wemake_python_styleguide.logics.functions import is_method\nfrom wemake_python_styleguide.types import AnyImport, ModuleMembers\nfrom wemake_python_styleguide.violations.complexity import (\n    TooManyConditionsViolation,\n    TooManyImportsViolation,\n    TooManyMethodsViolation,\n    TooManyModuleMembersViolation,\n)\nfrom wemake_python_styleguide.visitors.base import BaseNodeVisitor\n\nConditionNodes = Union[ast.If, ast.While, ast.IfExp]\n\n\nclass ModuleMembersVisitor(BaseNodeVisitor):\n    \"\"\"Counts classes and functions in a module.\"\"\"\n\n    def __init__(self, *args, **kwargs) -> None:\n        \"\"\"Creates a counter for tracked metrics.\"\"\"\n        super().__init__(*args, **kwargs)\n        self._public_items_count = 0\n\n    def _check_members_count(self, node: ModuleMembers) -> None:\n        \"\"\"This method increases the number of module members.\"\"\"\n        parent = getattr(node, 'parent', None)\n        is_real_method = is_method(getattr(node, 'function_type', None))\n\n        if isinstance(parent, ast.Module) and not is_real_method:\n            self._public_items_count += 1\n\n    def _post_visit(self) -> None:\n        if self._public_items_count > self.options.max_module_members:\n            self.add_violation(TooManyModuleMembersViolation())\n\n    def visit_module_members(self, node: ModuleMembers) -> None:\n        \"\"\"\n        Counts the number of ModuleMembers in a single module.\n\n        Raises:\n            TooManyModuleMembersViolation\n\n        \"\"\"\n        self._check_members_count(node)\n        self.generic_visit(node)\n\n    visit_ClassDef = visit_module_members\n    visit_AsyncFunctionDef = visit_FunctionDef = visit_module_members\n\n\nclass ImportMembersVisitor(BaseNodeVisitor):\n    \"\"\"Counts imports in a module.\"\"\"\n\n    def __init__(self, *args, **kwargs) -> None:\n        \"\"\"Creates a counter for tracked metrics.\"\"\"\n        super().__init__(*args, **kwargs)\n        self._imports_count = 0\n\n    def _post_visit(self) -> None:\n        if self._imports_count > self.options.max_imports:\n            self.add_violation(\n                TooManyImportsViolation(text=str(self._imports_count)),\n            )\n\n    def visit_Import(self, node: AnyImport) -> None:\n        \"\"\"\n        Counts the number of ``import`` and ``from ... import ...``.\n\n        Raises:\n            TooManyImportsViolation\n\n        \"\"\"\n        self._imports_count += 1\n        self.generic_visit(node)\n\n    visit_ImportFrom = visit_Import\n\n\nclass MethodMembersVisitor(BaseNodeVisitor):\n    \"\"\"Counts methods in a single class.\"\"\"\n\n    def __init__(self, *args, **kwargs) -> None:\n        \"\"\"Creates a counter for tracked methods in different classes.\"\"\"\n        super().__init__(*args, **kwargs)\n        self._methods: DefaultDict[ast.ClassDef, int] = defaultdict(int)\n\n    def _check_method(self, node: ast.FunctionDef) -> None:\n        parent = getattr(node, 'parent', None)\n        if isinstance(parent, ast.ClassDef):\n            self._methods[parent] += 1\n\n    def _post_visit(self) -> None:\n        for node, count in self._methods.items():\n            if count > self.options.max_methods:\n                self.add_violation(TooManyMethodsViolation(text=node.name))\n\n    def visit_FunctionDef(self, node: ast.FunctionDef) -> None:\n        \"\"\"\n        Counts the number of methods in a single class.\n\n        Raises:\n            TooManyMethodsViolation\n\n        \"\"\"\n        self._check_method(node)\n        self.generic_visit(node)\n\n\nclass ConditionsVisitor(BaseNodeVisitor):\n    \"\"\"Checks ``if`` and ``while`` statements for condition counts.\"\"\"\n\n    def __init__(self, *args, **kwargs) -> None:\n        \"\"\"Creates a counter for tracked conditions.\"\"\"\n        super().__init__(*args, **kwargs)\n        self._conditions: DefaultDict[ast.AST, int] = defaultdict(int)\n\n    def _check_conditions(self, node: ast.AST) -> None:\n        for condition in ast.walk(node):\n            if isinstance(condition, (ast.And, ast.Or)):\n                self._conditions[node] += 1\n\n    def _post_visit(self) -> None:\n        for node, count in self._conditions.items():\n            if count > self.options.max_conditions - 1:\n                self.add_violation(\n                    TooManyConditionsViolation(node, text=str(count)),\n                )\n\n    def visit_comprehension(self, node: ast.comprehension) -> None:\n        \"\"\"\n        Counts the number of conditions in list comprehensions.\n\n        Raises:\n            TooManyConditionsViolation\n\n        \"\"\"\n        if node.ifs:\n            # We only check the first `if`, since it is forbidden\n            # to have more than one at a time\n            # by `MultipleIfsInComprehensionViolation`\n            self._check_conditions(node.ifs[0])\n        self.generic_visit(node)\n\n    def visit_If(self, node: ConditionNodes) -> None:\n        \"\"\"\n        Counts the number of conditions.\n\n        Raises:\n            TooManyConditionsViolation\n\n        \"\"\"\n        self._check_conditions(node.test)\n        self.generic_visit(node)\n\n    visit_While = visit_IfExp = visit_If\n", "path": "wemake_python_styleguide/visitors/ast/complexity/counts.py"}]}