diff options
author | Martin Pool <mbp@google.com> | 2013-02-26 23:17:31 +0100 |
---|---|---|
committer | Martin Pool <mbp@google.com> | 2013-02-26 23:17:31 +0100 |
commit | b4e221395733240b6e45861433e2d0bec1a2a615 (patch) | |
tree | 8924034a7dc7545e65365d0a49fb8b7ff2c9e911 | |
parent | abeafad3d1503dcaa0586369dfe591fb9dd3a466 (diff) | |
download | pylint-git-b4e221395733240b6e45861433e2d0bec1a2a615.tar.gz |
give [deprecated-lambda] when a map/filter of a lambda could be a comprehension. Closes #120657
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | checkers/base.py | 40 | ||||
-rw-r--r-- | test/input/func_deprecated_lambda.py | 22 | ||||
-rw-r--r-- | test/messages/func_deprecated_lambda.txt | 2 |
4 files changed, 65 insertions, 2 deletions
@@ -24,6 +24,9 @@ ChangeLog for PyLint * #112728: add warning E0604 for non-string objects in __all__ (patch by Torsten Marek) + * #120657: add warning W0110/deprecated-lambda when a map/filter + of a lambda could be a comprehension (patch by Martin Pool) + * #113231: logging checker now looks at instances of Logger classes in addition to the base logging module. (patch by Mike Bryant) diff --git a/checkers/base.py b/checkers/base.py index 3cd592267..41e4b931f 100644 --- a/checkers/base.py +++ b/checkers/base.py @@ -23,7 +23,12 @@ from logilab.astng import are_exclusive from pylint.interfaces import IASTNGChecker from pylint.reporters import diff_string from pylint.checkers import BaseChecker, EmptyReport -from pylint.checkers.utils import check_messages, clobber_in_except, is_inside_except +from pylint.checkers.utils import ( + check_messages, + clobber_in_except, + is_inside_except, + safe_infer, + ) import re @@ -798,7 +803,7 @@ class PassChecker(_BasicChecker): msgs = {'W0107': ('Unnecessary pass statement', 'unnecessary-pass', 'Used when a "pass" statement that can be avoided is ' - 'encountered.)'), + 'encountered.'), } def visit_pass(self, node): @@ -806,6 +811,36 @@ class PassChecker(_BasicChecker): self.add_message('W0107', node=node) +class LambdaForComprehensionChecker(_BasicChecker): + """check for using a lambda where a comprehension would do. + + See <http://www.artima.com/weblogs/viewpost.jsp?thread=98196> + where GvR says comprehensions would be clearer. + """ + + msgs = {'W0110': ('map/filter on lambda could be replaced by comprehension', + 'deprecated-lambda', + 'Used when a lambda is the first argument to "map" or ' + '"filter". It could be clearer as a list ' + 'comprehension or generator expression.'), + } + + @check_messages('W0110') + def visit_callfunc(self, node): + """visit a CallFunc node, check if map or filter are called with a + lambda + """ + if not node.args: + return + if not isinstance(node.args[0], astng.Lambda): + return + infered = safe_infer(node.func) + if (infered + and infered.parent.name == '__builtin__' + and infered.name in ['map', 'filter']): + self.add_message('W0110', node=node) + + def register(linter): """required method to auto register this checker""" linter.register_checker(BasicErrorChecker(linter)) @@ -813,3 +848,4 @@ def register(linter): linter.register_checker(NameChecker(linter)) linter.register_checker(DocStringChecker(linter)) linter.register_checker(PassChecker(linter)) + linter.register_checker(LambdaForComprehensionChecker(linter)) diff --git a/test/input/func_deprecated_lambda.py b/test/input/func_deprecated_lambda.py new file mode 100644 index 000000000..973bb320f --- /dev/null +++ b/test/input/func_deprecated_lambda.py @@ -0,0 +1,22 @@ +# pylint: disable=missing-docstring,bad-builtin,invalid-name +__revision__ = "$Id$" + +# Don't do this, use a comprehension instead. +assert map(lambda x: x*2, [1, 2, 3]) == [2, 4, 6] + +assert filter(lambda x: x != 1, [1, 2, 3]) == [2, 3] + +# It's still ok to use map and filter with anything but an inline lambda. +double = lambda x: x * 2 +assert map(double, [1, 2, 3]) == [2, 4, 6] + +# It's also ok to pass lambdas to other functions. +assert reduce(lambda x, y: x * y, [1, 2, 3, 4]) == 24 + +# Or to a undefined function or one with varargs +def f(*a): + return len(a) + +f(lambda x, y: x + y, [1, 2, 3]) + +undefined_function(lambda: 2) # pylint: disable=undefined-variable diff --git a/test/messages/func_deprecated_lambda.txt b/test/messages/func_deprecated_lambda.txt new file mode 100644 index 000000000..e7ecd5bda --- /dev/null +++ b/test/messages/func_deprecated_lambda.txt @@ -0,0 +1,2 @@ +W: 5: map/filter on lambda could be replaced by comprehension +W: 7: map/filter on lambda could be replaced by comprehension |