Added isinstance type checks in the linter.

This commit is contained in:
Dave Halter
2015-12-03 16:14:26 +01:00
parent 8daa0b8784
commit 21faf2431a
4 changed files with 21 additions and 9 deletions

View File

@@ -19,6 +19,7 @@ CODES = {
'type-error-star': (10, TypeError, None),
'type-error-operation': (11, TypeError, None),
'type-error-not-iterable': (12, TypeError, None),
'type-error-isinstance': (13, TypeError, None),
}

View File

@@ -208,8 +208,8 @@ class CompiledObject(Base):
# Get rid of side effects, we won't call custom `__getitem__`s.
return
for obj in self.obj:
yield set([CompiledObject(obj)])
for part in self.obj:
yield set([CompiledObject(part)])
return actual
@property

View File

@@ -12,8 +12,13 @@ from jedi.evaluate.helpers import FakeName
from jedi.cache import underscore_memoization
def try_iter_content(types):
def try_iter_content(types, depth=0):
"""Helper method for static analysis."""
if depth > 10:
# It's possible that a loop has references on itself (especially with
# CompiledObject). Therefore don't loop infinitely.
return
for typ in types:
try:
f = typ.py__iter__
@@ -21,7 +26,7 @@ def try_iter_content(types):
pass
else:
for iter_types in f():
try_iter_content(iter_types)
try_iter_content(iter_types, depth + 1)
class Arguments(tree.Base):

View File

@@ -19,6 +19,7 @@ from jedi.parser import tree
from jedi import debug
from jedi.evaluate import precedence
from jedi.evaluate import param
from jedi.evaluate import analysis
class NotInStdLib(LookupError):
@@ -40,9 +41,11 @@ def execute(evaluator, obj, arguments):
# for now we just support builtin functions.
try:
return _implemented[module_name][obj_name](evaluator, obj, arguments)
func = _implemented[module_name][obj_name]
except KeyError:
pass
else:
return func(evaluator, obj, arguments)
raise NotInStdLib()
@@ -186,12 +189,15 @@ def builtins_isinstance(evaluator, objects, types, arguments):
for cls_or_tup in types:
if cls_or_tup.is_class():
bool_results.add(cls_or_tup in mro)
else:
# TODO Actually we should check for non iterables here (the
# type should be object or tuple of object)
elif str(cls_or_tup.name) == 'tuple' \
and cls_or_tup.get_parent_scope() == compiled.builtin:
# Check for tuples.
classes = iterable.py__iter__types(evaluator, set([cls_or_tup]))
classes = unite(cls_or_tup.py__iter__())
bool_results.add(any(cls in mro for cls in classes))
else:
_, nodes = list(arguments.unpack())[1]
for node in nodes:
analysis.add(evaluator, 'type-error-isinstance', node)
return set(compiled.keyword_from_value(x) for x in bool_results)