| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| 1 # This file is part of Adblock Plus <https://adblockplus.org/>, | 1 # This file is part of Adblock Plus <https://adblockplus.org/>, |
| 2 # Copyright (C) 2006-present eyeo GmbH | 2 # Copyright (C) 2006-present eyeo GmbH |
| 3 # | 3 # |
| 4 # Adblock Plus is free software: you can redistribute it and/or modify | 4 # Adblock Plus is free software: you can redistribute it and/or modify |
| 5 # it under the terms of the GNU General Public License version 3 as | 5 # it under the terms of the GNU General Public License version 3 as |
| 6 # published by the Free Software Foundation. | 6 # published by the Free Software Foundation. |
| 7 # | 7 # |
| 8 # Adblock Plus is distributed in the hope that it will be useful, | 8 # Adblock Plus is distributed in the hope that it will be useful, |
| 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 'unordered data')) | 280 'unordered data')) |
| 281 | 281 |
| 282 consts_first = single and not membership or symmetric | 282 consts_first = single and not membership or symmetric |
| 283 if consts_first and is_const(left) and not is_const(right): | 283 if consts_first and is_const(left) and not is_const(right): |
| 284 self.errors.append((left, 'A103 yoda condition')) | 284 self.errors.append((left, 'A103 yoda condition')) |
| 285 | 285 |
| 286 left = right | 286 left = right |
| 287 | 287 |
| 288 self.generic_visit(node) | 288 self.generic_visit(node) |
| 289 | 289 |
| 290 def visit_BoolOp(self, node): | |
| 291 if isinstance(node.op, ast.Or): | |
| 292 left = node.values[0] | |
| 293 right = node.values[1] | |
|
Sebastian Noack
2017/12/10 23:19:57
What if there is another condition in between? E.g
| |
| 294 if (isinstance(left, ast.Compare) and | |
| 295 isinstance(right, ast.Compare)): | |
| 296 if (isinstance(left.ops[0], ast.Eq) and | |
| 297 isinstance(left.ops[0], ast.Eq) or | |
|
Sebastian Noack
2017/12/10 23:19:57
This expression is the same as the left-hand side
| |
| 298 (isinstance(left.ops[0], ast.NotEq) and | |
| 299 isinstance(left.ops[0], ast.NotEq))): | |
| 300 value1names = [] | |
| 301 value2names = [] | |
| 302 # Gather variable names from the left comparison | |
| 303 if isinstance(left.left, ast.Name): | |
|
Sebastian Noack
2017/12/10 23:19:57
What if it is an Attribute node? E.g: x.a == 1 or
| |
| 304 value1names.append(left.left.id) | |
| 305 if isinstance(left.comparators[0], ast.Name): | |
| 306 value1names.append(left.comparators[0].id) | |
| 307 # Gather variable names from the right comparison | |
| 308 if isinstance(right.left, ast.Name): | |
| 309 value2names.append(right.left.id) | |
| 310 if isinstance(right.comparators[0], ast.Name): | |
| 311 value2names.append(right.comparators[0].id) | |
| 312 # Check for duplicates | |
| 313 for i in value1names: | |
| 314 if i in value2names: | |
| 315 self.errors.append((node, 'A208 `{} == x or {} == ' | |
| 316 'y` should be `{} in {{x' | |
| 317 ', y}}`'.format(i, i, | |
| 318 i))) | |
| 319 | |
| 290 def _check_deprecated(self, node, name): | 320 def _check_deprecated(self, node, name): |
| 291 substitute = DISCOURAGED_APIS.get(name) | 321 substitute = DISCOURAGED_APIS.get(name) |
| 292 if substitute: | 322 if substitute: |
| 293 self.errors.append((node, 'A301 use {}() instead of ' | 323 self.errors.append((node, 'A301 use {}() instead of ' |
| 294 '{}()'.format(substitute, name))) | 324 '{}()'.format(substitute, name))) |
| 295 | 325 |
| 296 def visit_Call(self, node): | 326 def visit_Call(self, node): |
| 297 func = get_identifier(node.func) | 327 func = get_identifier(node.func) |
| 298 arg = next(iter(node.args), None) | 328 arg = next(iter(node.args), None) |
| 299 redundant_literal = False | 329 redundant_literal = False |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 384 def check_quotes(logical_line, tokens, previous_logical, checker_state): | 414 def check_quotes(logical_line, tokens, previous_logical, checker_state): |
| 385 first_token = True | 415 first_token = True |
| 386 | 416 |
| 387 token_strings = [t[1] for t in tokens] | 417 token_strings = [t[1] for t in tokens] |
| 388 future_import = token_strings[:3] == ['from', '__future__', 'import'] | 418 future_import = token_strings[:3] == ['from', '__future__', 'import'] |
| 389 | 419 |
| 390 if future_import and 'unicode_literals' in token_strings: | 420 if future_import and 'unicode_literals' in token_strings: |
| 391 checker_state['has_unicode_literals'] = True | 421 checker_state['has_unicode_literals'] = True |
| 392 | 422 |
| 393 for kind, token, start, end, _ in tokens: | 423 for kind, token, start, end, _ in tokens: |
| 394 if kind == tokenize.INDENT or kind == tokenize.DEDENT: | 424 if kind in {tokenize.INDENT, tokenize.DEDENT}: |
| 395 continue | 425 continue |
| 396 | 426 |
| 397 if kind == tokenize.STRING: | 427 if kind == tokenize.STRING: |
| 398 match = re.search(r'^([rub]*)([\'"]{1,3})(.*)\2$', | 428 match = re.search(r'^([rub]*)([\'"]{1,3})(.*)\2$', |
| 399 token, re.IGNORECASE | re.DOTALL) | 429 token, re.IGNORECASE | re.DOTALL) |
| 400 prefixes, quote, text = match.groups() | 430 prefixes, quote, text = match.groups() |
| 401 prefixes = prefixes.lower() | 431 prefixes = prefixes.lower() |
| 402 | 432 |
| 403 if 'u' in prefixes: | 433 if 'u' in prefixes: |
| 404 yield (start, 'A112 use "from __future__ import ' | 434 yield (start, 'A112 use "from __future__ import ' |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 491 if is_tuple or is_nested_op or is_compare_in_assign: | 521 if is_tuple or is_nested_op or is_compare_in_assign: |
| 492 continue | 522 continue |
| 493 | 523 |
| 494 yield (pos[0], pos[1], 'A111 redundant parenthesis', None) | 524 yield (pos[0], pos[1], 'A111 redundant parenthesis', None) |
| 495 | 525 |
| 496 | 526 |
| 497 for checker in [check_ast, check_non_default_encoding, | 527 for checker in [check_ast, check_non_default_encoding, |
| 498 check_quotes, check_redundant_parenthesis]: | 528 check_quotes, check_redundant_parenthesis]: |
| 499 checker.name = 'eyeo' | 529 checker.name = 'eyeo' |
| 500 checker.version = __version__ | 530 checker.version = __version__ |
| OLD | NEW |