From 742228c05fdd0a63acda3a26976f6d4fec49342c Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 27 Apr 2020 20:55:02 -0700 Subject: re-allow decorated one-liners --- pycodestyle.py | 50 ++++++++++++++++++++++++++++++++++++++++---------- testsuite/E30not.py | 26 ++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/pycodestyle.py b/pycodestyle.py index 0ad37e2..b8f12d4 100755 --- a/pycodestyle.py +++ b/pycodestyle.py @@ -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, @@ -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 diff --git a/testsuite/E30not.py b/testsuite/E30not.py index a86b99e..9c33236 100644 --- a/testsuite/E30not.py +++ b/testsuite/E30not.py @@ -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 -*- -- cgit v1.2.1