Skip to content
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Semantic versioning in our case means:
### Bugfixes

- Fixes `WPS115` false-positive on `StrEnum`, `IntEnum`, `IntFlag` attributes, #3381

- Fixes `WPS432`, now it ignores magic numbers in `Literal`, #3397

## 1.1.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ def function_name(param1, param2: int = {0}):
set_definition = '{{"first", {0}, "other"}}'
tuple_definition = '({0}, )'

literal_type_hint = 'code: Literal[{0}] = {0}'
Comment thread
LordGvozd marked this conversation as resolved.
literal_type_hint_with_typing_module = 'code: typing.Literal[{0}] = {0}'
literal_type_hint_with_typing_exts_module = (
Comment thread
LordGvozd marked this conversation as resolved.
'code: typing_extensions.Literal[{0}] = {0}'
)


# Wrong usages:

assignment_binop = 'final = {0} + 1'
Expand Down Expand Up @@ -68,6 +75,12 @@ def method(self):
some_dict[{0}]
"""

not_literal_type_hint = """
foo: Bar[{0}] = {0}
"""

literal_type_with_not_typing_module = 'foo: bar.Literal[{0}] = {0}'


@pytest.mark.parametrize(
'code',
Expand All @@ -83,6 +96,9 @@ def method(self):
dict_definition_value,
set_definition,
tuple_definition,
literal_type_hint,
literal_type_hint_with_typing_module,
literal_type_hint_with_typing_exts_module,
],
)
@pytest.mark.parametrize(
Expand Down Expand Up @@ -145,6 +161,8 @@ def test_magic_number(
inside_method,
list_index,
dict_key,
not_literal_type_hint,
literal_type_with_not_typing_module,
],
)
@pytest.mark.parametrize(
Expand Down Expand Up @@ -194,6 +212,8 @@ def test_magic_number_whitelist(
inside_method,
list_index,
dict_key,
not_literal_type_hint,
literal_type_with_not_typing_module,
],
)
@pytest.mark.parametrize(
Expand Down Expand Up @@ -244,6 +264,8 @@ def test_magic_number_warning(
inside_method,
list_index,
dict_key,
not_literal_type_hint,
literal_type_with_not_typing_module,
],
)
@pytest.mark.parametrize(
Expand Down
28 changes: 22 additions & 6 deletions wemake_python_styleguide/visitors/ast/builtins.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,15 +189,18 @@ def visit_Num(self, node: ast.Constant) -> None:

def _check_is_magic(self, node: ast.Constant) -> None:
parent = operators.get_parent_ignoring_unary(node)
if isinstance(parent, self._allowed_parents):
return

if node.value in constants.MAGIC_NUMBERS_WHITELIST:
return
is_non_magic = (
isinstance(node.value, int) and node.value <= self._non_magic_modulo
)

if isinstance(node.value, int) and node.value <= self._non_magic_modulo:
if (
isinstance(parent, self._allowed_parents)
or node.value in constants.MAGIC_NUMBERS_WHITELIST
or is_non_magic
or self._check_is_number_in_typing_literal(parent)
):
return

try:
token = self._token_dict[node.lineno, node.col_offset]
except KeyError: # pragma: no cover
Expand All @@ -212,6 +215,19 @@ def _check_is_magic(self, node: ast.Constant) -> None:
best_practices.MagicNumberViolation(node, text=real_value),
)

def _check_is_number_in_typing_literal(self, node: ast.AST | None) -> bool:
Comment thread
LordGvozd marked this conversation as resolved.
Outdated
if isinstance(node, ast.Subscript):
if (
isinstance(node.value, ast.Attribute)
and isinstance(node.value.value, ast.Name)
and node.value.value.id in {'typing', 'typing_extensions'}
and node.value.attr == 'Literal'
):
return True
if isinstance(node.value, ast.Name) and node.value.id in 'Literal':
return True
return False

def _check_is_approximate_constant(self, node: ast.Constant) -> None:
try:
precision = len(str(node.value).split('.')[1])
Expand Down