diff options
| author | Claudiu Popa <pcmanticore@gmail.com> | 2018-05-12 14:33:18 -0400 |
|---|---|---|
| committer | Claudiu Popa <pcmanticore@gmail.com> | 2018-05-12 14:33:18 -0400 |
| commit | 2952e77a469f50ffb4ccfdea16a10878b6e86d05 (patch) | |
| tree | 499b0cd64a1fe6f0ca48f0dae9beec7ec44924e7 /pylint/checkers/python3.py | |
| parent | cc40b93c4d071136b822fd49b87c7fac15a51617 (diff) | |
| download | pylint-git-2952e77a469f50ffb4ccfdea16a10878b6e86d05.tar.gz | |
Added two new Python 3 porting checks, `exception-escape` and `comprehension-escape`
These two are emitted whenever pylint detects that a variable defined in the
said blocks is used outside of the given block. On Python 3 these values are deleted.
Diffstat (limited to 'pylint/checkers/python3.py')
| -rw-r--r-- | pylint/checkers/python3.py | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/pylint/checkers/python3.py b/pylint/checkers/python3.py index 111d9bde9..7941a54b4 100644 --- a/pylint/checkers/python3.py +++ b/pylint/checkers/python3.py @@ -413,6 +413,16 @@ class Python3Checker(checkers.BaseChecker): 'deprecated-sys-function', 'Used when accessing a field on sys module that has been ' 'removed in Python 3.',), + 'W1661': ('Using an exception object that was bound by an except handler', + 'exception-escape', + 'Emitted when using an exception, that was bound in an except handler, outside ' + 'of the except handler. On Python 3 these exceptions will be deleted once they get out ' + 'of the except handler.'), + 'W1662': ('Using a variable that was bound inside a comprehension', + 'comprehension-escape', + 'Emitted when using a variable, that was bound in a comprehension handler, outside ' + 'of the comprehension itself. On Python 3 these variables will be deleted outside of the ' + 'comprehension.'), } _bad_builtins = frozenset([ @@ -616,12 +626,28 @@ class Python3Checker(checkers.BaseChecker): def visit_name(self, node): """Detect when a "bad" built-in is referenced.""" - found_node = node.lookup(node.name)[0] + found_node, located_statements = node.lookup(node.name) if _is_builtin(found_node): if node.name in self._bad_builtins: message = node.name.lower() + '-builtin' self.add_message(message, node=node) + if len(located_statements) == 1: + assign_statement = located_statements[0].statement() + if isinstance(assign_statement, astroid.ExceptHandler): + current = node + while current and not isinstance(current.parent, astroid.ExceptHandler): + current = current.parent + + if current and isinstance(current.parent, astroid.ExceptHandler): + return + self.add_message('exception-escape', node=node) + + if isinstance(assign_statement, (astroid.Expr, astroid.Assign)): + if (isinstance(assign_statement.value, astroid.ListComp) + and not assign_statement.parent_of(node)): + self.add_message('comprehension-escape', node=node) + @utils.check_messages('print-statement') def visit_print(self, node): self.add_message('print-statement', node=node, always_warn=True) |
