Skip to content
Snippets Groups Projects
Commit 61c3924d authored by 5j9's avatar 5j9
Browse files

Detect N806 errors in multiple assignment

This will, at least partly, resolve issue #29.
parent 771b0171
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -18,13 +18,14 @@ LOWERCASE_REGEX = re.compile(r'[_a-z][_a-z0-9]*$')
UPPERCASE_REGEX = re.compile(r'[_A-Z][_A-Z0-9]*$')
MIXEDCASE_REGEX = re.compile(r'_?[A-Z][a-zA-Z0-9]*$')
 
PY2 = sys.version_info[0] == 2
 
# Node types which may contain class methods
METHOD_CONTAINER_NODES = {ast.If, ast.While, ast.For, ast.With} | (
{ast.TryExcept, ast.TryFinally} if sys.version_info[0] == 2 else {ast.Try})
{ast.TryExcept, ast.TryFinally} if PY2 else {ast.Try})
 
 
if sys.version_info[0] < 3:
if PY2:
def _unpack_args(args):
ret = []
for arg in args:
Loading
Loading
@@ -356,16 +357,36 @@ class VariablesInFunctionCheck(BaseASTCheck):
break
else:
return
if isinstance(node.value, ast.Call):
if isinstance(node.value.func, ast.Attribute):
if node.value.func.attr == 'namedtuple':
return
elif isinstance(node.value.func, ast.Name):
if node.value.func.id == 'namedtuple':
return
for target in node.targets:
name = isinstance(target, ast.Name) and target.id
if not name or name in parent_func.global_names:
return
if not self.check(name) and name[:1] != '_':
if isinstance(node.value, ast.Call):
if isinstance(node.value.func, ast.Attribute):
if node.value.func.attr == 'namedtuple':
return
elif isinstance(node.value.func, ast.Name):
if node.value.func.id == 'namedtuple':
return
for name in _extract_names(target):
if name in parent_func.global_names:
continue
if self.check(name) or name[:1] == '_':
continue
yield self.err(target, 'N806', name)
def _extract_names(assignment_target):
"""Return assignment_target target ids."""
target_type = type(assignment_target)
if target_type is ast.Name:
yield assignment_target.id
return
if target_type in (ast.Tuple, ast.List):
for element in assignment_target.elts:
element_type = type(element)
if element_type is ast.Name:
yield element.id
elif element_type in (ast.Tuple, ast.List):
for n in _extract_names(element):
yield n
elif not PY2 and element_type is ast.Starred: # PEP 3132
for n in _extract_names(element.value):
yield n
Loading
Loading
@@ -46,3 +46,24 @@ def bad():
# Currently don't support aliased imports of namedtuple
from collections import namedtuple as nt
Thing = nt('Thing', 'a b c')
#: N806
def unpacking_into_tuple():
Var1, Var2 = range(2)
#: Okay
def unpacking_into_tuple():
var1, var2 = range(2)
#: N806
def unpacking_into_list():
[Var1, Var2] = range(2)
#: Okay
def unpacking_into_list():
[var1, var2] = range(2)
#: Okay
a, [b, c] = [1, [2, 3]]
#: N806
def recursive_unpack():
a, [bB, c] = [1, [2, 3]]
#: Okay
def assingnment_to_attribute():
a.b = 1
# python3 only
#: Okay
VAR1, *VAR2, VAR3 = 1, 2, 3
#: Okay
[VAR1, *VAR2, VAR3] = (1, 2, 3)
#: N806
def extended_unpacking_ok():
Var1, *Var2, Var3 = 1, 2, 3
#: N806
def extended_unpacking_not_ok():
[Var1, *Var2, Var3] = (1, 2, 3)
#: Okay
def assing_to_unpack_ok():
a, *[b] = 1, 2
#: N806
def assing_to_unpack_not_ok():
a, *[bB] = 1, 2
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment