-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Implemented new check use-maxsplit-arg
#4469
Conversation
Leaving this as draft as a moment because I'm having difficulty with a particular test case: import os
path = "/home/"
dirs = os.listdirs(path)
extensions = [d.split(".")[-1] for d in dirs if "." in d] # should fire an error It seems like the d in this case can't be inferred as a string, and the .split() is also uninferrable -- however we know that os.listdirs returns a list of string. Therefore I'm somewhat stuck at the moment -- will experiment around and see if I could fix it |
consider-using-str-partition
It seems like some output of functions might not be infer-able, during my debugging process I found this and it seems like the return type information is not available for I'm not entirely sure if there's a utility function to check, but for now I will be changing this PR to be ready for review |
Further investigation further confirming difficulties with determining type of iterable returned from functions: list_of_strs = ["a", "b", "c", "d", "e", "f"]
for s in list_of_strs:
print(s.split(" ")[0]) # [consider-using-str-partition]
print(s.split(" ")[-1]) # [consider-using-str-partition]
print(s.split(" ")[-2])
my_dict = {"a":0, "b": 0, "c": 0, "d": 0, "e": 0, "f":0}
for s in my_dict:
print(s.split(" ")[0]) # [consider-using-str-partition] (NOT FIRED)
print(s.split(" ")[-1]) # [consider-using-str-partition] (NOT FIRED)
print(s.split(" ")[-2]) |
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.
Some initial comments.
--
import os path = "/home/" dirs = os.listdirs(path) extensions = [d.split(".")[-1] for d in dirs if "." in d] # should fire an errorIt seems like the d in this case can't be inferred as a string, and the .split() is also uninferrable -- however we know that os.listdirs returns a list of string.
Therefore I'm somewhat stuck at the moment -- will experiment around and see if I could fix it
I won't worry too much about this. It's probably best to just ignore everything that can't easily be inferred.
@cdce8p could I get another initial review on this? Have re-implemented as discussed -- but still in the midst of performing some refactoring (moving some code into utils) |
consider-using-str-partition
consider-using-maxsplit-arg
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.
Very nice checker, and the non-opinionated performance checks are always a pleasure to merge. Thanks a lot for handling all the comments during the review. The design on this one got better and better thanks to your perseverance. Probably the main feature in 2.8.3
!
Co-authored-by: Pierre Sassoulas <[email protected]>
thanks for the kind words :) |
consider-using-maxsplit-arg
use-maxsplit-arg
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.
It looks so good.. Unfortunately I noticed one small issue during the final test run. (See comment below)
FYI: I also pushed a small commit with formatting changes. It wouldn't have been worth it to mention these changes individually.
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.
They might be a bit contrived but I found two more cases that won't work properly:
"1,2,3".split('split')[-1]
"1,2,3".rsplit('rsplit')[0]
With the current logic, the separator will be replaced instead of the function name.
Some ideas
- Use
node.func.as_string()
and callrsplit
on it instead - I didn't know that myself, but whereas
utils.get_argument_from_call(node, 0, "sep").value
returns the unescaped separator, you can useutils.get_argument_from_call(node, 0, "sep").as_string()
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.
It's done! Tremendous work you did here @yushao2 🥇
The review process wasn't the easiest but you still did a really good job getting this one over the finish line. The next release will be awesome in no small part thanks to you 🐬
Will have to look at #4485 now I guess 😉 Can't be that you only contributed two new checkers for one release.
Steps
doc/whatsnew/<current release.rst>
.Description
Implemented a new checker,
consider-using-str-partition
, which checks for instances whereonly the first or last element of a
str.split()
is accessedType of Changes
Related Issue
Closes #4440
Notes:
It seems like the check has difficulty detecting if something is a string or not when iterating over an iterable of strings that is returned from a function. See:
#4469 (comment)
#4469 (comment)
#4469 (comment)
That being said, I'm not too sure how to resolve these specific cases, or if the checker is alright as it is -- I'm just worried that it might be a bit too "weak" for the cases mentioned. Thanks!