Make BuiltinMethod a Context object.

This commit is contained in:
Dave Halter
2017-09-28 12:04:44 +02:00
parent b08300813e
commit 47c249957d
4 changed files with 42 additions and 37 deletions
-24
View File
@@ -75,7 +75,6 @@ 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 evaluator_function_cache from jedi.evaluate.cache import evaluator_function_cache
from jedi.evaluate import stdlib
from jedi.evaluate import compiled from jedi.evaluate import compiled
from jedi.evaluate import helpers from jedi.evaluate import helpers
from jedi.evaluate.filters import TreeNameDefinition, ParamName from jedi.evaluate.filters import TreeNameDefinition, ParamName
@@ -202,29 +201,6 @@ class Evaluator(object):
def _eval_element_cached(self, context, element): def _eval_element_cached(self, context, element):
return eval_node(context, element) return eval_node(context, element)
@debug.increase_indent
def execute(self, obj, arguments):
if self.is_analysis:
arguments.eval_all()
debug.dbg('execute: %s %s', obj, arguments)
try:
# Some stdlib functions like super(), namedtuple(), etc. have been
# hard-coded in Jedi to support them.
return stdlib.execute(self, obj, arguments)
except stdlib.NotInStdLib:
pass
try:
func = obj.py__call__
except AttributeError:
debug.warning("no execution possible %s", obj)
return NO_CONTEXTS
else:
context_set = func(arguments)
debug.dbg('execute result: %s in %s', context_set, obj)
return context_set
def goto_definitions(self, context, name): def goto_definitions(self, context, name):
def_ = name.get_definition(import_name_always=True) def_ = name.get_definition(import_name_always=True)
if def_ is not None: if def_ is not None:
+1 -1
View File
@@ -266,7 +266,7 @@ class CompiledObject(Context):
# TODO do we? # TODO do we?
continue continue
bltn_obj = create(self.evaluator, bltn_obj) bltn_obj = create(self.evaluator, bltn_obj)
for result in self.evaluator.execute(bltn_obj, params): for result in bltn_obj.execute(params):
yield result yield result
for type_ in docstrings.infer_return_types(self): for type_ in docstrings.infer_return_types(self):
yield type_ yield type_
+32 -1
View File
@@ -1,5 +1,7 @@
from jedi._compatibility import Python3Method
from parso.python.tree import ExprStmt, CompFor from parso.python.tree import ExprStmt, CompFor
from jedi import debug
from jedi._compatibility import Python3Method
from jedi.parser_utils import clean_scope_docstring, get_doc_with_call_signature from jedi.parser_utils import clean_scope_docstring, get_doc_with_call_signature
from jedi.common import BaseContextSet from jedi.common import BaseContextSet
@@ -32,7 +34,36 @@ class Context(object):
return context return context
context = context.parent_context context = context.parent_context
@debug.increase_indent
def execute(self, arguments): def execute(self, arguments):
"""
In contrast to py__call__ this function is always available.
`hasattr(x, py__call__)` can also be checked to see if a context is
executable.
"""
if self.evaluator.is_analysis:
arguments.eval_all()
debug.dbg('execute: %s %s', self, arguments)
from jedi.evaluate import stdlib
try:
# Some stdlib functions like super(), namedtuple(), etc. have been
# hard-coded in Jedi to support them.
return stdlib.execute(self.evaluator, self, arguments)
except stdlib.NotInStdLib:
pass
try:
func = self.py__call__
except AttributeError:
debug.warning("no execution possible %s", self)
return NO_CONTEXTS
else:
context_set = func(arguments)
debug.dbg('execute result: %s in %s', context_set, self)
return context_set
return self.evaluator.execute(self, arguments) return self.evaluator.execute(self, arguments)
def execute_evaluated(self, *value_list): def execute_evaluated(self, *value_list):
+9 -11
View File
@@ -35,7 +35,7 @@ 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.evaluate import context from jedi.evaluate import context
from jedi.evaluate.context import ContextSet, NO_CONTEXTS from jedi.evaluate.context import ContextSet, NO_CONTEXTS, Context
from jedi.parser_utils import get_comp_fors from jedi.parser_utils import get_comp_fors
@@ -54,22 +54,20 @@ class AbstractSequence(context.Context):
return compiled.CompiledContextName(self, self.array_type) return compiled.CompiledContextName(self, self.array_type)
class BuiltinMethod(object): class BuiltinMethod(Context):
"""``Generator.__next__`` ``dict.values`` methods and so on.""" """``Generator.__next__`` ``dict.values`` methods and so on."""
api_type = 'function'
def __init__(self, builtin_context, method, builtin_func): def __init__(self, builtin_context, method, builtin_func):
self._builtin_context = builtin_context super(BuiltinMethod, self).__init__(
builtin_context.evaluator,
parent_context=builtin_context
)
self._method = method self._method = method
self._builtin_func = builtin_func self._builtin_func = builtin_func
# TODO it seems kind of stupid that we have to overwrite 3 methods here.
def py__call__(self, params): def py__call__(self, params):
return self._method(self._builtin_context) return self._method(self.parent_context)
def execute(self, *args, **kwargs):
return self._builtin_context.evaluator.execute(self, *args, **kwargs)
def execute_evaluated(self, *args, **kwargs):
return self._builtin_context.evaluator.execute_evaluated(self, *args, **kwargs)
def __getattr__(self, name): def __getattr__(self, name):
return getattr(self._builtin_func, name) return getattr(self._builtin_func, name)