One can use both r'abc' and 'abc' to represent a simple string.
But, r strings are only required when dealing with \ in your strings.
So, the rule is: if there's no \ in your string, then do not use r
This is an inverse rule to WPS342
Hi! I would like to take on this issue if I may?
Sure, @fwald! Thanks a lot! Feel free to ask any questions.
When implementing this, the linter complains about this expression in the file
constants.py:
# Used as a special name patterns for unused variables, like _, __:
UNUSED_VARIABLE_REGEX: Final = re.compile(r'^_+$')
Can this be changed to a normal string instead?
@fwald yes please! That's what I love about static analysis the most: finding new issues in code that you have seen so many times!
Hi, I'm working with @fwald on the issue. Enforcing this new rule also breaks tests in the test suite, so I'm working on modifying it.
But I struggle with this error when running pytest tests/test_visitors/test_tokenize/test_primitives/test_string_tokens/test_string_multiline.py:
___________________ test_incorrect_multiline_strings[other_var + {0}-regular_wrapper-r'''\n'''] ____________________
parse_tokens = <function parse_tokens.<locals>.factory at 0x7ffacd7592f0>
assert_errors = <function assert_errors.<locals>.factory at 0x7ffacd759158>
default_options = options(min_name_length=2, max_name_length=45, i_control_code=True, i_dont_control_code=True, max_noqa_comments=10, ne...el=4, max_attributes=6, max_cognitive_score=12, max_cognitive_average=8, max_call_level=3, max_annotation_complexity=3)
primitives_usages = 'other_var + {0}', primitive = "r'''\n'''"
mode = <function regular_wrapper.<locals>.factory at 0x7ffacd5c5598>
@pytest.mark.parametrize('primitive', [
'"""abc"""',
"'''abc'''",
'""""""',
"r'''\n'''",
'b"""some"""',
])
def test_incorrect_multiline_strings(
parse_tokens,
assert_errors,
default_options,
primitives_usages,
primitive,
mode,
):
"""Ensures that incorrect multiline strings are forbiden."""
file_tokens = parse_tokens(mode(primitives_usages.format(primitive)))
visitor = WrongStringTokenVisitor(default_options, file_tokens=file_tokens)
visitor.run()
> assert_errors(visitor, [WrongMultilineStringViolation])
tests/test_visitors/test_tokenize/test_primitives/test_string_tokens/test_string_multiline.py:79:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
visitor = <wemake_python_styleguide.visitors.tokenize.primitives.WrongStringTokenVisitor object at 0x7ffacd4dbc50>
errors = [<class 'wemake_python_styleguide.violations.consistency.WrongMultilineStringViolation'>]
ignored_types = None
def factory(
visitor: BaseVisitor,
errors: Sequence[str],
ignored_types=None,
):
if ignored_types:
real_errors = [
error
for error in visitor.violations
if not isinstance(error, ignored_types)
]
else:
real_errors = visitor.violations
> assert len(errors) == len(real_errors)
E AssertionError: assert 1 == 0
E + where 1 = len([<class 'wemake_python_styleguide.violations.consistency.WrongMultilineStringViolation'>])
E + and 0 = len([])
tests/test_visitors/conftest.py:31: AssertionError
I added a \n in the primitive to be consistent with the new rule, but something is still wrong and I don't understand why. Do you have a clue @sobolevn ?
Do not hesitate if you want more information on the bug.
You can use ignored_types= parameter on assert_errors. This happens when old tests are executed on updated visitor.
Or you can refactor old tests. Both cases are fine.