diff --git a/jedi/evaluate/analysis.py b/jedi/evaluate/analysis.py index ac3afdb8..d44f3d1d 100644 --- a/jedi/evaluate/analysis.py +++ b/jedi/evaluate/analysis.py @@ -3,12 +3,15 @@ Module for statical analysis. """ from jedi import debug +from jedi.parser import representation as pr +from jedi.evaluate.compiled import CompiledObject + CODES = { - 'attribute-error': (1, 'Potential AttributeError.'), - 'import-error': (2, 'Potential ImportError.'), - 'type-error-generator': (3, "TypeError: 'generator' object is not subscriptable."), + 'attribute-error': (1, AttributeError, 'Potential AttributeError.'), + 'import-error': (2, ImportError, 'Potential ImportError.'), + 'type-error-generator': (3, TypeError, "TypeError: 'generator' object is not subscriptable."), } @@ -59,7 +62,30 @@ class Warning(Error): def add(evaluator, name, jedi_obj, typ=Error): + exception = CODES[name][1] + if _check_for_exception_catch(evaluator, jedi_obj, exception): + return + module_path = jedi_obj.get_parent_until().path instance = typ(name, module_path, jedi_obj.start_pos) debug.warning(str(instance)) evaluator.analysis.append(instance) + + +def _check_for_exception_catch(evaluator, jedi_obj, exception): + def check_try_for_except(obj): + while obj.next is not None: + obj = obj.next + for i in obj.inputs: + except_classes = evaluator.eval_statement(i) + for cls in except_classes: + if isinstance(cls, CompiledObject) and cls.obj == exception: + return True + return False + + while jedi_obj is not None and not jedi_obj.isinstance(pr.Function, pr.Class): + if jedi_obj.isinstance(pr.Flow) and jedi_obj.command == 'try': + if check_try_for_except(jedi_obj): + return True + jedi_obj = jedi_obj.parent + return False diff --git a/jedi/parser/representation.py b/jedi/parser/representation.py index 114b8cbe..493482f7 100644 --- a/jedi/parser/representation.py +++ b/jedi/parser/representation.py @@ -1413,6 +1413,9 @@ class NamePart(object): def get_parent_until(self, *args, **kwargs): return self.parent.get_parent_until(*args, **kwargs) + def isinstance(self, *cls): + return isinstance(self, cls) + @property def start_pos(self): offset = self.parent._sub_module.line_offset diff --git a/test/static_analysis/generators.py b/test/static_analysis/generators.py index 9606d663..a7682a5d 100644 --- a/test/static_analysis/generators.py +++ b/test/static_analysis/generators.py @@ -5,4 +5,3 @@ def generator(): generator()[0] list(generator())[0] -