Repository: wemake-services/wemake-python-styleguide

Issue:
Make `WPS113` respect `i_control_code` setting
Currently `WPS113` raises a violation on

```python
# __init__.py
from classes.typeclass import typeclass as typeclass
```

Note this part: `typeclass as typeclass`
Why do we use it? Because we use `mypy` with `implicit_reexport = False` setting on.
So, when we define public interface for a module we need to use explicit reexport in a form of `from classes.typeclass import typeclass as typeclass`

So, that's why we need to tweak `WPS113` not to highlight these errors when we make libraries. 
In other words, when `i_control_code` is set to `True`, we need to ignore `WPS113` at all.


Discussion:
Hi, can I take this issue?

Resolving patch:
diff --git a/wemake_python_styleguide/violations/naming.py b/wemake_python_styleguide/violations/naming.py
--- a/wemake_python_styleguide/violations/naming.py
+++ b/wemake_python_styleguide/violations/naming.py
@@ -398,7 +398,13 @@ class SameAliasImportViolation(ASTViolation):
         # Wrong:
         from os import path as path
 
+    Configuration:
+        This rule is configurable with ``--i-control-code``.
+        Default:
+        :str:`wemake_python_styleguide.options.defaults.I_CONTROL_CODE`
+
     .. versionadded:: 0.1.0
+    .. versionchanged:: 0.13.0
 
     """
 
diff --git a/wemake_python_styleguide/visitors/ast/imports.py b/wemake_python_styleguide/visitors/ast/imports.py
--- a/wemake_python_styleguide/visitors/ast/imports.py
+++ b/wemake_python_styleguide/visitors/ast/imports.py
@@ -10,7 +10,7 @@
 from wemake_python_styleguide.constants import FUTURE_IMPORTS_WHITELIST
 from wemake_python_styleguide.logic import imports, nodes
 from wemake_python_styleguide.logic.naming import access
-from wemake_python_styleguide.types import AnyImport
+from wemake_python_styleguide.types import AnyImport, ConfigurationOptions
 from wemake_python_styleguide.violations.base import BaseViolation
 from wemake_python_styleguide.violations.best_practices import (
     FutureImportViolation,
@@ -32,8 +32,13 @@
 class _ImportsValidator(object):
     """Utility class to separate logic from the visitor."""
 
-    def __init__(self, error_callback: ErrorCallback) -> None:
+    def __init__(
+        self,
+        error_callback: ErrorCallback,
+        options: ConfigurationOptions,
+    ) -> None:
         self._error_callback = error_callback
+        self._options = options
 
     def check_nested_import(self, node: AnyImport) -> None:
         parent = nodes.get_parent(node)
@@ -61,7 +66,7 @@ def check_dotted_raw_import(self, node: ast.Import) -> None:
 
     def check_alias(self, node: AnyImport) -> None:
         for alias in node.names:
-            if alias.asname == alias.name:
+            if alias.asname == alias.name and not self._options.i_control_code:
                 self._error_callback(
                     SameAliasImportViolation(node, text=alias.name),
                 )
@@ -93,7 +98,7 @@ class WrongImportVisitor(BaseNodeVisitor):
     def __init__(self, *args, **kwargs) -> None:
         """Creates a checker for tracked violations."""
         super().__init__(*args, **kwargs)
-        self._validator = _ImportsValidator(self.add_violation)
+        self._validator = _ImportsValidator(self.add_violation, self.options)
 
     def visit_Import(self, node: ast.Import) -> None:
         """


Test patch:
diff --git a/tests/test_checker/test_noqa.py b/tests/test_checker/test_noqa.py
--- a/tests/test_checker/test_noqa.py
+++ b/tests/test_checker/test_noqa.py
@@ -33,7 +33,7 @@
     'WPS110': 3,
     'WPS111': 1,
     'WPS112': 1,
-    'WPS113': 1,
+    'WPS113': 0,
     'WPS114': 1,
     'WPS115': 1,
     'WPS116': 1,
diff --git a/tests/test_visitors/test_ast/test_imports/test_same_alias_import.py b/tests/test_visitors/test_ast/test_imports/test_same_alias_import.py
--- a/tests/test_visitors/test_ast/test_imports/test_same_alias_import.py
+++ b/tests/test_visitors/test_ast/test_imports/test_same_alias_import.py
@@ -20,13 +20,35 @@ def test_same_alias_import(
     code,
     default_options,
 ):
-    """Testing that imports with the same aliases are restricted."""
+    """Testing that imports with the same aliases are allowed."""
     same_alias = 'os'
     tree = parse_ast_tree(code.format(same_alias))
 
     visitor = WrongImportVisitor(default_options, tree=tree)
     visitor.run()
 
+    assert_errors(visitor, [])
+
+
+@pytest.mark.parametrize('code', [
+    regular_import,
+    from_import,
+])
+def test_same_alias_import_without_control(
+    assert_errors,
+    assert_error_text,
+    parse_ast_tree,
+    code,
+    options,
+):
+    """Testing that imports with the same aliases are restricted."""
+    same_alias = 'os'
+    tree = parse_ast_tree(code.format(same_alias))
+    custom_options = options(i_control_code=False)
+
+    visitor = WrongImportVisitor(custom_options, tree=tree)
+    visitor.run()
+
     assert_errors(visitor, [SameAliasImportViolation])
     assert_error_text(visitor, same_alias)