-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Fix parentheses around return type annotations #13381
Fix parentheses around return type annotations #13381
Conversation
|
Some more examples: @cache
-def _register_filesystems() -> (
- Mapping[
- str,
- Callable[[str | None, Properties], AbstractFileSystem] | Callable[[str | None], AbstractFileSystem],
- ]
-):
+def _register_filesystems() -> Mapping[
+ str,
+ Callable[[str | None, Properties], AbstractFileSystem] | Callable[[str | None], AbstractFileSystem],
+]:
scheme_to_fs = _BUILTIN_SCHEME_TO_FS.copy()
with Stats.timer("airflow.io.load_filesystems") as timer:
event_stream = exhaust_iterator_and_yield_results_with_exception(self)
- def _threadpool_wrap_map_fn() -> (
- Iterator[Union[Output, AssetMaterialization, AssetObservation, AssetCheckResult]]
- ):
+ def _threadpool_wrap_map_fn() -> Iterator[
+ Union[Output, AssetMaterialization, AssetObservation, AssetCheckResult]
+ ]:
with ThreadPoolExecutor(
if stt_audio_buffer:
# Send audio in the buffer first to speech-to-text, then move on to stt_stream.
# This is basically an async itertools.chain.
- async def buffer_then_audio_stream() -> (
- AsyncGenerator[ProcessedAudioChunk, None]
- ):
+ async def buffer_then_audio_stream() -> AsyncGenerator[
+ ProcessedAudioChunk, None
+ ]:
# Buffered audio
for chunk in stt_audio_buffer:
yield chunk
diff --git a/homeassistant/components/openhome/media_player.py b/homeassistant/components/openhome/media_player.py
index 12e5ed992c..2991bb4ef1 100644
--- a/homeassistant/components/openhome/media_player.py
+++ b/homeassistant/components/openhome/media_player.py
@@ -71,11 +71,9 @@ _ReturnFuncType = Callable[
]
-def catch_request_errors() -> (
- Callable[
- [_FuncType[_OpenhomeDeviceT, _P, _R]], _ReturnFuncType[_OpenhomeDeviceT, _P, _R]
- ]
-):
+def catch_request_errors() -> Callable[
+ [_FuncType[_OpenhomeDeviceT, _P, _R]], _ReturnFuncType[_OpenhomeDeviceT, _P, _R]
+]:
"""Catch TimeoutError, aiohttp.ClientError, UpnpError errors."""
def call_wrapper(
diff --git a/homeassistant/components/recorder/statistics.py b/homeassistant/components/recorder/statistics.py
index 41cf4e22b5..19bdccbf83 100644
--- a/homeassistant/components/recorder/statistics.py
+++ b/homeassistant/components/recorder/statistics.py
@@ -935,12 +935,10 @@ def _reduce_statistics(
return result
-def reduce_day_ts_factory() -> (
- tuple[
- Callable[[float, float], bool],
- Callable[[float], tuple[float, float]],
- ]
-):
+def reduce_day_ts_factory() -> tuple[
+ Callable[[float, float], bool],
+ Callable[[float], tuple[float, float]],
+]:
"""Return functions to match same day and day start end."""
_boundries: tuple[float, float] = (0, 0)
@@ -983,12 +981,10 @@ def _reduce_statistics_per_day(
)
-def reduce_week_ts_factory() -> (
- tuple[
- Callable[[float, float], bool],
- Callable[[float], tuple[float, float]],
- ]
-):
+def reduce_week_ts_factory() -> tuple[
+ Callable[[float, float], bool],
+ Callable[[float], tuple[float, float]],
+]:
"""Return functions to match same week and week start end."""
_boundries: tuple[float, float] = (0, 0)
@@ -1041,12 +1037,10 @@ def _find_month_end_time(timestamp: datetime) -> datetime:
)
-def reduce_month_ts_factory() -> (
- tuple[
- Callable[[float, float], bool],
- Callable[[float], tuple[float, float]],
- ]
-):
+def reduce_month_ts_factory() -> tuple[
+ Callable[[float, float], bool],
+ Callable[[float], tuple[float, float]],
+]:
"""Return functions to match same month and month start end."""
_boundries: tuple[float, float] = (0, 0)
diff --git a/homeassistant/exceptions.py b/homeassistant/exceptions.py
index 1eb964d82b..1bedc6bdac 100644
--- a/homeassistant/exceptions.py
+++ b/homeassistant/exceptions.py
@@ -15,9 +15,9 @@ if TYPE_CHECKING:
_function_cache: dict[str, Callable[[str, str, dict[str, str] | None], str]] = {}
-def import_async_get_exception_message() -> (
- Callable[[str, str, dict[str, str] | None], str]
-):
+def import_async_get_exception_message() -> Callable[
+ [str, str, dict[str, str] | None], str
+]:
"""Return a method that can fetch a translated exception message.
Defaults to English, requires translations to already be cached.
diff --git a/tests/components/conftest.py b/tests/components/conftest.py
index bde8cad5ea..ce24f0d614 100644
--- a/tests/components/conftest.py
+++ b/tests/components/conftest.py
@@ -161,9 +161,9 @@ def mock_legacy_device_scanner() -> "MockScanner":
@pytest.fixture
-def mock_legacy_device_tracker_setup() -> (
- Callable[[HomeAssistant, "MockScanner"], None]
-):
+def mock_legacy_device_tracker_setup() -> Callable[
+ [HomeAssistant, "MockScanner"], None
+]:
"""Return setup callable for legacy device tracker setup."""
from tests.components.device_tracker.common import mock_legacy_device_tracker_setup
|
@@ -82,30 +82,6 @@ | |||
|
|||
func([(x, y,) for (x, y) in z], bar) | |||
|
|||
# Ensure that return type annotations (which use `parenthesize_if_expands`) are also hugged. |
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.
This is no longer true. We never add parentheses around lists anymore
Ruff preserves the parentheses around: def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeedooooong() -> (
list[int, float]
): ... Edit: The reason why ruff adds parentheses above is because the The argument against it is that we don't do so when the function has a parameter: def a():
def b():
def c():
def d():
def e():
def f():
def g():
def h():
def i():
def j():
def k():
def l():
def m():
def n():
def o():
def p():
def q():
def r():
def s():
def t():
def u():
def thiiiiiiiiiiiiiiiiiis_iiiiiiiiiiiiiiiiiiiiiiiiiiiiiis_veeeeeeeeeeedooooong(
a,
) -> list[
int,
float,
]: ... But adding a Overall. This seems rare enough and I think not parenthesizing is the better outcome but parenthesizing in the first helps stay in the configured line length (as much as possible) |
d32126c
to
767ab25
Compare
767ab25
to
12b9e22
Compare
12b9e22
to
49e0aa3
Compare
- and foo.bar.baz().bop( | ||
- 1, | ||
- ) | ||
+def double() -> first_item and foo.bar.baz().bop( |
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.
This looks surprising but it matches black's formatting
This comment was marked as resolved.
This comment was marked as resolved.
a4c8940
to
7045b19
Compare
7045b19
to
1b5fef1
Compare
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.
Interesting... I do prefer what you implemented here. I was looking back at #6436 -- I'm wondering why we didn't make this change then? I guess we were biasing towards improving compatibility as much as possible, despite us not understanding why Black had different styling at that point in time.
Looking through the tests added in #6436 the once that are relevant for this change are -def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> (
- Set[
- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- ]
-): ...
+def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+]: ...
-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> (
- Set[
- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- ]
-): ...
+def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+]: ...
-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> (
- Set[
- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- ]
-): ...
+def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+]: ...
-def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> (
- Set[
- "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
- ]
-): ...
+def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
+ "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
+]: ... These are all cases where black keeps the parentheses. But it removes them as soon as the subscript contains another element def xxxxxxxxxxxxxxxxxxxxxxxxxxxx() -> Set[
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
]: ... That's why I see this mainly as a refinement of the formatting you implemented in #6436. |
## 0.6.9 ### Preview features - Fix codeblock dynamic line length calculation for indented docstring examples ([#13523](astral-sh/ruff#13523)) - \[`refurb`\] Mark `FURB118` fix as unsafe ([#13613](astral-sh/ruff#13613)) ### Rule changes - \[`pydocstyle`\] Don't raise `D208` when last line is non-empty ([#13372](astral-sh/ruff#13372)) - \[`pylint`\] Preserve trivia (i.e. comments) in `PLR5501` autofix ([#13573](astral-sh/ruff#13573)) ### Configuration - \[`pyflakes`\] Add `allow-unused-imports` setting for `unused-import` rule (`F401`) ([#13601](astral-sh/ruff#13601)) ### Bug fixes - Support ruff discovery in pip build environments ([#13591](astral-sh/ruff#13591)) - \[`flake8-bugbear`\] Avoid short circuiting `B017` for multiple context managers ([#13609](astral-sh/ruff#13609)) - \[`pylint`\] Do not offer an invalid fix for `PLR1716` when the comparisons contain parenthesis ([#13527](astral-sh/ruff#13527)) - \[`pyupgrade`\] Fix `UP043` to apply to `collections.abc.Generator` and `collections.abc.AsyncGenerator` ([#13611](astral-sh/ruff#13611)) - \[`refurb`\] Fix handling of slices in tuples for `FURB118`, e.g., `x[:, 1]` ([#13518](astral-sh/ruff#13518)) ### Documentation - Update GitHub Action link to `astral-sh/ruff-action` ([#13551](astral-sh/ruff#13551)) ## 0.6.8 ### Preview features - Remove unnecessary parentheses around `match case` clauses ([#13510](astral-sh/ruff#13510)) - Parenthesize overlong `if` guards in `match..case` clauses ([#13513](astral-sh/ruff#13513)) - Detect basic wildcard imports in `ruff analyze graph` ([#13486](astral-sh/ruff#13486)) - \[`pylint`\] Implement `boolean-chained-comparison` (`R1716`) ([#13435](astral-sh/ruff#13435)) ### Rule changes - \[`lake8-simplify`\] Detect `SIM910` when using variadic keyword arguments, i.e., `**kwargs` ([#13503](astral-sh/ruff#13503)) - \[`pyupgrade`\] Avoid false negatives with non-reference shadowed bindings of loop variables (`UP028`) ([#13504](astral-sh/ruff#13504)) ### Bug fixes - Detect tuples bound to variadic positional arguments i.e. `*args` ([#13512](astral-sh/ruff#13512)) - Exit gracefully on broken pipe errors ([#13485](astral-sh/ruff#13485)) - Avoid panic when analyze graph hits broken pipe ([#13484](astral-sh/ruff#13484)) ### Performance - Reuse `BTreeSets` in module resolver ([#13440](astral-sh/ruff#13440)) - Skip traversal for non-compound statements ([#13441](astral-sh/ruff#13441)) ## 0.6.7 ### Preview features - Add Python version support to ruff analyze CLI ([#13426](astral-sh/ruff#13426)) - Add `exclude` support to `ruff analyze` ([#13425](astral-sh/ruff#13425)) - Fix parentheses around return type annotations ([#13381](astral-sh/ruff#13381)) ### Rule changes - \[`pycodestyle`\] Fix: Don't autofix if the first line ends in a question mark? (D400) ([#13399](astral-sh/ruff#13399)) ### Bug fixes - Respect `lint.exclude` in ruff check `--add-noqa` ([#13427](astral-sh/ruff#13427)) ### Performance - Avoid tracking module resolver files in Salsa ([#13437](astral-sh/ruff#13437)) - Use `forget` for module resolver database ([#13438](astral-sh/ruff#13438)) ## 0.6.6 ### Preview features - \[`refurb`\] Skip `slice-to-remove-prefix-or-suffix` (`FURB188`) when non-trivial slice steps are present ([#13405](astral-sh/ruff#13405)) - Add a subcommand to generate dependency graphs ([#13402](astral-sh/ruff#13402)) ### Formatter - Fix placement of inline parameter comments ([#13379](astral-sh/ruff#13379)) ### Server - Fix off-by one error in the `LineIndex::offset` calculation ([#13407](astral-sh/ruff#13407)) ### Bug fixes - \[`fastapi`\] Respect FastAPI aliases in route definitions ([#13394](astral-sh/ruff#13394)) - \[`pydocstyle`\] Respect word boundaries when detecting function signature in docs ([#13388](astral-sh/ruff#13388)) ### Documentation - Add backlinks to rule overview linter ([#13368](astral-sh/ruff#13368)) - Fix documentation for editor vim plugin ALE ([#13348](astral-sh/ruff#13348)) - Fix rendering of `FURB188` docs ([#13406](astral-sh/ruff#13406))
Summary
This PR addresses the issue where subscript and other parenthesized expressions in function return type positions were wrapped in an extra pair of parentheses if the function has no parameters. This leads to rather verbose code:
It's also inconsistent to how the same return type gets formatted when the function has parameters:
Fixes #9447
Black deviation
The PR adds two fairly extensive tests that walk through the black deviations. The most notable deviation is that black tries to parenthesize types before splitting the type itself (only applies to subscript)
Black
But it only does so if the function has no parameters. Below is Black's formatting if the function has a parameter.
This seems inconsistent. Ruff only parenthesizes the
list
if the subscript value up to the[
exceeds the line lengthRuff
The main counterargument is that most changes in the ecosystem are cases where Black would parenthesize the subscript. I'm interested to get a second opinion on this.
Preview
This is a preview-only change because it changes the formatting of already formatted code.
Test Plan
I reformatted some projects locally and skimmed through the changes. Overall, there are only few, and I generally prefer the new formatting (see this comment). Whether one prefers Black's formatting with the extra parentheses or not is probably the only "questionable" formatting change. IMO, consistency is more important (it reduces surprises for users: Why is it parenthesized here?).