Repository: wemake-services/wemake-python-styleguide

Issue:
False positive WPS226 in f strings
### What's wrong

line
f'query:"{query}"'
in ast node generate node with string value " (double qoute)

so if we have several lines like with we get tricky and false positive violation of WPS226

 WPS226 Found string literal over-use: " > 3


### How it should be

f string should be considered as single node.

### Flake8 version and plugins

{
  "dependencies": [],
  "platform": {
    "python_implementation": "CPython",
    "python_version": "3.9.9",
    "system": "Linux"
  },
  "plugins": [
    {
      "is_local": false,
      "plugin": "flake8-bandit",
      "version": "3.0.0"
    },
    {
      "is_local": false,
      "plugin": "flake8-broken-line",
      "version": "0.4.0"
    },
    {
      "is_local": false,
      "plugin": "flake8-bugbear",
      "version": "22.10.27"
    },
    {
      "is_local": false,
      "plugin": "flake8-comprehensions",
      "version": "3.10.1"
    },
    {
      "is_local": false,
      "plugin": "flake8-darglint",
      "version": "1.8.1"
    },
    {
      "is_local": false,
      "plugin": "flake8-debugger",
      "version": "4.1.2"
    },
    {
      "is_local": false,
      "plugin": "flake8-docstrings",
      "version": "1.6.0, pydocstyle: 6.1.1"
    },
    {
      "is_local": false,
      "plugin": "flake8-eradicate",
      "version": "1.4.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.2.0"
    },
    {
      "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.12.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.7"
    },
    {
      "is_local": false,
      "plugin": "wemake_python_styleguide",
      "version": "0.16.1"
    }
  ],
  "version": "4.0.1"
}


### pip information

pip 22.3.1
(python 3.9)
absl-py==1.3.0
aiodns==3.0.0
aiohttp==3.8.1
aiosignal==1.3.1
aniso8601==7.0.0
asgiref==3.5.2
astor==0.8.1
astroid==2.12.12
astunparse==1.6.3
async-timeout==4.0.2
attrs==22.1.0
autoflake==1.4
bandit==1.7.4
black==22.3.0
boto3==1.23.4
botocore==1.26.10
Brotli==1.0.9
cachetools==5.0.0
cchardet==2.1.7
certifi==2022.9.24
cffi==1.15.1
cfgv==3.3.1
charset-normalizer==2.0.12
click==8.1.3
ConfigArgParse==1.5.3
coverage==6.5.0
darglint==1.8.1
Deprecated==1.2.13
dill==0.3.6
distlib==0.3.6
dj-database-url==1.0.0
dj-email-url==1.0.6
Django==4.0.6
django-cache-url==3.4.2
django-cors-headers==3.12.0
django-injector==0.2.5
django-stubs==1.13.0
django-stubs-ext==0.7.0
docutils==0.19
environs==9.5.0
eradicate==2.1.0
filelock==3.8.0
flake8==4.0.1
flake8-bandit==3.0.0
flake8-broken-line==0.4.0
flake8-bugbear==22.10.27
flake8-commas==2.1.0
flake8-comprehensions==3.10.1
flake8-debugger==4.1.2
flake8-docstrings==1.6.0
flake8-eradicate==1.4.0
flake8-isort==4.2.0
flake8-polyfill==1.0.2
flake8-quotes==3.3.1
flake8-rst-docstrings==0.2.7
flake8-string-format==0.3.0
Flask==2.2.2
Flask-BasicAuth==0.2.0
Flask-Cors==3.0.10
flatbuffers==1.12
frozenlist==1.3.3
gast==0.4.0
gevent==22.10.2
geventhttpclient==2.0.8
gitdb==4.0.9
GitPython==3.1.29
google-auth==2.14.1
google-auth-oauthlib==0.4.6
google-pasta==0.2.0
graphene==2.1.9
graphene-django==2.15.0
graphql-core==2.3.2
graphql-relay==2.0.1
greenlet==2.0.1
grpcio==1.50.0
gunicorn==20.1.0
h5py==3.7.0
hash-chunker==0.1.9
identify==2.5.8
idna==3.4
importlib-metadata==5.0.0
inflect==5.5.2
iniconfig==1.1.1
injector==0.20.1
isort==5.10.1
itsdangerous==2.1.2
Jinja2==3.1.2
jmespath==1.0.1
joblib==1.2.0
kazoo==2.8.0
keras==2.9.0
Keras-Preprocessing==1.1.2
lazy-object-proxy==1.8.0
libclang==14.0.6
locust==2.9.0
Markdown==3.4.1
MarkupSafe==2.1.1
marshmallow==3.19.0
mccabe==0.6.1
msgpack==1.0.4
multidict==6.0.2
mypy==0.990
mypy-extensions==0.4.3
mysqlclient==2.1.0
nodeenv==1.7.0
numpy==1.23.4
oauthlib==3.2.2
opt-einsum==3.3.0
packaging==21.3
pandas==1.4.2
pathspec==0.10.2
pbr==5.11.0
pep8-naming==0.12.1
platformdirs==2.5.4
pluggy==0.13.1
pre-commit==2.16.0
promise==2.3
protobuf==3.19.6
psutil==5.9.4
py==1.11.0
pyasn1==0.4.8
pyasn1-modules==0.2.8
pycares==4.2.2
pycodestyle==2.8.0
pycparser==2.21
pydocstyle==6.1.1
pyflakes==2.4.0
Pygments==2.13.0
pylint==2.15.4
pylint-django==2.5.3
pylint-plugin-utils==0.7
PyMySQL==1.0.2
pyparsing==3.0.9
pytest==6.2.4
pytest-cov==2.12.0
pytest-django==4.5.2
pytest-lazy-fixture==0.6.3
python-dateutil==2.8.2
python-dotenv==0.21.0
pytz==2022.6
PyYAML==6.0
pyzmq==22.3.0
redis==4.2.2
requests==2.27.1
requests-oauthlib==1.3.1
restructuredtext-lint==1.4.0
roundrobin==0.0.4
rsa==4.9
Rx==1.6.1
s3transfer==0.5.2
scikit-learn==1.0
scipy==1.9.3
singledispatch==3.7.0
six==1.16.0
smmap==5.0.0
snowballstemmer==2.2.0
SQLAlchemy==1.4.36
sqlparse==0.4.3
stevedore==4.1.1
tenacity==8.0.1
tensorboard==2.9.1
tensorboard-data-server==0.6.1
tensorboard-plugin-wit==1.8.1
tensorflow-cpu==2.9.1
tensorflow-estimator==2.9.0
tensorflow-io-gcs-filesystem==0.27.0
termcolor==2.1.0
text-unidecode==1.3
threadpoolctl==3.1.0
toml==0.10.2
tomli==2.0.1
tomlkit==0.11.6
tqdm==4.64.0
types-cachetools==5.0.1
types-pytz==2022.6.0.1
types-PyYAML==6.0.12.2
types-redis==4.2.5
types-requests==2.27.19
types-urllib3==1.26.25.3
typing_extensions==4.4.0
urllib3==1.26.12
virtualenv==20.16.7
wemake-python-styleguide==0.16.1
Werkzeug==2.2.2
wrapt==1.14.1
yarl==1.8.1
zipp==3.10.0
zope.event==4.5.0
zope.interface==5.5.1


### OS information

Ubuntu 22.04.1 LTS

Discussion:
codecov[bot]: ## [Codecov](https://codecov.io/gh/wemake-services/wemake-python-styleguide/pull/2619?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services) Report
> Merging [#2619](https://codecov.io/gh/wemake-services/wemake-python-styleguide/pull/2619?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services) (6e9b171) into [master](https://codecov.io/gh/wemake-services/wemake-python-styleguide/commit/52c7c4e55a6e8d9ee032db2c9761c9af39325c27?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services) (52c7c4e) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@            Coverage Diff            @@
##            master     #2619   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files          122       122           
  Lines         6552      6553    +1     
  Branches      1460      1458    -2     
=========================================
+ Hits          6552      6553    +1     
```


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

... and [17 files with indirect coverage changes](https://codecov.io/gh/wemake-services/wemake-python-styleguide/pull/2619/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=wemake-services)

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/wemake_python_styleguide/visitors/ast/complexity/overuses.py b/wemake_python_styleguide/visitors/ast/complexity/overuses.py
index 39d25855..7f755edf 100644
--- a/wemake_python_styleguide/visitors/ast/complexity/overuses.py
+++ b/wemake_python_styleguide/visitors/ast/complexity/overuses.py
@@ -49,6 +49,10 @@ class StringOveruseVisitor(base.BaseNodeVisitor):
         '\r\n',
         '\t',
         '|',
+        '"',
+        "'",
+        b'"',
+        b"'",
         b' ',
         b'.',
         b',',


Test patch:
diff --git a/tests/test_visitors/test_ast/test_complexity/test_overuses/test_overused_string.py b/tests/test_visitors/test_ast/test_complexity/test_overuses/test_overused_string.py
index 7fb4dad0..dfb6190c 100644
--- a/tests/test_visitors/test_ast/test_complexity/test_overuses/test_overused_string.py
+++ b/tests/test_visitors/test_ast/test_complexity/test_overuses/test_overused_string.py
@@ -204,6 +204,8 @@ def test_string_type_annotations(
     '""',
     '","',
     '"."',
+    "'\"'",
+    '"\'"',
 ])
 @pytest.mark.parametrize('prefix', [
     'b',