@@ -1423,28 +1423,58 @@ def ambiguous_identifier(logical_line, tokens):
1423
1423
1424
1424
Variables can be bound in several other contexts, including class
1425
1425
and function definitions, 'global' and 'nonlocal' statements,
1426
- exception handlers, and 'with' statements.
1426
+ exception handlers, and 'with' and 'for' statements.
1427
+ In addition, we have a special handling for function parameters.
1427
1428
1428
1429
Okay: except AttributeError as o:
1429
1430
Okay: with lock as L:
1431
+ Okay: foo(l=12)
1432
+ Okay: for a in foo(l=12):
1430
1433
E741: except AttributeError as O:
1431
1434
E741: with lock as l:
1432
1435
E741: global I
1433
1436
E741: nonlocal l
1437
+ E741: def foo(l):
1438
+ E741: def foo(l=12):
1439
+ E741: l = foo(l=12)
1440
+ E741: for l in range(10):
1434
1441
E742: class I(object):
1435
1442
E743: def l(x):
1436
1443
"""
1444
+ is_func_def = False # Set to true if 'def' is found
1445
+ parameter_parentheses_level = 0
1437
1446
idents_to_avoid = ('l' , 'O' , 'I' )
1438
1447
prev_type , prev_text , prev_start , prev_end , __ = tokens [0 ]
1439
1448
for token_type , text , start , end , line in tokens [1 :]:
1440
1449
ident = pos = None
1450
+ # find function definitions
1451
+ if prev_text == 'def' :
1452
+ is_func_def = True
1453
+ # update parameter parentheses level
1454
+ if parameter_parentheses_level == 0 and \
1455
+ prev_type == tokenize .NAME and \
1456
+ token_type == tokenize .OP and text == '(' :
1457
+ parameter_parentheses_level = 1
1458
+ elif parameter_parentheses_level > 0 and \
1459
+ token_type == tokenize .OP :
1460
+ if text == '(' :
1461
+ parameter_parentheses_level += 1
1462
+ elif text == ')' :
1463
+ parameter_parentheses_level -= 1
1441
1464
# identifiers on the lhs of an assignment operator
1442
- if token_type == tokenize .OP and '=' in text :
1465
+ if token_type == tokenize .OP and '=' in text and \
1466
+ parameter_parentheses_level == 0 :
1443
1467
if prev_text in idents_to_avoid :
1444
1468
ident = prev_text
1445
1469
pos = prev_start
1446
- # identifiers bound to values with 'as', 'global', or 'nonlocal'
1447
- if prev_text in ('as' , 'global' , 'nonlocal' ):
1470
+ # identifiers bound to values with 'as', 'for',
1471
+ # 'global', or 'nonlocal'
1472
+ if prev_text in ('as' , 'for' , 'global' , 'nonlocal' ):
1473
+ if text in idents_to_avoid :
1474
+ ident = text
1475
+ pos = start
1476
+ # function parameter definitions
1477
+ if is_func_def :
1448
1478
if text in idents_to_avoid :
1449
1479
ident = text
1450
1480
pos = start
@@ -1456,6 +1486,7 @@ def ambiguous_identifier(logical_line, tokens):
1456
1486
yield start , "E743 ambiguous function definition '%s'" % text
1457
1487
if ident :
1458
1488
yield pos , "E741 ambiguous variable name '%s'" % ident
1489
+ prev_type = token_type
1459
1490
prev_text = text
1460
1491
prev_start = start
1461
1492
0 commit comments