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')
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 wrapper(evaluator, obj, parent=builtin, module=None):
# 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 import debug
from jedi.common import PushBackIterator
from jedi.evaluate.compiled import (CompiledObject, create, builtin, false_obj,
true_obj, none_obj)
from jedi.evaluate.compiled import (CompiledObject, create, builtin,
keyword_from_value)
from jedi.evaluate import analysis
# Maps Python syntax to the operator module.
@@ -249,7 +249,7 @@ def _factor_calculate(evaluator, operator, right):
value = right.py__bool__()
if value is None: # Uncertainty.
return None
return _keyword_from_value(not value)
return keyword_from_value(not value)
return right
@@ -277,15 +277,6 @@ def _is_list(obj):
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):
from jedi.evaluate import iterable, representation as er
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.
left = left.obj
right = right.obj
return [_keyword_from_value(operation(left, right))]
return [keyword_from_value(operation(left, right))]
def check(obj):
"""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)]
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):
"""
Implementation of the namedtuple function.
@@ -179,6 +204,7 @@ _implemented = {
'type': builtins_type,
'super': builtins_super,
'reversed': builtins_reversed,
'isinstance': builtins_isinstance,
},
'copy': {
'copy': _return_first_param,

View File

@@ -155,8 +155,12 @@ a
# isinstance
# -----------------
class A(): pass
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
elif isinstance(x, (float, tuple)):
return list
@@ -164,8 +168,8 @@ def isinst(x):
return tuple
return 1
#? set
isinst(1)
#? dict
isinst(A())
#? set
isinst(True)
#? list