1
0
forked from VimPlug/jedi

Start refactoring arguments.

This commit is contained in:
Dave Halter
2017-09-09 15:43:37 +02:00
parent 2f213f89e5
commit 04c4313dc7
6 changed files with 74 additions and 45 deletions

View File

@@ -189,7 +189,7 @@ def _execute_array_values(evaluator, array):
@evaluator_method_cache()
def infer_param(execution_context, param):
from jedi.evaluate.instance import InstanceFunctionExecution
from jedi.evaluate.instance import AnonymousInstanceFunctionExecution
def eval_docstring(docstring):
return set(
@@ -203,7 +203,7 @@ def infer_param(execution_context, param):
return set()
types = eval_docstring(execution_context.py__doc__())
if isinstance(execution_context, InstanceFunctionExecution) and \
if isinstance(execution_context, AnonymousInstanceFunctionExecution) and \
execution_context.function_context.name.string_name == '__init__':
class_context = execution_context.instance.class_context
types |= eval_docstring(class_context.py__doc__())

View File

@@ -22,7 +22,7 @@ from jedi import settings
from jedi import debug
from jedi.evaluate.cache import evaluator_function_cache
from jedi.evaluate import imports
from jedi.evaluate.param import TreeArguments, create_default_param
from jedi.evaluate.param import TreeArguments, create_default_params
from jedi.evaluate.helpers import is_stdlib_path
from jedi.common import to_list, unite
from jedi.parser_utils import get_parent_scope
@@ -68,7 +68,7 @@ def search_params(evaluator, execution_context, funcdef):
is.
"""
if not settings.dynamic_params:
return []
return create_default_params(execution_context, funcdef)
evaluator.dynamic_params_depth += 1
try:
@@ -78,7 +78,7 @@ def search_params(evaluator, execution_context, funcdef):
# don't work with it (except if you are a core maintainer, sorry).
# This makes everything slower. Just disable it and run the tests,
# you will see the slowdown, especially in 3.6.
return []
return create_default_params(execution_context, funcdef)
debug.dbg('Dynamic param search in %s.', funcdef.name.value, color='MAGENTA')
@@ -96,7 +96,7 @@ def search_params(evaluator, execution_context, funcdef):
params = [MergedExecutedParams(executed_params) for executed_params in zipped_params]
# Evaluate the ExecutedParams to types.
else:
params = [create_default_param(execution_context, p) for p in funcdef.get_params()]
return create_default_params(execution_context, funcdef)
debug.dbg('Dynamic param result finished', color='MAGENTA')
return params
finally:

View File

@@ -7,6 +7,7 @@ from jedi.evaluate import compiled
from jedi.evaluate import filters
from jedi.evaluate.context import Context, LazyKnownContext, LazyKnownContexts
from jedi.evaluate.cache import evaluator_method_cache
from jedi.evaluate.param import AbstractArguments, AnonymousArguments
from jedi.cache import memoize_method
from jedi.evaluate import representation as er
from jedi.evaluate.dynamic import search_params
@@ -14,11 +15,31 @@ from jedi.evaluate import iterable
from jedi.parser_utils import get_parent_scope
class InstanceFunctionExecution(er.FunctionExecutionContext):
def __init__(self, instance, parent_context, function_context, var_args):
self.instance = instance
var_args = InstanceVarArgs(self, function_context.tree_node, var_args)
super(InstanceFunctionExecution, self).__init__(
instance.evaluator, parent_context, function_context, var_args)
class AnonymousInstanceFunctionExecution(er.FunctionExecutionContext):
function_execution_filter = filters.AnonymousInstanceFunctionExecutionFilter
def __init__(self, instance, parent_context, function_context, var_args):
self.instance = instance
super(AnonymousInstanceFunctionExecution, self).__init__(
instance.evaluator, parent_context, function_context, var_args)
class AbstractInstanceContext(Context):
"""
This class is used to evaluate instances.
"""
api_type = 'instance'
function_execution_cls = InstanceFunctionExecution
def __init__(self, evaluator, parent_context, class_context, var_args):
super(AbstractInstanceContext, self).__init__(evaluator, parent_context)
@@ -136,7 +157,7 @@ class AbstractInstanceContext(Context):
bound_method = BoundMethod(
self.evaluator, self, class_context, self.parent_context, func_node
)
return InstanceFunctionExecution(
return self.function_execution_cls(
self,
class_context.parent_context,
bound_method,
@@ -208,12 +229,14 @@ class TreeInstance(AbstractInstanceContext):
class AnonymousInstance(TreeInstance):
function_execution_cls = AnonymousInstanceFunctionExecution
def __init__(self, evaluator, parent_context, class_context):
super(AnonymousInstance, self).__init__(
evaluator,
parent_context,
class_context,
var_args=None
var_args=AnonymousArguments(self),
)
@@ -264,8 +287,9 @@ class BoundMethod(er.FunctionContext):
def get_function_execution(self, arguments=None):
if arguments is None:
arguments = AnonymousArguments(self)
return AnonymousInstanceFunctionExecution(
self._instance, self.parent_context, self)
self._instance, self.parent_context, self, arguments)
else:
return InstanceFunctionExecution(
self._instance, self.parent_context, self, arguments)
@@ -411,7 +435,7 @@ class ParamArguments(object):
return []
class InstanceVarArgs(object):
class InstanceVarArgs(AbstractArguments):
def __init__(self, execution_context, funcdef, var_args):
self._execution_context = execution_context
self._funcdef = funcdef
@@ -419,12 +443,16 @@ class InstanceVarArgs(object):
@memoize_method
def _get_var_args(self):
if self._var_args is None:
# TODO this parent_context might be wrong. test?!
return ParamArguments(self._execution_context, self._funcdef)
return self._var_args
@property
def argument_node(self):
return self._var_args.argument_node
@property
def trailer(self):
return self._var_args.trailer
def unpack(self, func=None):
yield None, LazyKnownContext(self._execution_context.instance)
for values in self._get_var_args().unpack(func):
@@ -432,23 +460,3 @@ class InstanceVarArgs(object):
def get_calling_nodes(self):
return self._get_var_args().get_calling_nodes()
def __getattr__(self, name):
return getattr(self._var_args, name)
class InstanceFunctionExecution(er.FunctionExecutionContext):
def __init__(self, instance, parent_context, function_context, var_args):
self.instance = instance
var_args = InstanceVarArgs(self, function_context.tree_node, var_args)
super(InstanceFunctionExecution, self).__init__(
instance.evaluator, parent_context, function_context, var_args)
class AnonymousInstanceFunctionExecution(InstanceFunctionExecution):
function_execution_filter = filters.AnonymousInstanceFunctionExecutionFilter
def __init__(self, instance, parent_context, function_context):
super(AnonymousInstanceFunctionExecution, self).__init__(
instance, parent_context, function_context, None)

View File

@@ -73,6 +73,22 @@ class AbstractArguments():
def get_calling_nodes(self):
raise NotImplementedError
def unpack(self, funcdef=None):
raise NotImplementedError
def get_params(self, execution_context):
return get_params(execution_context, self)
class AnonymousArguments(AbstractArguments):
def __init__(self, anonymous_context):
self.context = anonymous_context
def get_params(self, execution_context):
from jedi.evaluate.dynamic import search_params
return search_params(self.context.evaluator, execution_context, execution_context.tree_node)
class TreeArguments(AbstractArguments):
def __init__(self, evaluator, context, argument_node, trailer=None):
@@ -191,6 +207,7 @@ class TreeArguments(AbstractArguments):
arguments = param.var_args
break
print(arguments)
return [arguments.argument_node or arguments.trailer]
@@ -395,7 +412,7 @@ def _error_argument_count(funcdef, actual_count):
% (funcdef.name, before, len(params), actual_count))
def create_default_param(execution_context, param):
def _create_default_param(execution_context, param):
if param.star_count == 1:
result_arg = context.LazyKnownContext(
iterable.FakeSequence(execution_context.evaluator, 'tuple', [])
@@ -409,3 +426,9 @@ def create_default_param(execution_context, param):
else:
result_arg = context.LazyTreeContext(execution_context.parent_context, param.default)
return ExecutedParam(execution_context, param, result_arg)
def create_default_params(execution_context, funcdef):
return [_create_default_param(execution_context, p)
for p in funcdef.get_params()]

View File

@@ -62,7 +62,6 @@ from jedi.evaluate.filters import ParserTreeFilter, FunctionExecutionFilter, \
GlobalNameFilter, DictFilter, ContextName, AbstractNameDefinition, \
ParamName, AnonymousInstanceParamName, TreeNameDefinition, \
ContextNameMixin
from jedi.evaluate.dynamic import search_params
from jedi.evaluate import context
from jedi.evaluate.context import ContextualizedNode
from jedi import parser_utils
@@ -418,18 +417,15 @@ class FunctionExecutionContext(context.TreeContext):
@evaluator_method_cache()
def get_params(self):
return param.get_params(self, self.var_args)
return self.var_args.get_params(self)
class AnonymousFunctionExecution(FunctionExecutionContext):
def __init__(self, evaluator, parent_context, function_context):
super(AnonymousFunctionExecution, self).__init__(
evaluator, parent_context, function_context, var_args=None)
@evaluator_method_cache()
def get_params(self):
# We need to do a dynamic search here.
return search_params(self.evaluator, self, self.tree_node)
evaluator, parent_context, function_context,
var_args=param.AnonymousArguments(self)
)
class ModuleAttributeName(AbstractNameDefinition):

View File

@@ -16,7 +16,8 @@ from jedi.common import unite
from jedi.evaluate import compiled
from jedi.evaluate import representation as er
from jedi.evaluate.instance import InstanceFunctionExecution, \
AbstractInstanceContext, CompiledInstance, BoundMethod
AbstractInstanceContext, CompiledInstance, BoundMethod, \
AnonymousInstanceFunctionExecution
from jedi.evaluate import iterable
from jedi import debug
from jedi.evaluate import precedence
@@ -163,7 +164,8 @@ class SuperInstance(AbstractInstanceContext):
@argument_clinic('[type[, obj]], /', want_context=True)
def builtins_super(evaluator, types, objects, context):
# TODO make this able to detect multiple inheritance super
if isinstance(context, InstanceFunctionExecution):
if isinstance(context, (InstanceFunctionExecution,
AnonymousInstanceFunctionExecution)):
su = context.instance.py__class__().py__bases__()
return unite(context.execute_evaluated() for context in su[0].infer())
return set()