diff --git a/shopify_python/google_styleguide.py b/shopify_python/google_styleguide.py index b3a1b42..12249c0 100644 --- a/shopify_python/google_styleguide.py +++ b/shopify_python/google_styleguide.py @@ -71,6 +71,10 @@ class GoogleStyleGuideChecker(checkers.BaseChecker): 'lambda-too-long', "Okay to use them for one-liners. If the code inside the lambda function is any longer than a " "certain length, it's probably better to define it as a regular (nested) function."), + 'C6012': ('Multiple generators in list comprehension', + 'complex-list-comp', + "Complicated list comprehensions or generator expressions can be hard to read; " + "don't use multiple 'for' keywords"), } options = ( @@ -105,6 +109,9 @@ def visit_excepthandler(self, node): # type: (astroid.ExceptHandler) -> None def visit_lambda(self, node): # type: (astroid.Lambda) -> None self.__use_simple_lambdas(node) + def visit_listcomp(self, node): # type: (astroid.ListComp) -> None + self.__use_simple_list_comp(node) + def visit_tryexcept(self, node): # type: (astroid.TryExcept) -> None self.__minimize_code_in_try_except(node) @@ -216,3 +223,8 @@ def __minimize_code_in_finally(self, node): # type: (astroid.TryFinally) -> Non def __use_simple_lambdas(self, node): # type: (astroid.Lambda) -> None if shopify_python.ast.count_tree_size(node) > self.config.max_lambda_nodes: # pylint: disable=no-member self.add_message('use-simple-lambdas', node=node) + + def __use_simple_list_comp(self, node): # type: (astroid.ListComp) -> None + """List comprehensions are okay to use for simple cases.""" + if len(node.generators) > 1: + self.add_message('complex-list-comp', node=node) diff --git a/tests/shopify_python/test_google_styleguide.py b/tests/shopify_python/test_google_styleguide.py index da1226d..3fa9d0d 100644 --- a/tests/shopify_python/test_google_styleguide.py +++ b/tests/shopify_python/test_google_styleguide.py @@ -186,3 +186,15 @@ def fnc(): message = pylint.testutils.Message('use-simple-lambdas', node=bad_list_comp) with self.assertAddsMessages(message): self.walk(root) + + def test_use_simple_list_comps(self): + root = astroid.builder.parse(""" + def fnc(): + good = [x for x in range(0,10)] + bad = [(x, y) for x in range(0,10) for y in range(0,10)] + """) + fnc = root.body[0] + bad_list_comp = fnc.body[1].value + message = pylint.testutils.Message('complex-list-comp', node=bad_list_comp) + with self.assertAddsMessages(message): + self.walk(root)