forked from VimPlug/jedi
Use the memoize function for faked arguments only when needed.
It's important to note that memoizing every object would mean that theoretically all objects passed through get_faked would get memoized. This would have been a possible memory leak, which we should avoid. Obviously the previous solution proposed in #649 was still better, but this issue was a new one. Also using str() around keys was not a good idea. Refs #649.
This commit is contained in:
@@ -9,7 +9,6 @@ import inspect
|
||||
import types
|
||||
|
||||
from jedi._compatibility import is_py3, builtins, unicode, is_py34
|
||||
from jedi.cache import memoize_function
|
||||
from jedi.parser import ParserWithRecovery, load_grammar
|
||||
from jedi.parser import tree as pt
|
||||
from jedi.evaluate.helpers import FakeName
|
||||
@@ -44,6 +43,10 @@ if is_py3:
|
||||
NOT_CLASS_TYPES += (types.DynamicClassAttribute,)
|
||||
|
||||
|
||||
class FakeDoesNotExist(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def _load_faked_module(module):
|
||||
module_name = module.__name__
|
||||
if module_name == '__builtin__' and not is_py3:
|
||||
@@ -143,13 +146,35 @@ def _faked(module, obj, name):
|
||||
return search_scope(cls, name)
|
||||
|
||||
|
||||
@memoize_function
|
||||
def get_faked(module, obj, name=None):
|
||||
def memoize_faked(obj):
|
||||
"""
|
||||
A typical memoize function that ignores issues with non hashable results.
|
||||
"""
|
||||
cache = obj.cache = {}
|
||||
|
||||
def memoizer(*args, **kwargs):
|
||||
key = (obj, args, frozenset(kwargs.items()))
|
||||
try:
|
||||
result = cache[key]
|
||||
except TypeError:
|
||||
return obj(*args, **kwargs)
|
||||
except KeyError:
|
||||
result = obj(*args, **kwargs)
|
||||
if result is not None:
|
||||
cache[key] = obj(*args, **kwargs)
|
||||
return result
|
||||
else:
|
||||
return result
|
||||
return memoizer
|
||||
|
||||
|
||||
@memoize_faked
|
||||
def _get_faked(module, obj, name=None):
|
||||
obj = type(obj) if is_class_instance(obj) else obj
|
||||
result = _faked(module, obj, name)
|
||||
if result is None or isinstance(result, pt.Class):
|
||||
# We're not interested in classes. What we want is functions.
|
||||
return None
|
||||
raise FakeDoesNotExist
|
||||
else:
|
||||
# Set the docstr which was previously not set (faked modules don't
|
||||
# contain it).
|
||||
@@ -162,6 +187,12 @@ def get_faked(module, obj, name=None):
|
||||
return result
|
||||
|
||||
|
||||
def get_faked(module, obj, name=None, parent=None):
|
||||
faked = _get_faked(module, obj, name)
|
||||
faked.parent = parent
|
||||
return faked
|
||||
|
||||
|
||||
def is_class_instance(obj):
|
||||
"""Like inspect.* methods."""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user