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

Introduce an Arguments AST node for function calls and class definitions #6259

Merged
merged 3 commits into from
Aug 2, 2023

Conversation

charliermarsh
Copy link
Member

Summary

This PR adds a new Arguments AST node, which we can use for function calls and class definitions.

The Arguments node spans from the left (open) to right (close) parentheses inclusive.

In the case of classes, the Arguments is an option, to differentiate between:

# None
class C: ...

# Some, with empty vectors
class C(): ...

In this PR, we don't really leverage this change (except that a few rules get much simpler, since we don't need to lex to find the start and end ranges of the parentheses, e.g., crates/ruff/src/rules/pyupgrade/rules/lru_cache_without_parameters.rs, crates/ruff/src/rules/pyupgrade/rules/unnecessary_class_parentheses.rs).

In future PRs, this will be especially helpful for the formatter, since we can track comments enclosed on the node itself.

Test Plan

cargo test

args,
keywords,
range: _,
},
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 tended to favor destructuring to minimize code changes (i.e., we didn't have to change this method at all, only the let match here).

decorator.expression.range(),
diagnostic.set_fix(Fix::automatic(Edit::deletion(
arguments.start(),
arguments.end(),
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 is an improvement (delete from left to right parens).

diagnostic.set_fix(Fix::automatic(Edit::deletion(
arguments.start(),
arguments.end(),
)));
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 is way simpler (delete from left to right paren).

@github-actions
Copy link
Contributor

github-actions bot commented Aug 1, 2023

PR Check Results

Ecosystem

✅ ecosystem check detected no changes.

Benchmark

Linux

group                                      main                                   pr
-----                                      ----                                   --
formatter/large/dataset.py                 1.01      8.4±0.11ms     4.9 MB/sec    1.00      8.3±0.06ms     4.9 MB/sec
formatter/numpy/ctypeslib.py               1.00  1634.6±14.00µs    10.2 MB/sec    1.00   1633.7±6.80µs    10.2 MB/sec
formatter/numpy/globals.py                 1.01    182.9±1.78µs    16.1 MB/sec    1.00    181.9±0.93µs    16.2 MB/sec
formatter/pydantic/types.py                1.00      3.5±0.10ms     7.2 MB/sec    1.01      3.6±0.09ms     7.2 MB/sec
linter/all-rules/large/dataset.py          1.02     11.4±0.11ms     3.6 MB/sec    1.00     11.2±0.16ms     3.6 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.00      2.8±0.01ms     5.9 MB/sec    1.00      2.8±0.03ms     5.9 MB/sec
linter/all-rules/numpy/globals.py          1.00    385.6±0.95µs     7.7 MB/sec    1.00    385.3±0.82µs     7.7 MB/sec
linter/all-rules/pydantic/types.py         1.00      5.0±0.05ms     5.1 MB/sec    1.00      5.0±0.09ms     5.1 MB/sec
linter/default-rules/large/dataset.py      1.00      5.8±0.03ms     7.0 MB/sec    1.00      5.8±0.06ms     7.0 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.00   1202.7±2.86µs    13.8 MB/sec    1.00   1197.9±7.69µs    13.9 MB/sec
linter/default-rules/numpy/globals.py      1.01    133.6±0.27µs    22.1 MB/sec    1.00    132.5±0.30µs    22.3 MB/sec
linter/default-rules/pydantic/types.py     1.00      2.6±0.01ms    10.0 MB/sec    1.00      2.5±0.03ms    10.0 MB/sec

Windows

group                                      main                                   pr
-----                                      ----                                   --
formatter/large/dataset.py                 1.02     10.0±0.07ms     4.1 MB/sec    1.00      9.9±0.07ms     4.1 MB/sec
formatter/numpy/ctypeslib.py               1.02  1934.6±19.59µs     8.6 MB/sec    1.00  1905.6±18.66µs     8.7 MB/sec
formatter/numpy/globals.py                 1.00    200.4±2.28µs    14.7 MB/sec    1.01    202.8±7.03µs    14.5 MB/sec
formatter/pydantic/types.py                1.02      4.3±0.04ms     5.9 MB/sec    1.00      4.2±0.03ms     6.0 MB/sec
linter/all-rules/large/dataset.py          1.00     13.4±0.09ms     3.0 MB/sec    1.00     13.5±0.10ms     3.0 MB/sec
linter/all-rules/numpy/ctypeslib.py        1.00      3.6±0.02ms     4.6 MB/sec    1.00      3.6±0.02ms     4.6 MB/sec
linter/all-rules/numpy/globals.py          1.00    364.8±5.04µs     8.1 MB/sec    1.00    363.4±5.01µs     8.1 MB/sec
linter/all-rules/pydantic/types.py         1.00      6.1±0.05ms     4.2 MB/sec    1.00      6.1±0.04ms     4.2 MB/sec
linter/default-rules/large/dataset.py      1.00      7.3±0.05ms     5.6 MB/sec    1.01      7.4±0.05ms     5.5 MB/sec
linter/default-rules/numpy/ctypeslib.py    1.00  1459.4±11.95µs    11.4 MB/sec    1.02  1485.6±14.38µs    11.2 MB/sec
linter/default-rules/numpy/globals.py      1.00    145.8±3.77µs    20.2 MB/sec    1.00    146.2±1.60µs    20.2 MB/sec
linter/default-rules/pydantic/types.py     1.00      3.2±0.03ms     7.9 MB/sec    1.00      3.2±0.02ms     7.9 MB/sec

@charliermarsh
Copy link
Member Author

(I am going to leverage these in the formatter in a separate change, to fix the trailing comment bug we have today.)

Copy link
Member

@konstin konstin left a comment

Choose a reason for hiding this comment

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

skimmed through it

@charliermarsh charliermarsh merged commit 981e64f into main Aug 2, 2023
17 checks passed
@charliermarsh charliermarsh deleted the charlie/class-base-comments branch August 2, 2023 14:01
charliermarsh added a commit that referenced this pull request Aug 2, 2023
## Summary

Similar to #6259, this PR adds a `TypeParams` node to the AST, to
capture the list of type parameters with their surrounding brackets.

If a statement lacks type parameters, the `type_params` field will be
`None`.
charliermarsh added a commit that referenced this pull request Aug 2, 2023
## Summary

This PR leverages the `Arguments` AST node introduced in #6259 in the
formatter, which ensures that we correctly handle trailing comments in
calls, like:

```python
f(
  1,
  # comment
)

pass
```

(Previously, this was treated as a leading comment on `pass`.)

This also allows us to unify the argument handling across calls and
class definitions.

## Test Plan

A bunch of new fixture tests, plus improved Black compatibility.
Comment on lines +169 to +175
pub fn bases(&self) -> impl Iterator<Item = &Expr> {
self.arguments
.as_ref()
.map(|arguments| &arguments.args)
.into_iter()
.flatten()
}
Copy link
Member

@MichaReiser MichaReiser Aug 3, 2023

Choose a reason for hiding this comment

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

Nit: We could return a slice here by using

Suggested change
pub fn bases(&self) -> impl Iterator<Item = &Expr> {
self.arguments
.as_ref()
.map(|arguments| &arguments.args)
.into_iter()
.flatten()
}
pub fn bases(&self) -> &[Expr] {
match &self.arguments {
Some(arguments) => &arguments.args,
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.

Good call.

@@ -2951,9 +3003,9 @@ mod size_assertions {
use super::*;
use static_assertions::assert_eq_size;

assert_eq_size!(Stmt, [u8; 168]);
assert_eq_size!(Stmt, [u8; 176]);
Copy link
Member

Choose a reason for hiding this comment

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

👀

charliermarsh added a commit that referenced this pull request Aug 3, 2023
Slices are strictly more flexible, since you can always convert to an
iterator, etc., but not the other way around. Suggested in
#6259 (comment).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants