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 recursion
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 finder
from jedi.evaluate import compiled
@@ -139,7 +139,7 @@ class Evaluator(object):
return self._eval_stmt(context, stmt, seek_name)
return set()
#@memoize_default(default=[], evaluator_is_first_arg=True)
#@evaluator_function_cache(default=[])
@debug.increase_indent
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_cached(context, element)
@memoize_default(default=set(), evaluator_is_first_arg=True)
@evaluator_function_cache(default=set())
def _eval_element_cached(self, 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.
- ``CachedMetaClass`` uses ``memoize_default`` to do the same with classes.
- ``CachedMetaClass`` uses ``_memoize_default`` to do the same with classes.
"""
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:
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:
return memo[key]
else:
if default is not NO_DEFAULT:
if default is not _NO_DEFAULT:
memo[key] = default
rv = function(obj, *args, **kwargs)
if inspect.isgenerator(rv):
@@ -47,16 +47,16 @@ def memoize_default(default=NO_DEFAULT, evaluator_is_first_arg=False, second_arg
return func
def evaluator_function_cache(default=NO_DEFAULT):
def evaluator_function_cache(default=_NO_DEFAULT):
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
def evaluator_method_cache(default=NO_DEFAULT):
def evaluator_method_cache(default=_NO_DEFAULT):
def decorator(func):
return memoize_default(default=default)(func)
return _memoize_default(default=default)(func)
return decorator
@@ -67,6 +67,6 @@ class CachedMetaClass(type):
class initializations. Either you do it this way or with decorators, but
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):
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.evaluate import imports
from jedi.evaluate.context import Context
from jedi.evaluate.cache import memoize_default
from jedi.evaluate.cache import evaluator_function_cache
class MixedObject(object):
@@ -102,7 +102,7 @@ class MixedObjectFilter(compiled.CompiledObjectFilter):
#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):
module = evaluator.grammar.parse(
path=path,

View File

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

View File

@@ -20,7 +20,7 @@ It works as follows:
from parso.python import tree
from jedi import settings
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.param import TreeArguments, create_default_param
from jedi.common import to_list, unite
@@ -93,7 +93,7 @@ def search_params(evaluator, execution_context, funcdef):
evaluator.dynamic_params_depth -= 1
@memoize_default([], evaluator_is_first_arg=True)
@evaluator_function_cache(default=[])
@to_list
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 compiled
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
# This memoization is needed, because otherwise we will infinitely loop on
# certain imports.
@memoize_default(default=set())
@evaluator_method_cache(default=set())
def infer_import(context, tree_name, is_goto=False):
module_context = context.get_root_context()
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 filters
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.evaluate import representation as er
from jedi.evaluate.dynamic import search_params
@@ -148,7 +148,7 @@ class AbstractInstanceContext(Context):
if isinstance(name, LazyInstanceName):
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):
if node.parent.type in ('funcdef', 'classdef'):
node = node.parent

View File

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

View File

@@ -27,7 +27,7 @@ from parso import ParserSyntaxError
from parso.python import tree
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.context import LazyTreeContext
from jedi import debug
@@ -81,7 +81,7 @@ def _fix_forward_reference(context, node):
return node
@memoize_default()
@evaluator_method_cache()
def infer_param(execution_context, param):
annotation = param.annotation
module_context = execution_context.get_root_context()
@@ -101,7 +101,7 @@ def py__annotations__(funcdef):
return dct
@memoize_default()
@evaluator_method_cache()
def infer_return_types(function_context):
annotation = py__annotations__(function_context.tree_node).get("return", None)
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 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 recursion
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)
self.tree_node = classdef
@memoize_default(default=())
@evaluator_method_cache(default=())
def py__mro__(self):
def add(cls):
if cls not in mro:
@@ -151,7 +151,7 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext)):
add(cls_new)
return tuple(mro)
@memoize_default(default=())
@evaluator_method_cache(default=())
def py__bases__(self):
arglist = self.tree_node.get_super_arglist()
if arglist:
@@ -312,7 +312,7 @@ class FunctionExecutionContext(context.TreeContext):
self.tree_node = function_context.tree_node
self.var_args = var_args
@memoize_default(default=set())
@evaluator_method_cache(default=set())
@recursion.execution_recursion_decorator()
def get_return_values(self, check_yields=False):
funcdef = self.tree_node
@@ -414,7 +414,7 @@ class FunctionExecutionContext(context.TreeContext):
until_position=until_position,
origin_scope=origin_scope)
@memoize_default(default=NO_DEFAULT)
@evaluator_method_cache()
def get_params(self):
return param.get_params(self, self.var_args)
@@ -424,7 +424,7 @@ class AnonymousFunctionExecution(FunctionExecutionContext):
super(AnonymousFunctionExecution, self).__init__(
evaluator, parent_context, function_context, var_args=None)
@memoize_default(default=NO_DEFAULT)
@evaluator_method_cache()
def get_params(self):
# We need to do a dynamic search here.
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
# 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.
@memoize_default([])
@evaluator_method_cache([])
def star_imports(self):
modules = []
for i in self.tree_node.iter_imports():
@@ -496,7 +496,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext)):
modules += new
return modules
@memoize_default()
@evaluator_method_cache()
def _module_attributes_dict(self):
names = ['__file__', '__package__', '__doc__', '__name__']
# 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))
@property
@memoize_default()
@evaluator_method_cache()
def name(self):
return ModuleName(self, self._string_name)
@@ -597,7 +597,7 @@ class ModuleContext(use_metaclass(CachedMetaClass, context.TreeContext)):
else:
return self._py__path__
@memoize_default()
@evaluator_method_cache()
def _sub_modules_dict(self):
"""
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())
@property
@memoize_default()
@evaluator_method_cache()
def name(self):
string_name = self.py__package__().rpartition('.')[-1]
return ImplicitNSName(self, string_name)
@@ -678,7 +678,7 @@ class ImplicitNamespaceContext(use_metaclass(CachedMetaClass, context.TreeContex
def py__path__(self):
return lambda: [self.paths]
@memoize_default()
@evaluator_method_cache()
def _sub_modules_dict(self):
names = {}

View File

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

View File

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