Skip to content

Commit

Permalink
Closes #1168
Browse files Browse the repository at this point in the history
  • Loading branch information
sobolevn committed Feb 24, 2020
1 parent 1bca8ee commit 6a254a8
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Semantic versioning in our case means:
- Fixes `WPS204` reporting overused return type annotations
- Fixes `WPS204` reporting `self.` attribute access
- Fixes `WPS331` reporting cases that do require some extra steps before return
- Fixes `WPS612` not reporing `super()` calls without return

### Misc

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
from wemake_python_styleguide.visitors.ast.classes import WrongMethodVisitor

regular_method_detailed = """
class Useless(object):
{decorator}
def function(self, {args_definition}):
{statements}
super({super_args}).{method_name}({args_invocation})
"""

regular_method_detailed_with_return = """
class Useless(object):
{decorator}
def function(self, {args_definition}):
Expand All @@ -22,8 +30,14 @@ def function({args}):
{statement}
"""

_MethodArgs = NamedTuple('_MethodArgs', definition=str, invocation=str)
regular_method_short_with_extra = """
class Useless(object):
def function({args}):
{statement}
return None
"""

_MethodArgs = NamedTuple('_MethodArgs', definition=str, invocation=str)

valid_method_args: List[_MethodArgs] = [
_MethodArgs('', ''),
Expand Down Expand Up @@ -115,6 +129,7 @@ def function({args}):

@pytest.mark.parametrize('code', [
regular_method_detailed,
regular_method_detailed_with_return,
])
@pytest.mark.parametrize('statements', valid_statements)
@pytest.mark.parametrize('method_args', valid_method_args)
Expand Down Expand Up @@ -148,6 +163,7 @@ def test_useless_overwriting(

@pytest.mark.parametrize('code', [
regular_method_detailed,
regular_method_detailed_with_return,
])
@pytest.mark.parametrize('decorator', [
'@decorator',
Expand Down Expand Up @@ -185,6 +201,7 @@ def test_useful_due_to_invalid_decorator(

@pytest.mark.parametrize('code', [
regular_method_detailed,
regular_method_detailed_with_return,
])
@pytest.mark.parametrize('statements', invalid_statements)
@pytest.mark.parametrize('method_args', valid_method_args)
Expand Down Expand Up @@ -218,6 +235,7 @@ def test_useful_due_to_invalid_statements(

@pytest.mark.parametrize('code', [
regular_method_detailed,
regular_method_detailed_with_return,
])
@pytest.mark.parametrize('statements', valid_statements)
@pytest.mark.parametrize('method_args', valid_method_args)
Expand Down Expand Up @@ -251,6 +269,7 @@ def test_useful_due_to_invalid_super_args(

@pytest.mark.parametrize('code', [
regular_method_detailed,
regular_method_detailed_with_return,
])
@pytest.mark.parametrize('statements', valid_statements)
@pytest.mark.parametrize('method_args', valid_method_args)
Expand Down Expand Up @@ -284,6 +303,7 @@ def test_useful_due_to_invalid_method(

@pytest.mark.parametrize('code', [
regular_method_detailed,
regular_method_detailed_with_return,
])
@pytest.mark.parametrize('statements', valid_statements)
@pytest.mark.parametrize('method_args', invalid_method_args)
Expand Down Expand Up @@ -317,6 +337,7 @@ def test_useful_due_to_invalid_method_args(

@pytest.mark.parametrize('code', [
regular_method_short,
regular_method_short_with_extra,
])
@pytest.mark.parametrize(('args', 'statement'), [
('self', '""""""'),
Expand Down
31 changes: 20 additions & 11 deletions wemake_python_styleguide/visitors/ast/classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,19 @@ def _get_call_stmt_of_useless_method(
self,
node: types.AnyFunctionDef,
) -> Optional[ast.Call]:
# consider next body as possible candidate of useless method:
# 1) Optional[docstring]
# 2) return statement with call
"""
Fetches ``super`` call statement from function definition.
Consider next body as possible candidate of useless method:
1. Optional[docstring]
2. single return statement with call
3. single statement with call, but without return
Related:
https://github.com/wemake-services/wemake-python-styleguide/issues/1168
"""
statements_number = len(node.body)
if statements_number > 2 or statements_number == 0:
return None
Expand All @@ -201,14 +211,13 @@ def _get_call_stmt_of_useless_method(
if not strings.is_doc_string(node.body[0]):
return None

return_stmt = node.body[-1]
if not isinstance(return_stmt, ast.Return):
return None

call_stmt = return_stmt.value
if not isinstance(call_stmt, ast.Call):
return None
return call_stmt
stmt = node.body[-1]
if isinstance(stmt, ast.Return):
call_stmt = stmt.value
return call_stmt if isinstance(call_stmt, ast.Call) else None
elif isinstance(stmt, ast.Expr) and isinstance(stmt.value, ast.Call):
return stmt.value
return None

def _check_useless_overwritten_methods(
self,
Expand Down

0 comments on commit 6a254a8

Please sign in to comment.