-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Extend R1735 use-dict-literal to highlight all usages of dict that can be replaced with a literal #7691
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
Extend R1735 use-dict-literal to highlight all usages of dict that can be replaced with a literal #7691
Conversation
|
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.
Thank you for bringing a proof of concept with the issue 👌
I was also wondering if we should just extend what the existing message is doing or create another one. The former prevent user that don't want the new thing to disable it, but the second one add confusion. We could also rename the existing message to make things clearer and have the best of both world (?)
Regarding code suggestion, we should be careful to not create a behemoth message if the input dict is big we don't want a 400 lines message.
Pull Request Test Coverage Report for Build 3426938040
💛 - Coveralls |
My personal opinion would be: Keep the name and code. Extend the functionality of the existing message. The name fits for both situations anyway. People should expect new lint messages when upgrading the pylint package. But it's easy for me to say 😀 I don't have to work with huge code bases. |
Regarding the failing "readthedocs" build:
No idea what to do here. My branch is up-to-date. Do I need to add anything else to the docs? Or is this related to the changes in |
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.
Made some comments, I'm waiting for other maintainer opinion regarding the new message or the extension of the old one :)
This comment has been minimized.
This comment has been minimized.
There is surprisingly few violation on the primer which is a very good sign. The primer for sentry:
https://github.com/getsentry/sentry/blob/4be98deb27375dac541740b9c8d7ce871ff2bc99/src/sentry/api/endpoints/organization_sdk_updates.py#L44 |
I like the suggestion of extending the previous message! |
I fixed those and added test cases. The code suggestion is now constructed "manually" to be able to handle |
This comment has been minimized.
This comment has been minimized.
If you have the final say, I will go ahead. Or will others want to chime in? |
They obviously can (and are encouraged to do so of course), but I think two maintainers thinking positively about this is a good sign to go ahead 😄 |
It happened in the past that 2 maintainers agreed on something and another one made an argument so good we changed our mind but it's pretty rare 😄 |
Ok, so I did the following:
Important! The confidence level of an existing message changesWhile it was still a separate message, we set the confidence to |
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 looks pretty good already, thank you !
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
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.
Just some minor comments from my side. Looks good to me overall!
I'm also +1 for extending the existing message.
I'm still unsure about the wording in Btw. because I was curious I did a similar performance test with list joining compared to string concatenation: https://gist.github.com/hofrob/95b0d31ee4e168b876ecf82c92db2df4 Since we're using this in when creating the suggestion, I will leave it is. |
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 is looking better and better 🔥
self._check_use_list_literal(node) | ||
self._check_use_dict_literal(node) |
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.
The call to inferred = utils.safe_infer(node.func)
is pretty costly, I think we should keep list/dict together for better performance.
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 don't think we will prevent any calls to utils.safe_infer
in this case. The list-check _check_use_list_literal
will only do it if node.as_string() == "list()"
and _check_use_dict_literal
will always do it if isinstance(node.func, astroid.Name)
¹.
The only thing we could improve are the checks _check_use_dict_literal
¹, right? Doing both in one method will not have any effect. Or will it?
¹: I added a check there now: node.as_string().startswith("dict(")
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 added a check there now: node.as_string().startswith("dict(")
That "solution" sucks. I will do node.func.name != 'dict'
.
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.
Of course, this won't work for the following code:
foo = dict
new_dict = foo(asdf=1)
But I think we can live with it for performance reasons?
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 don't think we will prevent any calls to utils.safe_infer in this case. The list-check _check_use_list_literal will only do it if node.as_string() == "list()"
Fair point, I missed that.
Of course, this won't work for the following code:
foo = dict
new_dict = foo(asdf=1)But I think we can live with it for performance reasons?
Yes definitely. Let's not punish everyone with slower linter to be accurate for those who redefine dict. They don't deserve a linter anyway 😄
Sorry for the confusion - I actually liked that concrete number here, as it showed that we are not just talking about a 0.x % increase. I simply meant to add the Python version additionally, so we know in the future to what version this benchmark referred to. |
This comment has been minimized.
This comment has been minimized.
Sorry for the delay! I'm dealing with separate things for the moment. Thanks for the feedback for now! I hope I'll be able to take another look in the course of the next week. |
Sorry, this was from a quick DM with @Pierre-Sassoulas. I added it back now:
|
This comment has been minimized.
This comment has been minimized.
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.
The primer looks pretty good now, there's a case when the last argument under a certain length is very long that does not get truncated:
Consider using '{"by": dict(((key, reverse_resolve_tag_value(self._use_case_id, self._organization_id, value, weak=True)) if groupby_alias_to_groupby_column.get(key) not in NON_RESOLVABLE_TAG_VALUES else (key, value) for (key, value) in tags)), … }' instead of a call to 'dict'.
But I think it's acceptable.
Great first contribution @hofrob, this is definitely going in 2.16.0 :)
self._check_use_list_literal(node) | ||
self._check_use_dict_literal(node) |
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 don't think we will prevent any calls to utils.safe_infer in this case. The list-check _check_use_list_literal will only do it if node.as_string() == "list()"
Fair point, I missed that.
Of course, this won't work for the following code:
foo = dict
new_dict = foo(asdf=1)But I think we can live with it for performance reasons?
Yes definitely. Let's not punish everyone with slower linter to be accurate for those who redefine dict. They don't deserve a linter anyway 😄
This test fail under Windows seems genuine. |
Ah yes. This may have failed because of the ellipsis character I replaced it with dots |
FYI: I replaced all ellipsis characters with dots since there seems to be an issue with windows. Details: When running the test |
Ha, right, probably the same encoding issue than with emojis in #7612. No need to use a unicode character for ellipsis, three dots are just fine. |
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.
Love this change! Thanks very much!
Type of Changes
Description
Refs #7690
Closes #7690