forked from VimPlug/jedi
hasattr checks working now, #408
This commit is contained in:
@@ -71,9 +71,9 @@ class Warning(Error):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def add(evaluator, name, jedi_obj, message=None, typ=Error):
|
def add(evaluator, name, jedi_obj, message=None, typ=Error, payload=None):
|
||||||
exception = CODES[name][1]
|
exception = CODES[name][1]
|
||||||
if _check_for_exception_catch(evaluator, jedi_obj, exception):
|
if _check_for_exception_catch(evaluator, jedi_obj, exception, payload):
|
||||||
return
|
return
|
||||||
|
|
||||||
module_path = jedi_obj.get_parent_until().path
|
module_path = jedi_obj.get_parent_until().path
|
||||||
@@ -82,7 +82,8 @@ def add(evaluator, name, jedi_obj, message=None, typ=Error):
|
|||||||
evaluator.analysis.append(instance)
|
evaluator.analysis.append(instance)
|
||||||
|
|
||||||
|
|
||||||
def _check_for_exception_catch(evaluator, jedi_obj, exception):
|
def _check_for_exception_catch(evaluator, jedi_obj, exception, payload=None):
|
||||||
|
"""Returns True if the exception was catched."""
|
||||||
def check_match(cls):
|
def check_match(cls):
|
||||||
return isinstance(cls, CompiledObject) and cls.obj == exception
|
return isinstance(cls, CompiledObject) and cls.obj == exception
|
||||||
|
|
||||||
@@ -103,11 +104,38 @@ def _check_for_exception_catch(evaluator, jedi_obj, exception):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
while jedi_obj is not None and not jedi_obj.isinstance(pr.Function, pr.Class):
|
def check_hasattr(stmt):
|
||||||
if jedi_obj.isinstance(pr.Flow) and jedi_obj.command == 'try':
|
expression_list = stmt.expression_list()
|
||||||
if check_try_for_except(jedi_obj):
|
try:
|
||||||
|
assert len(expression_list) == 1
|
||||||
|
call = expression_list[0]
|
||||||
|
assert isinstance(call, pr.Call) and str(call.name) == 'hasattr'
|
||||||
|
execution = call.execution
|
||||||
|
assert execution and len(execution) == 2
|
||||||
|
|
||||||
|
# check if the names match
|
||||||
|
names = evaluator.eval_statement(execution[1])
|
||||||
|
assert len(names) == 1 and isinstance(names[0], CompiledObject)
|
||||||
|
assert names[0].obj == str(payload[1])
|
||||||
|
|
||||||
|
objects = evaluator.eval_statement(execution[0])
|
||||||
|
return payload[0] in objects
|
||||||
|
except AssertionError:
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
obj = jedi_obj
|
||||||
|
while obj is not None and not obj.isinstance(pr.Function, pr.Class):
|
||||||
|
if obj.isinstance(pr.Flow):
|
||||||
|
# try/except catch check
|
||||||
|
if obj.command == 'try' and check_try_for_except(obj):
|
||||||
return True
|
return True
|
||||||
jedi_obj = jedi_obj.parent
|
# hasattr check
|
||||||
|
if exception == AttributeError and obj.command in ('if', 'while'):
|
||||||
|
if obj.inputs and check_hasattr(obj.inputs[0]):
|
||||||
|
return True
|
||||||
|
obj = obj.parent
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,11 +48,12 @@ class NameFinder(object):
|
|||||||
if not names and not types \
|
if not names and not types \
|
||||||
and not (isinstance(self.name_str, pr.NamePart)
|
and not (isinstance(self.name_str, pr.NamePart)
|
||||||
and isinstance(self.name_str.parent.parent, pr.Param)):
|
and isinstance(self.name_str.parent.parent, pr.Param)):
|
||||||
if not isinstance(self.name_str, (str, unicode)): # TODO Remove
|
if not isinstance(self.name_str, (str, unicode)): # TODO Remove?
|
||||||
err_type = 'name-error' if search_global else 'attribute-error'
|
err_type = 'name-error' if search_global else 'attribute-error'
|
||||||
message = ('AttributeError: %s has no attribute %s'
|
message = ('AttributeError: %s has no attribute %s'
|
||||||
% (self._last_filter_name_scope, self.name_str))
|
% (self._last_filter_name_scope, self.name_str))
|
||||||
analysis.add(self._evaluator, err_type, self.name_str, message)
|
analysis.add(self._evaluator, err_type, self.name_str, message,
|
||||||
|
payload=(self.scope, self.name_str))
|
||||||
|
|
||||||
debug.dbg('finder._names_to_types: %s -> %s', names, types)
|
debug.dbg('finder._names_to_types: %s -> %s', names, types)
|
||||||
return self._resolve_descriptors(types)
|
return self._resolve_descriptors(types)
|
||||||
|
|||||||
@@ -55,11 +55,13 @@ except [AttributeError]: pass
|
|||||||
# kind of similar: hasattr
|
# kind of similar: hasattr
|
||||||
# -----------------
|
# -----------------
|
||||||
|
|
||||||
if hasattr(object, 'undefined'):
|
if hasattr(str, 'undefined'):
|
||||||
str.undefined
|
str.undefined
|
||||||
str.upper
|
str.upper
|
||||||
#! 4 attribute-error
|
#! 4 attribute-error
|
||||||
str.undefined2
|
str.undefined2
|
||||||
|
#! 4 attribute-error
|
||||||
|
int.undefined
|
||||||
else:
|
else:
|
||||||
str.upper
|
str.upper
|
||||||
#! 4 attribute-error
|
#! 4 attribute-error
|
||||||
|
|||||||
Reference in New Issue
Block a user