Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

re-allow decorated one-liners #927

Merged
merged 1 commit into from
May 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 40 additions & 10 deletions pycodestyle.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,41 @@ def maximum_line_length(physical_line, max_line_length, multiline,
########################################################################


def _is_one_liner(logical_line, indent_level, lines, line_number):
if not STARTSWITH_TOP_LEVEL_REGEX.match(logical_line):
return False

line_idx = line_number - 1

if line_idx < 1:
prev_indent = 0
else:
prev_indent = expand_indent(lines[line_idx - 1])

if prev_indent > indent_level:
return False

while line_idx < len(lines):
line = lines[line_idx].strip()
if not line.startswith('@') and STARTSWITH_TOP_LEVEL_REGEX.match(line):
break
else:
line_idx += 1
else:
return False # invalid syntax: EOF while searching for def/class

next_idx = line_idx + 1
while next_idx < len(lines):
if lines[next_idx].strip():
break
else:
next_idx += 1
else:
return True # line is last in the file

return expand_indent(lines[next_idx]) <= indent_level


@register_check
def blank_lines(logical_line, blank_lines, indent_level, line_number,
blank_before, previous_logical,
Expand Down Expand Up @@ -360,16 +395,11 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number,
):
yield 0, "E303 too many blank lines (%d)" % blank_lines
elif STARTSWITH_TOP_LEVEL_REGEX.match(logical_line):
# If this is a one-liner (i.e. this is not a decorator and the
# next line is not more indented), and the previous line is also
# not deeper (it would be better to check if the previous line
# is part of another def/class at the same level), don't require
# blank lines around this.
prev_line = lines[line_number - 2] if line_number >= 2 else ''
next_line = lines[line_number] if line_number < len(lines) else ''
if (not logical_line.startswith("@") and
expand_indent(prev_line) <= indent_level and
expand_indent(next_line) <= indent_level):
# allow a group of one-liners
if (
_is_one_liner(logical_line, indent_level, lines, line_number) and
blank_before == 0
):
return
if indent_level:
if not (blank_before == method_lines or
Expand Down
26 changes: 26 additions & 0 deletions testsuite/E30not.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,32 @@ def foo():
# for no E30x being emitted.
def bar(): pass
def baz(): pass
#: E704:8:1 E704:10:1
from typing import overload
from typing import Union


# This emits the (ignored-by-default) E704, but here we're testing
# for no E30x being emitted.
@overload
def f(x: int) -> int: ...
@overload
def f(x: str) -> str: ...


def f(x: Union[int, str]) -> Union[int, str]:
return x
#: E704:8:5 E704:10:5
from typing import Protocol


class C(Protocol):
# This emits the (ignored-by-default) E704, but here we're testing
# for no E30x being emitted.
@property
def f(self) -> int: ...
@property
def g(self) -> str: ...
#: Okay
#!python
# -*- coding: utf-8 -*-
Expand Down