@@ -1423,28 +1423,58 @@ def ambiguous_identifier(logical_line, tokens):
14231423
14241424 Variables can be bound in several other contexts, including class
14251425 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.
14271428
14281429 Okay: except AttributeError as o:
14291430 Okay: with lock as L:
1431+ Okay: foo(l=12)
1432+ Okay: for a in foo(l=12):
14301433 E741: except AttributeError as O:
14311434 E741: with lock as l:
14321435 E741: global I
14331436 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):
14341441 E742: class I(object):
14351442 E743: def l(x):
14361443 """
1444+ is_func_def = False # Set to true if 'def' is found
1445+ parameter_parentheses_level = 0
14371446 idents_to_avoid = ('l' , 'O' , 'I' )
14381447 prev_type , prev_text , prev_start , prev_end , __ = tokens [0 ]
14391448 for token_type , text , start , end , line in tokens [1 :]:
14401449 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
14411464 # 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 :
14431467 if prev_text in idents_to_avoid :
14441468 ident = prev_text
14451469 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 :
14481478 if text in idents_to_avoid :
14491479 ident = text
14501480 pos = start
@@ -1456,6 +1486,7 @@ def ambiguous_identifier(logical_line, tokens):
14561486 yield start , "E743 ambiguous function definition '%s'" % text
14571487 if ident :
14581488 yield pos , "E741 ambiguous variable name '%s'" % ident
1489+ prev_type = token_type
14591490 prev_text = text
14601491 prev_start = start
14611492
0 commit comments