Skip to content

Commit

Permalink
Fix BitwiseAndBooleanMixupViolation in type annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
bo5o committed Feb 20, 2021
1 parent 2ff1038 commit e9db62c
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,30 @@ def test_correct_binary(
visitor.run()

assert_errors(visitor, [])


@pytest.mark.parametrize('context', [
'foo: {0}',
'def fun(foo) -> {0}: ...',
'def fun(foo: {0}): ...',
])
@pytest.mark.parametrize('expression', [
'str | int',
'int | None',
'First | None',
'First | Second',
])
def test_union_type(
assert_errors,
parse_ast_tree,
context,
expression,
default_options,
):
"""Testing PEP 604 union types."""
tree = parse_ast_tree(context.format(expression))

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

assert_errors(visitor, [])
16 changes: 16 additions & 0 deletions wemake_python_styleguide/visitors/ast/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from wemake_python_styleguide.compat.aliases import TextNodes
from wemake_python_styleguide.compat.nodes import NamedExpr
from wemake_python_styleguide.logic import walk
from wemake_python_styleguide.logic.nodes import get_parent
from wemake_python_styleguide.logic.tree.operators import (
count_unary_operator,
unwrap_unary_node,
Expand Down Expand Up @@ -297,9 +298,24 @@ def _check_logical_bitwise_operator(self, node: ast.BinOp) -> None:
if not isinstance(node.op, (ast.BitOr, ast.BitAnd)):
return

if self._is_type_annotation(node):
return

if self._is_bool_like(node.left) or self._is_bool_like(node.right):
self.add_violation(BitwiseAndBooleanMixupViolation(node))

# checks either side of the Bitwise operation invalid usage
def _is_bool_like(self, node: ast.expr) -> bool:
return isinstance(node, self._invalid_nodes)

# checks whether bitwise operator is used in a type annotation
def _is_type_annotation(self, node: ast.BinOp) -> bool:
parent_node = get_parent(node)

if isinstance(parent_node, (ast.AnnAssign, ast.arg)):
return node is parent_node.annotation

if isinstance(parent_node, ast.FunctionDef):
return node is parent_node.returns

return False

0 comments on commit e9db62c

Please sign in to comment.