Skip to content

Commit 9c95b9c

Browse files
committed
introduce A005 for lambda
1 parent cb97ac8 commit 9c95b9c

File tree

2 files changed

+30
-3
lines changed

2 files changed

+30
-3
lines changed

flake8_builtins.py

+20-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class BuiltinsChecker:
1212
argument_msg = 'A002 argument "{0}" is shadowing a Python builtin'
1313
class_attribute_msg = 'A003 class attribute "{0}" is shadowing a Python builtin'
1414
import_msg = 'A004 import statement "{0}" is shadowing a Python builtin'
15+
lambda_argument_msg = 'A005 lambda argument "{0}" is shadowing a Python builtin'
1516

1617
names = []
1718
ignore_list = {
@@ -58,7 +59,7 @@ def run(self):
5859
for child in ast.iter_child_nodes(statement):
5960
child.__flake8_builtins_parent = statement
6061

61-
function_nodes = [ast.FunctionDef, ast.Lambda]
62+
function_nodes = [ast.FunctionDef]
6263
if getattr(ast, 'AsyncFunctionDef', None):
6364
function_nodes.append(ast.AsyncFunctionDef)
6465
function_nodes = tuple(function_nodes)
@@ -88,6 +89,9 @@ def run(self):
8889
elif isinstance(statement, function_nodes):
8990
value = self.check_function_definition(statement)
9091

92+
elif isinstance(statement, ast.Lambda):
93+
value = self.check_lambda_definition(statement)
94+
9195
elif isinstance(statement, for_nodes):
9296
value = self.check_for_loop(statement)
9397

@@ -136,7 +140,7 @@ def check_assignment(self, statement):
136140
stack.extend(list(item.value.elts))
137141

138142
def check_function_definition(self, statement):
139-
if not isinstance(statement, ast.Lambda) and statement.name in self.names:
143+
if statement.name in self.names:
140144
msg = self.assign_msg
141145
if type(statement.__flake8_builtins_parent) is ast.ClassDef:
142146
msg = self.class_attribute_msg
@@ -156,6 +160,20 @@ def check_function_definition(self, statement):
156160
variable=arg.arg,
157161
)
158162

163+
def check_lambda_definition(self, statement):
164+
all_arguments = []
165+
all_arguments.extend(statement.args.args)
166+
all_arguments.extend(getattr(statement.args, 'kwonlyargs', []))
167+
all_arguments.extend(getattr(statement.args, 'posonlyargs', []))
168+
169+
for arg in all_arguments:
170+
if isinstance(arg, ast.arg) and arg.arg in self.names:
171+
yield self.error(
172+
arg,
173+
message=self.lambda_argument_msg,
174+
variable=arg.arg,
175+
)
176+
159177
def check_for_loop(self, statement):
160178
stack = [statement.target]
161179
while stack:

run_tests.py

+10-1
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def bla(list):
142142

143143
def test_lambda_argument_message():
144144
source = 'takefirst = lambda list: list[0]'
145-
check_code(source, 'A002')
145+
check_code(source, 'A005')
146146

147147

148148
def test_keyword_argument_message():
@@ -171,6 +171,15 @@ def bla(list, /):
171171
"""
172172
check_code(source, 'A002')
173173

174+
@pytest.mark.skipif(
175+
sys.version_info < (3, 8),
176+
reason='This syntax is only valid in Python 3.8+',
177+
)
178+
def test_lambda_posonly_argument_message():
179+
source = """
180+
takefirst = lambda list, /: list[0]
181+
"""
182+
check_code(source, 'A005')
174183

175184
def test_no_error():
176185
source = """def bla(first):\n b = 4"""

0 commit comments

Comments
 (0)