Repository: wemake-services/wemake-python-styleguide

Issue:
WPS204: Overused expression should not count -1
### What's wrong

WPS complains about -1 being used to often as overused expression. Example: `position = (0, -1)`

### How it should be

No violation should be raised.

See https://github.com/wemake-services/wemake-python-styleguide/issues/1753

### Flake8 version and plugins

{
  "dependencies": [],
  "platform": {
    "python_implementation": "CPython",
    "python_version": "3.9.10",
    "system": "Linux"
  },
  "plugins": [
    {
      "is_local": false,
      "plugin": "flake8-bandit",
      "version": "2.1.2"
    },
    {
      "is_local": false,
      "plugin": "flake8-broken-line",
      "version": "0.4.0"
    },
    {
      "is_local": false,
      "plugin": "flake8-bugbear",
      "version": "21.9.2"
    },
    {
      "is_local": false,
      "plugin": "flake8-comprehensions",
      "version": "3.7.0"
    },
    {
      "is_local": false,
      "plugin": "flake8-darglint",
      "version": "1.8.1"
    },
    {
      "is_local": false,
      "plugin": "flake8-debugger",
      "version": "4.0.0"
    },
    {
      "is_local": false,
      "plugin": "flake8-docstrings",
      "version": "1.6.0, pydocstyle: 6.1.1"
    },
    {
      "is_local": false,
      "plugin": "flake8-eradicate",
      "version": "1.2.0"
    },
    {
      "is_local": false,
      "plugin": "flake8-string-format",
      "version": "0.3.0"
    },
    {
      "is_local": false,
      "plugin": "flake8_commas",
      "version": "2.1.0"
    },
    {
      "is_local": false,
      "plugin": "flake8_isort",
      "version": "4.1.1"
    },
       {
      "is_local": false,
      "plugin": "flake8_quotes",
      "version": "3.3.1"
    },
    {
      "is_local": false,
      "plugin": "mccabe",
      "version": "0.6.1"
    },
    {
      "is_local": false,
      "plugin": "naming",
      "version": "0.11.1"
    },
    {
      "is_local": false,
      "plugin": "pycodestyle",
      "version": "2.8.0"
    },
    {
      "is_local": false,
      "plugin": "pyflakes",
      "version": "2.4.0"
    },
    {
      "is_local": false,
      "plugin": "rst-docstrings",
      "version": "0.2.3"
    },
    {
      "is_local": false,
      "plugin": "wemake_python_styleguide",
      "version": "0.16.0"
    }
  ],
  "version": "4.0.1"
}


### pip information

please be more specific about package versions you actually need

### OS information

Ubuntu 20.04 LTS

Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/wemake-services/wemake-python-styleguide/pull/2500?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services) Report
> Merging [#2500](https://codecov.io/gh/wemake-services/wemake-python-styleguide/pull/2500?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services) (86becb0) into [master](https://codecov.io/gh/wemake-services/wemake-python-styleguide/commit/534008bb26577ebad9da6cbbf2b15cdc42c6ecb9?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services) (534008b) will **not change** coverage.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff            @@
##            master     #2500   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          119       119           
  Lines         6381      6383    +2     
  Branches      1445      1446    +1     
=========================================
+ Hits          6381      6383    +2     
```


| [Impacted Files](https://codecov.io/gh/wemake-services/wemake-python-styleguide/pull/2500?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services) | Coverage Δ | |
|---|---|---|
| [...ake\_python\_styleguide/logic/complexity/overuses.py](https://codecov.io/gh/wemake-services/wemake-python-styleguide/pull/2500/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services#diff-d2VtYWtlX3B5dGhvbl9zdHlsZWd1aWRlL2xvZ2ljL2NvbXBsZXhpdHkvb3ZlcnVzZXMucHk=) | `100.00% <100.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services)


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2bcb3228..0f1b69f5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,9 +21,16 @@ Semantic versioning in our case means:
 
 ### Features
 
+- **Breaking**: drops `python3.6` support
 - Adds `__init_subclass__` in the beginning of accepted methods
   order as per WPS338 #2411
 
+### Bugfixes
+
+- Fixes `WPS226` false positives on `|` use in `SomeType | AnotherType`
+  type hints syntax
+- Now `-1` is not reported to be an overused expression
+
 ### Misc
 
 - Adds full violation codes to docs and `BaseViolation.full_code` #2409
@@ -32,10 +39,6 @@ Semantic versioning in our case means:
 - Domain name was changed from `wemake-python-stylegui.de`
   to `wemake-python-styleguide.rtfd.io`
 
-### Bugfixes
-
-- Fixes `WPS226` false positives on `|` use in `SomeType | AnotherType` type hints syntax
-
 
 ## 0.16.1
 
diff --git a/wemake_python_styleguide/logic/complexity/overuses.py b/wemake_python_styleguide/logic/complexity/overuses.py
index ff0d0377..40aee519 100644
--- a/wemake_python_styleguide/logic/complexity/overuses.py
+++ b/wemake_python_styleguide/logic/complexity/overuses.py
@@ -102,12 +102,12 @@ def is_unary_minus(node: ast.AST) -> bool:
     We use this predicate to allow values
     like ``-some_value`` to be overused.
 
-    Although negative constants like ``-1``
+    Although negative constants like ``-5``
     should raise violation to force naming them.
     """
-    if isinstance(node, ast.UnaryOp):
-        return (
-            isinstance(node.op, ast.USub) and
-            not isinstance(node.operand, (Constant, ast.Num))
-        )
+    if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
+        # We allow variables, attributes, subscripts, and `-1`
+        if isinstance(node.operand, (Constant, ast.Num)):
+            return node.operand.n == 1
+        return True
     return False


Test patch:
diff --git a/tests/test_visitors/test_ast/test_complexity/test_overuses/test_overused_expressions.py b/tests/test_visitors/test_ast/test_complexity/test_overuses/test_overused_expressions.py
index 636b2f3f..64a05255 100644
--- a/tests/test_visitors/test_ast/test_complexity/test_overuses/test_overused_expressions.py
+++ b/tests/test_visitors/test_ast/test_complexity/test_overuses/test_overused_expressions.py
@@ -134,8 +134,8 @@ violating_expressions = (
     '{a for a in other}',
 
     # Unary nodes:
-    '-1',  # unary minus operator is raising when used with literal
     '+some',  # unary plus always raises
+    '~other',
 
     # Special cases for self:
     'self.method([star])',  # `[star]` is raising
@@ -169,6 +169,8 @@ ignored_expressions = (
     'some.prop',
     # unary operator
     '-value',
+    '-value.attr',
+    '-1',
 )