1
0
forked from VimPlug/jedi

Refactor compiled.CompiledObject so it always owns an evaluator instance.

This commit is contained in:
Dave Halter
2015-12-08 02:19:33 +01:00
parent 18a10c436f
commit bef5fca516
13 changed files with 149 additions and 139 deletions

View File

@@ -12,7 +12,7 @@ import warnings
import sys
from itertools import chain
from jedi._compatibility import unicode, builtins
from jedi._compatibility import unicode
from jedi.parser import Parser, load_grammar
from jedi.parser.tokenize import source_tokens
from jedi.parser import tree
@@ -179,7 +179,7 @@ class Script(object):
if unfinished_dotted:
return completion_names
else:
return keywords.keyword_names('import')
return keywords.keyword_names(self._evaluator, 'import')
if isinstance(user_stmt, tree.Import):
module = self._parser.module()
@@ -190,7 +190,7 @@ class Script(object):
if names is None and not isinstance(user_stmt, tree.Import):
if not path and not dot:
# add keywords
completion_names += keywords.keyword_names(all=True)
completion_names += keywords.keyword_names(self._evaluator, all=True)
# TODO delete? We should search for valid parser
# transformations.
completion_names += self._simple_complete(path, dot, like)
@@ -206,8 +206,7 @@ class Script(object):
user_stmt = self._parser.user_stmt_with_whitespace()
b = compiled.builtin
completion_names = get_completions(user_stmt, b)
completion_names = get_completions(user_stmt, self._evaluator.BUILTINS)
if not dot:
# add named params
@@ -647,7 +646,7 @@ class Interpreter(Script):
paths = path.split('.') if path else []
namespaces = (NamespaceModule(), builtins)
namespaces = (NamespaceModule(), BUILTINS)
for p in paths:
old, namespaces = namespaces, []
for n in old:

View File

@@ -15,7 +15,6 @@ from jedi.parser import load_grammar
from jedi.parser.fast import FastParser
from jedi.evaluate import helpers
from jedi.evaluate import iterable
from jedi.evaluate import representation as er
def add_namespaces_to_parser(evaluator, namespaces, parser_module):
@@ -92,10 +91,7 @@ class LazyName(helpers.FakeName):
parser_path)
if not found:
evaluated = compiled.CompiledObject(obj)
if evaluated == builtins:
# The builtins module is special and always cached.
evaluated = compiled.builtin
evaluated = compiled.create(self._evaluator, obj)
found = [evaluated]
content = iterable.AlreadyEvaluated(found)

View File

@@ -3,7 +3,6 @@ import keyword
from jedi._compatibility import is_py3
from jedi import common
from jedi.evaluate import compiled
from jedi.evaluate.helpers import FakeName
try:
@@ -18,27 +17,27 @@ else:
keys = keyword.kwlist + ['None', 'False', 'True']
def keywords(string='', pos=(0, 0), all=False):
def keywords(evaluator, string='', pos=(0, 0), all=False):
if all:
return set([Keyword(k, pos) for k in keys])
return set([Keyword(evaluator, k, pos) for k in keys])
if string in keys:
return set([Keyword(string, pos)])
return set([Keyword(evaluator, string, pos)])
return set()
def keyword_names(*args, **kwargs):
return [k.name for k in keywords(*args, **kwargs)]
def keyword_names(evaluator, *args, **kwargs):
return [k.name for k in keywords(evaluator, *args, **kwargs)]
def get_operator(string, pos):
return Keyword(string, pos)
def get_operator(evaluator, string, pos):
return Keyword(evaluator, string, pos)
class Keyword(object):
def __init__(self, name, pos):
def __init__(self, evaluator, name, pos):
self.name = FakeName(name, self, pos)
self.start_pos = pos
self.parent = compiled.builtin
self.parent = evaluator.BUILTINS
def get_parent_until(self):
return self.parent

View File

@@ -33,7 +33,7 @@ enable_notice = False
# callback, interface: level, str
debug_function = None
ignored_modules = ['jedi.evaluate.builtin', 'jedi.parser']
ignored_modules = ['jedi.parser']
_debug_indent = 0
_start_time = time.time()

View File

@@ -86,8 +86,8 @@ class Evaluator(object):
# To memorize modules -> equals `sys.modules`.
self.modules = {} # like `sys.modules`.
self.compiled_cache = {} # see `compiled.create()`
self.recursion_detector = recursion.RecursionDetector()
self.execution_recursion_detector = recursion.ExecutionRecursionDetector()
self.recursion_detector = recursion.RecursionDetector(self)
self.execution_recursion_detector = recursion.ExecutionRecursionDetector(self)
self.analysis = []
self.predefined_if_name_dict_dict = {}
self.is_analysis = False
@@ -100,6 +100,9 @@ class Evaluator(object):
except ValueError:
pass
# Constants
self.BUILTINS = compiled.get_special_object(self, 'BUILTINS')
def wrap(self, element):
if isinstance(element, tree.Class):
return er.Class(self, element)
@@ -256,14 +259,15 @@ class Evaluator(object):
@debug.increase_indent
def _eval_element_not_cached(self, element):
debug.dbg('eval_element %s@%s', element, element.start_pos)
types = set()
if isinstance(element, (tree.Name, tree.Literal)) or tree.is_node(element, 'atom'):
types = self._eval_atom(element)
elif isinstance(element, tree.Keyword):
# For False/True/None
if element.value in ('False', 'True', 'None'):
types = set([compiled.builtin.get_by_name(element.value)])
types.add(compiled.builtin_from_name(self, element.value))
else:
types = set()
raise NotImplementedError
elif element.isinstance(tree.Lambda):
types = set([er.LambdaWrapper(self, element)])
elif element.isinstance(er.LambdaWrapper):

View File

@@ -41,7 +41,8 @@ class CompiledObject(Base):
path = None # modules have this attribute - set it to None.
used_names = {} # To be consistent with modules.
def __init__(self, obj, parent=None):
def __init__(self, evaluator, obj, parent=None):
self._evaluator = evaluator
self.obj = obj
self.parent = parent
@@ -60,7 +61,7 @@ class CompiledObject(Base):
@CheckAttribute
def py__class__(self, evaluator):
return CompiledObject(self.obj.__class__, parent=self.parent)
return create(evaluator, self.obj.__class__, parent=self.parent)
@CheckAttribute
def py__mro__(self, evaluator):
@@ -142,7 +143,7 @@ class CompiledObject(Base):
# happens with numpy.core.umath._UFUNC_API (you get it
# automatically by doing `import numpy`.
c = type(None)
return CompiledObject(c, self.parent)
return create(self._evaluator, c, self.parent)
return self
@property
@@ -159,17 +160,18 @@ class CompiledObject(Base):
search_global shouldn't change the fact that there's one dict, this way
there's only one `object`.
"""
return [LazyNamesDict(self._cls(), is_instance)]
return [LazyNamesDict(self._evaluator, self._cls(), is_instance)]
def get_subscope_by_name(self, name):
if name in dir(self._cls().obj):
return CompiledName(self._cls(), name).parent
return CompiledName(self._evaluator, self._cls(), name).parent
else:
raise KeyError("CompiledObject doesn't have an attribute '%s'." % name)
def get_index_types(self, evaluator, index_array=()):
# If the object doesn't have `__getitem__`, just raise the
# AttributeError.
raise NotImplementedError
if not hasattr(self.obj, '__getitem__'):
debug.warning('Tried to call __getitem__ on non-iterable.')
return set()
@@ -203,13 +205,13 @@ class CompiledObject(Base):
if not hasattr(self.obj, '__iter__'):
raise AttributeError('No __iter__ on %s' % self.obj)
def actual():
def actual(evaluator):
if type(self.obj) not in (str, list, tuple, unicode, bytes, bytearray, dict):
# Get rid of side effects, we won't call custom `__getitem__`s.
return
for part in self.obj:
yield set([CompiledObject(part)])
yield set([create(evaluator, part)])
return actual
@property
@@ -223,12 +225,13 @@ class CompiledObject(Base):
for name in self._parse_function_doc()[1].split():
try:
bltn_obj = _create_from_name(builtin, builtin, name)
bltn_obj = builtin_from_name(evaluator, name)
except AttributeError:
continue
else:
if isinstance(bltn_obj, CompiledObject) and bltn_obj.obj is None:
# We want everything except None.
if bltn_obj.obj is None:
# We want to evaluate everything except None.
# TODO do we?
continue
for result in evaluator.execute(bltn_obj, params):
yield result
@@ -263,7 +266,8 @@ class LazyNamesDict(object):
"""
A names_dict instance for compiled objects, resembles the parser.tree.
"""
def __init__(self, compiled_obj, is_instance):
def __init__(self, evaluator, compiled_obj, is_instance):
self._evaluator = evaluator
self._compiled_obj = compiled_obj
self._is_instance = is_instance
@@ -276,7 +280,7 @@ class LazyNamesDict(object):
getattr(self._compiled_obj.obj, name)
except AttributeError:
raise KeyError('%s in %s not found.' % (name, self._compiled_obj))
return [CompiledName(self._compiled_obj, name)]
return [CompiledName(self._evaluator, self._compiled_obj, name)]
def values(self):
obj = self._compiled_obj.obj
@@ -291,13 +295,14 @@ class LazyNamesDict(object):
# dir doesn't include the type names.
if not inspect.ismodule(obj) and obj != type and not self._is_instance:
values += _type_names_dict.values()
values += create(self._evaluator, type).names_dict.values()
return values
class CompiledName(FakeName):
def __init__(self, obj, name):
def __init__(self, evaluator, obj, name):
super(CompiledName, self).__init__(name)
self._evaluator = evaluator
self._obj = obj
self.name = name
@@ -315,7 +320,7 @@ class CompiledName(FakeName):
@underscore_memoization
def parent(self):
module = self._obj.get_parent_until()
return _create_from_name(module, self._obj, self.name)
return _create_from_name(self._evaluator, module, self._obj, self.name)
@parent.setter
def parent(self, value):
@@ -383,7 +388,7 @@ def load_module(evaluator, path=None, name=None):
# complicated import structure of Python.
module = sys.modules[dotted_path]
return CompiledObject(module)
return create(evaluator, module)
docstr_defaults = {
@@ -455,19 +460,7 @@ def _parse_function_doc(doc):
return param_str, ret
class Builtin(CompiledObject):
@memoize_method
def get_by_name(self, name):
return self.names_dict[name][0].parent
def _a_generator(foo):
"""Used to have an object to return for generators."""
yield 42
yield foo
def _create_from_name(module, parent, name):
def _create_from_name(evaluator, module, parent, name):
faked = fake.get_faked(module.obj, parent.obj, name)
# only functions are necessary.
if faked is not None:
@@ -481,35 +474,39 @@ def _create_from_name(module, parent, name):
# PyQt4.QtGui.QStyleOptionComboBox.currentText
# -> just set it to None
obj = None
return CompiledObject(obj, parent)
return create(evaluator, obj, parent)
builtin = Builtin(_builtins)
# TODO Rename magic_function_class to just function_class or something similar.
magic_function_class = CompiledObject(type(load_module), parent=builtin)
module_class = CompiledObject(type(os))
generator_obj = CompiledObject(_a_generator(1.0))
_type_names_dict = builtin.get_by_name('type').names_dict
none_obj = builtin.get_by_name('None')
false_obj = builtin.get_by_name('False')
true_obj = builtin.get_by_name('True')
object_obj = builtin.get_by_name('object')
def builtin_from_name(evaluator, string):
bltn_obj = getattr(_builtins, string)
return create(evaluator, bltn_obj)
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 _a_generator(foo):
"""Used to have an object to return for generators."""
yield 42
yield foo
_SPECIAL_OBJECTS = {
'FUNCTION_CLASS': type(load_module),
'MODULE_CLASS': type(os),
'GENERATOR_OBJECT': _a_generator(1.0),
'BUILTINS': _builtins,
}
def get_special_object(evaluator, identifier):
obj = _SPECIAL_OBJECTS[identifier]
return create(evaluator, obj, parent=create(evaluator, _builtins))
def compiled_objects_cache(func):
def wrapper(evaluator, obj, parent=builtin, module=None):
def wrapper(evaluator, obj, parent=None, module=None):
# Do a very cheap form of caching here.
if parent is None and obj != _builtins:
parent = create(evaluator, _builtins)
key = id(obj), id(parent), id(module)
try:
return evaluator.compiled_cache[key][0]
@@ -522,22 +519,22 @@ def compiled_objects_cache(func):
@compiled_objects_cache
def create(evaluator, obj, parent=builtin, module=None):
def create(evaluator, obj, parent=None, module=None):
"""
A very weird interface class to this module. The more options provided the
more acurate loading compiled objects is.
"""
if not inspect.ismodule(obj):
faked = fake.get_faked(module and module.obj, obj)
if faked is not None:
faked.parent = parent
return faked
try:
if parent == builtin and obj.__module__ in ('builtins', '__builtin__'):
return builtin.get_by_name(obj.__name__)
except AttributeError:
pass
# TODO delete
#try:
#if parent == builtin and obj.__module__ in ('builtins', '__builtin__'):
#return builtin.get_by_name(obj.__name__)
#except AttributeError:
#pass
return CompiledObject(obj, parent)
return CompiledObject(evaluator, obj, parent)

View File

@@ -63,6 +63,9 @@ def get_module(obj):
except AttributeError:
# Unfortunately in some cases like `int` there's no __module__
return builtins
else:
if imp_plz is None:
return builtins
else:
return __import__(imp_plz)
@@ -83,17 +86,23 @@ def _faked(module, obj, name):
return search_scope(faked_mod, obj.__name__)
elif not inspect.isclass(obj):
# object is a method or descriptor
cls = search_scope(faked_mod, obj.__objclass__.__name__)
try:
objclass = obj.__objclass__
except AttributeError:
return None
else:
cls = search_scope(faked_mod, objclass.__name__)
if cls is None:
return
return None
return search_scope(cls, obj.__name__)
else:
if obj == module:
return search_scope(faked_mod, name)
else:
cls = search_scope(faked_mod, obj.__name__)
if cls is None:
return
return None
return search_scope(cls, name)

View File

@@ -212,7 +212,7 @@ class NameFinder(object):
break
debug.dbg('finder.filter_name "%s" in (%s): %s@%s', self.name_str,
self.scope, u(names), self.position)
self.scope, names, self.position)
return list(self._clean_names(names))
def _clean_names(self, names):
@@ -398,7 +398,7 @@ def _eval_param(evaluator, param, scope):
if not res_new:
if param.stars:
t = 'tuple' if param.stars == 1 else 'dict'
typ = list(evaluator.find_types(compiled.builtin, t))[0]
typ = list(evaluator.find_types(evaluator.BUILTINS, t))[0]
res_new = evaluator.execute(typ)
if param.default:
res_new |= evaluator.eval_element(param.default)
@@ -538,7 +538,7 @@ def global_names_dict_generator(evaluator, scope, position):
scope = evaluator.wrap(scope.get_parent_scope())
# Add builtins to the global scope.
for names_dict in compiled.builtin.names_dicts(True):
for names_dict in evaluator.BUILTINS.names_dicts(True):
yield names_dict, None

View File

@@ -41,7 +41,8 @@ class GeneratorMixin(object):
def names_dicts(self, search_global=False): # is always False
dct = {}
executes_generator = '__next__', 'send', 'next'
for names in compiled.generator_obj.names_dict.values():
gen_obj = compiled.get_special_object(self._evaluator, 'GENERATOR_OBJECT')
for names in gen_obj.names_dict.values():
for name in names:
if name.value in executes_generator:
parent = GeneratorMethod(self, name.parent)
@@ -59,7 +60,8 @@ class GeneratorMixin(object):
return True
def py__class__(self, evaluator):
return compiled.generator_obj.py__class__(evaluator)
gen_obj = compiled.get_special_object(self._evaluator, 'GENERATOR_OBJECT')
return gen_obj.py__class__(evaluator)
class Generator(use_metaclass(CachedMetaClass, IterableWrapper, GeneratorMixin)):
@@ -185,7 +187,7 @@ class ArrayMixin(object):
@memoize_default()
def names_dicts(self, search_global=False): # Always False.
# `array.type` is a string with the type, e.g. 'list'.
scope = compiled.builtin.get_by_name(self.type)
scope = compiled.builtin_from_name(self._evaluator, self.type)
# builtins only have one class -> [0]
scopes = self._evaluator.execute_evaluated(scope, self)
return list(scopes)[0].names_dicts(search_global)
@@ -194,7 +196,7 @@ class ArrayMixin(object):
return None # We don't know the length, because of appends.
def py__class__(self, evaluator):
return compiled.builtin.get_by_name(self.type)
return compiled.builtin_from_name(evaluator, self.type)
class ListComprehension(Comprehension, ArrayMixin):
@@ -294,10 +296,10 @@ class Array(IterableWrapper, ArrayMixin):
@safe_property
def parent(self):
return compiled.builtin
return self._evaluator.BUILTINS
def get_parent_until(self):
return compiled.builtin
return self._evaluator.BUILTINS
def __getattr__(self, name):
if name not in ['start_pos', 'get_only_subelement', 'parent',

View File

@@ -6,8 +6,7 @@ import operator
from jedi._compatibility import unicode
from jedi.parser import tree
from jedi import debug
from jedi.evaluate.compiled import (CompiledObject, create, builtin,
keyword_from_value, true_obj, false_obj)
from jedi.evaluate.compiled import CompiledObject, create
from jedi.evaluate import analysis
# Maps Python syntax to the operator module.
@@ -31,8 +30,8 @@ def literals_to_types(evaluator, result):
if is_literal(typ):
# Literals are only valid as long as the operations are
# correct. Otherwise add a value-free instance.
cls = builtin.get_by_name(typ.name.get_code())
new_result.add(list(evaluator.execute(cls))[0])
cls = create(evaluator, typ.name.value)
new_result |= evaluator.execute(cls)
else:
new_result.add(typ)
return new_result
@@ -97,7 +96,7 @@ def factor_calculate(evaluator, types, operator):
value = typ.py__bool__()
if value is None: # Uncertainty.
return
yield keyword_from_value(not value)
yield create(evaluator, not value)
else:
yield typ
@@ -156,10 +155,12 @@ def _element_calculate(evaluator, left, operator, right):
right = right.obj
try:
return set([keyword_from_value(operation(left, right))])
result = operation(left, right)
except TypeError:
# Could be True or False.
return set([true_obj, false_obj])
return set([create(evaluator, True), create(evaluator, False)])
else:
return set([create(evaluator, result)])
elif operator == 'in':
return set()

View File

@@ -9,7 +9,6 @@ count the function calls.
"""
from jedi import debug
from jedi import settings
from jedi.evaluate import compiled
from jedi.evaluate import iterable
@@ -31,12 +30,13 @@ class RecursionDetector(object):
A decorator to detect recursions in statements. In a recursion a statement
at the same place, in the same module may not be executed two times.
"""
def __init__(self):
def __init__(self, evaluator):
self.top = None
self.current = None
self._evaluator = evaluator
def push_stmt(self, stmt):
self.current = _RecursionNode(stmt, self.current)
self.current = _RecursionNode(self._evaluator, stmt, self.current)
check = self._check_recursion()
if check:
debug.warning('catched stmt recursion: %s against %s @%s', stmt,
@@ -71,7 +71,8 @@ class RecursionDetector(object):
class _RecursionNode(object):
""" A node of the RecursionDecorator. """
def __init__(self, stmt, parent):
def __init__(self, evaluator, stmt, parent):
self._evaluator = evaluator
self.script = stmt.get_parent_until()
self.position = stmt.start_pos
self.parent = parent
@@ -80,7 +81,7 @@ class _RecursionNode(object):
# Don't check param instances, they are not causing recursions
# The same's true for the builtins, because the builtins are really
# simple.
self.is_ignored = self.script == compiled.builtin
self.is_ignored = self.script == self._evaluator.BUILTINS
def __eq__(self, other):
if not other:
@@ -107,13 +108,13 @@ def execution_recursion_decorator(func):
class ExecutionRecursionDetector(object):
"""
Catches recursions of executions.
It is designed like a Singelton. Only one instance should exist.
"""
def __init__(self):
def __init__(self, evaluator):
self.recursion_level = 0
self.parent_execution_funcs = []
self.execution_funcs = set()
self.execution_count = 0
self._evaluator = evaluator
def __call__(self, execution):
debug.dbg('Execution recursions: %s', execution, self.recursion_level,
@@ -125,33 +126,33 @@ class ExecutionRecursionDetector(object):
self.pop_execution()
return result
def pop_execution(cls):
cls.parent_execution_funcs.pop()
cls.recursion_level -= 1
def pop_execution(self):
self.parent_execution_funcs.pop()
self.recursion_level -= 1
def push_execution(cls, execution):
in_par_execution_funcs = execution.base in cls.parent_execution_funcs
in_execution_funcs = execution.base in cls.execution_funcs
cls.recursion_level += 1
cls.execution_count += 1
cls.execution_funcs.add(execution.base)
cls.parent_execution_funcs.append(execution.base)
def push_execution(self, execution):
in_par_execution_funcs = execution.base in self.parent_execution_funcs
in_execution_funcs = execution.base in self.execution_funcs
self.recursion_level += 1
self.execution_count += 1
self.execution_funcs.add(execution.base)
self.parent_execution_funcs.append(execution.base)
if cls.execution_count > settings.max_executions:
if self.execution_count > settings.max_executions:
return True
if isinstance(execution.base, (iterable.Array, iterable.Generator)):
return False
module = execution.get_parent_until()
if module == compiled.builtin:
if module == self._evaluator.BUILTINS:
return False
if in_par_execution_funcs:
if cls.recursion_level > settings.max_function_recursion_level:
if self.recursion_level > settings.max_function_recursion_level:
return True
if in_execution_funcs and \
len(cls.execution_funcs) > settings.max_until_execution_unique:
len(self.execution_funcs) > settings.max_until_execution_unique:
return True
if cls.execution_count > settings.max_executions_without_builtins:
if self.execution_count > settings.max_executions_without_builtins:
return True
return False

View File

@@ -86,7 +86,7 @@ class Instance(use_metaclass(CachedMetaClass, Executed)):
self.is_generated = is_generated
if base.name.get_code() in ['list', 'set'] \
and compiled.builtin == base.get_parent_until():
and evaluator.BUILTINS == base.get_parent_until():
# compare the module path with the builtin name.
self.var_args = iterable.check_array_instances(evaluator, self)
elif not is_generated:
@@ -179,7 +179,8 @@ class Instance(use_metaclass(CachedMetaClass, Executed)):
""" Throws a KeyError if there's no method. """
# Arguments in __get__ descriptors are obj, class.
# `method` is the new parent of the array, don't know if that's good.
args = [obj, obj.base] if isinstance(obj, Instance) else [compiled.none_obj, obj]
none_obj = compiled.create(self._evaluator, None)
args = [obj, obj.base] if isinstance(obj, Instance) else [none_obj, obj]
try:
return self.execute_subscope_by_name('__get__', *args)
except KeyError:
@@ -454,7 +455,7 @@ class Class(use_metaclass(CachedMetaClass, Wrapper)):
args = param.Arguments(self._evaluator, arglist)
return list(chain.from_iterable(args.eval_args()))
else:
return [compiled.object_obj]
return [compiled.create(evaluator, object)]
def py__call__(self, evaluator, params):
return set([Instance(evaluator, self, params)])
@@ -463,7 +464,7 @@ class Class(use_metaclass(CachedMetaClass, Wrapper)):
return self._evaluator.find_types(self, name)
def py__class__(self, evaluator):
return compiled.builtin.get_by_name('type')
return compiled.create(evaluator, 'type')
@property
def params(self):
@@ -569,7 +570,8 @@ class Function(use_metaclass(CachedMetaClass, Wrapper)):
if search_global:
yield self.names_dict
else:
for names_dict in compiled.magic_function_class.names_dicts(False):
scope = compiled.get_special_object(self._evaluator, 'FUNCTION_CLASS')
for names_dict in scope.names_dicts(False):
yield names_dict
@Python3Method
@@ -580,7 +582,7 @@ class Function(use_metaclass(CachedMetaClass, Wrapper)):
return FunctionExecution(evaluator, self, params).get_return_types()
def py__class__(self, evaluator):
return compiled.magic_function_class
return compiled.get_special_object(evaluator, 'FUNCTION_CLASS')
def __getattr__(self, name):
return getattr(self.base_func, name)
@@ -920,7 +922,7 @@ class ModuleWrapper(use_metaclass(CachedMetaClass, tree.Module, Wrapper)):
return names
def py__class__(self, evaluator):
return compiled.module_class
return compiled.get_special_object(evaluator, 'MODULE_CLASS')
def __getattr__(self, name):
return getattr(self._module, name)

View File

@@ -32,7 +32,7 @@ def execute(evaluator, obj, arguments):
except AttributeError:
pass
else:
if obj.parent == compiled.builtin:
if obj.parent == evaluator.BUILTINS:
module_name = 'builtins'
elif isinstance(obj.parent, tree.Module):
module_name = str(obj.parent.name)
@@ -183,7 +183,7 @@ def builtins_isinstance(evaluator, objects, types, arguments):
# This is temporary. Everything should have a class attribute in
# Python?! Maybe we'll leave it here, because some numpy objects or
# whatever might not.
return set([compiled.true_obj, compiled.false_obj])
return set([compiled.create(True), compiled.create(False)])
mro = mro_func(evaluator)
@@ -191,7 +191,7 @@ def builtins_isinstance(evaluator, objects, types, arguments):
if cls_or_tup.is_class():
bool_results.add(cls_or_tup in mro)
elif str(cls_or_tup.name) == 'tuple' \
and cls_or_tup.get_parent_scope() == compiled.builtin:
and cls_or_tup.get_parent_scope() == evaluator.BUILTINS:
# Check for tuples.
classes = unite(cls_or_tup.py__iter__())
bool_results.add(any(cls in mro for cls in classes))
@@ -200,7 +200,7 @@ def builtins_isinstance(evaluator, objects, types, arguments):
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.create(evaluator, x) for x in bool_results)
def collections_namedtuple(evaluator, obj, arguments):