diff options
author | Ikraduya Edian <ikraduya@gmail.com> | 2021-02-20 21:50:19 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-20 15:50:19 +0100 |
commit | 45c824549f9a7fa38df04ae8648d1647c82ba9b4 (patch) | |
tree | c6d05e8979245ddb0c5ed84437ac8219616858bb /pylint/checkers/refactoring/refactoring_checker.py | |
parent | 570e65536147b00ab8a5743e761d7caa326afa21 (diff) | |
download | pylint-git-45c824549f9a7fa38df04ae8648d1647c82ba9b4.tar.gz |
Add new `consider-using-generator` and 'use-a-generator' checkers
See issue #3165 (#3309)
See https://github.com/PyCQA/pylint/pull/3309#discussion_r576683109
Co-authored-by: Pierre Sassoulas <pierre.sassoulas@gmail.com>
Co-authored-by: Daniel Hahler <github@thequod.de>
Diffstat (limited to 'pylint/checkers/refactoring/refactoring_checker.py')
-rw-r--r-- | pylint/checkers/refactoring/refactoring_checker.py | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/pylint/checkers/refactoring/refactoring_checker.py b/pylint/checkers/refactoring/refactoring_checker.py index 81bb18213..07d9d5f58 100644 --- a/pylint/checkers/refactoring/refactoring_checker.py +++ b/pylint/checkers/refactoring/refactoring_checker.py @@ -1,4 +1,22 @@ # -*- coding: utf-8 -*- +# Copyright (c) 2016-2018 Claudiu Popa <pcmanticore@gmail.com> +# Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com> +# Copyright (c) 2016 Moises Lopez <moylop260@vauxoo.com> +# Copyright (c) 2016 Alexander Todorov <atodorov@otb.bg> +# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com> +# Copyright (c) 2017 Ville Skyttä <ville.skytta@iki.fi> +# Copyright (c) 2017-2018 Bryce Guinta <bryce.paul.guinta@gmail.com> +# Copyright (c) 2017 Hugo <hugovk@users.noreply.github.com> +# Copyright (c) 2017 Łukasz Sznuk <ls@rdprojekt.pl> +# Copyright (c) 2017 Alex Hearn <alex.d.hearn@gmail.com> +# Copyright (c) 2017 Antonio Ossa <aaossa@uc.cl> +# Copyright (c) 2018 Konstantin Manna <Konstantin@Manna.uno> +# Copyright (c) 2018 Konstantin <Github@pheanex.de> +# Copyright (c) 2018 Sushobhit <31987769+sushobhit27@users.noreply.github.com> +# Copyright (c) 2018 Matej Marušák <marusak.matej@gmail.com> +# Copyright (c) 2018 Ville Skyttä <ville.skytta@upcloud.com> +# Copyright (c) 2018 Mr. Senko <atodorov@mrsenko.com> +# Copyright (c) 2019 Ikraduya Edian <ikraduya@gmail.com> # Licensed under the GPL: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html # For details: https://github.com/PyCQA/pylint/blob/master/COPYING @@ -282,6 +300,18 @@ class RefactoringChecker(checkers.BaseTokenChecker): "Emitted when calling the super() builtin with the current class " "and instance. On Python 3 these arguments are the default and they can be omitted.", ), + "R1728": ( + "Consider using a generator instead '%s(%s)'", + "consider-using-generator", + "If your container can be large using " + "a generator will bring better performance.", + ), + "R1729": ( + "Use a generator instead '%s(%s)'", + "use-a-generator", + "Comprehension inside of 'any' or 'all' is unnecessary. " + "A generator would be sufficient and faster.", + ), } options = ( ( @@ -684,18 +714,49 @@ class RefactoringChecker(checkers.BaseTokenChecker): message_name = "consider-using-set-comprehension" self.add_message(message_name, node=node) + def _check_consider_using_generator(self, node): + # 'any' and 'all' definitely should use generator, while 'list' and 'tuple' need to be considered first + # See https://github.com/PyCQA/pylint/pull/3309#discussion_r576683109 + checked_call = ["any", "all", "list", "tuple"] + if ( + isinstance(node, astroid.Call) + and node.func + and isinstance(node.func, astroid.Name) + and node.func.name in checked_call + ): + # functions in checked_calls take exactly one argument + # check whether the argument is list comprehension + if len(node.args) == 1 and isinstance(node.args[0], astroid.ListComp): + # remove square brackets '[]' + inside_comp = node.args[0].as_string()[1:-1] + call_name = node.func.name + if call_name in ["any", "all"]: + self.add_message( + "use-a-generator", + node=node, + args=(call_name, inside_comp), + ) + else: + self.add_message( + "consider-using-generator", + node=node, + args=(call_name, inside_comp), + ) + @utils.check_messages( "stop-iteration-return", "consider-using-dict-comprehension", "consider-using-set-comprehension", "consider-using-sys-exit", "super-with-arguments", + "consider-using-generator", ) def visit_call(self, node): self._check_raising_stopiteration_in_generator_next_call(node) self._check_consider_using_comprehension_constructor(node) self._check_quit_exit_call(node) self._check_super_with_arguments(node) + self._check_consider_using_generator(node) @staticmethod def _has_exit_in_scope(scope): |