mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
Replace a lot more of empty sets and unite calls.
This commit is contained in:
@@ -35,6 +35,9 @@ class ContextSet(object):
|
||||
def __bool__(self):
|
||||
return bool(self._set)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._set)
|
||||
|
||||
def __repr__(self):
|
||||
return '%s(%s)' % (self.__class__.__name__, ', '.join(str(s) for s in self._set))
|
||||
|
||||
|
||||
@@ -433,7 +433,7 @@ class Evaluator(object):
|
||||
node = ()
|
||||
|
||||
if trailer_op == '[':
|
||||
return ContextSet(iterable.py__getitem__(self, context, types, trailer))
|
||||
return iterable.py__getitem__(self, context, types, trailer)
|
||||
else:
|
||||
context_set = ContextSet()
|
||||
for typ in types:
|
||||
|
||||
@@ -223,7 +223,10 @@ def _execute_types_in_stmt(module_context, stmt):
|
||||
contain is executed. (Used as type information).
|
||||
"""
|
||||
definitions = module_context.eval_node(stmt)
|
||||
return unite(_execute_array_values(module_context.evaluator, d) for d in definitions)
|
||||
return ContextSet.from_sets(
|
||||
_execute_array_values(module_context.evaluator, d)
|
||||
for d in definitions
|
||||
)
|
||||
|
||||
|
||||
def _execute_array_values(evaluator, array):
|
||||
@@ -234,7 +237,10 @@ def _execute_array_values(evaluator, array):
|
||||
if isinstance(array, SequenceLiteralContext):
|
||||
values = []
|
||||
for lazy_context in array.py__iter__():
|
||||
objects = unite(_execute_array_values(evaluator, typ) for typ in lazy_context.infer())
|
||||
objects = ContextSet.from_sets(
|
||||
_execute_array_values(evaluator, typ)
|
||||
for typ in lazy_context.infer()
|
||||
)
|
||||
values.append(context.LazyKnownContexts(objects))
|
||||
return set([FakeSequence(evaluator, array.array_type, values)])
|
||||
else:
|
||||
|
||||
@@ -24,7 +24,8 @@ from jedi.evaluate.cache import evaluator_function_cache
|
||||
from jedi.evaluate import imports
|
||||
from jedi.evaluate.param import TreeArguments, create_default_params
|
||||
from jedi.evaluate.helpers import is_stdlib_path
|
||||
from jedi.evaluate.utils import to_list, unite
|
||||
from jedi.evaluate.utils import to_list
|
||||
from jedi.common import ContextSet
|
||||
from jedi.parser_utils import get_parent_scope
|
||||
|
||||
|
||||
@@ -50,7 +51,7 @@ class MergedExecutedParams(object):
|
||||
self._executed_params = executed_params
|
||||
|
||||
def infer(self):
|
||||
return unite(p.infer() for p in self._executed_params)
|
||||
return ContextSet.from_sets(p.infer() for p in self._executed_params)
|
||||
|
||||
|
||||
@debug.increase_indent
|
||||
@@ -103,7 +104,7 @@ def search_params(evaluator, execution_context, funcdef):
|
||||
evaluator.dynamic_params_depth -= 1
|
||||
|
||||
|
||||
@evaluator_function_cache(default=[])
|
||||
@evaluator_function_cache(default=None)
|
||||
@to_list
|
||||
def _search_function_executions(evaluator, module_context, funcdef):
|
||||
"""
|
||||
|
||||
@@ -6,9 +6,9 @@ from abc import abstractmethod
|
||||
|
||||
from parso.tree import search_ancestor
|
||||
from jedi.evaluate import flow_analysis
|
||||
from jedi.evaluate.utils import to_list, unite
|
||||
from jedi.common import ContextSet
|
||||
from jedi.parser_utils import get_parent_scope
|
||||
from jedi.evaluate.utils import to_list
|
||||
|
||||
|
||||
class AbstractNameDefinition(object):
|
||||
@@ -36,10 +36,10 @@ class AbstractNameDefinition(object):
|
||||
return '<%s: %s@%s>' % (self.__class__.__name__, self.string_name, self.start_pos)
|
||||
|
||||
def execute(self, arguments):
|
||||
return unite(context.execute(arguments) for context in self.infer())
|
||||
return self.infer().execute(arguments)
|
||||
|
||||
def execute_evaluated(self, *args, **kwargs):
|
||||
return unite(context.execute_evaluated(*args, **kwargs) for context in self.infer())
|
||||
return self.infer().execute_evaluated(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def api_type(self):
|
||||
|
||||
@@ -233,10 +233,7 @@ def _name_to_types(evaluator, context, tree_name):
|
||||
# TODO check for types that are not classes and add it to
|
||||
# the static analysis report.
|
||||
exceptions = context.eval_node(tree_name.get_previous_sibling().get_previous_sibling())
|
||||
types = unite(
|
||||
evaluator.execute(t, param.ValuesArguments([]))
|
||||
for t in exceptions
|
||||
)
|
||||
types = exceptions.execute_evaluated()
|
||||
else:
|
||||
raise ValueError("Should not happen.")
|
||||
return types
|
||||
@@ -274,8 +271,7 @@ def _apply_decorators(evaluator, context, node):
|
||||
debug.warning('decorator not found: %s on %s', dec, node)
|
||||
return initial
|
||||
|
||||
values = unite(dec_value.execute(param.ValuesArguments([values]))
|
||||
for dec_value in dec_values)
|
||||
values = dec_values.execute(param.ValuesArguments([values]))
|
||||
if not len(values):
|
||||
debug.warning('not possible to resolve wrappers found %s', node)
|
||||
return initial
|
||||
|
||||
@@ -24,7 +24,6 @@ from parso import python_bytes_to_unicode
|
||||
from jedi._compatibility import find_module, unicode, ImplicitNSInfo
|
||||
from jedi import debug
|
||||
from jedi import settings
|
||||
from jedi.evaluate.utils import unite
|
||||
from jedi.evaluate import sys_path
|
||||
from jedi.evaluate import helpers
|
||||
from jedi.evaluate import compiled
|
||||
@@ -67,13 +66,11 @@ def infer_import(context, tree_name, is_goto=False):
|
||||
return NO_CONTEXTS
|
||||
|
||||
if from_import_name is not None:
|
||||
types = unite(
|
||||
t.py__getattribute__(
|
||||
from_import_name,
|
||||
name_context=context,
|
||||
is_goto=is_goto,
|
||||
analysis_errors=False
|
||||
) for t in types
|
||||
types = types.py__getattribute__(
|
||||
from_import_name,
|
||||
name_context=context,
|
||||
is_goto=is_goto,
|
||||
analysis_errors=False
|
||||
)
|
||||
|
||||
if not types:
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from abc import abstractproperty
|
||||
|
||||
from jedi._compatibility import is_py3
|
||||
from jedi.evaluate.utils import unite
|
||||
from jedi import debug
|
||||
from jedi.evaluate import compiled
|
||||
from jedi.evaluate import filters
|
||||
@@ -11,7 +10,7 @@ from jedi.evaluate.param import AbstractArguments, AnonymousArguments
|
||||
from jedi.cache import memoize_method
|
||||
from jedi.evaluate import representation as er
|
||||
from jedi.evaluate import iterable
|
||||
from jedi.common import ContextSet, iterator_to_context_set
|
||||
from jedi.common import ContextSet, iterator_to_context_set, NO_CONTEXTS
|
||||
from jedi.parser_utils import get_parent_scope
|
||||
|
||||
|
||||
@@ -59,7 +58,7 @@ class AbstractInstanceContext(Context):
|
||||
raise AttributeError
|
||||
|
||||
def execute(arguments):
|
||||
return unite(name.execute(arguments) for name in names)
|
||||
return ContextSet.from_sets(name.execute(arguments) for name in names)
|
||||
|
||||
return execute
|
||||
|
||||
@@ -81,7 +80,7 @@ class AbstractInstanceContext(Context):
|
||||
return []
|
||||
|
||||
def execute_function_slots(self, names, *evaluated_args):
|
||||
return unite(
|
||||
return ContextSet.from_sets(
|
||||
name.execute_evaluated(*evaluated_args)
|
||||
for name in names
|
||||
)
|
||||
@@ -97,7 +96,7 @@ class AbstractInstanceContext(Context):
|
||||
none_obj = compiled.create(self.evaluator, None)
|
||||
return self.execute_function_slots(names, none_obj, obj)
|
||||
else:
|
||||
return set([self])
|
||||
return ContextSet(self)
|
||||
|
||||
def get_filters(self, search_global=None, until_position=None,
|
||||
origin_scope=None, include_self_names=True):
|
||||
@@ -123,7 +122,7 @@ class AbstractInstanceContext(Context):
|
||||
names = self.get_function_slot_names('__getitem__')
|
||||
except KeyError:
|
||||
debug.warning('No __getitem__, cannot access the array.')
|
||||
return set()
|
||||
return NO_CONTEXTS
|
||||
else:
|
||||
index_obj = compiled.create(self.evaluator, index)
|
||||
return self.execute_function_slots(names, index_obj)
|
||||
|
||||
@@ -144,7 +144,7 @@ class GeneratorMixin(object):
|
||||
@register_builtin_method('__next__', python_version_match=3)
|
||||
def py__next__(self):
|
||||
# TODO add TypeError if params are given.
|
||||
return unite(lazy_context.infer() for lazy_context in self.py__iter__())
|
||||
return ContextSet.from_sets(lazy_context.infer() for lazy_context in self.py__iter__())
|
||||
|
||||
def get_filters(self, search_global, until_position=None, origin_scope=None):
|
||||
gen_obj = compiled.get_special_object(self.evaluator, 'GENERATOR_OBJECT')
|
||||
@@ -297,7 +297,8 @@ class ArrayMixin(object):
|
||||
return self.evaluator.BUILTINS
|
||||
|
||||
def dict_values(self):
|
||||
return unite(self._defining_context.eval_node(v) for k, v in self._items())
|
||||
return ContextSet.from_sets(self._defining_context.eval_node(v)
|
||||
for k, v in self._items())
|
||||
|
||||
|
||||
class ListComprehension(ArrayMixin, Comprehension):
|
||||
@@ -335,7 +336,7 @@ class DictComprehension(ArrayMixin, Comprehension):
|
||||
return self.dict_values()
|
||||
|
||||
def dict_values(self):
|
||||
return unite(values for keys, values in self._iterate())
|
||||
return ContextSet.from_sets(values for keys, values in self._iterate())
|
||||
|
||||
@register_builtin_method('values')
|
||||
def _imitate_values(self):
|
||||
@@ -414,7 +415,7 @@ class SequenceLiteralContext(ArrayMixin, AbstractSequence):
|
||||
def _values(self):
|
||||
"""Returns a list of a list of node."""
|
||||
if self.array_type == 'dict':
|
||||
return unite(v for k, v in self._items())
|
||||
return ContextSet.from_sets(v for k, v in self._items())
|
||||
else:
|
||||
return self._items()
|
||||
|
||||
@@ -532,7 +533,7 @@ class FakeDict(_FakeArray):
|
||||
return self._dct[index].infer()
|
||||
|
||||
def dict_values(self):
|
||||
return unite(lazy_context.infer() for lazy_context in self._dct.values())
|
||||
return ContextSet.from_sets(lazy_context.infer() for lazy_context in self._dct.values())
|
||||
|
||||
def _items(self):
|
||||
raise DeprecationWarning
|
||||
@@ -555,7 +556,7 @@ class MergedArray(_FakeArray):
|
||||
yield lazy_context
|
||||
|
||||
def py__getitem__(self, index):
|
||||
return unite(lazy_context.infer() for lazy_context in self.py__iter__())
|
||||
return ContextSet.from_sets(lazy_context.infer() for lazy_context in self.py__iter__())
|
||||
|
||||
def _items(self):
|
||||
for array in self._arrays:
|
||||
@@ -633,7 +634,7 @@ def py__iter__types(evaluator, types, contextualized_node=None):
|
||||
Calls `py__iter__`, but ignores the ordering in the end and just returns
|
||||
all types that it contains.
|
||||
"""
|
||||
return unite(
|
||||
return ContextSet.from_sets(
|
||||
lazy_context.infer()
|
||||
for lazy_context in py__iter__(evaluator, types, contextualized_node)
|
||||
)
|
||||
@@ -740,7 +741,7 @@ def _check_array_additions(context, sequence):
|
||||
is_list = sequence.name.string_name == 'list'
|
||||
search_names = (['append', 'extend', 'insert'] if is_list else ['add', 'update'])
|
||||
|
||||
added_types = NO_CONTEXTS()
|
||||
added_types = NO_CONTEXTS
|
||||
for add_name in search_names:
|
||||
try:
|
||||
possible_names = module_context.tree_node.get_used_names()[add_name]
|
||||
|
||||
@@ -10,6 +10,7 @@ from jedi.evaluate import context
|
||||
from jedi.evaluate import docstrings
|
||||
from jedi.evaluate import pep0484
|
||||
from jedi.evaluate.filters import ParamName
|
||||
from jedi.common import NO_CONTEXTS
|
||||
|
||||
|
||||
def add_argument_issue(parent_context, error_name, lazy_context, message):
|
||||
@@ -51,7 +52,7 @@ class AbstractArguments():
|
||||
debug.warning('TypeError: %s expected at least %s arguments, got %s',
|
||||
name, len(parameters), i)
|
||||
raise ValueError
|
||||
values = set() if argument is None else argument.infer()
|
||||
values = NO_CONTEXTS if argument is None else argument.infer()
|
||||
|
||||
if not values and not optional:
|
||||
# For the stdlib we always want values. If we don't get them,
|
||||
|
||||
@@ -25,11 +25,10 @@ import re
|
||||
from parso import ParserSyntaxError
|
||||
from parso.python import tree
|
||||
|
||||
from jedi.evaluate.utils import unite
|
||||
from jedi.evaluate.cache import evaluator_method_cache
|
||||
from jedi.evaluate import compiled
|
||||
from jedi.evaluate.context import LazyTreeContext
|
||||
from jedi.common import NO_CONTEXTS
|
||||
from jedi.common import NO_CONTEXTS, ContextSet
|
||||
from jedi import debug
|
||||
from jedi import _compatibility
|
||||
from jedi import parser_utils
|
||||
@@ -146,7 +145,7 @@ def py__getitem__(context, typ, node):
|
||||
if type_name in ("Union", '_Union'):
|
||||
# In Python 3.6 it's still called typing.Union but it's an instance
|
||||
# called _Union.
|
||||
return unite(context.eval_node(node) for node in nodes)
|
||||
return ContextSet.from_sets(context.eval_node(node) for node in nodes)
|
||||
if type_name in ("Optional", '_Optional'):
|
||||
# Here we have the same issue like in Union. Therefore we also need to
|
||||
# check for the instance typing._Optional (Python 3.6).
|
||||
|
||||
@@ -7,7 +7,7 @@ from jedi._compatibility import unicode
|
||||
from jedi import debug
|
||||
from jedi.evaluate.compiled import CompiledObject, create, builtin_from_name
|
||||
from jedi.evaluate import analysis
|
||||
from jedi.common import ContextSet
|
||||
from jedi.common import ContextSet, NO_CONTEXTS
|
||||
|
||||
# Maps Python syntax to the operator module.
|
||||
COMPARISON_OPERATORS = {
|
||||
@@ -162,7 +162,7 @@ def _element_calculate(evaluator, context, left, operator, right):
|
||||
else:
|
||||
return ContextSet(create(evaluator, result))
|
||||
elif operator == 'in':
|
||||
return set()
|
||||
return NO_CONTEXTS
|
||||
|
||||
def check(obj):
|
||||
"""Checks if a Jedi object is either a float or an int."""
|
||||
|
||||
@@ -29,6 +29,7 @@ therefore the quality might not always be maximal.
|
||||
from contextlib import contextmanager
|
||||
|
||||
from jedi import debug
|
||||
from jedi.common import NO_CONTEXTS
|
||||
|
||||
|
||||
recursion_limit = 15
|
||||
@@ -71,7 +72,7 @@ def execution_allowed(evaluator, node):
|
||||
pushed_nodes.pop()
|
||||
|
||||
|
||||
def execution_recursion_decorator(default=set()):
|
||||
def execution_recursion_decorator(default=NO_CONTEXTS):
|
||||
def decorator(func):
|
||||
def wrapper(execution, **kwargs):
|
||||
detector = execution.evaluator.execution_recursion_detector
|
||||
|
||||
@@ -24,6 +24,7 @@ from jedi.evaluate import precedence
|
||||
from jedi.evaluate import param
|
||||
from jedi.evaluate import analysis
|
||||
from jedi.evaluate.context import LazyTreeContext, ContextualizedNode
|
||||
from jedi.common import NO_CONTEXTS, ContextSet
|
||||
|
||||
# Now this is all part of fake tuples in Jedi. However super doesn't work on
|
||||
# __init__ and __new__ doesn't work at all. So adding this to nametuples is
|
||||
@@ -77,7 +78,7 @@ def _follow_param(evaluator, arguments, index):
|
||||
try:
|
||||
key, lazy_context = list(arguments.unpack())[index]
|
||||
except IndexError:
|
||||
return set()
|
||||
return NO_CONTEXTS
|
||||
else:
|
||||
return lazy_context.infer()
|
||||
|
||||
@@ -109,7 +110,7 @@ def argument_clinic(string, want_obj=False, want_context=False, want_arguments=F
|
||||
try:
|
||||
lst = list(arguments.eval_argument_clinic(clinic_args))
|
||||
except ValueError:
|
||||
return set()
|
||||
return NO_CONTEXTS
|
||||
else:
|
||||
kwargs = {}
|
||||
if want_context:
|
||||
@@ -137,15 +138,16 @@ def builtins_next(evaluator, iterators, defaults):
|
||||
else:
|
||||
name = '__next__'
|
||||
|
||||
types = set()
|
||||
context_set = NO_CONTEXTS
|
||||
for iterator in iterators:
|
||||
if isinstance(iterator, AbstractInstanceContext):
|
||||
for filter in iterator.get_filters(include_self_names=True):
|
||||
for n in filter.get(name):
|
||||
for context in n.infer():
|
||||
types |= context.execute_evaluated()
|
||||
if types:
|
||||
return types
|
||||
context_set = ContextSet.from_sets(
|
||||
n.infer()
|
||||
for filter in iterator.get_filters(include_self_names=True)
|
||||
for n in filter.get(name)
|
||||
).execute_evaluated()
|
||||
if context_set:
|
||||
return context_set
|
||||
return defaults
|
||||
|
||||
|
||||
@@ -159,16 +161,16 @@ def builtins_getattr(evaluator, objects, names, defaults=None):
|
||||
else:
|
||||
debug.warning('getattr called without str')
|
||||
continue
|
||||
return set()
|
||||
return NO_CONTEXTS
|
||||
|
||||
|
||||
@argument_clinic('object[, bases, dict], /')
|
||||
def builtins_type(evaluator, objects, bases, dicts):
|
||||
if bases or dicts:
|
||||
# It's a type creation... maybe someday...
|
||||
return set()
|
||||
return NO_CONTEXTS
|
||||
else:
|
||||
return set([o.py__class__() for o in objects])
|
||||
return ContextSet.from_iterable(o.py__class__() for o in objects)
|
||||
|
||||
|
||||
class SuperInstance(AbstractInstanceContext):
|
||||
@@ -185,7 +187,7 @@ def builtins_super(evaluator, types, objects, context):
|
||||
AnonymousInstanceFunctionExecution)):
|
||||
su = context.instance.py__class__().py__bases__()
|
||||
return unite(context.execute_evaluated() for context in su[0].infer())
|
||||
return set()
|
||||
return NO_CONTEXTS
|
||||
|
||||
|
||||
@argument_clinic('sequence, /', want_obj=True, want_arguments=True)
|
||||
@@ -207,12 +209,12 @@ def builtins_reversed(evaluator, sequences, obj, arguments):
|
||||
# just returned the result directly.
|
||||
seq = iterable.FakeSequence(evaluator, 'list', rev)
|
||||
arguments = param.ValuesArguments([[seq]])
|
||||
return set([CompiledInstance(evaluator, evaluator.BUILTINS, obj, arguments)])
|
||||
return ContextSet(CompiledInstance(evaluator, evaluator.BUILTINS, obj, arguments))
|
||||
|
||||
|
||||
@argument_clinic('obj, type, /', want_arguments=True)
|
||||
def builtins_isinstance(evaluator, objects, types, arguments):
|
||||
bool_results = set([])
|
||||
bool_results = set()
|
||||
for o in objects:
|
||||
try:
|
||||
mro_func = o.py__class__().py__mro__
|
||||
@@ -220,7 +222,7 @@ def builtins_isinstance(evaluator, objects, types, arguments):
|
||||
# This is temporary. Everything should have a class attribute in
|
||||
# Python?! Maybe we'll leave it here, because some numpy objects or
|
||||
# whatever might not.
|
||||
return set([compiled.create(True), compiled.create(False)])
|
||||
return ContextSet(compiled.create(True), compiled.create(False))
|
||||
|
||||
mro = mro_func()
|
||||
|
||||
@@ -244,7 +246,7 @@ def builtins_isinstance(evaluator, objects, types, arguments):
|
||||
'not %s.' % cls_or_tup
|
||||
analysis.add(lazy_context._context, 'type-error-isinstance', node, message)
|
||||
|
||||
return set(compiled.create(evaluator, x) for x in bool_results)
|
||||
return ContextSet.from_iterable(compiled.create(evaluator, x) for x in bool_results)
|
||||
|
||||
|
||||
def collections_namedtuple(evaluator, obj, arguments):
|
||||
@@ -259,7 +261,7 @@ def collections_namedtuple(evaluator, obj, arguments):
|
||||
"""
|
||||
# Namedtuples are not supported on Python 2.6
|
||||
if not hasattr(collections, '_class_template'):
|
||||
return set()
|
||||
return NO_CONTEXTS
|
||||
|
||||
# Process arguments
|
||||
# TODO here we only use one of the types, we should use all.
|
||||
@@ -274,7 +276,7 @@ def collections_namedtuple(evaluator, obj, arguments):
|
||||
for v in lazy_context.infer() if hasattr(v, 'obj')
|
||||
]
|
||||
else:
|
||||
return set()
|
||||
return NO_CONTEXTS
|
||||
|
||||
base = collections._class_template
|
||||
base += _NAMEDTUPLE_INIT
|
||||
@@ -293,7 +295,7 @@ def collections_namedtuple(evaluator, obj, arguments):
|
||||
module = evaluator.grammar.parse(source)
|
||||
generated_class = next(module.iter_classdefs())
|
||||
parent_context = er.ModuleContext(evaluator, module, '')
|
||||
return set([er.ClassContext(evaluator, generated_class, parent_context)])
|
||||
return ContextSet(er.ClassContext(evaluator, generated_class, parent_context))
|
||||
|
||||
|
||||
@argument_clinic('first, /')
|
||||
@@ -314,8 +316,8 @@ _implemented = {
|
||||
'deepcopy': _return_first_param,
|
||||
},
|
||||
'json': {
|
||||
'load': lambda *args: set(),
|
||||
'loads': lambda *args: set(),
|
||||
'load': lambda *args: NO_CONTEXTS,
|
||||
'loads': lambda *args: NO_CONTEXTS,
|
||||
},
|
||||
'collections': {
|
||||
'namedtuple': collections_namedtuple,
|
||||
|
||||
Reference in New Issue
Block a user