Skip to content

Commit

Permalink
Closes #1173, closes #1235, closes #1228
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Mar 6, 2020
1 parent fe020a9 commit 256de41
Show file tree
Hide file tree
Showing 32 changed files with 423 additions and 180 deletions.
16 changes: 11 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ Semantic versioning in our case means:
- **Breaking**: removes `flake8-print`, now using `WPS421` instead of `T001`
- **Breaking**: removes `flake8-annotations-complexity`,
now using `WPS234` instead of `TAE002`
- **Breaking**: removes `flake8-pep3101`, now using `WPS323` instead of `S001`,
we also use a new logic for this violation:
we check string defs for `%` patterns, and not for `%` operator
- **Breaking**: `WPS441` is no longer triggered for `except` blocks,
it is now handled by `F821` from `flake8`
- **Breaking**: Removes `radon`,
- **Breaking**: removes `radon`,
because `cognitive-complexity` and `mccabe` is enough
- **Breaking**: Removes `flake8-loggin-format` as a direct dependency
- **Breaking**: Removes `ImplicitTernaryViolation` or `WPS332`,
- **Breaking**: removes `flake8-loggin-format` as a direct dependency
- **Breaking**: removes `ImplicitTernaryViolation` or `WPS332`,
because it has too many false positives #1099
- Removes `flake8-coding`, all encoding strings, visitor and tests
for old `WPS323` which is now reused for modulo formatting checks
- Adds `python3.8` support
- Changes `styleguide.toml` and `flake8.toml` scripts definition
- Extracts new violation - `WPS450` from `WPS436` #1118
Expand All @@ -35,14 +40,13 @@ Semantic versioning in our case means:
- Forbids to use positional only `/` arguments
- Forbids to have too many names imported from a single `from ... import`
- Forbids to use `continue` and `break` in `finally`
- Forbids to use `__reduce__` and `__reduce_ex__` magic methods
- Adds `__call__` to list of methods that should be on top #1125
- Allows `_` to be now used as a defined variable
- Removes `cognitive_complexity` dependency, now it is built in into our linter
- Adds baseline information for all complexity violation messages: `x > baseline`
- Changes how cognitive complexity is calculated
- Adds support for positional arguments in different checks
- Removes flake8-coding, all encoding strings, visitor and tests
for `EmptyLineAfterCodingViolation`

### Bugfixes

Expand Down Expand Up @@ -77,6 +81,8 @@ Semantic versioning in our case means:
- Fixes `WPS509` not reporting nested ternary in grandchildren of `if`
- Fixes `WPS509` not reporting nested ternary in ternary
- Fixes `WPS426` not reporting nested `lambda` in comprehensions
- Fixes several violations to reporting for `ast.Bytes` and `ast.FormattedStr`
where `ast.Str` was checked

### Misc

Expand Down
1 change: 0 additions & 1 deletion docs/pages/usage/violations/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ flake8-broken-line `N400 <https://github.com/sobolevn/flake8-broken-
pep8-naming `N800 - N820 <https://github.com/PyCQA/pep8-naming>`_
flake8-string-format `P101 - P302 <https://github.com/xZise/flake8-string-format#error-codes>`_
flake8-quotes `Q000 <https://github.com/zheller/flake8-quotes>`_
flake8-pep3101 `S001 <https://github.com/gforcada/flake8-pep3101/blob/master/flake8_pep3101.py>`_
flake8-bandit `S100 - S710 <https://github.com/tylerwince/flake8-bandit>`_, see also original ``bandit`` `codes <https://bandit.readthedocs.io/en/latest/plugins/index.html#complete-test-plugin-listing>`_
flake8-debugger `T100 <https://github.com/JBKahn/flake8-debugger/blob/master/flake8_debugger.py>`_
flake8-rst-docstrings `RST201 - RST499 <https://github.com/peterjc/flake8-rst-docstrings>`_
Expand Down
25 changes: 1 addition & 24 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ flake8-comprehensions = "^3.1.0"
flake8-docstrings = "^1.3.1"
flake8-string-format = "^0.2"
flake8-bugbear = "^19.3"
flake8-pep3101 = "^1.2"
flake8-debugger = "^3.1"
flake8-isort = "^2.6"
flake8-eradicate = "^0.2"
Expand Down
6 changes: 3 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ ignore = D100, D104, D401, W504, RST303, RST304, DAR103, DAR203
per-file-ignores =
# These function names are part of 3d party API:
wemake_python_styleguide/visitors/ast/*.py: N802
# These modules should contain a lot of classes:
wemake_python_styleguide/violations/*.py: WPS202
# These modules should contain a lot of classes and can have `%` in docs:
wemake_python_styleguide/violations/*.py: WPS202, WPS323
# Eval is a complex task:
wemake_python_styleguide/logic/safe_eval.py: WPS232
# This module should contain magic numbers:
Expand All @@ -51,7 +51,7 @@ per-file-ignores =
# Allows mypy type hinting, `Ellipsis`` usage, multiple methods:
wemake_python_styleguide/types.py: D102, WPS214, WPS220, WPS428
# There are multiple fixtures, `assert`s, and subprocesses in tests:
tests/*.py: S101, S105, S404, S603, S607, WPS211, WPS226
tests/*.py: S101, S105, S404, S603, S607, WPS211, WPS226, WPS323
# Docs can have the configuration they need:
docs/conf.py: WPS407
# Pytest fixtures
Expand Down
1 change: 0 additions & 1 deletion tests/fixtures/external_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ def camelCase(): ...

'{}'.format(1)
""
'%s' % 'test'

assert True
ipdb.set_trace()
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/noqa/noqa.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ def function( # noqa: WPS320

string_modifier = R'(s)' # noqa: WPS321
multiline_string = """abc""" # noqa: WPS322
modulo_formatting = 'some %s' # noqa: WPS323


def function_with_wrong_return():
Expand Down
2 changes: 1 addition & 1 deletion tests/test_checker/test_noqa.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
'WPS320': 2,
'WPS321': 1,
'WPS322': 1,
'WPS323': 0, # violation is deprecated
'WPS323': 1,
'WPS324': 1,
'WPS325': 1,
'WPS326': 1,
Expand Down
1 change: 0 additions & 1 deletion tests/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
'P101', # flake8-string-format
'Q000', # flake8-quotes
'Q003', # flake8-quotes
'S001', # flake8-pep3101
'S101', # flake8-bandit
'T100', # flake8-debugger
'RST215', # flake8-rst-docstrings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
from wemake_python_styleguide.violations.best_practices import (
StringConstantRedefinedViolation,
)
from wemake_python_styleguide.violations.consistency import (
FormattedStringViolation,
)
from wemake_python_styleguide.visitors.ast.builtins import WrongStringVisitor


Expand All @@ -18,15 +21,23 @@
string.ascii_lowercase,
string.ascii_letters,
])
@pytest.mark.parametrize('prefix', [
'',
'b',
'u',
'r',
'rb',
])
def test_alphabet_as_string_violation(
assert_errors,
assert_error_text,
parse_ast_tree,
code,
prefix,
default_options,
):
"""Testing that the strings violate the rules."""
tree = parse_ast_tree('"{0}"'.format(code))
tree = parse_ast_tree('{0}"{1}"'.format(prefix, code))

visitor = WrongStringVisitor(default_options, tree=tree)
visitor.run()
Expand All @@ -35,6 +46,22 @@ def test_alphabet_as_string_violation(
assert_error_text(visitor, code)


def test_alphabet_as_fstring_violation(
assert_errors,
parse_ast_tree,
default_options,
):
"""Testing that the fstrings violate the rules."""
tree = parse_ast_tree('f"{0}"'.format(string.ascii_letters))

visitor = WrongStringVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [StringConstantRedefinedViolation], (
FormattedStringViolation,
))


@pytest.mark.parametrize('code', [
'ABCDE',
'1234',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
unicode_string = "u'unicode'"
string_variable = "some = '123'"
formated_string = "'x + y = {0}'.format(2)"
procent_format = "'x = %d' % 1"
key_formated_string = "'x + y = {res}'.format(res=2)"
variable_format = """
some = 'x = {0}'
Expand All @@ -27,7 +26,6 @@
unicode_string,
string_variable,
formated_string,
procent_format,
key_formated_string,
variable_format,
])
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import pytest

from wemake_python_styleguide.violations.consistency import (
FormattedStringViolation,
ModuloStringFormatViolation,
)
from wemake_python_styleguide.visitors.ast.builtins import WrongStringVisitor

_PREFIXES = (
'',
'b',
'u',
'r',
'rb',
'f',
'fr',
)


@pytest.mark.parametrize('code', [
# All examples are copied from https://pyformat.info/
'%10s',
'%-10s',
'%.5s',
'%-10.5s',
'%4d',
'%06.2f',
'%04d',
'%+d',
'%.*s',
'%*.*f',
# Our own examples:
'%%',
'%#d',
'%0d',
'%0*d',
'%0*hd',
'%0*Li',
'%0*li',
'%(first)s',
'%(f1_abc)+d',
'%d-%m-%Y (%H:%M:%S)',
'%d',
'%i',
'%o',
'%u',
'%x',
'%X',
'%e',
'%E',
'%f',
'%F',
'%g',
'%G',
'%c',
'%r',
'%s',
'%a',
])
@pytest.mark.parametrize('prefix', _PREFIXES)
def test_modulo_formatting(
assert_errors,
parse_ast_tree,
code,
prefix,
default_options,
):
"""Testing that the strings violate the rules."""
tree = parse_ast_tree('{0}"{1}"'.format(prefix, code))

visitor = WrongStringVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [ModuloStringFormatViolation], (
FormattedStringViolation,
))


@pytest.mark.parametrize('code', [
'% d', # technically it is a format string, but we disallow ` ` inside
'%10',
'10%',
'1%0',
'some % name',
'99.9% of cases', # spaces should not cause errors
'%l',
'%@',
'%.',
'%+',
'%_%',
'\%\%', # noqa: W605
'%\d', # noqa: W605
'%[prefix]s',
'%(invalid@name)s',
'%(also-invalid)d',
'',
'regular string',
'some%value',
'to format: {0}',
'named {format}',
'%t',
'%y',
'%m-%Y (%H:%M:%S)',
])
@pytest.mark.parametrize('prefix', _PREFIXES)
def test_regular_modulo_string(
assert_errors,
parse_ast_tree,
code,
prefix,
default_options,
):
"""Testing that the strings violate the rules."""
tree = parse_ast_tree('{0}"{1}"'.format(prefix, code))

visitor = WrongStringVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [], (FormattedStringViolation,))


@pytest.mark.parametrize('code', [
'x % 1',
'"str" % 1',
'name % value',
'1 % name',
'"a" % "b"',
])
def test_modulo_operations(
assert_errors,
parse_ast_tree,
code,
default_options,
):
"""Testing that the modulo operations are not affected."""
tree = parse_ast_tree(code)

visitor = WrongStringVisitor(default_options, tree=tree)
visitor.run()

assert_errors(visitor, [])
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ class ClassWithoutSlots(object):
'("123",)',
'("1_var",)',
'("*notvalid",)',
'("*a", *a)',
'("*a", *a)', # invalid name
'("a", b"b")', # bytes
)

correct_slots = (
Expand Down
Loading

0 comments on commit 256de41

Please sign in to comment.