Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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
Add RUF016: Detection of invalid index types #5602
Add RUF016: Detection of invalid index types #5602
Changes from 17 commits
dd6f4db
521ebbe
4c61297
0521648
359fef8
f9a4809
6a7aa1a
ccfab1d
bdeb8c7
0280bd2
2360d00
f016250
39a6924
9b78e88
26f4f68
e65e9ba
983d381
5b7030c
7743c8e
933661f
e058e24
File filter
Filter by extension
Conversations
Jump to
There are no files selected for viewing
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.
@charliermarsh I retained this expect because I'd rather not silently return in this case. A developer has broken this rule if the type is not checkable.
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.
To me it would be a bit more natural to do this before the
if !matches
(likelet Some(value_type) = ... else { return; };
), then have anif !matches(value_type, CheckableExprType::List | ...)
to enforce the further narrowing. That way theexpect
is unnecessary as the condition is impossible. But it's not blocking.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.
I did this before then moved it back to an
expect
, I feel like it confuses the logic of the rule. Like...If the value is a list, byte, string, or tuple then we want to enforce this rule.
To display a violation, we happen to use
CheckableExprType
to generate a type name for the value. However, this is just for display purposes not a limitation of the rule itself.If someone were to extend the rule to apply to a new type, e.g. byte arrays, I would not expect this function to exit early because there is not an implementation for displaying the type name. In this case, the
expect
would point a developer to the next step in their implementation.🤷♀️ it does feel like a subtle stylistic choice in the end — maybe you shouldn't have sent me that BurntSushi article 😝
I'm kind of curious to see what lessons I learn from making my own stylistic choices but I'm happy to follow precedent for the project too!
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 makes sense. I'd say run with what you have here! I tend to be pretty defensive around
expect
andunwrap
(which are ~equivalent) because they're not recoverable in any way, so e.g. if we shipped a release that had an oversight here, Ruff would bail entirely on files that hit this codepath.The "right" answer here may be to extend
CheckableExprType
to instead implement all expression types (so it doesn't returnOption
), or perhaps to use a debug assertion so that we see this failure in debug builds but fail silently in releases. But it's also ok for now, we know that it's a superset of expressions on thematch
anyway. (And we're obviously overdoing it on this one point just for educational / discussion purposes, it's not a sticking point in practice :))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.
I'm pretty happy with that as an approach.
Although... I'd also want a user to report a failure here because it's a bug in Ruff. I guess it's a matter of if we want to panic and make the rule entirely unusable for their code or fail silently and hope they notice that the rule isn't raising a violation. I can understand preferring the second as a safer user experience :)
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.
I wanted
debug_panic!(...)
but I guessdebug_assert!(false, ...)
will do e058e24There 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.
I'm happy with whatever! If it were me on a desert island, I guess I'd write something like
let Some(value_type) = CheckableExprType::try_from(value) else { return; };
but I'm not convinced that's the best option. This looks good to me.(Again just to complete the picture, I think if we hit a panic here, the behavior the user would see is that we'd throw up a message asking them to file an issue and wouldn't print any violations for the failing file, but would print out violations for all other files as usual.)