Skip to content

Commit

Permalink
Ignore additional complex duplicate-key cases
Browse files Browse the repository at this point in the history
  • Loading branch information
myint committed Jan 4, 2018
1 parent b5f223e commit 9dbef4f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 5 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
check:
pyflakes ./*.py
pyflakes autoflake.py setup.py test_autoflake.py
pylint \
--reports=no \
--rcfile=/dev/null \
--errors-only \
autoflake.py setup.py
pycodestyle ./*.py
pycodestyle autoflake.py setup.py test_autoflake.py
pydocstyle autoflake.py setup.py
check-manifest
python setup.py --long-description | rstcheck -
Expand Down
29 changes: 26 additions & 3 deletions autoflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,11 @@ def filter_code(source, additional_imports=None,
if remove_duplicate_keys:
marked_key_line_numbers = frozenset(
duplicate_key_line_numbers(messages))
if (
marked_key_line_numbers and
any_complex_duplicate_key_cases(marked_key_line_numbers, source)
):
marked_key_line_numbers = frozenset()
else:
marked_key_line_numbers = frozenset()

Expand Down Expand Up @@ -375,6 +380,22 @@ def filter_code(source, additional_imports=None,
previous_line = line


def any_complex_duplicate_key_cases(marked_line_numbers, source):
"""Return True if duplicate key lines contain complex code.
We don't want to bother trying to parse this stuff and get it right.
"""
lines = source.split('\n')
for line_number in marked_line_numbers:
line = lines[line_number - 1]

if line.rstrip().endswith((':', '\\')):
return True

if ':' not in line or '#' in line:
return True


def get_messages_by_line(messages):
"""Return dictionary that maps line number to message."""
line_messages = {}
Expand Down Expand Up @@ -467,9 +488,9 @@ def is_last_in_object(line, line_number, key, marked_line_numbers, source):
source
)

if len(obj_lines) <= 1:
# This means it is too complex for us to parse. Keep the item by
# assuming it is the last item.
if obj_lines is None or len(obj_lines) <= 1:
# We failed to parse something. Don't touch. Keep the item by assuming
# it is the last item.
return True

if line_number == obj_lines[-1]:
Expand All @@ -481,6 +502,8 @@ def is_last_in_object(line, line_number, key, marked_line_numbers, source):
def dict_entry_has_key(line, key):
"""Return True if `line` is a dict entry that uses `key`."""
result = re.match(r'\s*(.*)\s*:.*,?\s*$', line)
if not result:
return False

try:
candidate_key = ast.literal_eval(result.group(1))
Expand Down
35 changes: 35 additions & 0 deletions test_autoflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,41 @@ def test_filter_code_should_ignore_complex_case_of_duplicate_key(self):
(0,1): 3,
}
print(a)
"""

self.assertEqual(
code,
''.join(autoflake.filter_code(code,
remove_duplicate_keys=True)))

def test_filter_code_should_ignore_more_cases_of_duplicate_key(self):
"""We only handle simple cases."""
code = """\
a = {
(0,1):
1,
(0, 1): 'two',
(0,1): 3,
}
print(a)
"""

self.assertEqual(
code,
''.join(autoflake.filter_code(code,
remove_duplicate_keys=True)))

def test_filter_code_should_ignore_duplicate_key_with_comments(self):
"""We only handle simple cases."""
code = """\
a = {
(0,1) # : f
:
1,
(0, 1): 'two',
(0,1): 3,
}
print(a)
"""

self.assertEqual(
Expand Down

0 comments on commit 9dbef4f

Please sign in to comment.