From 85ce57a863ba1e8900ba5c92fbf2b1c53467a189 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Sun, 26 Nov 2017 18:26:02 +0100 Subject: [PATCH] Creating objects works now a bit better but is a huge mess. --- jedi/evaluate/compiled/__init__.py | 59 +++++++++++------------------- jedi/evaluate/compiled/access.py | 28 ++++++++++++-- jedi/evaluate/compiled/mixed.py | 3 +- jedi/evaluate/stdlib.py | 2 - 4 files changed, 49 insertions(+), 43 deletions(-) diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index d210060a..27148096 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -15,6 +15,7 @@ from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition, \ ContextNameMixin from jedi.evaluate.base_context import Context, ContextSet from jedi.evaluate.compiled.access import DirectObjectAccess, _sentinel, create_access +from jedi.evaluate.cache import evaluator_function_cache from . import fake @@ -512,47 +513,32 @@ def get_special_object(evaluator, identifier): return create(evaluator, obj, parent_context=parent_context) -def compiled_objects_cache(attribute_name): - def decorator(func): - """ - This decorator caches just the ids, oopposed to caching the object itself. - Caching the id has the advantage that an object doesn't need to be - hashable. - """ - def wrapper(evaluator, obj, parent_context=None, faked=None): - cache = getattr(evaluator, attribute_name) - # Do a very cheap form of caching here. - key = id(obj), id(parent_context) - try: - return cache[key][0] - except KeyError: - # TODO this whole decorator is way too ugly - result = func(evaluator, obj, parent_context, faked) - # Need to cache all of them, otherwise the id could be overwritten. - cache[key] = result, obj, parent_context, faked - return result - return wrapper - - return decorator +def _normalize_create_args(func): + """The cache doesn't care about keyword vs. normal args.""" + def wrapper(evaluator, obj, parent_context=None, faked=None): + return func(evaluator, obj, parent_context, faked) + return wrapper -@compiled_objects_cache('compiled_cache') def create(evaluator, obj, parent_context=None, faked=None): - """ - A very weird interface class to this module. The more options provided the - more acurate loading compiled objects is. - """ - if isinstance(obj, DirectObjectAccess): - access = obj - else: - print('xxx', obj) - return create(evaluator, create_access(evaluator, obj), parent_context, faked) - if inspect.ismodule(obj): if parent_context is not None: # Modules don't have parents, be careful with caching: recurse. return create(evaluator, obj) + if isinstance(obj, DirectObjectAccess): + return _create(evaluator, obj, parent_context, faked) + else: + return _create(evaluator, create_access(evaluator, obj), parent_context, faked) + + +@_normalize_create_args +@evaluator_function_cache() +def _create(evaluator, access, parent_context=None, faked=None): + """ + A very weird interface class to this module. The more options provided the + more acurate loading compiled objects is. + """ #if parent_context is None and obj is not _builtins: #return create(evaluator, obj, create(evaluator, _builtins)) @@ -577,11 +563,10 @@ def create(evaluator, obj, parent_context=None, faked=None): # TODO wow this is a mess.... if parent_context is None and not faked: parent_context = create(evaluator, _builtins) - return create(evaluator, obj, parent_context) + return create(evaluator, access, parent_context) - print('OOOOOOOOOO', obj) - if access._obj == _builtins and parent_context is not None: - raise 1 + if access._obj == str: + print('OOOOOOOOOO', id(access), id(parent_context), id(faked)) return CompiledObject(evaluator, access, parent_context, faked) diff --git a/jedi/evaluate/compiled/access.py b/jedi/evaluate/compiled/access.py index 28e6a592..98ca26ea 100644 --- a/jedi/evaluate/compiled/access.py +++ b/jedi/evaluate/compiled/access.py @@ -5,7 +5,6 @@ from collections import namedtuple from jedi._compatibility import unicode, is_py3, is_py34, builtins, py_version from jedi.evaluate.compiled.getattr_static import getattr_static -from jedi.evaluate.cache import evaluator_function_cache MethodDescriptorType = type(str.replace) @@ -77,9 +76,32 @@ _OPERATORS.update(COMPARISON_OPERATORS) SignatureParam = namedtuple('SignatureParam', 'name default empty annotation') -@evaluator_function_cache() +def compiled_objects_cache(attribute_name): + def decorator(func): + """ + This decorator caches just the ids, oopposed to caching the object itself. + Caching the id has the advantage that an object doesn't need to be + hashable. + """ + def wrapper(evaluator, obj): + cache = getattr(evaluator, attribute_name) + # Do a very cheap form of caching here. + key = id(obj) + try: + cache[key] + return cache[key][0] + except KeyError: + result = func(evaluator, obj) + # Need to cache all of them, otherwise the id could be overwritten. + cache[key] = result, obj + return result + return wrapper + + return decorator + + +@compiled_objects_cache('compiled_cache') def create_access(evaluator, obj): - print('create', obj) return DirectObjectAccess(evaluator, obj) diff --git a/jedi/evaluate/compiled/mixed.py b/jedi/evaluate/compiled/mixed.py index c0845374..9d793f9d 100644 --- a/jedi/evaluate/compiled/mixed.py +++ b/jedi/evaluate/compiled/mixed.py @@ -13,6 +13,7 @@ from jedi.evaluate.base_context import Context, ContextSet from jedi.evaluate.context import ModuleContext from jedi.evaluate.cache import evaluator_function_cache from jedi.evaluate.compiled.getattr_static import getattr_static +from jedi.evaluate.compiled.access import compiled_objects_cache class MixedObject(object): @@ -191,7 +192,7 @@ def _find_syntax_node_name(evaluator, access): return names[-1].parent, path -@compiled.compiled_objects_cache('mixed_cache') +@compiled_objects_cache('mixed_cache') def _create(evaluator, access, parent_context=None, *args): tree_node, path = _find_syntax_node_name(evaluator, access) diff --git a/jedi/evaluate/stdlib.py b/jedi/evaluate/stdlib.py index 07bb393c..76a58177 100644 --- a/jedi/evaluate/stdlib.py +++ b/jedi/evaluate/stdlib.py @@ -226,7 +226,6 @@ def builtins_isinstance(evaluator, objects, types, arguments): return ContextSet(compiled.create(evaluator, True), compiled.create(evaluator, False)) mro = mro_func() - print(mro, types) for cls_or_tup in types: if cls_or_tup.is_class(): @@ -249,7 +248,6 @@ def builtins_isinstance(evaluator, objects, types, arguments): 'not %s.' % cls_or_tup analysis.add(lazy_context._context, 'type-error-isinstance', node, message) - print(objects, types, bool_results) return ContextSet.from_iterable(compiled.create(evaluator, x) for x in bool_results)