diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 16d3d997..9ddc7b7e 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -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: diff --git a/jedi/api/interpreter.py b/jedi/api/interpreter.py index 331ade37..7325c9bc 100644 --- a/jedi/api/interpreter.py +++ b/jedi/api/interpreter.py @@ -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) diff --git a/jedi/api/keywords.py b/jedi/api/keywords.py index 2a54ba2d..97839f9f 100644 --- a/jedi/api/keywords.py +++ b/jedi/api/keywords.py @@ -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 diff --git a/jedi/debug.py b/jedi/debug.py index 0c72bc8a..430a0329 100644 --- a/jedi/debug.py +++ b/jedi/debug.py @@ -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() diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 9ea011bf..042bd43d 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -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): diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index b5b5ecba..92856987 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -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) diff --git a/jedi/evaluate/compiled/fake.py b/jedi/evaluate/compiled/fake.py index 0037cfc7..947fef26 100644 --- a/jedi/evaluate/compiled/fake.py +++ b/jedi/evaluate/compiled/fake.py @@ -64,7 +64,10 @@ def get_module(obj): # Unfortunately in some cases like `int` there's no __module__ return builtins else: - return __import__(imp_plz) + if imp_plz is None: + return builtins + else: + return __import__(imp_plz) def _faked(module, obj, name): @@ -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__) - if cls is None: - return - return search_scope(cls, obj.__name__) + try: + objclass = obj.__objclass__ + except AttributeError: + return None + else: + cls = search_scope(faked_mod, objclass.__name__) + if cls is None: + 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) diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index edaf9e85..9e25ad6d 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -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 diff --git a/jedi/evaluate/iterable.py b/jedi/evaluate/iterable.py index 42ba251e..0e9ff086 100644 --- a/jedi/evaluate/iterable.py +++ b/jedi/evaluate/iterable.py @@ -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', diff --git a/jedi/evaluate/precedence.py b/jedi/evaluate/precedence.py index 38c772ab..778d3574 100644 --- a/jedi/evaluate/precedence.py +++ b/jedi/evaluate/precedence.py @@ -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() diff --git a/jedi/evaluate/recursion.py b/jedi/evaluate/recursion.py index 86443b1d..a95ba3e0 100644 --- a/jedi/evaluate/recursion.py +++ b/jedi/evaluate/recursion.py @@ -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 diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 3b58ef2a..9cd60a0a 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -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) diff --git a/jedi/evaluate/stdlib.py b/jedi/evaluate/stdlib.py index bab0d9cc..0bd23e62 100644 --- a/jedi/evaluate/stdlib.py +++ b/jedi/evaluate/stdlib.py @@ -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):