From a936cea9874d4f5ec79d635845ebde28c1d376a3 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Thu, 26 Jun 2014 12:21:19 +0200 Subject: [PATCH] jedi issues now warnings instead of errors for AttributeErrors that happen in instances with __getattr__/__getattribute__ methods --- jedi/evaluate/analysis.py | 23 +++++++++++++++++++---- jedi/evaluate/finder.py | 11 ++++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/jedi/evaluate/analysis.py b/jedi/evaluate/analysis.py index fa35ed61..322780e7 100644 --- a/jedi/evaluate/analysis.py +++ b/jedi/evaluate/analysis.py @@ -82,10 +82,25 @@ def add(evaluator, name, jedi_obj, message=None, typ=Error, payload=None): evaluator.analysis.append(instance) -def add_attribute_error(evaluator, jedi_obj, message, scope): - typ = Error - payload = scope, jedi_obj # jedi_obj is a name_part. - add(evaluator, 'attribute-error', jedi_obj, message, typ, payload) +def add_attribute_error(evaluator, scope, name_part): + message = ('AttributeError: %s has no attribute %s.' % (scope, name_part)) + from jedi.evaluate.representation import Instance + # Check for __getattr__/__getattribute__ existance and issue a warning + # instead of an error, if that happens. + if isinstance(scope, Instance): + typ = Warning + try: + scope.get_subscope_by_name('__getattr__') + except KeyError: + try: + scope.get_subscope_by_name('__getattribute__') + except KeyError: + typ = Error + else: + typ = Error + + payload = scope, name_part + add(evaluator, 'attribute-error', name_part, message, typ, payload) def _check_for_exception_catch(evaluator, jedi_obj, exception, payload=None): diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index e5bda942..15ee8499 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -50,17 +50,14 @@ class NameFinder(object): and not (isinstance(self.name_str, pr.NamePart) and isinstance(self.name_str.parent.parent, pr.Param)): if not isinstance(self.name_str, (str, unicode)): # TODO Remove? - err_type = 'name-error' if search_global else 'attribute-error' - if err_type == 'name-error': + if search_global: message = ("NameError: name '%s' is not defined." % self.name_str) + analysis.add(self._evaluator, 'name-error', self.name_str, + message) else: - message = ('AttributeError: %s has no attribute %s.' - % (self._last_filter_name_scope, self.name_str)) - payload = self.name_str analysis.add_attribute_error(self._evaluator, - self.name_str, message, - self.scope) + self.scope, self.name_str) debug.dbg('finder._names_to_types: %s -> %s', names, types) return self._resolve_descriptors(types)