From 75a02a13d90e90f51609cd9b53d2fdbc32fe2ed1 Mon Sep 17 00:00:00 2001 From: Dave Halter Date: Mon, 24 Sep 2018 20:21:29 +0200 Subject: [PATCH] Use ContextSet closer to they way how Python's set works --- jedi/api/__init__.py | 2 +- jedi/common/context.py | 23 +++---------- jedi/evaluate/__init__.py | 4 +-- jedi/evaluate/arguments.py | 2 +- jedi/evaluate/base_context.py | 12 +++---- jedi/evaluate/compiled/context.py | 26 +++++++-------- jedi/evaluate/compiled/mixed.py | 6 ++-- jedi/evaluate/context/function.py | 6 ++-- jedi/evaluate/context/instance.py | 4 +-- jedi/evaluate/context/iterable.py | 26 +++++++-------- jedi/evaluate/context/klass.py | 6 ++-- jedi/evaluate/context/typing.py | 30 ++++++++--------- jedi/evaluate/docstrings.py | 2 +- jedi/evaluate/filters.py | 6 ++-- jedi/evaluate/finder.py | 6 ++-- jedi/evaluate/helpers.py | 2 +- jedi/evaluate/imports.py | 6 ++-- jedi/evaluate/lazy_context.py | 2 +- jedi/evaluate/pep0484.py | 2 +- jedi/evaluate/syntax_tree.py | 55 +++++++++++++++---------------- jedi/plugins/stdlib.py | 12 +++---- jedi/plugins/typeshed.py | 2 +- 22 files changed, 114 insertions(+), 128 deletions(-) diff --git a/jedi/api/__init__.py b/jedi/api/__init__.py index 116471a5..26f388e5 100644 --- a/jedi/api/__init__.py +++ b/jedi/api/__init__.py @@ -155,7 +155,7 @@ class Script(object): string_names=names, code_lines=self._code_lines, ) - self._evaluator.module_cache.add(names, ContextSet(module)) + self._evaluator.module_cache.add(names, ContextSet([module])) return module def __repr__(self): diff --git a/jedi/common/context.py b/jedi/common/context.py index 0d873900..b690ad33 100644 --- a/jedi/common/context.py +++ b/jedi/common/context.py @@ -12,18 +12,10 @@ class BaseContext(object): class BaseContextSet(object): - def __init__(self, *args): - if len(args) == 1 and hasattr(args[0], '__iter__'): - # TODO replace with this everywhere. - self._set = frozenset(args[0]) - return - for arg in args: - assert not isinstance(arg, BaseContextSet) - self._set = frozenset(args) - - @classmethod - def from_iterable(cls, iterable): - return cls.from_set(set(iterable)) + def __init__(self, iterable): + self._set = frozenset(iterable) + for context in iterable: + assert not isinstance(context, BaseContextSet) @classmethod def _from_frozen_set(cls, frozenset_): @@ -31,11 +23,6 @@ class BaseContextSet(object): self._set = frozenset_ return self - # TODO remove this function - @classmethod - def from_set(cls, set_): - return cls(*set_) - @classmethod def from_sets(cls, sets): """ @@ -69,7 +56,7 @@ class BaseContextSet(object): return '%s(%s)' % (self.__class__.__name__, ', '.join(str(s) for s in self._set)) def filter(self, filter_func): - return self.from_iterable(filter(filter_func, self._set)) + return self.__class__(filter(filter_func, self._set)) def __getattr__(self, name): def mapper(*args, **kwargs): diff --git a/jedi/evaluate/__init__.py b/jedi/evaluate/__init__.py index 32932987..827fbddf 100644 --- a/jedi/evaluate/__init__.py +++ b/jedi/evaluate/__init__.py @@ -220,14 +220,14 @@ class Evaluator(object): new_name_dicts = list(original_name_dicts) for i, name_dict in enumerate(new_name_dicts): new_name_dicts[i] = name_dict.copy() - new_name_dicts[i][if_name.value] = ContextSet(definition) + new_name_dicts[i][if_name.value] = ContextSet([definition]) name_dicts += new_name_dicts else: for name_dict in name_dicts: name_dict[if_name.value] = definitions if len(name_dicts) > 1: - result = ContextSet() + result = NO_CONTEXTS for name_dict in name_dicts: with helpers.predefine_names(context, if_stmt, name_dict): result |= eval_node(context, element) diff --git a/jedi/evaluate/arguments.py b/jedi/evaluate/arguments.py index ae4e58c9..eeef882a 100644 --- a/jedi/evaluate/arguments.py +++ b/jedi/evaluate/arguments.py @@ -81,7 +81,7 @@ def _iterate_argument_clinic(evaluator, arguments, parameters): break lazy_contexts.append(argument) - yield ContextSet(iterable.FakeSequence(evaluator, u'tuple', lazy_contexts)) + yield ContextSet([iterable.FakeSequence(evaluator, u'tuple', lazy_contexts)]) lazy_contexts continue elif stars == 2: diff --git a/jedi/evaluate/base_context.py b/jedi/evaluate/base_context.py index 04a8a63c..b1fdb9ac 100644 --- a/jedi/evaluate/base_context.py +++ b/jedi/evaluate/base_context.py @@ -264,7 +264,7 @@ def _getitem(context, index_contexts, contextualized_node): # The actual getitem call. simple_getitem = getattr(context, 'py__simple_getitem__', None) - result = ContextSet() + result = NO_CONTEXTS unused_contexts = set() for index_context in index_contexts: if simple_getitem is not None: @@ -293,7 +293,7 @@ def _getitem(context, index_contexts, contextualized_node): # all results. if unused_contexts or not index_contexts: result |= context.py__getitem__( - ContextSet.from_set(unused_contexts), + ContextSet(unused_contexts), contextualized_node ) debug.dbg('py__getitem__ result: %s', result) @@ -302,7 +302,7 @@ def _getitem(context, index_contexts, contextualized_node): class ContextSet(BaseContextSet): def py__class__(self): - return ContextSet.from_iterable(c.py__class__() for c in self._set) + return ContextSet(c.py__class__() for c in self._set) def iterate(self, contextualized_node=None, is_async=False): from jedi.evaluate.lazy_context import get_merged_lazy_context @@ -322,7 +322,7 @@ class ContextSet(BaseContextSet): return ContextSet.from_sets(_getitem(c, *args, **kwargs) for c in self._set) def try_merge(self, function_name): - context_set = self.__class__() + context_set = self.__class__([]) for c in self._set: try: method = getattr(c, function_name) @@ -333,11 +333,11 @@ class ContextSet(BaseContextSet): return context_set -NO_CONTEXTS = ContextSet() +NO_CONTEXTS = ContextSet([]) def iterator_to_context_set(func): def wrapper(*args, **kwargs): - return ContextSet.from_iterable(func(*args, **kwargs)) + return ContextSet(func(*args, **kwargs)) return wrapper diff --git a/jedi/evaluate/compiled/context.py b/jedi/evaluate/compiled/context.py index ec0bd503..cf0a0eb0 100644 --- a/jedi/evaluate/compiled/context.py +++ b/jedi/evaluate/compiled/context.py @@ -9,7 +9,7 @@ from jedi._compatibility import force_unicode, Parameter from jedi.cache import underscore_memoization, memoize_method from jedi.evaluate.filters import AbstractFilter, AbstractNameDefinition, \ ContextNameMixin -from jedi.evaluate.base_context import Context, ContextSet +from jedi.evaluate.base_context import Context, ContextSet, NO_CONTEXTS from jedi.evaluate.lazy_context import LazyKnownContext from jedi.evaluate.compiled.access import _sentinel from jedi.evaluate.cache import evaluator_function_cache @@ -61,11 +61,11 @@ class CompiledObject(Context): ).py__call__(arguments=arguments) if self.access_handle.is_class(): from jedi.evaluate.context import CompiledInstance - return ContextSet( + return ContextSet([ CompiledInstance(self.evaluator, self.parent_context, self, arguments) - ) + ]) else: - return ContextSet.from_iterable(self._execute_function(arguments)) + return ContextSet(self._execute_function(arguments)) @CheckAttribute() def py__class__(self): @@ -157,13 +157,13 @@ class CompiledObject(Context): with reraise_getitem_errors(IndexError, KeyError, TypeError): access = self.access_handle.py__simple_getitem__(index) if access is None: - return ContextSet() + return NO_CONTEXTS - return ContextSet(create_from_access_path(self.evaluator, access)) + return ContextSet([create_from_access_path(self.evaluator, access)]) @CheckAttribute() def py__getitem__(self, index_context_set, contextualized_node): - return ContextSet.from_iterable( + return ContextSet( create_from_access_path(self.evaluator, access) for access in self.access_handle.py__getitem__all_values() ) @@ -243,9 +243,9 @@ class CompiledName(AbstractNameDefinition): @underscore_memoization def infer(self): - return ContextSet(create_from_name( + return ContextSet([create_from_name( self._evaluator, self.parent_context, self.string_name - )) + )]) class SignatureParamName(AbstractNameDefinition): @@ -268,9 +268,9 @@ class SignatureParamName(AbstractNameDefinition): def infer(self): p = self._signature_param evaluator = self.parent_context.evaluator - contexts = ContextSet() + contexts = NO_CONTEXTS if p.has_default: - contexts = ContextSet(create_from_access_path(evaluator, p.default)) + contexts = ContextSet([create_from_access_path(evaluator, p.default)]) if p.has_annotation: annotation = create_from_access_path(evaluator, p.annotation) contexts |= execute_evaluated(annotation) @@ -288,7 +288,7 @@ class UnresolvableParamName(AbstractNameDefinition): return Parameter.POSITIONAL_ONLY def infer(self): - return ContextSet() + return NO_CONTEXTS class CompiledContextName(ContextNameMixin, AbstractNameDefinition): @@ -309,7 +309,7 @@ class EmptyCompiledName(AbstractNameDefinition): self.string_name = name def infer(self): - return ContextSet() + return NO_CONTEXTS class CompiledObjectFilter(AbstractFilter): diff --git a/jedi/evaluate/compiled/mixed.py b/jedi/evaluate/compiled/mixed.py index 82e0703c..1a60d18f 100644 --- a/jedi/evaluate/compiled/mixed.py +++ b/jedi/evaluate/compiled/mixed.py @@ -82,9 +82,9 @@ class MixedName(compiled.CompiledName): access_handle = self.parent_context.access_handle # TODO use logic from compiled.CompiledObjectFilter access_handle = access_handle.getattr(self.string_name, default=None) - return ContextSet( + return ContextSet([ _create(self._evaluator, access_handle, parent_context=self.parent_context) - ) + ]) @property def api_type(self): @@ -213,7 +213,7 @@ def _create(evaluator, access_handle, parent_context, *args): code_lines=code_lines, ) if name is not None: - evaluator.module_cache.add(string_names, ContextSet(module_context)) + evaluator.module_cache.add(string_names, ContextSet([module_context])) tree_context = module_context.create_context( tree_node, diff --git a/jedi/evaluate/context/function.py b/jedi/evaluate/context/function.py index 3b245981..c5afc758 100644 --- a/jedi/evaluate/context/function.py +++ b/jedi/evaluate/context/function.py @@ -34,7 +34,7 @@ class LambdaName(AbstractNameDefinition): return self._lambda_context.tree_node.start_pos def infer(self): - return ContextSet(self._lambda_context) + return ContextSet([self._lambda_context]) class AbstractFunction(TreeContext): @@ -195,7 +195,7 @@ class FunctionExecutionContext(TreeContext): children = r.children except AttributeError: ctx = compiled.builtin_from_name(self.evaluator, u'None') - context_set |= ContextSet(ctx) + context_set |= ContextSet([ctx]) else: context_set |= self.eval_node(children[1]) if check is flow_analysis.REACHABLE: @@ -341,7 +341,7 @@ class FunctionExecutionContext(TreeContext): ).execute_annotation() else: if is_generator: - return ContextSet(iterable.Generator(evaluator, self)) + return ContextSet([iterable.Generator(evaluator, self)]) else: return self.get_return_values() diff --git a/jedi/evaluate/context/instance.py b/jedi/evaluate/context/instance.py index 16e7e011..8830545b 100644 --- a/jedi/evaluate/context/instance.py +++ b/jedi/evaluate/context/instance.py @@ -25,7 +25,7 @@ class InstanceExecutedParam(object): self.string_name = self._tree_param.name.value def infer(self): - return ContextSet(self._instance) + return ContextSet([self._instance]) def matches_signature(self): return True @@ -120,7 +120,7 @@ class AbstractInstanceContext(Context): none_obj = compiled.builtin_from_name(self.evaluator, u'None') return self.execute_function_slots(names, none_obj, obj) else: - return ContextSet(self) + return ContextSet([self]) def get_filters(self, search_global=None, until_position=None, origin_scope=None, include_self_names=True): diff --git a/jedi/evaluate/context/iterable.py b/jedi/evaluate/context/iterable.py index b43ede8a..0d7c9e44 100644 --- a/jedi/evaluate/context/iterable.py +++ b/jedi/evaluate/context/iterable.py @@ -44,7 +44,7 @@ from jedi.parser_utils import get_comp_fors class IterableMixin(object): def py__stop_iteration_returns(self): - return ContextSet(compiled.builtin_from_name(self.evaluator, u'None')) + return ContextSet([compiled.builtin_from_name(self.evaluator, u'None')]) class GeneratorBase(BuiltinOverwrite, IterableMixin): @@ -210,7 +210,7 @@ class Sequence(BuiltinOverwrite, IterableMixin): def py__getitem__(self, index_context_set, contextualized_node): if self.array_type == 'dict': return self._dict_values() - return iterate_contexts(ContextSet(self)) + return iterate_contexts(ContextSet([self])) class ListComprehension(ComprehensionMixin, Sequence): @@ -218,7 +218,7 @@ class ListComprehension(ComprehensionMixin, Sequence): def py__simple_getitem__(self, index): if isinstance(index, slice): - return ContextSet(self) + return ContextSet([self]) all_types = list(self.py__iter__()) with reraise_getitem_errors(IndexError, TypeError): @@ -254,7 +254,7 @@ class DictComprehension(ComprehensionMixin, Sequence): @publish_method('values') def _imitate_values(self): lazy_context = LazyKnownContexts(self._dict_values()) - return ContextSet(FakeSequence(self.evaluator, u'list', [lazy_context])) + return ContextSet([FakeSequence(self.evaluator, u'list', [lazy_context])]) @publish_method('items') def _imitate_items(self): @@ -270,7 +270,7 @@ class DictComprehension(ComprehensionMixin, Sequence): for key, value in self._iterate() ] - return ContextSet(FakeSequence(self.evaluator, u'list', lazy_contexts)) + return ContextSet([FakeSequence(self.evaluator, u'list', lazy_contexts)]) class GeneratorComprehension(ComprehensionMixin, GeneratorBase): @@ -310,7 +310,7 @@ class SequenceLiteralContext(Sequence): raise SimpleGetItemNotFound('No key found in dictionary %s.' % self) if isinstance(index, slice): - return ContextSet(self) + return ContextSet([self]) else: with reraise_getitem_errors(TypeError, KeyError, IndexError): node = self.get_tree_entries()[index] @@ -323,7 +323,7 @@ class SequenceLiteralContext(Sequence): """ if self.array_type == u'dict': # Get keys. - types = ContextSet() + types = NO_CONTEXTS for k, _ in self.get_tree_entries(): types |= self._defining_context.eval_node(k) # We don't know which dict index comes first, therefore always @@ -417,7 +417,7 @@ class DictLiteralContext(SequenceLiteralContext): @publish_method('values') def _imitate_values(self): lazy_context = LazyKnownContexts(self._dict_values()) - return ContextSet(FakeSequence(self.evaluator, u'list', [lazy_context])) + return ContextSet([FakeSequence(self.evaluator, u'list', [lazy_context])]) @publish_method('items') def _imitate_items(self): @@ -429,7 +429,7 @@ class DictLiteralContext(SequenceLiteralContext): )) for key_node, value_node in self.get_tree_entries() ] - return ContextSet(FakeSequence(self.evaluator, u'list', lazy_contexts)) + return ContextSet([FakeSequence(self.evaluator, u'list', lazy_contexts)]) def _dict_keys(self): return ContextSet.from_sets( @@ -503,10 +503,10 @@ class FakeDict(_FakeArray): @publish_method('values') def _values(self): - return ContextSet(FakeSequence( + return ContextSet([FakeSequence( self.evaluator, u'tuple', [LazyKnownContexts(self._dict_values())] - )) + )]) def _dict_values(self): return ContextSet.from_sets(lazy_context.infer() for lazy_context in self._dct.values()) @@ -601,7 +601,7 @@ def _check_array_additions(context, sequence): module_context = context.get_root_context() if not settings.dynamic_array_additions or isinstance(module_context, compiled.CompiledObject): debug.dbg('Dynamic array search aborted.', color='MAGENTA') - return ContextSet() + return NO_CONTEXTS def find_additions(context, arglist, add_name): params = list(arguments.TreeArguments(context.evaluator, context, arglist).unpack()) @@ -673,7 +673,7 @@ def get_dynamic_array_instance(instance, arguments): """Used for set() and list() instances.""" ai = _ArrayInstance(instance, arguments) from jedi.evaluate import arguments - return arguments.ValuesArguments([ContextSet(ai)]) + return arguments.ValuesArguments([ContextSet([ai])]) class _ArrayInstance(object): diff --git a/jedi/evaluate/context/klass.py b/jedi/evaluate/context/klass.py index de199e43..f214124e 100644 --- a/jedi/evaluate/context/klass.py +++ b/jedi/evaluate/context/klass.py @@ -197,7 +197,7 @@ class ClassContext(use_metaclass(CachedMetaClass, TreeContext)): def py__call__(self, arguments): from jedi.evaluate.context import TreeInstance - return ContextSet(TreeInstance(self.evaluator, self.parent_context, self, arguments)) + return ContextSet([TreeInstance(self.evaluator, self.parent_context, self, arguments)]) def py__class__(self): return compiled.builtin_from_name(self.evaluator, u'type') @@ -263,8 +263,8 @@ class ClassContext(use_metaclass(CachedMetaClass, TreeContext)): def py__getitem__(self, index_context_set, contextualized_node): from jedi.evaluate.context.typing import AnnotatedClass if not index_context_set: - return ContextSet(self) - return ContextSet.from_iterable( + return ContextSet([self]) + return ContextSet( AnnotatedClass( self.evaluator, self.parent_context, diff --git a/jedi/evaluate/context/typing.py b/jedi/evaluate/context/typing.py index d99056c4..a71840ad 100644 --- a/jedi/evaluate/context/typing.py +++ b/jedi/evaluate/context/typing.py @@ -39,7 +39,7 @@ class TypingName(AbstractTreeName): self._context = context def infer(self): - return ContextSet(self._context) + return ContextSet([self._context]) class _BaseTypingContext(Context): @@ -72,7 +72,7 @@ class _BaseTypingContext(Context): class TypingModuleName(NameWrapper): def infer(self): - return ContextSet.from_iterable(self._remap()) + return ContextSet(self._remap()) def _remap(self): name = self.string_name @@ -157,22 +157,22 @@ class TypingContextWithIndex(_WithIndexBase): # Optional is basically just saying it's either None or the actual # type. return self._execute_annotations_for_all_indexes() \ - | ContextSet(builtin_from_name(self.evaluator, u'None')) + | ContextSet([builtin_from_name(self.evaluator, u'None')]) elif string_name == 'Type': # The type is actually already given in the index_context - return ContextSet(self._index_context) + return ContextSet([self._index_context]) elif string_name == 'ClassVar': # For now don't do anything here, ClassVars are always used. return self._index_context.execute_annotation() cls = globals()[string_name] - return ContextSet(cls( + return ContextSet([cls( self.evaluator, self.parent_context, self._tree_name, self._index_context, self._context_of_index - )) + )]) class TypingContext(_BaseTypingContext): @@ -180,7 +180,7 @@ class TypingContext(_BaseTypingContext): py__simple_getitem__ = None def py__getitem__(self, index_context_set, contextualized_node): - return ContextSet.from_iterable( + return ContextSet( self.index_class.create_cached( self.evaluator, self.parent_context, @@ -210,7 +210,7 @@ def _iter_over_arguments(maybe_tuple_context, defining_context): for lazy_context in maybe_tuple_context.py__iter__(): yield lazy_context.infer() else: - yield ContextSet(maybe_tuple_context) + yield ContextSet([maybe_tuple_context]) def resolve_forward_references(context_set): for context in context_set: @@ -224,7 +224,7 @@ def _iter_over_arguments(maybe_tuple_context, defining_context): yield context for context_set in iterate(): - yield ContextSet.from_iterable(resolve_forward_references(context_set)) + yield ContextSet(resolve_forward_references(context_set)) class TypeAlias(HelperContextMixin): @@ -341,13 +341,13 @@ class TypeVarClass(_BaseTypingContext): debug.warning('Found a variable without a name %s', arguments) return NO_CONTEXTS - return ContextSet(TypeVar.create_cached( + return ContextSet([TypeVar.create_cached( self.evaluator, self.parent_context, self._tree_name, var_name, unpacked - )) + )]) def _find_string_name(self, lazy_context): if lazy_context is None: @@ -451,7 +451,7 @@ class BoundTypeVarName(AbstractNameDefinition): yield constraint else: yield context - return ContextSet.from_iterable(iter_()) + return ContextSet(iter_()) def py__name__(self): return self._type_var.py__name__() @@ -530,7 +530,7 @@ class _AbstractAnnotatedClass(ClassContext): def py__call__(self, arguments): instance, = super(_AbstractAnnotatedClass, self).py__call__(arguments) - return ContextSet(InstanceWrapper(instance)) + return ContextSet([InstanceWrapper(instance)]) def get_given_types(self): raise NotImplementedError @@ -590,7 +590,7 @@ class LazyAnnotatedBaseClass(object): def _remap_type_vars(self, base): filter = self._class_context.get_type_var_filter() for type_var_set in base.get_given_types(): - new = ContextSet() + new = NO_CONTEXTS for type_var in type_var_set: if isinstance(type_var, TypeVar): names = filter.get(type_var.py__name__()) @@ -601,7 +601,7 @@ class LazyAnnotatedBaseClass(object): # Mostly will be type vars, except if in some cases # a concrete type will already be there. In that # case just add it to the context set. - new |= ContextSet(type_var) + new |= ContextSet([type_var]) yield new diff --git a/jedi/evaluate/docstrings.py b/jedi/evaluate/docstrings.py index d4002f98..639ae5ce 100644 --- a/jedi/evaluate/docstrings.py +++ b/jedi/evaluate/docstrings.py @@ -272,7 +272,7 @@ def infer_param(execution_context, param): from jedi.evaluate.context import FunctionExecutionContext def eval_docstring(docstring): - return ContextSet.from_iterable( + return ContextSet( p for param_str in _search_param_in_docstr(docstring, param.name.value) for p in _evaluate_for_statement_string(module_context, param_str) diff --git a/jedi/evaluate/filters.py b/jedi/evaluate/filters.py index ab9aaaa3..a312978e 100644 --- a/jedi/evaluate/filters.py +++ b/jedi/evaluate/filters.py @@ -69,7 +69,7 @@ class AbstractTreeName(AbstractNameDefinition): class ContextNameMixin(object): def infer(self): - return ContextSet(self._context) + return ContextSet([self._context]) def get_root_context(self): if self.parent_context is None: @@ -384,9 +384,9 @@ class SpecialMethodFilter(DictFilter): else: continue break - return ContextSet( + return ContextSet([ _BuiltinMappedMethod(self.parent_context, self._callable, builtin_func) - ) + ]) def __init__(self, context, dct, builtin_context): super(SpecialMethodFilter, self).__init__(dct) diff --git a/jedi/evaluate/finder.py b/jedi/evaluate/finder.py index 22147970..438f6d6f 100644 --- a/jedi/evaluate/finder.py +++ b/jedi/evaluate/finder.py @@ -26,7 +26,7 @@ from jedi.evaluate.arguments import TreeArguments from jedi.evaluate import helpers from jedi.evaluate.context import iterable from jedi.evaluate.filters import get_global_filters, TreeNameDefinition -from jedi.evaluate.base_context import ContextSet +from jedi.evaluate.base_context import ContextSet, NO_CONTEXTS from jedi.parser_utils import is_scope, get_parent_scope @@ -60,7 +60,7 @@ class NameFinder(object): node=self._name, ) if check is flow_analysis.UNREACHABLE: - return ContextSet() + return NO_CONTEXTS return self._found_predefined_types types = self._names_to_types(names, attribute_lookup) @@ -266,7 +266,7 @@ def _check_isinstance_type(context, element, search_name): except AssertionError: return None - context_set = ContextSet() + context_set = NO_CONTEXTS for cls_or_tup in lazy_context_cls.infer(): if isinstance(cls_or_tup, iterable.Sequence) and cls_or_tup.array_type == 'tuple': for lazy_context in cls_or_tup.py__iter__(): diff --git a/jedi/evaluate/helpers.py b/jedi/evaluate/helpers.py index 3986fd30..ba0dd38a 100644 --- a/jedi/evaluate/helpers.py +++ b/jedi/evaluate/helpers.py @@ -237,5 +237,5 @@ def execute_evaluated(context, *value_list): # TODO move this out of here to the evaluator. from jedi.evaluate.arguments import ValuesArguments from jedi.evaluate.base_context import ContextSet - arguments = ValuesArguments([ContextSet(value) for value in value_list]) + arguments = ValuesArguments([ContextSet([value]) for value in value_list]) return context.evaluator.execute(context, arguments) diff --git a/jedi/evaluate/imports.py b/jedi/evaluate/imports.py index e67338d9..25dac530 100644 --- a/jedi/evaluate/imports.py +++ b/jedi/evaluate/imports.py @@ -93,7 +93,7 @@ def infer_import(context, tree_name, is_goto=False): for t in types ) if not is_goto: - types = ContextSet.from_set(types) + types = ContextSet(types) if not types: path = import_path + [from_import_name] @@ -450,7 +450,7 @@ def import_module(evaluator, import_names, parent_module_context, sys_path): safe_module_name=True, ) - return ContextSet(module) + return ContextSet([module]) def _load_module(evaluator, path=None, code=None, sys_path=None, @@ -528,7 +528,7 @@ def get_modules_containing_name(evaluator, modules, name): sys_path=e_sys_path, import_names=import_names, ) - evaluator.module_cache.add(import_names, ContextSet(module)) + evaluator.module_cache.add(import_names, ContextSet([module])) return module # skip non python modules diff --git a/jedi/evaluate/lazy_context.py b/jedi/evaluate/lazy_context.py index 84b375c1..bb8dd3e2 100644 --- a/jedi/evaluate/lazy_context.py +++ b/jedi/evaluate/lazy_context.py @@ -16,7 +16,7 @@ class AbstractLazyContext(object): class LazyKnownContext(AbstractLazyContext): """data is a context.""" def infer(self): - return ContextSet(self.data) + return ContextSet([self.data]) class LazyKnownContexts(AbstractLazyContext): diff --git a/jedi/evaluate/pep0484.py b/jedi/evaluate/pep0484.py index bdaee016..7fb03c20 100644 --- a/jedi/evaluate/pep0484.py +++ b/jedi/evaluate/pep0484.py @@ -240,7 +240,7 @@ def infer_return_types(function_execution_context): for from_, to in zip(unknown_type_vars, context.list_type_vars()) } return type_var_dict - return ContextSet.from_iterable( + return ContextSet( define_type_vars( annotation_context, remap_type_vars(annotation_context, type_var_dict), diff --git a/jedi/evaluate/syntax_tree.py b/jedi/evaluate/syntax_tree.py index 0a553729..6d06f277 100644 --- a/jedi/evaluate/syntax_tree.py +++ b/jedi/evaluate/syntax_tree.py @@ -51,7 +51,7 @@ def _limit_context_infers(func): def _py__stop_iteration_returns(generators): - results = ContextSet() + results = NO_CONTEXTS for generator in generators: try: method = generator.py__stop_iteration_returns @@ -71,7 +71,7 @@ def eval_node(context, element): if typ in ('name', 'number', 'string', 'atom', 'strings', 'keyword'): return eval_atom(context, element) elif typ == 'lambdef': - return ContextSet(FunctionContext.from_context(context, element)) + return ContextSet([FunctionContext.from_context(context, element)]) elif typ == 'expr_stmt': return eval_expr_stmt(context, element) elif typ in ('power', 'atom_expr'): @@ -100,12 +100,11 @@ def eval_node(context, element): await_context_set = context_set.py__getattribute__(u"__await__") if not await_context_set: debug.warning('Tried to run py__await__ on context %s', context) - context_set = ContextSet() return _py__stop_iteration_returns(await_context_set.execute_evaluated()) return context_set elif typ in ('testlist_star_expr', 'testlist',): # The implicit tuple in statements. - return ContextSet(iterable.SequenceLiteralContext(evaluator, context, element)) + return ContextSet([iterable.SequenceLiteralContext(evaluator, context, element)]) elif typ in ('not_test', 'factor'): context_set = context.eval_node(element.children[-1]) for operator in element.children[:-1]: @@ -122,7 +121,7 @@ def eval_node(context, element): if element.value not in ('.', '...'): origin = element.parent raise AssertionError("unhandled operator %s in %s " % (repr(element.value), origin)) - return ContextSet(compiled.builtin_from_name(evaluator, u'Ellipsis')) + return ContextSet([compiled.builtin_from_name(evaluator, u'Ellipsis')]) elif typ == 'dotted_name': context_set = eval_atom(context, element.children[0]) for next_name in element.children[2::2]: @@ -158,7 +157,7 @@ def eval_trailer(context, base_contexts, trailer): foo = set(base_contexts) # special case: PEP0484 typing module, see # https://github.com/davidhalter/jedi/issues/663 - result = ContextSet() + result = NO_CONTEXTS for typ in list(foo): continue if isinstance(typ, (ClassContext, TreeInstance)): @@ -213,7 +212,7 @@ def eval_atom(context, atom): elif atom.type == 'keyword': # For False/True/None if atom.value in ('False', 'True', 'None'): - return ContextSet(compiled.builtin_from_name(context.evaluator, atom.value)) + return ContextSet([compiled.builtin_from_name(context.evaluator, atom.value)]) elif atom.value == 'print': # print e.g. could be evaluated like this in Python 2.7 return NO_CONTEXTS @@ -225,7 +224,7 @@ def eval_atom(context, atom): elif isinstance(atom, tree.Literal): string = context.evaluator.compiled_subprocess.safe_literal_eval(atom.value) - return ContextSet(compiled.create_simple_object(context.evaluator, string)) + return ContextSet([compiled.create_simple_object(context.evaluator, string)]) elif atom.type == 'strings': # Will be multiple string. context_set = eval_atom(context, atom.children[0]) @@ -254,9 +253,9 @@ def eval_atom(context, atom): pass if comp_for.type == 'comp_for': - return ContextSet(iterable.comprehension_from_atom( + return ContextSet([iterable.comprehension_from_atom( context.evaluator, context, atom - )) + )]) # It's a dict/list/tuple literal. array_node = c[1] @@ -269,7 +268,7 @@ def eval_atom(context, atom): context = iterable.DictLiteralContext(context.evaluator, context, atom) else: context = iterable.SequenceLiteralContext(context.evaluator, context, atom) - return ContextSet(context) + return ContextSet([context]) @_limit_context_infers @@ -397,7 +396,7 @@ def _literals_to_types(evaluator, result): cls = compiled.builtin_from_name(evaluator, typ.name.string_name) new_result |= helpers.execute_evaluated(cls) else: - new_result |= ContextSet(typ) + new_result |= ContextSet([typ]) return new_result @@ -459,26 +458,26 @@ def _eval_comparison_part(evaluator, context, left, operator, right): if str_operator == '*': # for iterables, ignore * operations if isinstance(left, iterable.Sequence) or is_string(left): - return ContextSet(left) + return ContextSet([left]) elif isinstance(right, iterable.Sequence) or is_string(right): - return ContextSet(right) + return ContextSet([right]) elif str_operator == '+': if l_is_num and r_is_num or is_string(left) and is_string(right): - return ContextSet(left.execute_operation(right, str_operator)) + return ContextSet([left.execute_operation(right, str_operator)]) elif _is_tuple(left) and _is_tuple(right) or _is_list(left) and _is_list(right): - return ContextSet(iterable.MergedArray(evaluator, (left, right))) + return ContextSet([iterable.MergedArray(evaluator, (left, right))]) elif str_operator == '-': if l_is_num and r_is_num: - return ContextSet(left.execute_operation(right, str_operator)) + return ContextSet([left.execute_operation(right, str_operator)]) elif str_operator == '%': # With strings and numbers the left type typically remains. Except for # `int() % float()`. - return ContextSet(left) + return ContextSet([left]) elif str_operator in COMPARISON_OPERATORS: if is_compiled(left) and is_compiled(right): # Possible, because the return is not an option. Just compare. try: - return ContextSet(left.execute_operation(right, str_operator)) + return ContextSet([left.execute_operation(right, str_operator)]) except TypeError: # Could be True or False. pass @@ -486,9 +485,9 @@ def _eval_comparison_part(evaluator, context, left, operator, right): if str_operator in ('is', '!=', '==', 'is not'): operation = COMPARISON_OPERATORS[str_operator] bool_ = operation(left, right) - return ContextSet(_bool_to_context(evaluator, bool_)) + return ContextSet([_bool_to_context(evaluator, bool_)]) - return ContextSet(_bool_to_context(evaluator, True), _bool_to_context(evaluator, False)) + return ContextSet([_bool_to_context(evaluator, True), _bool_to_context(evaluator, False)]) elif str_operator == 'in': return NO_CONTEXTS @@ -504,7 +503,7 @@ def _eval_comparison_part(evaluator, context, left, operator, right): analysis.add(context, 'type-error-operation', operator, message % (left, right)) - result = ContextSet(left, right) + result = ContextSet([left, right]) debug.dbg('Used operator %s resulting in %s', result) return result @@ -525,7 +524,7 @@ def _remove_statements(evaluator, context, stmt, name): def tree_name_to_contexts(evaluator, context, tree_name): - context_set = ContextSet() + context_set = NO_CONTEXTS module_node = context.get_root_context().tree_node if module_node is not None: names = module_node.get_used_names().get(tree_name.value, []) @@ -611,7 +610,7 @@ def _apply_decorators(context, node): ) else: decoratee_context = FunctionContext.from_context(context, node) - initial = values = ContextSet(decoratee_context) + initial = values = ContextSet([decoratee_context]) for dec in reversed(node.get_decorators()): debug.dbg('decorator: %s %s', dec, values) dec_values = context.eval_node(dec.children[1]) @@ -651,7 +650,7 @@ def check_tuple_assignments(evaluator, contextualized_name, context_set): # would allow this loop to run for a very long time if the # index number is high. Therefore break if the loop is # finished. - return ContextSet() + return NO_CONTEXTS context_set = lazy_context.infer() return context_set @@ -662,7 +661,7 @@ def eval_subscript_list(evaluator, context, index): """ if index == ':': # Like array[:] - return ContextSet(iterable.Slice(context, None, None, None)) + return ContextSet([iterable.Slice(context, None, None, None)]) elif index.type == 'subscript' and not index.children[0] == '.': # subscript basically implies a slice operation, except for Python 2's @@ -680,9 +679,9 @@ def eval_subscript_list(evaluator, context, index): result.append(el) result += [None] * (3 - len(result)) - return ContextSet(iterable.Slice(context, *result)) + return ContextSet([iterable.Slice(context, *result)]) elif index.type == 'subscriptlist': - return ContextSet(iterable.SequenceLiteralContext(evaluator, context, index)) + return ContextSet([iterable.SequenceLiteralContext(evaluator, context, index)]) # No slices return context.eval_node(index) diff --git a/jedi/plugins/stdlib.py b/jedi/plugins/stdlib.py index b5d00ec5..5b1074e5 100644 --- a/jedi/plugins/stdlib.py +++ b/jedi/plugins/stdlib.py @@ -224,7 +224,7 @@ def builtins_reversed(sequences, obj, arguments): # would fail in certain cases like `reversed(x).__iter__` if we # just returned the result directly. instance = TreeInstance(obj.evaluator, obj.parent_context, obj, ValuesArguments([])) - return ContextSet(ReversedObject(instance, list(reversed(ordered)))) + return ContextSet([ReversedObject(instance, list(reversed(ordered)))]) @argument_clinic('obj, type, /', want_arguments=True, want_evaluator=True) @@ -263,7 +263,7 @@ def builtins_isinstance(objects, types, arguments, evaluator): 'not %s.' % cls_or_tup analysis.add(lazy_context._context, 'type-error-isinstance', node, message) - return ContextSet.from_iterable( + return ContextSet( compiled.builtin_from_name(evaluator, force_unicode(str(b))) for b in bool_results ) @@ -328,7 +328,7 @@ def collections_namedtuple(obj, arguments): code_lines=parso.split_lines(code, keepends=True), ) - return ContextSet(ClassContext(evaluator, parent_context, generated_class)) + return ContextSet([ClassContext(evaluator, parent_context, generated_class)]) class PartialObject(object): @@ -367,7 +367,7 @@ class MergedPartialArguments(AbstractArguments): def functools_partial(obj, arguments): - return ContextSet.from_iterable( + return ContextSet( PartialObject(instance, arguments) for instance in obj.py__call__(arguments) ) @@ -395,7 +395,7 @@ class ItemGetterCallable(object): @repack_with_argument_clinic('item, /') def py__call__(self, item_context_set): - context_set = ContextSet() + context_set = NO_CONTEXTS for args_context in self._args_context_set: lazy_contexts = list(args_context.py__iter__()) if len(lazy_contexts) == 1: @@ -411,7 +411,7 @@ class ItemGetterCallable(object): def _operator_itemgetter(args_context_set, obj, arguments): # final = obj.py__call__(arguments) # TODO use this as a context wrapper - return ContextSet(ItemGetterCallable(obj.evaluator, args_context_set)) + return ContextSet([ItemGetterCallable(obj.evaluator, args_context_set)]) _implemented = { diff --git a/jedi/plugins/typeshed.py b/jedi/plugins/typeshed.py index ee4167fe..ada77c34 100644 --- a/jedi/plugins/typeshed.py +++ b/jedi/plugins/typeshed.py @@ -164,7 +164,7 @@ class TypeshedPlugin(BasePlugin): code_lines=[], ) modules = _merge_modules(context_set, stub_module_context) - return ContextSet.from_iterable(modules) + return ContextSet(modules) # If no stub is found, just return the default. return context_set return wrapper