summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Stapleton Cordasco <graffatcolmingov@gmail.com>2020-05-08 09:23:22 -0500
committerGitHub <noreply@github.com>2020-05-08 09:23:22 -0500
commit90026afea11298f0450194ed44af0b659ff6fc91 (patch)
tree9a019c52de7814d7a5c63adebc2ab9e79378b92f
parenta238201edd2883fcc0400df4a11cbb6fd5f6e5d7 (diff)
parent742228c05fdd0a63acda3a26976f6d4fec49342c (diff)
downloadpep8-90026afea11298f0450194ed44af0b659ff6fc91.tar.gz
Merge pull request #927 from asottile/allow_typing_one_liners_again
re-allow decorated one-liners
-rwxr-xr-xpycodestyle.py50
-rw-r--r--testsuite/E30not.py26
2 files changed, 66 insertions, 10 deletions
diff --git a/pycodestyle.py b/pycodestyle.py
index fe45548..7198639 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 -*-