-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
More concise formatting for dummy implementations #3796
Changes from 5 commits
9a10436
c38a470
aaf9f5e
e5aaaa3
44378ab
5b228b1
7de270e
b1c4014
f140252
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -165,6 +165,13 @@ def is_def(self) -> bool: | |
and second_leaf.value == "def" | ||
) | ||
|
||
@property | ||
def is_stub_def(self) -> bool: | ||
"""Is this line a function definition with a body consisting only of "..."?""" | ||
return self.is_def and self.leaves[-3:] == [ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this also match something like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this is true (and true for the is Also note some of the pyi code we now use in linegen.py will trigger in some cases involving other statements, although it's not unreasonable when it happens. |
||
Leaf(token.DOT, ".") for _ in range(3) | ||
] | ||
|
||
@property | ||
def is_class_paren_empty(self) -> bool: | ||
"""Is this a class with no base classes but using parentheses? | ||
|
@@ -578,6 +585,8 @@ def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]: | |
first_leaf.prefix = "" | ||
else: | ||
before = 0 | ||
|
||
user_hint_before = before | ||
hauntsaninja marked this conversation as resolved.
Show resolved
Hide resolved
|
||
depth = current_line.depth | ||
|
||
previous_def = None | ||
|
@@ -624,7 +633,9 @@ def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]: | |
before = 2 | ||
|
||
if current_line.is_decorator or current_line.is_def or current_line.is_class: | ||
return self._maybe_empty_lines_for_class_or_def(current_line, before) | ||
return self._maybe_empty_lines_for_class_or_def( | ||
current_line, before, user_hint_before | ||
) | ||
|
||
if ( | ||
self.previous_line | ||
|
@@ -648,8 +659,8 @@ def _maybe_empty_lines(self, current_line: Line) -> Tuple[int, int]: | |
return 0, 0 | ||
return before, 0 | ||
|
||
def _maybe_empty_lines_for_class_or_def( | ||
self, current_line: Line, before: int | ||
def _maybe_empty_lines_for_class_or_def( # noqa: C901 | ||
self, current_line: Line, before: int, user_hint_before: int | ||
) -> Tuple[int, int]: | ||
if not current_line.is_decorator: | ||
self.previous_defs.append(current_line) | ||
|
@@ -714,7 +725,14 @@ def _maybe_empty_lines_for_class_or_def( | |
else: | ||
newlines = 0 | ||
else: | ||
newlines = 1 if current_line.depth else 2 | ||
if ( | ||
Preview.dummy_implementations in self.mode | ||
and self.previous_line.is_stub_def | ||
and (current_line.is_stub_def or current_line.is_decorator) | ||
): | ||
newlines = user_hint_before | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is perhaps controversial, but it allows users to group things as they want (e.g. in the test case, dummy and other are grouped separately) and solves some lookahead problems when dealing with decorators |
||
else: | ||
newlines = 1 if current_line.depth else 2 | ||
if comment_to_add_newlines is not None: | ||
previous_block = comment_to_add_newlines.previous_block | ||
if previous_block is not None: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
from typing import NoReturn, Protocol, Union, overload | ||
|
||
|
||
def dummy(a): ... | ||
def other(b): ... | ||
|
||
|
||
@overload | ||
def a(arg: int) -> int: ... | ||
@overload | ||
hauntsaninja marked this conversation as resolved.
Show resolved
Hide resolved
|
||
def a(arg: str) -> str: ... | ||
@overload | ||
def a(arg: object) -> NoReturn: ... | ||
def a(arg: Union[int, str, object]) -> Union[int, str]: | ||
if not isinstance(arg, (int, str)): | ||
raise TypeError | ||
return arg | ||
|
||
class Proto(Protocol): | ||
def foo(self, a: int) -> int: | ||
... | ||
|
||
def bar(self, b: str) -> str: ... | ||
def baz(self, c: bytes) -> str: | ||
... | ||
|
||
# output | ||
|
||
from typing import NoReturn, Protocol, Union, overload | ||
|
||
|
||
def dummy(a): ... | ||
def other(b): ... | ||
|
||
|
||
@overload | ||
def a(arg: int) -> int: ... | ||
@overload | ||
def a(arg: str) -> str: ... | ||
@overload | ||
def a(arg: object) -> NoReturn: ... | ||
|
||
|
||
def a(arg: Union[int, str, object]) -> Union[int, str]: | ||
if not isinstance(arg, (int, str)): | ||
raise TypeError | ||
return arg | ||
|
||
|
||
class Proto(Protocol): | ||
def foo(self, a: int) -> int: ... | ||
|
||
def bar(self, b: str) -> str: ... | ||
def baz(self, c: bytes) -> str: ... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mirrors
is_stub_class
from a couple lines above