Introduce a dedicated isinstance function implementation.

This commit is contained in:
Dave Halter
2014-08-19 23:57:59 +02:00
parent 49163e135c
commit 09ca47fa93
4 changed files with 48 additions and 16 deletions

View File

@@ -421,6 +421,17 @@ true_obj = builtin.get_by_name('True')
object_obj = builtin.get_by_name('object') object_obj = builtin.get_by_name('object')
def keyword_from_value(obj):
if obj is None:
return none_obj
elif obj is False:
return false_obj
elif obj is True:
return true_obj
else:
raise NotImplementedError
def compiled_objects_cache(func): def compiled_objects_cache(func):
def wrapper(evaluator, obj, parent=builtin, module=None): def wrapper(evaluator, obj, parent=builtin, module=None):
# Do a very cheap form of caching here. # Do a very cheap form of caching here.

View File

@@ -7,8 +7,8 @@ from jedi._compatibility import unicode
from jedi.parser import representation as pr from jedi.parser import representation as pr
from jedi import debug from jedi import debug
from jedi.common import PushBackIterator from jedi.common import PushBackIterator
from jedi.evaluate.compiled import (CompiledObject, create, builtin, false_obj, from jedi.evaluate.compiled import (CompiledObject, create, builtin,
true_obj, none_obj) keyword_from_value)
from jedi.evaluate import analysis from jedi.evaluate import analysis
# Maps Python syntax to the operator module. # Maps Python syntax to the operator module.
@@ -249,7 +249,7 @@ def _factor_calculate(evaluator, operator, right):
value = right.py__bool__() value = right.py__bool__()
if value is None: # Uncertainty. if value is None: # Uncertainty.
return None return None
return _keyword_from_value(not value) return keyword_from_value(not value)
return right return right
@@ -277,15 +277,6 @@ def _is_list(obj):
return isinstance(obj, iterable.Array) and obj.type == pr.Array.LIST return isinstance(obj, iterable.Array) and obj.type == pr.Array.LIST
def _keyword_from_value(obj):
if obj is None:
return none_obj
elif obj is False:
return false_obj
elif obj is True:
return true_obj
def _element_calculate(evaluator, left, operator, right): def _element_calculate(evaluator, left, operator, right):
from jedi.evaluate import iterable, representation as er from jedi.evaluate import iterable, representation as er
l_is_num = _is_number(left) l_is_num = _is_number(left)
@@ -314,7 +305,7 @@ def _element_calculate(evaluator, left, operator, right):
# Possible, because the return is not an option. Just compare. # Possible, because the return is not an option. Just compare.
left = left.obj left = left.obj
right = right.obj right = right.obj
return [_keyword_from_value(operation(left, right))] return [keyword_from_value(operation(left, right))]
def check(obj): def check(obj):
"""Checks if a Jedi object is either a float or an int.""" """Checks if a Jedi object is either a float or an int."""

View File

@@ -124,6 +124,31 @@ def builtins_reversed(evaluator, obj, params):
return [er.Instance(evaluator, obj, objects)] return [er.Instance(evaluator, obj, objects)]
def builtins_isinstance(evaluator, obj, params):
any_bool = [compiled.false_obj, compiled.true_obj]
obj = _follow_param(evaluator, params, 0)
raw_classes = _follow_param(evaluator, params, 1)
classes = []
# Check for tuples.
for cls_or_tup in raw_classes:
if isinstance(cls_or_tup, er.Class):
classes.append(cls_or_tup)
else:
classes += iterable.get_iterator_types([cls_or_tup])
bool_results = []
for o in obj:
for cls in classes:
try:
mro_func = o.base.py__mro__
except AttributeError:
return any_bool
else:
bool_result = cls in mro_func(evaluator)
bool_results.append(compiled.keyword_from_value(bool_result))
return set(bool_results)
def collections_namedtuple(evaluator, obj, params): def collections_namedtuple(evaluator, obj, params):
""" """
Implementation of the namedtuple function. Implementation of the namedtuple function.
@@ -179,6 +204,7 @@ _implemented = {
'type': builtins_type, 'type': builtins_type,
'super': builtins_super, 'super': builtins_super,
'reversed': builtins_reversed, 'reversed': builtins_reversed,
'isinstance': builtins_isinstance,
}, },
'copy': { 'copy': {
'copy': _return_first_param, 'copy': _return_first_param,

View File

@@ -155,8 +155,12 @@ a
# isinstance # isinstance
# ----------------- # -----------------
class A(): pass
def isinst(x): def isinst(x):
if isinstance(x, int) and x == 1 or x is True: if isinstance(x, A):
return dict
elif isinstance(x, int) and x == 1 or x is True:
return set return set
elif isinstance(x, (float, tuple)): elif isinstance(x, (float, tuple)):
return list return list
@@ -164,8 +168,8 @@ def isinst(x):
return tuple return tuple
return 1 return 1
#? set #? dict
isinst(1) isinst(A())
#? set #? set
isinst(True) isinst(True)
#? list #? list