mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Added isinstance type checks in the linter.
This commit is contained in:
@@ -19,6 +19,7 @@ CODES = {
|
|||||||
'type-error-star': (10, TypeError, None),
|
'type-error-star': (10, TypeError, None),
|
||||||
'type-error-operation': (11, TypeError, None),
|
'type-error-operation': (11, TypeError, None),
|
||||||
'type-error-not-iterable': (12, TypeError, None),
|
'type-error-not-iterable': (12, TypeError, None),
|
||||||
|
'type-error-isinstance': (13, TypeError, None),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -208,8 +208,8 @@ class CompiledObject(Base):
|
|||||||
# Get rid of side effects, we won't call custom `__getitem__`s.
|
# Get rid of side effects, we won't call custom `__getitem__`s.
|
||||||
return
|
return
|
||||||
|
|
||||||
for obj in self.obj:
|
for part in self.obj:
|
||||||
yield set([CompiledObject(obj)])
|
yield set([CompiledObject(part)])
|
||||||
return actual
|
return actual
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -12,8 +12,13 @@ from jedi.evaluate.helpers import FakeName
|
|||||||
from jedi.cache import underscore_memoization
|
from jedi.cache import underscore_memoization
|
||||||
|
|
||||||
|
|
||||||
def try_iter_content(types):
|
def try_iter_content(types, depth=0):
|
||||||
"""Helper method for static analysis."""
|
"""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:
|
for typ in types:
|
||||||
try:
|
try:
|
||||||
f = typ.py__iter__
|
f = typ.py__iter__
|
||||||
@@ -21,7 +26,7 @@ def try_iter_content(types):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
for iter_types in f():
|
for iter_types in f():
|
||||||
try_iter_content(iter_types)
|
try_iter_content(iter_types, depth + 1)
|
||||||
|
|
||||||
|
|
||||||
class Arguments(tree.Base):
|
class Arguments(tree.Base):
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ from jedi.parser import tree
|
|||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi.evaluate import precedence
|
from jedi.evaluate import precedence
|
||||||
from jedi.evaluate import param
|
from jedi.evaluate import param
|
||||||
|
from jedi.evaluate import analysis
|
||||||
|
|
||||||
|
|
||||||
class NotInStdLib(LookupError):
|
class NotInStdLib(LookupError):
|
||||||
@@ -40,9 +41,11 @@ def execute(evaluator, obj, arguments):
|
|||||||
|
|
||||||
# for now we just support builtin functions.
|
# for now we just support builtin functions.
|
||||||
try:
|
try:
|
||||||
return _implemented[module_name][obj_name](evaluator, obj, arguments)
|
func = _implemented[module_name][obj_name]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
else:
|
||||||
|
return func(evaluator, obj, arguments)
|
||||||
raise NotInStdLib()
|
raise NotInStdLib()
|
||||||
|
|
||||||
|
|
||||||
@@ -186,12 +189,15 @@ def builtins_isinstance(evaluator, objects, types, arguments):
|
|||||||
for cls_or_tup in types:
|
for cls_or_tup in types:
|
||||||
if cls_or_tup.is_class():
|
if cls_or_tup.is_class():
|
||||||
bool_results.add(cls_or_tup in mro)
|
bool_results.add(cls_or_tup in mro)
|
||||||
else:
|
elif str(cls_or_tup.name) == 'tuple' \
|
||||||
# TODO Actually we should check for non iterables here (the
|
and cls_or_tup.get_parent_scope() == compiled.builtin:
|
||||||
# type should be object or tuple of object)
|
|
||||||
# Check for tuples.
|
# 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))
|
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)
|
return set(compiled.keyword_from_value(x) for x in bool_results)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user