Skip to content

Commit

Permalink
Recreated #1171 (#1183)
Browse files Browse the repository at this point in the history
* Issue #1111 - Forbid to use \r in line breaks: Made base rule check and test script

* Issue #1111 - Forbid to use \r in line breaks: updated CHANGELOG.md in this case

* Issue #1111 - Forbid to use \r in line breaks: some minor processing

* Issue #1111 - Forbid to use \r in line breaks: some minor processing [step2]

* Issue #1111 - Forbid to use \r in line breaks: some minor processing [step3]

* Issue #1111 ~~~: [step4] 'Repair test' by update WPS-record for new #noqa violation in #/tests/test_checker/test_noqa.py

* Issue #1111 ~~~: [step5] by update WPS-record for new #noqa violation and it Count in #/tests/test_checker/test_noqa.py

* Issue #1111 ~~~: [step6] by update WPS-record for new #noqa violation and chng it's Count to Zero in #/tests/test_checker/test_noqa.py

* Issue #1111 ~~~: [step7] change sort order with CR-newline Violation(code=357) in #/violations/consistency.py

* Issue #1111: fixed logical mistake with if-condition in #/visitors/tokenize/syntax.py

* Issue #1111: add new condition in #/visitors/tokenize/syntax.py

* Issue #1111: add new condition in #/visitors/tokenize/syntax.py

* Issue #1111: add new condition in #/visitors/tokenize/syntax.py

* Issue #1111: removed excess condition with 'line' variable in #/visitors/tokenize/syntax.py

* Issue #1111: add new condition with token.line in #/visitors/tokenize/syntax.py (locally tested OK)

* Fixes build

Co-authored-by: ilia shb <45450122+jigi-33@users.noreply.github.com>
  • Loading branch information
sobolevn and jigi-33 committed Feb 24, 2020
1 parent 6a254a8 commit 0c165ad
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ Semantic versioning in our case means:
- Adds domain names options:
`--allowed-domain-names` and `--forbidden-domain-names`,
that are used to create variable names' blacklist #1106
- Forbids to use `:=` operator, it reuses `WPS332` code
- Forbids to use `\r` (carriage return) as line breaks in strings #1111
- Forbids to use `:=` operator, it now reuses `WPS332` code
- Forbids to use positional only `/` arguments
- Forbids to have too many names imported from a single `from ... import`
- Adds `__call__` to list of methods that should be on top #1125
Expand Down
1 change: 1 addition & 0 deletions tests/test_checker/test_noqa.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
'WPS354': 1,
'WPS355': 1,
'WPS356': 1,
'WPS357': 0, # logically unacceptable.

'WPS400': 0, # defined in ignored violations.
'WPS401': 0, # logically unacceptable.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# -*- coding: utf-8 -*-

import pytest

from wemake_python_styleguide.violations.consistency import (
LineCompriseCarriageReturnViolation,
)
from wemake_python_styleguide.visitors.tokenize.syntax import (
WrongKeywordTokenVisitor,
)

# Correct:

correct_newline = 'print(1)\nprint(2)'
correct_nl = 'print(1,\n 2)'
correct_string = '"\r"'
correct_raw_string = 'r"\r"'
correct_real_newline = """
print(1)
print(2)
"""

# Wrong:

wrong_newline_single = 'print(1)\r\nprint(2)'
wrong_newline_sequenced1 = 'print(1)\nprint(2)\r\n'
wrong_newline_sequenced2 = 'print(1)\r\nprint(2)\n'
wrong_newline_sequenced3 = 'print(1,\r\n 2)'
wrong_newline_in_multiline = """print(2)\r
print(3)
"""


@pytest.mark.parametrize('code', [
wrong_newline_single,
wrong_newline_sequenced1,
wrong_newline_sequenced2,
wrong_newline_sequenced3,
wrong_newline_in_multiline,
])
def test_string_wrong_line_breaks(
parse_tokens,
assert_errors,
default_options,
code,
):
"""Ensures that obsolete string's line break raise a violation."""
file_tokens = parse_tokens(code)

visitor = WrongKeywordTokenVisitor(
default_options, file_tokens=file_tokens,
)
visitor.run()

assert_errors(visitor, [LineCompriseCarriageReturnViolation])


@pytest.mark.parametrize('code', [
correct_newline,
correct_nl,
correct_string,
correct_raw_string,
correct_real_newline,
])
def test_string_proper_line_breaks(
parse_tokens,
assert_errors,
default_options,
code,
):
"""Ensures that proper string's line break are fine."""
file_tokens = parse_tokens(code)

visitor = WrongKeywordTokenVisitor(
default_options, file_tokens=file_tokens,
)
visitor.run()

assert_errors(visitor, [])
23 changes: 23 additions & 0 deletions wemake_python_styleguide/violations/consistency.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
ConsecutiveYieldsViolation
BracketBlankLineViolation
IterableUnpackingViolation
LineCompriseCarriageReturnViolation
Consistency checks
------------------
Expand Down Expand Up @@ -143,6 +144,7 @@
.. autoclass:: ConsecutiveYieldsViolation
.. autoclass:: BracketBlankLineViolation
.. autoclass:: IterableUnpackingViolation
.. autoclass:: LineCompriseCarriageReturnViolation
"""

Expand Down Expand Up @@ -2120,3 +2122,24 @@ class IterableUnpackingViolation(ASTViolation):

error_template = 'Found an unnecessary iterable unpacking'
code = 356


@final
class LineCompriseCarriageReturnViolation(TokenizeViolation):
r"""
Forbids to use ``\r`` (carriage return) in line breaks.
Reasoning:
We enforce Unix-style newlines.
We only use newlines (``\n``), not carriage returns.
So ``\r`` line breaks not allowed in code.
Solution:
Use only ``\n`` (not ``\r\n`` or ``\r``) to break lines.
.. versionadded:: 0.14.0
"""

error_template = r'Found a ``\r`` (carriage return) line break'
code = 357
4 changes: 3 additions & 1 deletion wemake_python_styleguide/violations/oop.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,9 @@ class UselessOverwrittenMethodViolation(ASTViolation):
# Correct:
class Test(Base):
...
def method(self, argument):
super().method(argument)
return argument # or None, or anything!
# Wrong:
class Test(object):
Expand Down
22 changes: 22 additions & 0 deletions wemake_python_styleguide/visitors/tokenize/syntax.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@
from typing_extensions import final

from wemake_python_styleguide.violations.consistency import (
LineCompriseCarriageReturnViolation,
LineStartsWithDotViolation,
MissingSpaceBetweenKeywordAndParenViolation,
)
from wemake_python_styleguide.visitors.base import BaseTokenVisitor
from wemake_python_styleguide.visitors.decorators import alias


@final
@alias('visit_any_newline', (
'visit_newline',
'visit_nl',
))
class WrongKeywordTokenVisitor(BaseTokenVisitor):
"""Visits keywords and finds violations related to their usage."""

Expand All @@ -36,6 +42,16 @@ def visit_dot(self, token: tokenize.TokenInfo) -> None:
"""
self._check_line_starts_with_dot(token)

def visit_any_newline(self, token: tokenize.TokenInfo) -> None:
r"""
Checks ``\r`` (carriage return) in line breaks.
Raises:
LineCompriseCarriageReturnViolation
"""
self._check_line_comprise_carriage_return(token)

def _check_space_before_open_paren(self, token: tokenize.TokenInfo) -> None:
if not keyword.iskeyword(token.string):
return
Expand All @@ -49,3 +65,9 @@ def _check_line_starts_with_dot(self, token: tokenize.TokenInfo) -> None:
line = token.line.lstrip()
if line.startswith('.') and not line.startswith('...'):
self.add_violation(LineStartsWithDotViolation(token))

def _check_line_comprise_carriage_return(
self, token: tokenize.TokenInfo,
) -> None:
if '\r' in token.string:
self.add_violation(LineCompriseCarriageReturnViolation(token))

0 comments on commit 0c165ad

Please sign in to comment.