1
0
forked from VimPlug/jedi

Creating objects works now a bit better but is a huge mess.

This commit is contained in:
Dave Halter
2017-11-26 18:26:02 +01:00
parent e71f0062dd
commit 85ce57a863
4 changed files with 49 additions and 43 deletions

View File

@@ -15,6 +15,7 @@ from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition, \
ContextNameMixin ContextNameMixin
from jedi.evaluate.base_context import Context, ContextSet from jedi.evaluate.base_context import Context, ContextSet
from jedi.evaluate.compiled.access import DirectObjectAccess, _sentinel, create_access from jedi.evaluate.compiled.access import DirectObjectAccess, _sentinel, create_access
from jedi.evaluate.cache import evaluator_function_cache
from . import fake from . import fake
@@ -512,47 +513,32 @@ def get_special_object(evaluator, identifier):
return create(evaluator, obj, parent_context=parent_context) return create(evaluator, obj, parent_context=parent_context)
def compiled_objects_cache(attribute_name): def _normalize_create_args(func):
def decorator(func): """The cache doesn't care about keyword vs. normal args."""
"""
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): def wrapper(evaluator, obj, parent_context=None, faked=None):
cache = getattr(evaluator, attribute_name) return func(evaluator, obj, parent_context, faked)
# 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 wrapper
return decorator
@compiled_objects_cache('compiled_cache')
def create(evaluator, obj, parent_context=None, faked=None): 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 inspect.ismodule(obj):
if parent_context is not None: if parent_context is not None:
# Modules don't have parents, be careful with caching: recurse. # Modules don't have parents, be careful with caching: recurse.
return create(evaluator, obj) 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: #if parent_context is None and obj is not _builtins:
#return create(evaluator, obj, create(evaluator, _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.... # TODO wow this is a mess....
if parent_context is None and not faked: if parent_context is None and not faked:
parent_context = create(evaluator, _builtins) parent_context = create(evaluator, _builtins)
return create(evaluator, obj, parent_context) return create(evaluator, access, parent_context)
print('OOOOOOOOOO', obj) if access._obj == str:
if access._obj == _builtins and parent_context is not None: print('OOOOOOOOOO', id(access), id(parent_context), id(faked))
raise 1
return CompiledObject(evaluator, access, parent_context, faked) return CompiledObject(evaluator, access, parent_context, faked)

View File

@@ -5,7 +5,6 @@ from collections import namedtuple
from jedi._compatibility import unicode, is_py3, is_py34, builtins, py_version from jedi._compatibility import unicode, is_py3, is_py34, builtins, py_version
from jedi.evaluate.compiled.getattr_static import getattr_static from jedi.evaluate.compiled.getattr_static import getattr_static
from jedi.evaluate.cache import evaluator_function_cache
MethodDescriptorType = type(str.replace) MethodDescriptorType = type(str.replace)
@@ -77,9 +76,32 @@ _OPERATORS.update(COMPARISON_OPERATORS)
SignatureParam = namedtuple('SignatureParam', 'name default empty annotation') 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): def create_access(evaluator, obj):
print('create', obj)
return DirectObjectAccess(evaluator, obj) return DirectObjectAccess(evaluator, obj)

View File

@@ -13,6 +13,7 @@ from jedi.evaluate.base_context import Context, ContextSet
from jedi.evaluate.context import ModuleContext from jedi.evaluate.context import ModuleContext
from jedi.evaluate.cache import evaluator_function_cache from jedi.evaluate.cache import evaluator_function_cache
from jedi.evaluate.compiled.getattr_static import getattr_static from jedi.evaluate.compiled.getattr_static import getattr_static
from jedi.evaluate.compiled.access import compiled_objects_cache
class MixedObject(object): class MixedObject(object):
@@ -191,7 +192,7 @@ def _find_syntax_node_name(evaluator, access):
return names[-1].parent, path return names[-1].parent, path
@compiled.compiled_objects_cache('mixed_cache') @compiled_objects_cache('mixed_cache')
def _create(evaluator, access, parent_context=None, *args): def _create(evaluator, access, parent_context=None, *args):
tree_node, path = _find_syntax_node_name(evaluator, access) tree_node, path = _find_syntax_node_name(evaluator, access)

View File

@@ -226,7 +226,6 @@ def builtins_isinstance(evaluator, objects, types, arguments):
return ContextSet(compiled.create(evaluator, True), compiled.create(evaluator, False)) return ContextSet(compiled.create(evaluator, True), compiled.create(evaluator, False))
mro = mro_func() mro = mro_func()
print(mro, types)
for cls_or_tup in types: for cls_or_tup in types:
if cls_or_tup.is_class(): if cls_or_tup.is_class():
@@ -249,7 +248,6 @@ def builtins_isinstance(evaluator, objects, types, arguments):
'not %s.' % cls_or_tup 'not %s.' % cls_or_tup
analysis.add(lazy_context._context, 'type-error-isinstance', node, message) 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) return ContextSet.from_iterable(compiled.create(evaluator, x) for x in bool_results)