Replace memoize_default with two nicer functions.

This commit is contained in:
Dave Halter
2017-09-05 18:45:06 +02:00
parent e81486894f
commit e85000b798
12 changed files with 47 additions and 48 deletions

View File

@@ -72,7 +72,7 @@ from jedi.evaluate import representation as er
from jedi.evaluate import imports from jedi.evaluate import imports
from jedi.evaluate import recursion from jedi.evaluate import recursion
from jedi.evaluate import iterable from jedi.evaluate import iterable
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import evaluator_function_cache
from jedi.evaluate import stdlib from jedi.evaluate import stdlib
from jedi.evaluate import finder from jedi.evaluate import finder
from jedi.evaluate import compiled from jedi.evaluate import compiled
@@ -139,7 +139,7 @@ class Evaluator(object):
return self._eval_stmt(context, stmt, seek_name) return self._eval_stmt(context, stmt, seek_name)
return set() return set()
#@memoize_default(default=[], evaluator_is_first_arg=True) #@evaluator_function_cache(default=[])
@debug.increase_indent @debug.increase_indent
def _eval_stmt(self, context, stmt, seek_name=None): def _eval_stmt(self, context, stmt, seek_name=None):
""" """
@@ -267,7 +267,7 @@ class Evaluator(object):
return self._eval_element_not_cached(context, element) return self._eval_element_not_cached(context, element)
return self._eval_element_cached(context, element) return self._eval_element_cached(context, element)
@memoize_default(default=set(), evaluator_is_first_arg=True) @evaluator_function_cache(default=set())
def _eval_element_cached(self, context, element): def _eval_element_cached(self, context, element):
return self._eval_element_not_cached(context, element) return self._eval_element_not_cached(context, element)

View File

@@ -1,15 +1,15 @@
""" """
- the popular ``memoize_default`` works like a typical memoize and returns the - the popular ``_memoize_default`` works like a typical memoize and returns the
default otherwise. default otherwise.
- ``CachedMetaClass`` uses ``memoize_default`` to do the same with classes. - ``CachedMetaClass`` uses ``_memoize_default`` to do the same with classes.
""" """
import inspect import inspect
NO_DEFAULT = object() _NO_DEFAULT = object()
def memoize_default(default=NO_DEFAULT, evaluator_is_first_arg=False, second_arg_is_evaluator=False): def _memoize_default(default=_NO_DEFAULT, evaluator_is_first_arg=False, second_arg_is_evaluator=False):
""" This is a typical memoization decorator, BUT there is one difference: """ This is a typical memoization decorator, BUT there is one difference:
To prevent recursion it sets defaults. To prevent recursion it sets defaults.
@@ -36,7 +36,7 @@ def memoize_default(default=NO_DEFAULT, evaluator_is_first_arg=False, second_arg
if key in memo: if key in memo:
return memo[key] return memo[key]
else: else:
if default is not NO_DEFAULT: if default is not _NO_DEFAULT:
memo[key] = default memo[key] = default
rv = function(obj, *args, **kwargs) rv = function(obj, *args, **kwargs)
if inspect.isgenerator(rv): if inspect.isgenerator(rv):
@@ -47,16 +47,16 @@ def memoize_default(default=NO_DEFAULT, evaluator_is_first_arg=False, second_arg
return func return func
def evaluator_function_cache(default=NO_DEFAULT): def evaluator_function_cache(default=_NO_DEFAULT):
def decorator(func): def decorator(func):
return memoize_default(default=default, evaluator_is_first_arg=True)(func) return _memoize_default(default=default, evaluator_is_first_arg=True)(func)
return decorator return decorator
def evaluator_method_cache(default=NO_DEFAULT): def evaluator_method_cache(default=_NO_DEFAULT):
def decorator(func): def decorator(func):
return memoize_default(default=default)(func) return _memoize_default(default=default)(func)
return decorator return decorator
@@ -67,6 +67,6 @@ class CachedMetaClass(type):
class initializations. Either you do it this way or with decorators, but class initializations. Either you do it this way or with decorators, but
with decorators you lose class access (isinstance, etc). with decorators you lose class access (isinstance, etc).
""" """
@memoize_default(None, second_arg_is_evaluator=True) @_memoize_default(None, second_arg_is_evaluator=True)
def __call__(self, *args, **kwargs): def __call__(self, *args, **kwargs):
return super(CachedMetaClass, self).__call__(*args, **kwargs) return super(CachedMetaClass, self).__call__(*args, **kwargs)

View File

@@ -10,7 +10,7 @@ from jedi.evaluate import compiled
from jedi.cache import underscore_memoization from jedi.cache import underscore_memoization
from jedi.evaluate import imports from jedi.evaluate import imports
from jedi.evaluate.context import Context from jedi.evaluate.context import Context
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import evaluator_function_cache
class MixedObject(object): class MixedObject(object):
@@ -102,7 +102,7 @@ class MixedObjectFilter(compiled.CompiledObjectFilter):
#return MixedName(self._evaluator, self._compiled_object, name) #return MixedName(self._evaluator, self._compiled_object, name)
@memoize_default(evaluator_is_first_arg=True) @evaluator_function_cache()
def _load_module(evaluator, path, python_object): def _load_module(evaluator, path, python_object):
module = evaluator.grammar.parse( module = evaluator.grammar.parse(
path=path, path=path,

View File

@@ -21,7 +21,7 @@ from textwrap import dedent
from jedi._compatibility import u from jedi._compatibility import u
from jedi.common import unite from jedi.common import unite
from jedi.evaluate import context from jedi.evaluate import context
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import evaluator_method_cache
from jedi.common import indent_block from jedi.common import indent_block
from jedi.evaluate.iterable import SequenceLiteralContext, FakeSequence from jedi.evaluate.iterable import SequenceLiteralContext, FakeSequence
@@ -187,7 +187,7 @@ def _execute_array_values(evaluator, array):
return array.execute_evaluated() return array.execute_evaluated()
@memoize_default() @evaluator_method_cache()
def infer_param(execution_context, param): def infer_param(execution_context, param):
from jedi.evaluate.instance import InstanceFunctionExecution from jedi.evaluate.instance import InstanceFunctionExecution
@@ -211,7 +211,7 @@ def infer_param(execution_context, param):
return types return types
@memoize_default() @evaluator_method_cache()
def infer_return_types(function_context): def infer_return_types(function_context):
def search_return_in_docstr(code): def search_return_in_docstr(code):
for p in DOCSTRING_RETURN_PATTERNS: for p in DOCSTRING_RETURN_PATTERNS:

View File

@@ -20,7 +20,7 @@ It works as follows:
from parso.python import tree from parso.python import tree
from jedi import settings from jedi import settings
from jedi import debug from jedi import debug
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import evaluator_function_cache
from jedi.evaluate import imports from jedi.evaluate import imports
from jedi.evaluate.param import TreeArguments, create_default_param from jedi.evaluate.param import TreeArguments, create_default_param
from jedi.common import to_list, unite from jedi.common import to_list, unite
@@ -93,7 +93,7 @@ def search_params(evaluator, execution_context, funcdef):
evaluator.dynamic_params_depth -= 1 evaluator.dynamic_params_depth -= 1
@memoize_default([], evaluator_is_first_arg=True) @evaluator_function_cache(default=[])
@to_list @to_list
def _search_function_executions(evaluator, module_context, funcdef): def _search_function_executions(evaluator, module_context, funcdef):
""" """

View File

@@ -29,13 +29,13 @@ from jedi.evaluate import sys_path
from jedi.evaluate import helpers from jedi.evaluate import helpers
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate import analysis from jedi.evaluate import analysis
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import evaluator_method_cache
from jedi.evaluate.filters import AbstractNameDefinition from jedi.evaluate.filters import AbstractNameDefinition
# This memoization is needed, because otherwise we will infinitely loop on # This memoization is needed, because otherwise we will infinitely loop on
# certain imports. # certain imports.
@memoize_default(default=set()) @evaluator_method_cache(default=set())
def infer_import(context, tree_name, is_goto=False): def infer_import(context, tree_name, is_goto=False):
module_context = context.get_root_context() module_context = context.get_root_context()
import_node = search_ancestor(tree_name, 'import_name', 'import_from') import_node = search_ancestor(tree_name, 'import_name', 'import_from')

View File

@@ -6,7 +6,7 @@ from jedi import debug
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate import filters from jedi.evaluate import filters
from jedi.evaluate.context import Context, LazyKnownContext, LazyKnownContexts from jedi.evaluate.context import Context, LazyKnownContext, LazyKnownContexts
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import evaluator_method_cache
from jedi.cache import memoize_method from jedi.cache import memoize_method
from jedi.evaluate import representation as er from jedi.evaluate import representation as er
from jedi.evaluate.dynamic import search_params from jedi.evaluate.dynamic import search_params
@@ -148,7 +148,7 @@ class AbstractInstanceContext(Context):
if isinstance(name, LazyInstanceName): if isinstance(name, LazyInstanceName):
yield self._create_init_execution(name.class_context, name.tree_name.parent) yield self._create_init_execution(name.class_context, name.tree_name.parent)
@memoize_default() @evaluator_method_cache()
def create_instance_context(self, class_context, node): def create_instance_context(self, class_context, node):
if node.parent.type in ('funcdef', 'classdef'): if node.parent.type in ('funcdef', 'classdef'):
node = node.parent node = node.parent

View File

@@ -32,7 +32,7 @@ from jedi.evaluate import pep0484
from jedi.evaluate import context from jedi.evaluate import context
from jedi.evaluate import precedence from jedi.evaluate import precedence
from jedi.evaluate import recursion from jedi.evaluate import recursion
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import evaluator_method_cache
from jedi.evaluate.filters import DictFilter, AbstractNameDefinition, \ from jedi.evaluate.filters import DictFilter, AbstractNameDefinition, \
ParserTreeFilter ParserTreeFilter
from jedi.parser_utils import get_comp_fors from jedi.parser_utils import get_comp_fors
@@ -228,7 +228,7 @@ class Comprehension(AbstractSequence):
""" """
return self._get_comprehension().children[index] return self._get_comprehension().children[index]
@memoize_default() @evaluator_method_cache()
def _get_comp_for_context(self, parent_context, comp_for): def _get_comp_for_context(self, parent_context, comp_for):
# TODO shouldn't this be part of create_context? # TODO shouldn't this be part of create_context?
return CompForContext.from_comp_for(parent_context, comp_for) return CompForContext.from_comp_for(parent_context, comp_for)
@@ -261,7 +261,7 @@ class Comprehension(AbstractSequence):
else: else:
yield iterated yield iterated
@memoize_default(default=[]) @evaluator_method_cache(default=[])
@common.to_list @common.to_list
def _iterate(self): def _iterate(self):
comp_fors = tuple(get_comp_fors(self._get_comp_for())) comp_fors = tuple(get_comp_fors(self._get_comp_for()))
@@ -698,7 +698,7 @@ def check_array_additions(context, sequence):
return _check_array_additions(context, sequence) return _check_array_additions(context, sequence)
@memoize_default(default=set()) @evaluator_method_cache(default=set())
@debug.increase_indent @debug.increase_indent
def _check_array_additions(context, sequence): def _check_array_additions(context, sequence):
""" """

View File

@@ -27,7 +27,7 @@ from parso import ParserSyntaxError
from parso.python import tree from parso.python import tree
from jedi.common import unite from jedi.common import unite
from jedi.evaluate.cache import memoize_default from jedi.evaluate.cache import evaluator_method_cache
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate.context import LazyTreeContext from jedi.evaluate.context import LazyTreeContext
from jedi import debug from jedi import debug
@@ -81,7 +81,7 @@ def _fix_forward_reference(context, node):
return node return node
@memoize_default() @evaluator_method_cache()
def infer_param(execution_context, param): def infer_param(execution_context, param):
annotation = param.annotation annotation = param.annotation
module_context = execution_context.get_root_context() module_context = execution_context.get_root_context()
@@ -101,7 +101,7 @@ def py__annotations__(funcdef):
return dct return dct
@memoize_default() @evaluator_method_cache()
def infer_return_types(function_context): def infer_return_types(function_context):
annotation = py__annotations__(function_context.tree_node).get("return", None) annotation = py__annotations__(function_context.tree_node).get("return", None)
module_context = function_context.get_root_context() module_context = function_context.get_root_context()

View File

@@ -48,7 +48,7 @@ from parso import python_bytes_to_unicode
from jedi._compatibility import use_metaclass from jedi._compatibility import use_metaclass
from jedi import debug from jedi import debug
from jedi.evaluate.cache import memoize_default, CachedMetaClass, NO_DEFAULT from jedi.evaluate.cache import evaluator_method_cache, CachedMetaClass
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate import recursion from jedi.evaluate import recursion
from jedi.evaluate import iterable from jedi.evaluate import iterable
@@ -115,7 +115,7 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext)):
super(ClassContext, self).__init__(evaluator, parent_context=parent_context) super(ClassContext, self).__init__(evaluator, parent_context=parent_context)
self.tree_node = classdef self.tree_node = classdef
@memoize_default(default=()) @evaluator_method_cache(default=())
def py__mro__(self): def py__mro__(self):
def add(cls): def add(cls):
if cls not in mro: if cls not in mro:
@@ -151,7 +151,7 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext)):
add(cls_new) add(cls_new)
return tuple(mro) return tuple(mro)
@memoize_default(default=()) @evaluator_method_cache(default=())
def py__bases__(self): def py__bases__(self):
arglist = self.tree_node.get_super_arglist() arglist = self.tree_node.get_super_arglist()
if arglist: if arglist:
@@ -312,7 +312,7 @@ class FunctionExecutionContext(context.TreeContext):
self.tree_node = function_context.tree_node self.tree_node = function_context.tree_node
self.var_args = var_args self.var_args = var_args
@memoize_default(default=set()) @evaluator_method_cache(default=set())
@recursion.execution_recursion_decorator() @recursion.execution_recursion_decorator()
def get_return_values(self, check_yields=False): def get_return_values(self, check_yields=False):
funcdef = self.tree_node funcdef = self.tree_node
@@ -414,7 +414,7 @@ class FunctionExecutionContext(context.TreeContext):
until_position=until_position, until_position=until_position,
origin_scope=origin_scope) origin_scope=origin_scope)
@memoize_default(default=NO_DEFAULT) @evaluator_method_cache()
def get_params(self): def get_params(self):
return param.get_params(self, self.var_args) return param.get_params(self, self.var_args)
@@ -424,7 +424,7 @@ class AnonymousFunctionExecution(FunctionExecutionContext):
super(AnonymousFunctionExecution, self).__init__( super(AnonymousFunctionExecution, self).__init__(
evaluator, parent_context, function_context, var_args=None) evaluator, parent_context, function_context, var_args=None)
@memoize_default(default=NO_DEFAULT) @evaluator_method_cache()
def get_params(self): def get_params(self):
# We need to do a dynamic search here. # We need to do a dynamic search here.
return search_params(self.evaluator, self, self.tree_node) return search_params(self.evaluator, self, self.tree_node)
@@ -483,7 +483,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext)):
# I'm not sure if the star import cache is really that effective anymore # I'm not sure if the star import cache is really that effective anymore
# with all the other really fast import caches. Recheck. Also we would need # with all the other really fast import caches. Recheck. Also we would need
# to push the star imports into Evaluator.modules, if we reenable this. # to push the star imports into Evaluator.modules, if we reenable this.
@memoize_default([]) @evaluator_method_cache([])
def star_imports(self): def star_imports(self):
modules = [] modules = []
for i in self.tree_node.iter_imports(): for i in self.tree_node.iter_imports():
@@ -496,7 +496,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext)):
modules += new modules += new
return modules return modules
@memoize_default() @evaluator_method_cache()
def _module_attributes_dict(self): def _module_attributes_dict(self):
names = ['__file__', '__package__', '__doc__', '__name__'] names = ['__file__', '__package__', '__doc__', '__name__']
# All the additional module attributes are strings. # All the additional module attributes are strings.
@@ -514,7 +514,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext)):
return re.sub('\.[a-z]+-\d{2}[mud]{0,3}$', '', r.group(1)) return re.sub('\.[a-z]+-\d{2}[mud]{0,3}$', '', r.group(1))
@property @property
@memoize_default() @evaluator_method_cache()
def name(self): def name(self):
return ModuleName(self, self._string_name) return ModuleName(self, self._string_name)
@@ -597,7 +597,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext)):
else: else:
return self._py__path__ return self._py__path__
@memoize_default() @evaluator_method_cache()
def _sub_modules_dict(self): def _sub_modules_dict(self):
""" """
Lists modules in the directory of this module (if this module is a Lists modules in the directory of this module (if this module is a
@@ -661,7 +661,7 @@ class ImplicitNamespaceContext(use_metaclass(CachedMetaClass, context.TreeContex
yield DictFilter(self._sub_modules_dict()) yield DictFilter(self._sub_modules_dict())
@property @property
@memoize_default() @evaluator_method_cache()
def name(self): def name(self):
string_name = self.py__package__().rpartition('.')[-1] string_name = self.py__package__().rpartition('.')[-1]
return ImplicitNSName(self, string_name) return ImplicitNSName(self, string_name)
@@ -678,7 +678,7 @@ class ImplicitNamespaceContext(use_metaclass(CachedMetaClass, context.TreeContex
def py__path__(self): def py__path__(self):
return lambda: [self.paths] return lambda: [self.paths]
@memoize_default() @evaluator_method_cache()
def _sub_modules_dict(self): def _sub_modules_dict(self):
names = {} names = {}

View File

@@ -4,8 +4,7 @@ import sys
from jedi.evaluate.site import addsitedir from jedi.evaluate.site import addsitedir
from jedi._compatibility import exec_function, unicode from jedi._compatibility import exec_function, unicode
from parso.python import tree from jedi.evaluate.cache import evaluator_function_cache
from jedi.evaluate.cache import memoize_default
from jedi.evaluate.compiled import CompiledObject from jedi.evaluate.compiled import CompiledObject
from jedi.evaluate.context import ContextualizedNode from jedi.evaluate.context import ContextualizedNode
from jedi import settings from jedi import settings
@@ -184,7 +183,7 @@ def _check_module(module_context):
return sys_path return sys_path
@memoize_default(evaluator_is_first_arg=True, default=[]) @evaluator_function_cache(default=[])
def sys_path_with_modifications(evaluator, module_context): def sys_path_with_modifications(evaluator, module_context):
path = module_context.py__file__() path = module_context.py__file__()
if path is None: if path is None:

View File

@@ -15,8 +15,8 @@ sys.path.append('a' +* '/thirdparty')
#? ['evaluate'] #? ['evaluate']
import evaluate import evaluate
#? ['Evaluator'] #? ['evaluator_function_cache']
evaluate.Evaluator evaluate.Evaluator_fu
#? ['jedi_'] #? ['jedi_']
import jedi_ import jedi_