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

Format target: annotation = value? expressions #5661

Merged
merged 2 commits into from
Jul 11, 2023

Conversation

MichaReiser
Copy link
Member

Summary

This PR implements formatting of target: annotation (= value)? expressions.

It resulted in me going down a rabbit hole because I then noticed that tuples inside of subscript should not be parenthesized. So I fixed that too.

Test Plan

I added new tests. I fixed the skip_magic_comma test to run it with magic comma disabled (This test got me really confused because one test wanted to have trailing comma and this test wanted not to have trailing commas).

@MichaReiser
Copy link
Member Author

MichaReiser commented Jul 10, 2023

@@ -6,20 +6,20 @@ use ruff_text_size::TextSize;
use rustpython_parser::ast::Ranged;

/// Adds parentheses and indents `content` if it doesn't fit on a line.
pub(crate) fn optional_parentheses<'ast, T>(content: &T) -> OptionalParentheses<'_, 'ast>
pub(crate) fn parenthesize_if_expands<'ast, T>(content: &T) -> ParenthesizeIfExpands<'_, 'ast>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this name is better. The rest of the code refers to optional parentheses that we sometimes omit because they are unnecessary. These are parentheses that we always add if the content expands.

@@ -106,30 +105,9 @@ impl FormatRule<Expr, PyFormatContext<'_>> for FormatExpr {
// Add optional parentheses. Ignore if the item renders parentheses itself.
Parentheses::Optional => {
if can_omit_optional_parentheses(item, f.context()) {
let saved_level = f.context().node_level();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this, unchanged, to parentheses.rs

return_annotation
.format()
.with_options(Parenthesize::IfBreaks)
optional_parentheses(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function defs are weird. They add parentheses around subscript expressions.

let options = PyFormatOptions::default();
let options_path = input_path.with_extension("options.json");

let options: PyFormatOptions = if let Ok(options_file) = fs::File::open(options_path) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds support for options for black tests.


-class F(A, C): ...

-def spam() -> None: ...
+class F(A, C):
+ ...
+
+
+def spam() -> None:
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, we'll need into single line bodies at some point. Potentially something that our suite refactor would simplify but we shouldn't be blocked by it.l

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🥳

@MichaReiser MichaReiser linked an issue Jul 10, 2023 that may be closed by this pull request
@MichaReiser MichaReiser added the formatter Related to the formatter label Jul 10, 2023
@MichaReiser MichaReiser requested a review from konstin July 10, 2023 18:07
@github-actions
Copy link
Contributor

github-actions bot commented Jul 10, 2023

PR Check Results

Ecosystem

✅ ecosystem check detected no changes.

Benchmark

Linux

group                                      main                                   pr
-----                                      ----                                   --
formatter/large/dataset.py                 1.00      8.0±0.03ms     5.1 MB/sec    1.01      8.1±0.02ms     5.0 MB/sec
formatter/numpy/ctypeslib.py               1.00   1859.2±7.73µs     9.0 MB/sec    1.01   1875.0±5.49µs     8.9 MB/sec
formatter/numpy/globals.py                 1.00    206.2±4.40µs    14.3 MB/sec    1.00    206.9±1.26µs    14.3 MB/sec
formatter/pydantic/types.py                1.00      4.0±0.01ms     6.4 MB/sec    1.02      4.1±0.01ms     6.3 MB/sec
linter/all-rules/large/dataset.py          1.00     13.5±0.10ms     3.0 MB/sec    1.00     13.6±0.06ms     3.0 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.00      3.4±0.00ms     4.9 MB/sec    1.00      3.4±0.02ms     4.9 MB/sec
linter/all-rules/numpy/globals.py          1.00    432.7±0.72µs     6.8 MB/sec    1.00    433.4±0.97µs     6.8 MB/sec
linter/all-rules/pydantic/types.py         1.00      6.0±0.02ms     4.3 MB/sec    1.01      6.0±0.02ms     4.2 MB/sec
linter/default-rules/large/dataset.py      1.00      6.7±0.02ms     6.1 MB/sec    1.01      6.8±0.02ms     6.0 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.00   1459.5±8.10µs    11.4 MB/sec    1.01   1468.3±4.07µs    11.3 MB/sec
linter/default-rules/numpy/globals.py      1.00    166.1±1.22µs    17.8 MB/sec    1.00    166.8±0.26µs    17.7 MB/sec
linter/default-rules/pydantic/types.py     1.00      3.0±0.01ms     8.5 MB/sec    1.01      3.0±0.01ms     8.4 MB/sec

Windows

group                                      main                                   pr
-----                                      ----                                   --
formatter/large/dataset.py                 1.00     12.2±0.39ms     3.3 MB/sec    1.00     12.2±0.38ms     3.3 MB/sec
formatter/numpy/ctypeslib.py               1.00      2.8±0.14ms     6.1 MB/sec    1.00      2.8±0.14ms     6.1 MB/sec
formatter/numpy/globals.py                 1.00   312.2±15.55µs     9.5 MB/sec    1.01   316.5±18.32µs     9.3 MB/sec
formatter/pydantic/types.py                1.00      5.8±0.20ms     4.4 MB/sec    1.05      6.1±0.23ms     4.2 MB/sec
linter/all-rules/large/dataset.py          1.04     21.4±0.63ms  1942.5 KB/sec    1.00     20.7±0.78ms  2012.2 KB/sec
linter/all-rules/numpy/ctypeslib.py        1.03      5.5±0.24ms     3.0 MB/sec    1.00      5.4±0.19ms     3.1 MB/sec
linter/all-rules/numpy/globals.py          1.03   664.3±31.46µs     4.4 MB/sec    1.00   642.8±21.80µs     4.6 MB/sec
linter/all-rules/pydantic/types.py         1.00      9.5±0.36ms     2.7 MB/sec    1.00      9.4±0.31ms     2.7 MB/sec
linter/default-rules/large/dataset.py      1.05     11.0±0.44ms     3.7 MB/sec    1.00     10.4±0.36ms     3.9 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.07      2.3±0.12ms     7.2 MB/sec    1.00      2.2±0.07ms     7.7 MB/sec
linter/default-rules/numpy/globals.py      1.01   283.2±13.42µs    10.4 MB/sec    1.00   280.9±23.97µs    10.5 MB/sec
linter/default-rules/pydantic/types.py     1.04      4.8±0.21ms     5.3 MB/sec    1.00      4.7±0.14ms     5.5 MB/sec

@MichaReiser MichaReiser changed the base branch from expression-ref to main July 11, 2023 12:31
@MichaReiser MichaReiser reopened this Jul 11, 2023
@MichaReiser MichaReiser merged commit f1d3676 into main Jul 11, 2023
16 of 32 checks passed
@MichaReiser MichaReiser deleted the format-annotated-assignment branch July 11, 2023 14:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
formatter Related to the formatter
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Formatter: AnnAssign
2 participants