From 32917d55651864cf497427218b2785469b7170fc Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Fri, 29 Sep 2017 15:28:17 +0200 Subject: [PATCH] Remove the function context to a separate module. --- jedi/api/classes.py | 5 +- jedi/evaluate/__init__.py | 5 +- jedi/evaluate/compiled/__init__.py | 4 +- jedi/evaluate/context/function.py | 226 ++++++++++++++++++++++++++++ jedi/evaluate/context/instance.py | 11 +- jedi/evaluate/docstrings.py | 2 +- jedi/evaluate/dynamic.py | 4 +- jedi/evaluate/filters.py | 2 +- jedi/evaluate/representation.py | 224 +-------------------------- jedi/evaluate/syntax_tree.py | 5 +- test/test_evaluate/test_compiled.py | 2 +- 11 files changed, 251 insertions(+), 239 deletions(-) create mode 100644 jedi/evaluate/context/function.py diff --git a/jedi/api/classes.py b/jedi/api/classes.py index 6f5cf867..ca8a1cb4 100644 --- a/jedi/api/classes.py +++ b/jedi/api/classes.py @@ -18,6 +18,7 @@ from jedi.evaluate import compiled from jedi.evaluate.filters import ParamName from jedi.evaluate.imports import ImportName from jedi.evaluate.context import instance +from jedi.evaluate.context.function import FunctionContext, FunctionExecutionContext from jedi.api.keywords import KeywordName @@ -354,10 +355,10 @@ class BaseDefinition(object): if context is None: return None - if isinstance(context, er.FunctionExecutionContext): + if isinstance(context, FunctionExecutionContext): # TODO the function context should be a part of the function # execution context. - context = er.FunctionContext( + context = FunctionContext( self._evaluator, context.parent_context, context.tree_node) return Definition(self._evaluator, context.name) diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 6261e458..44ed8e2d 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -81,6 +81,7 @@ from jedi.evaluate.filters import TreeNameDefinition, ParamName from jedi.evaluate.context.instance import AnonymousInstance, BoundMethod from jedi.evaluate.context import ContextualizedName, ContextualizedNode, \ ContextSet, NO_CONTEXTS, iterate_contexts +from jedi.evaluate.context.function import FunctionContext from jedi.evaluate.syntax_tree import eval_trailer, eval_expr_stmt, \ eval_node, check_tuple_assignments from jedi import parser_utils @@ -208,7 +209,7 @@ class Evaluator(object): if type_ == 'classdef': return [er.ClassContext(self, context, name.parent)] elif type_ == 'funcdef': - return [er.FunctionContext(self, context, name.parent)] + return [FunctionContext(self, context, name.parent)] if type_ == 'expr_stmt': is_simple_name = name.parent.type not in ('power', 'trailer') @@ -330,7 +331,7 @@ class Evaluator(object): parent_context.parent_context, scope_node ) else: - func = er.FunctionContext( + func = FunctionContext( self, parent_context, scope_node diff --git a/jedi/evaluate/compiled/__init__.py b/jedi/evaluate/compiled/__init__.py index dede6bc2..dca1df34 100644 --- a/jedi/evaluate/compiled/__init__.py +++ b/jedi/evaluate/compiled/__init__.py @@ -552,7 +552,7 @@ def _create_from_name(evaluator, module, compiled_object, name): try: faked = fake.get_faked(evaluator, module, obj, parent_context=compiled_object, name=name) if faked.type == 'funcdef': - from jedi.evaluate.representation import FunctionContext + from jedi.evaluate.context.function import FunctionContext return FunctionContext(evaluator, compiled_object, faked) except fake.FakeDoesNotExist: pass @@ -633,7 +633,7 @@ def create(evaluator, obj, parent_context=None, module=None, faked=None): try: faked = fake.get_faked(evaluator, module, obj, parent_context=parent_context) if faked.type == 'funcdef': - from jedi.evaluate.representation import FunctionContext + from jedi.evaluate.context.function import FunctionContext return FunctionContext(evaluator, parent_context, faked) except fake.FakeDoesNotExist: pass diff --git a/jedi/evaluate/context/function.py b/jedi/evaluate/context/function.py new file mode 100644 index 00000000..b2373f50 --- /dev/null +++ b/jedi/evaluate/context/function.py @@ -0,0 +1,226 @@ +from parso.python import tree + +from jedi._compatibility import use_metaclass +from jedi import debug +from jedi.evaluate.cache import evaluator_method_cache, CachedMetaClass +from jedi.evaluate import compiled +from jedi.evaluate import recursion +from jedi.evaluate import docstrings +from jedi.evaluate import pep0484 +from jedi.evaluate import param +from jedi.evaluate import flow_analysis +from jedi.evaluate import helpers +from jedi.evaluate import iterable +from jedi.evaluate.filters import ParserTreeFilter, FunctionExecutionFilter, \ + ContextName, AbstractNameDefinition, ParamName +from jedi.evaluate import context +from jedi.evaluate.context import ContextualizedNode, NO_CONTEXTS, ContextSet +from jedi import parser_utils +from jedi.evaluate.parser_cache import get_yield_exprs + + +class LambdaName(AbstractNameDefinition): + string_name = '' + + def __init__(self, lambda_context): + self._lambda_context = lambda_context + self.parent_context = lambda_context.parent_context + + def start_pos(self): + return self._lambda_context.tree_node.start_pos + + def infer(self): + return ContextSet(self._lambda_context) + + +class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext)): + """ + Needed because of decorators. Decorators are evaluated here. + """ + api_type = 'function' + + def __init__(self, evaluator, parent_context, funcdef): + """ This should not be called directly """ + super(FunctionContext, self).__init__(evaluator, parent_context) + self.tree_node = funcdef + + def get_filters(self, search_global, until_position=None, origin_scope=None): + if search_global: + yield ParserTreeFilter( + self.evaluator, + context=self, + until_position=until_position, + origin_scope=origin_scope + ) + else: + scope = self.py__class__() + for filter in scope.get_filters(search_global=False, origin_scope=origin_scope): + yield filter + + def infer_function_execution(self, function_execution): + """ + Created to be used by inheritance. + """ + yield_exprs = get_yield_exprs(self.evaluator, self.tree_node) + if yield_exprs: + return ContextSet(iterable.Generator(self.evaluator, function_execution)) + else: + return function_execution.get_return_values() + + def get_function_execution(self, arguments=None): + if arguments is None: + arguments = param.AnonymousArguments() + + return FunctionExecutionContext(self.evaluator, self.parent_context, self, arguments) + + def py__call__(self, arguments): + function_execution = self.get_function_execution(arguments) + return self.infer_function_execution(function_execution) + + def py__class__(self): + # This differentiation is only necessary for Python2. Python3 does not + # use a different method class. + if isinstance(parser_utils.get_parent_scope(self.tree_node), tree.Class): + name = 'METHOD_CLASS' + else: + name = 'FUNCTION_CLASS' + return compiled.get_special_object(self.evaluator, name) + + @property + def name(self): + if self.tree_node.type == 'lambdef': + return LambdaName(self) + return ContextName(self, self.tree_node.name) + + def get_param_names(self): + function_execution = self.get_function_execution() + return [ParamName(function_execution, param.name) + for param in self.tree_node.get_params()] + + +class FunctionExecutionContext(context.TreeContext): + """ + This class is used to evaluate functions and their returns. + + This is the most complicated class, because it contains the logic to + transfer parameters. It is even more complicated, because there may be + multiple calls to functions and recursion has to be avoided. But this is + responsibility of the decorators. + """ + function_execution_filter = FunctionExecutionFilter + + def __init__(self, evaluator, parent_context, function_context, var_args): + super(FunctionExecutionContext, self).__init__(evaluator, parent_context) + self.function_context = function_context + self.tree_node = function_context.tree_node + self.var_args = var_args + + @evaluator_method_cache(default=NO_CONTEXTS) + @recursion.execution_recursion_decorator() + def get_return_values(self, check_yields=False): + funcdef = self.tree_node + if funcdef.type == 'lambdef': + return self.evaluator.eval_element(self, funcdef.children[-1]) + + if check_yields: + context_set = NO_CONTEXTS + returns = get_yield_exprs(self.evaluator, funcdef) + else: + returns = funcdef.iter_return_stmts() + context_set = docstrings.infer_return_types(self.function_context) + context_set |= pep0484.infer_return_types(self.function_context) + + for r in returns: + check = flow_analysis.reachability_check(self, funcdef, r) + if check is flow_analysis.UNREACHABLE: + debug.dbg('Return unreachable: %s', r) + else: + if check_yields: + context_set |= ContextSet.from_sets( + lazy_context.infer() + for lazy_context in self._eval_yield(r) + ) + else: + try: + children = r.children + except AttributeError: + context_set |= ContextSet(compiled.create(self.evaluator, None)) + else: + context_set |= self.eval_node(children[1]) + if check is flow_analysis.REACHABLE: + debug.dbg('Return reachable: %s', r) + break + return context_set + + def _eval_yield(self, yield_expr): + if yield_expr.type == 'keyword': + # `yield` just yields None. + yield context.LazyKnownContext(compiled.create(self.evaluator, None)) + return + + node = yield_expr.children[1] + if node.type == 'yield_arg': # It must be a yield from. + cn = ContextualizedNode(self, node.children[1]) + for lazy_context in cn.infer().iterate(cn): + yield lazy_context + else: + yield context.LazyTreeContext(self, node) + + @recursion.execution_recursion_decorator(default=iter([])) + def get_yield_values(self): + for_parents = [(y, tree.search_ancestor(y, 'for_stmt', 'funcdef', + 'while_stmt', 'if_stmt')) + for y in get_yield_exprs(self.evaluator, self.tree_node)] + + # Calculate if the yields are placed within the same for loop. + yields_order = [] + last_for_stmt = None + for yield_, for_stmt in for_parents: + # For really simple for loops we can predict the order. Otherwise + # we just ignore it. + parent = for_stmt.parent + if parent.type == 'suite': + parent = parent.parent + if for_stmt.type == 'for_stmt' and parent == self.tree_node \ + and parser_utils.for_stmt_defines_one_name(for_stmt): # Simplicity for now. + if for_stmt == last_for_stmt: + yields_order[-1][1].append(yield_) + else: + yields_order.append((for_stmt, [yield_])) + elif for_stmt == self.tree_node: + yields_order.append((None, [yield_])) + else: + types = self.get_return_values(check_yields=True) + if types: + yield context.LazyKnownContexts(types) + return + last_for_stmt = for_stmt + + for for_stmt, yields in yields_order: + if for_stmt is None: + # No for_stmt, just normal yields. + for yield_ in yields: + for result in self._eval_yield(yield_): + yield result + else: + input_node = for_stmt.get_testlist() + cn = ContextualizedNode(self, input_node) + ordered = cn.infer().iterate(cn) + ordered = list(ordered) + for lazy_context in ordered: + dct = {str(for_stmt.children[1].value): lazy_context.infer()} + with helpers.predefine_names(self, for_stmt, dct): + for yield_in_same_for_stmt in yields: + for result in self._eval_yield(yield_in_same_for_stmt): + yield result + + def get_filters(self, search_global, until_position=None, origin_scope=None): + yield self.function_execution_filter(self.evaluator, self, + until_position=until_position, + origin_scope=origin_scope) + + @evaluator_method_cache() + def get_params(self): + return self.var_args.get_params(self) + + diff --git a/jedi/evaluate/context/instance.py b/jedi/evaluate/context/instance.py index 747f5802..437c355a 100644 --- a/jedi/evaluate/context/instance.py +++ b/jedi/evaluate/context/instance.py @@ -10,12 +10,13 @@ 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.context.function import FunctionExecutionContext, FunctionContext from jedi.evaluate import iterable from jedi.parser_utils import get_parent_scope -class InstanceFunctionExecution(er.FunctionExecutionContext): +class InstanceFunctionExecution(FunctionExecutionContext): def __init__(self, instance, parent_context, function_context, var_args): self.instance = instance var_args = InstanceVarArgs(self, var_args) @@ -24,7 +25,7 @@ class InstanceFunctionExecution(er.FunctionExecutionContext): instance.evaluator, parent_context, function_context, var_args) -class AnonymousInstanceFunctionExecution(er.FunctionExecutionContext): +class AnonymousInstanceFunctionExecution(FunctionExecutionContext): function_execution_filter = filters.AnonymousInstanceFunctionExecutionFilter def __init__(self, instance, parent_context, function_context, var_args): @@ -253,7 +254,7 @@ class CompiledInstanceName(compiled.CompiledName): @iterator_to_context_set def infer(self): for result_context in super(CompiledInstanceName, self).infer(): - if isinstance(result_context, er.FunctionContext): + if isinstance(result_context, FunctionContext): parent_context = result_context.parent_context while parent_context.is_class(): parent_context = parent_context.parent_context @@ -285,7 +286,7 @@ class CompiledInstanceClassFilter(compiled.CompiledObjectFilter): self._evaluator, self._instance, self._compiled_object, name) -class BoundMethod(er.FunctionContext): +class BoundMethod(FunctionContext): def __init__(self, evaluator, instance, class_context, *args, **kwargs): super(BoundMethod, self).__init__(evaluator, *args, **kwargs) self._instance = instance @@ -333,7 +334,7 @@ class LazyInstanceClassName(LazyInstanceName): @iterator_to_context_set def infer(self): for result_context in super(LazyInstanceClassName, self).infer(): - if isinstance(result_context, er.FunctionContext): + if isinstance(result_context, FunctionContext): # Classes are never used to resolve anything within the # functions. Only other functions and modules will resolve # those things. diff --git a/jedi/evaluate/docstrings.py b/jedi/evaluate/docstrings.py index fa8f4c6f..e3c06595 100644 --- a/jedi/evaluate/docstrings.py +++ b/jedi/evaluate/docstrings.py @@ -202,7 +202,7 @@ def _evaluate_for_statement_string(module_context, string): except (AttributeError, IndexError): return [] - from jedi.evaluate.representation import FunctionContext + from jedi.evaluate.context.function import FunctionContext function_context = FunctionContext( module_context.evaluator, module_context, diff --git a/jedi/evaluate/dynamic.py b/jedi/evaluate/dynamic.py index 1260c3bf..e5b20d8b 100644 --- a/jedi/evaluate/dynamic.py +++ b/jedi/evaluate/dynamic.py @@ -151,7 +151,7 @@ def _get_possible_nodes(module_context, func_string_name): def _check_name_for_execution(evaluator, context, compare_node, name, trailer): - from jedi.evaluate import representation as er + from jedi.evaluate.context.function import FunctionExecutionContext def create_func_excs(): arglist = trailer.children[1] @@ -175,7 +175,7 @@ def _check_name_for_execution(evaluator, context, compare_node, name, trailer): if compare_node == value_node: for func_execution in create_func_excs(): yield func_execution - elif isinstance(value.parent_context, er.FunctionExecutionContext) and \ + elif isinstance(value.parent_context, FunctionExecutionContext) and \ compare_node.type == 'funcdef': # Here we're trying to find decorators by checking the first # parameter. It's not very generic though. Should find a better diff --git a/jedi/evaluate/filters.py b/jedi/evaluate/filters.py index 735b27b7..71e2dd61 100644 --- a/jedi/evaluate/filters.py +++ b/jedi/evaluate/filters.py @@ -327,7 +327,7 @@ def get_global_filters(evaluator, context, until_position, origin_scope): >>> filters[4].values() #doctest: +ELLIPSIS [, ...] """ - from jedi.evaluate.representation import FunctionExecutionContext + from jedi.evaluate.context.function import FunctionExecutionContext while context is not None: # Names in methods cannot be resolved within the class. for filter in context.get_filters( diff --git a/jedi/evaluate/representation.py b/jedi/evaluate/representation.py index 7cb01d1e..91249616 100644 --- a/jedi/evaluate/representation.py +++ b/jedi/evaluate/representation.py @@ -40,28 +40,15 @@ py__doc__(include_call_signature: Returns the docstring for a context. import os from itertools import chain -from parso.python import tree - from jedi._compatibility import use_metaclass -from jedi import debug from jedi.evaluate.cache import evaluator_method_cache, CachedMetaClass from jedi.evaluate import compiled -from jedi.evaluate import recursion -from jedi.evaluate import docstrings -from jedi.evaluate import pep0484 from jedi.evaluate import param -from jedi.evaluate import flow_analysis from jedi.evaluate import imports -from jedi.evaluate import helpers -from jedi.evaluate import iterable -from jedi.evaluate.filters import ParserTreeFilter, FunctionExecutionFilter, \ - DictFilter, ContextName, AbstractNameDefinition, \ - ParamName, AnonymousInstanceParamName, TreeNameDefinition +from jedi.evaluate.filters import ParserTreeFilter, TreeNameDefinition, \ + DictFilter, ContextName, AbstractNameDefinition, AnonymousInstanceParamName from jedi.evaluate import context -from jedi.evaluate.context import ContextualizedNode, NO_CONTEXTS, \ - ContextSet, iterator_to_context_set -from jedi import parser_utils -from jedi.evaluate.parser_cache import get_yield_exprs +from jedi.evaluate.context import NO_CONTEXTS, ContextSet, iterator_to_context_set def apply_py__get__(context, base_context): @@ -213,211 +200,6 @@ class ClassContext(use_metaclass(CachedMetaClass, context.TreeContext)): return ContextName(self, self.tree_node.name) -class LambdaName(AbstractNameDefinition): - string_name = '' - - def __init__(self, lambda_context): - self._lambda_context = lambda_context - self.parent_context = lambda_context.parent_context - - def start_pos(self): - return self._lambda_context.tree_node.start_pos - - def infer(self): - return ContextSet(self._lambda_context) - - -class FunctionContext(use_metaclass(CachedMetaClass, context.TreeContext)): - """ - Needed because of decorators. Decorators are evaluated here. - """ - api_type = 'function' - - def __init__(self, evaluator, parent_context, funcdef): - """ This should not be called directly """ - super(FunctionContext, self).__init__(evaluator, parent_context) - self.tree_node = funcdef - - def get_filters(self, search_global, until_position=None, origin_scope=None): - if search_global: - yield ParserTreeFilter( - self.evaluator, - context=self, - until_position=until_position, - origin_scope=origin_scope - ) - else: - scope = self.py__class__() - for filter in scope.get_filters(search_global=False, origin_scope=origin_scope): - yield filter - - def infer_function_execution(self, function_execution): - """ - Created to be used by inheritance. - """ - yield_exprs = get_yield_exprs(self.evaluator, self.tree_node) - if yield_exprs: - return ContextSet(iterable.Generator(self.evaluator, function_execution)) - else: - return function_execution.get_return_values() - - def get_function_execution(self, arguments=None): - if arguments is None: - arguments = param.AnonymousArguments() - - return FunctionExecutionContext(self.evaluator, self.parent_context, self, arguments) - - def py__call__(self, arguments): - function_execution = self.get_function_execution(arguments) - return self.infer_function_execution(function_execution) - - def py__class__(self): - # This differentiation is only necessary for Python2. Python3 does not - # use a different method class. - if isinstance(parser_utils.get_parent_scope(self.tree_node), tree.Class): - name = 'METHOD_CLASS' - else: - name = 'FUNCTION_CLASS' - return compiled.get_special_object(self.evaluator, name) - - @property - def name(self): - if self.tree_node.type == 'lambdef': - return LambdaName(self) - return ContextName(self, self.tree_node.name) - - def get_param_names(self): - function_execution = self.get_function_execution() - return [ParamName(function_execution, param.name) - for param in self.tree_node.get_params()] - - -class FunctionExecutionContext(context.TreeContext): - """ - This class is used to evaluate functions and their returns. - - This is the most complicated class, because it contains the logic to - transfer parameters. It is even more complicated, because there may be - multiple calls to functions and recursion has to be avoided. But this is - responsibility of the decorators. - """ - function_execution_filter = FunctionExecutionFilter - - def __init__(self, evaluator, parent_context, function_context, var_args): - super(FunctionExecutionContext, self).__init__(evaluator, parent_context) - self.function_context = function_context - self.tree_node = function_context.tree_node - self.var_args = var_args - - @evaluator_method_cache(default=NO_CONTEXTS) - @recursion.execution_recursion_decorator() - def get_return_values(self, check_yields=False): - funcdef = self.tree_node - if funcdef.type == 'lambdef': - return self.evaluator.eval_element(self, funcdef.children[-1]) - - if check_yields: - context_set = NO_CONTEXTS - returns = get_yield_exprs(self.evaluator, funcdef) - else: - returns = funcdef.iter_return_stmts() - context_set = docstrings.infer_return_types(self.function_context) - context_set |= pep0484.infer_return_types(self.function_context) - - for r in returns: - check = flow_analysis.reachability_check(self, funcdef, r) - if check is flow_analysis.UNREACHABLE: - debug.dbg('Return unreachable: %s', r) - else: - if check_yields: - context_set |= ContextSet.from_sets( - lazy_context.infer() - for lazy_context in self._eval_yield(r) - ) - else: - try: - children = r.children - except AttributeError: - context_set |= ContextSet(compiled.create(self.evaluator, None)) - else: - context_set |= self.eval_node(children[1]) - if check is flow_analysis.REACHABLE: - debug.dbg('Return reachable: %s', r) - break - return context_set - - def _eval_yield(self, yield_expr): - if yield_expr.type == 'keyword': - # `yield` just yields None. - yield context.LazyKnownContext(compiled.create(self.evaluator, None)) - return - - node = yield_expr.children[1] - if node.type == 'yield_arg': # It must be a yield from. - cn = ContextualizedNode(self, node.children[1]) - for lazy_context in cn.infer().iterate(cn): - yield lazy_context - else: - yield context.LazyTreeContext(self, node) - - @recursion.execution_recursion_decorator(default=iter([])) - def get_yield_values(self): - for_parents = [(y, tree.search_ancestor(y, 'for_stmt', 'funcdef', - 'while_stmt', 'if_stmt')) - for y in get_yield_exprs(self.evaluator, self.tree_node)] - - # Calculate if the yields are placed within the same for loop. - yields_order = [] - last_for_stmt = None - for yield_, for_stmt in for_parents: - # For really simple for loops we can predict the order. Otherwise - # we just ignore it. - parent = for_stmt.parent - if parent.type == 'suite': - parent = parent.parent - if for_stmt.type == 'for_stmt' and parent == self.tree_node \ - and parser_utils.for_stmt_defines_one_name(for_stmt): # Simplicity for now. - if for_stmt == last_for_stmt: - yields_order[-1][1].append(yield_) - else: - yields_order.append((for_stmt, [yield_])) - elif for_stmt == self.tree_node: - yields_order.append((None, [yield_])) - else: - types = self.get_return_values(check_yields=True) - if types: - yield context.LazyKnownContexts(types) - return - last_for_stmt = for_stmt - - for for_stmt, yields in yields_order: - if for_stmt is None: - # No for_stmt, just normal yields. - for yield_ in yields: - for result in self._eval_yield(yield_): - yield result - else: - input_node = for_stmt.get_testlist() - cn = ContextualizedNode(self, input_node) - ordered = cn.infer().iterate(cn) - ordered = list(ordered) - for lazy_context in ordered: - dct = {str(for_stmt.children[1].value): lazy_context.infer()} - with helpers.predefine_names(self, for_stmt, dct): - for yield_in_same_for_stmt in yields: - for result in self._eval_yield(yield_in_same_for_stmt): - yield result - - def get_filters(self, search_global, until_position=None, origin_scope=None): - yield self.function_execution_filter(self.evaluator, self, - until_position=until_position, - origin_scope=origin_scope) - - @evaluator_method_cache() - def get_params(self): - return self.var_args.get_params(self) - - class ImplicitNSName(AbstractNameDefinition): """ Accessing names for implicit namespace packages should infer to nothing. diff --git a/jedi/evaluate/syntax_tree.py b/jedi/evaluate/syntax_tree.py index e9a1d07d..a9ad39b7 100644 --- a/jedi/evaluate/syntax_tree.py +++ b/jedi/evaluate/syntax_tree.py @@ -19,6 +19,7 @@ from jedi.evaluate import iterable from jedi.evaluate import imports from jedi.evaluate import param from jedi.evaluate import representation as er +from jedi.evaluate.context.function import FunctionContext from jedi.evaluate.context.instance import TreeInstance, CompiledInstance from jedi.evaluate.finder import NameFinder from jedi.evaluate.helpers import is_string, is_literal, is_number, is_compiled @@ -63,7 +64,7 @@ def eval_node(context, element): # else: print e.g. could be evaluated like this in Python 2.7 return NO_CONTEXTS elif typ == 'lambdef': - return ContextSet(er.FunctionContext(evaluator, context, element)) + return ContextSet(FunctionContext(evaluator, context, element)) elif typ == 'expr_stmt': return eval_expr_stmt(context, element) elif typ in ('power', 'atom_expr'): @@ -508,7 +509,7 @@ def _apply_decorators(context, node): classdef=node ) else: - decoratee_context = er.FunctionContext( + decoratee_context = FunctionContext( context.evaluator, parent_context=context, funcdef=node diff --git a/test/test_evaluate/test_compiled.py b/test/test_evaluate/test_compiled.py index fef590b2..dff964c9 100644 --- a/test/test_evaluate/test_compiled.py +++ b/test/test_evaluate/test_compiled.py @@ -5,7 +5,7 @@ import parso from jedi._compatibility import builtins, is_py3 from jedi.evaluate import compiled from jedi.evaluate.context import instance -from jedi.evaluate.representation import FunctionContext +from jedi.evaluate.context.function import FunctionContext from jedi.evaluate import Evaluator from jedi.parser_utils import clean_scope_docstring from jedi import Script