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 Function definitions #4951

Merged
merged 4 commits into from
Jun 8, 2023
Merged

Format Function definitions #4951

merged 4 commits into from
Jun 8, 2023

Conversation

MichaReiser
Copy link
Member

@MichaReiser MichaReiser commented Jun 8, 2023

Summary

This PR implements formatting for function definitions and async function definitions. The formatting should be fairly complete.

Test Plan

I added a few of my own test cases and reviewed the black differences.

@github-actions
Copy link
Contributor

github-actions bot commented Jun 8, 2023

PR Check Results

Ecosystem

✅ ecosystem check detected no changes.

Benchmark

Linux

group                                      main                                   pr
-----                                      ----                                   --
formatter/large/dataset.py                 1.00      7.2±0.19ms     5.7 MB/sec    1.02      7.3±0.11ms     5.6 MB/sec
formatter/numpy/ctypeslib.py               1.00  1294.9±26.02µs    12.9 MB/sec    1.00  1297.4±26.58µs    12.8 MB/sec
formatter/numpy/globals.py                 1.00    146.5±3.94µs    20.1 MB/sec    1.02    149.2±1.42µs    19.8 MB/sec
formatter/pydantic/types.py                1.00      3.0±0.05ms     8.6 MB/sec    1.02      3.0±0.05ms     8.5 MB/sec
linter/all-rules/large/dataset.py          1.00     16.3±0.23ms     2.5 MB/sec    1.00     16.3±0.29ms     2.5 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.01      3.9±0.05ms     4.3 MB/sec    1.00      3.9±0.07ms     4.3 MB/sec
linter/all-rules/numpy/globals.py          1.00   469.2±13.01µs     6.3 MB/sec    1.03    484.2±4.42µs     6.1 MB/sec
linter/all-rules/pydantic/types.py         1.00      6.7±0.11ms     3.8 MB/sec    1.02      6.8±0.10ms     3.7 MB/sec
linter/default-rules/large/dataset.py      1.00      7.7±0.18ms     5.3 MB/sec    1.03      7.9±0.07ms     5.2 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.00  1628.2±44.42µs    10.2 MB/sec    1.04  1688.6±23.05µs     9.9 MB/sec
linter/default-rules/numpy/globals.py      1.02    186.4±2.03µs    15.8 MB/sec    1.00    183.4±3.77µs    16.1 MB/sec
linter/default-rules/pydantic/types.py     1.00      3.5±0.08ms     7.3 MB/sec    1.02      3.5±0.04ms     7.2 MB/sec

Windows

group                                      main                                   pr
-----                                      ----                                   --
formatter/large/dataset.py                 1.00      9.1±0.29ms     4.5 MB/sec    1.01      9.3±0.23ms     4.4 MB/sec
formatter/numpy/ctypeslib.py               1.00  1581.2±59.49µs    10.5 MB/sec    1.03  1627.8±50.84µs    10.2 MB/sec
formatter/numpy/globals.py                 1.00   174.8±10.52µs    16.9 MB/sec    1.02    178.9±8.62µs    16.5 MB/sec
formatter/pydantic/types.py                1.00      3.7±0.11ms     6.9 MB/sec    1.04      3.8±0.13ms     6.7 MB/sec
linter/all-rules/large/dataset.py          1.00     18.6±0.44ms     2.2 MB/sec    1.11     20.7±0.51ms  2010.3 KB/sec
linter/all-rules/numpy/ctypeslib.py        1.00      4.8±0.16ms     3.5 MB/sec    1.10      5.2±0.14ms     3.2 MB/sec
linter/all-rules/numpy/globals.py          1.00   561.3±27.93µs     5.3 MB/sec    1.06   597.6±18.10µs     4.9 MB/sec
linter/all-rules/pydantic/types.py         1.00      8.0±0.25ms     3.2 MB/sec    1.09      8.8±0.25ms     2.9 MB/sec
linter/default-rules/large/dataset.py      1.00      9.4±0.25ms     4.3 MB/sec    1.13     10.6±0.22ms     3.8 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.00      2.1±0.09ms     8.0 MB/sec    1.08      2.3±0.09ms     7.4 MB/sec
linter/default-rules/numpy/globals.py      1.00    237.5±9.24µs    12.4 MB/sec    1.05   249.3±17.36µs    11.8 MB/sec
linter/default-rules/pydantic/types.py     1.00      4.5±0.13ms     5.7 MB/sec    1.07      4.8±0.18ms     5.3 MB/sec

@MichaReiser MichaReiser force-pushed the format-function-definition branch from 01a9a40 to c0c645e Compare June 8, 2023 10:13
@MichaReiser MichaReiser added internal An internal refactor or improvement formatter Related to the formatter labels Jun 8, 2023
@MichaReiser MichaReiser force-pushed the format-function-definition branch from 7ba434b to 875cd8b Compare June 8, 2023 10:58
@@ -77,6 +77,11 @@ def to_camel_case(node: str) -> str:
# )
# src.joinpath(groups[group]).joinpath("mod.rs").write_text(rustfmt(mod_section))
for node in group_nodes:
node_path = src.joinpath(groups[group]).joinpath(f"{to_camel_case(node)}.rs")
# Don't override existing manual implementations
if node_path.exists():
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 was a bit unexpected haha...

.unwrap_or_default()
.len();
let match_stmt_indentation =
whitespace::indentation(locator, match_stmt).map_or(usize::MAX, str::len);
Copy link
Member Author

Choose a reason for hiding this comment

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

using default here yields an incorrect result if the body is on the same line as the case header. Using usize::MAX should be fairly safe ;)

@@ -39,19 +39,17 @@ where
N: AstNode,
{
fn fmt(&self, node: &N, f: &mut PyFormatter) -> FormatResult<()> {
write!(f, [source_position(node.start())])?;
Copy link
Member Author

Choose a reason for hiding this comment

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

The leading and trailing comments normally appear before the node and have lower source positions. That's why we should move the node's source position to just cover the node itself.

@@ -234,65 +234,69 @@ def stable_quote_normalization_with_immediate_inner_single_quote(self):
```diff
--- Black
+++ Ruff
@@ -1,219 +1,105 @@
@@ -1,219 +1,149 @@
-class MyClass:
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 PR does not implement any special handling for docstrings yet.

@MichaReiser MichaReiser marked this pull request as ready for review June 8, 2023 11:01
@MichaReiser MichaReiser linked an issue Jun 8, 2023 that may be closed by this pull request
@MichaReiser MichaReiser force-pushed the format-function-definition branch from 875cd8b to 3c45cf3 Compare June 8, 2023 11:05
@MichaReiser MichaReiser requested a review from konstin June 8, 2023 11:07
crates/ruff_python_formatter/src/other/arg.rs Outdated Show resolved Hide resolved

write!(f, [if_group_breaks(&text(","))])?;

if let Some(last_node) = last_node {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if let Some(last_node) = last_node {
// Break group if there is a trailing comma
if let Some(last_node) = last_node {

Copy link
Member

Choose a reason for hiding this comment

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

Does this also need to read the magic trailing comma setting?

Copy link
Member Author

Choose a reason for hiding this comment

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

If we introduce a setting for this, then yes

Copy link
Member

Choose a reason for hiding this comment

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

i forgot this isn't merged: https://github.com/astral-sh/ruff/pull/4878/files#diff-c1f1071e384c9f14936cad67780f301345744791e34afd93cada2cf43af8dcb5R18

I haven't looked into how to pass settings, but i think it makes sense to introduce the boolean for that now

Copy link
Member Author

@MichaReiser MichaReiser Jun 8, 2023

Choose a reason for hiding this comment

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

The intended way for settings is that Ruff defines a PyFormatOption struct that implements FormatOptions and is passed to the PyFormatContext (instead of using the generic SimpleFormatOptions). You can then access it with f.context().options()....

https://github.com/charliermarsh/ruff/blob/dc7cdb04e17cd9aae7ab63976424b01bf040f8d3/crates/ruff_formatter/src/lib.rs#L257-L277

konstin added a commit that referenced this pull request Jun 8, 2023
This implements StmtPass as `pass`.

The snapshot diff is small because pass mainly occurs in bodies and function (#4951) and if/for bodies.
@konstin konstin mentioned this pull request Jun 8, 2023
konstin added a commit that referenced this pull request Jun 8, 2023
This implements StmtReturn as `return` or `return {value}`.

The snapshot diff is small because return occurs in functions (#4951)
@konstin konstin mentioned this pull request Jun 8, 2023
@MichaReiser MichaReiser force-pushed the format-function-definition branch from 3c45cf3 to 60dd48a Compare June 8, 2023 13:38
@MichaReiser MichaReiser mentioned this pull request Jun 8, 2023
konstin added a commit that referenced this pull request Jun 8, 2023
This implements StmtPass as `pass`.

The snapshot diff is small because pass mainly occurs in bodies and function (#4951) and if/for bodies.
konstin added a commit that referenced this pull request Jun 8, 2023
* Implement StmtPass

This implements StmtPass as `pass`.

The snapshot diff is small because pass mainly occurs in bodies and function (#4951) and if/for bodies.

* Implement StmtReturn

This implements StmtReturn as `return` or `return {value}`.

The snapshot diff is small because return occurs in functions (#4951)
@MichaReiser MichaReiser force-pushed the format-function-definition branch from 60dd48a to 26a4a83 Compare June 8, 2023 15:27
@MichaReiser MichaReiser force-pushed the format-function-definition branch from 26a4a83 to 3be5049 Compare June 8, 2023 15:34
Base automatically changed from simple-lexer to main June 8, 2023 15:37
@MichaReiser MichaReiser force-pushed the format-function-definition branch from 3be5049 to dcb2aaa Compare June 8, 2023 15:38
@MichaReiser MichaReiser enabled auto-merge (squash) June 8, 2023 15:38
@MichaReiser MichaReiser closed this Jun 8, 2023
auto-merge was automatically disabled June 8, 2023 15:54

Pull request was closed

@MichaReiser MichaReiser reopened this Jun 8, 2023
@MichaReiser MichaReiser force-pushed the format-function-definition branch from dcb2aaa to 3b8b3a9 Compare June 8, 2023 15:57
@MichaReiser MichaReiser enabled auto-merge (squash) June 8, 2023 15:57
@MichaReiser MichaReiser merged commit 6896924 into main Jun 8, 2023
@MichaReiser MichaReiser deleted the format-function-definition branch June 8, 2023 16:07
konstin added a commit that referenced this pull request Jun 13, 2023
This implements StmtPass as `pass`.

The snapshot diff is small because pass mainly occurs in bodies and function (#4951) and if/for bodies.
konstin added a commit that referenced this pull request Jun 13, 2023
* Implement StmtPass

This implements StmtPass as `pass`.

The snapshot diff is small because pass mainly occurs in bodies and function (#4951) and if/for bodies.

* Implement StmtReturn

This implements StmtReturn as `return` or `return {value}`.

The snapshot diff is small because return occurs in functions (#4951)
konstin pushed a commit that referenced this pull request Jun 13, 2023
@cnpryer cnpryer mentioned this pull request Jul 16, 2023
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
formatter Related to the formatter internal An internal refactor or improvement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FunctionDef / AsyncFunctionDef (Includes Arguments, and Arg)
2 participants