Don't catch IndexError where we don't have to

This commit is contained in:
Dave Halter
2018-04-20 01:46:14 +02:00
parent 5f37d08761
commit 88243d2408
5 changed files with 51 additions and 10 deletions

View File

@@ -12,6 +12,8 @@ from jedi import debug
from jedi._compatibility import Python3Method, zip_longest, unicode
from jedi.parser_utils import clean_scope_docstring, get_doc_with_call_signature
from jedi.common import BaseContextSet, BaseContext
from jedi.evaluate.helpers import EvaluatorIndexError, EvaluatorTypeError, \
EvaluatorKeyError
class Context(BaseContext):
@@ -128,11 +130,15 @@ class Context(BaseContext):
else:
try:
result |= getitem(index)
except IndexError:
except EvaluatorIndexError:
result |= iterate_contexts(ContextSet(self))
except KeyError:
except EvaluatorKeyError:
# Must be a dict. Lists don't raise KeyErrors.
result |= self.dict_values()
except EvaluatorTypeError:
# The type is wrong and therefore it makes no sense to do
# anything anymore.
result = NO_CONTEXTS
return result
def eval_node(self, node):

View File

@@ -13,6 +13,7 @@ from jedi.evaluate.base_context import Context, ContextSet
from jedi.evaluate.lazy_context import LazyKnownContext
from jedi.evaluate.compiled.access import _sentinel
from jedi.evaluate.cache import evaluator_function_cache
from jedi.evaluate.helpers import reraise_as_evaluator
from . import fake
@@ -145,7 +146,8 @@ class CompiledObject(Context):
@CheckAttribute
def py__getitem__(self, index):
access = self.access_handle.py__getitem__(index)
with reraise_as_evaluator(IndexError, KeyError, TypeError):
access = self.access_handle.py__getitem__(index)
if access is None:
return ContextSet()

View File

@@ -30,7 +30,8 @@ from jedi.evaluate import recursion
from jedi.evaluate.lazy_context import LazyKnownContext, LazyKnownContexts, \
LazyTreeContext
from jedi.evaluate.helpers import get_int_or_none, is_string, \
predefine_names, evaluate_call_of_leaf
predefine_names, evaluate_call_of_leaf, reraise_as_evaluator, \
EvaluatorKeyError
from jedi.evaluate.utils import safe_property
from jedi.evaluate.utils import to_list
from jedi.evaluate.cache import evaluator_method_cache
@@ -219,7 +220,9 @@ class ListComprehension(ComprehensionMixin, Sequence):
return ContextSet(self)
all_types = list(self.py__iter__())
return all_types[index].infer()
with reraise_as_evaluator(IndexError, TypeError):
lazy_context = all_types[index]
return lazy_context.infer()
class SetComprehension(ComprehensionMixin, Sequence):
@@ -293,13 +296,15 @@ class SequenceLiteralContext(Sequence):
if isinstance(k, compiled.CompiledObject) \
and k.execute_operation(compiled_obj_index, u'==').get_safe_value():
return self._defining_context.eval_node(value)
raise KeyError('No key found in dictionary %s.' % self)
raise EvaluatorKeyError('No key found in dictionary %s.' % self)
# Can raise an IndexError
if isinstance(index, slice):
return ContextSet(self)
else:
return self._defining_context.eval_node(self._items()[index])
with reraise_as_evaluator(TypeError, KeyError, IndexError):
node = self._items()[index]
return self._defining_context.eval_node(node)
def py__iter__(self):
"""
@@ -413,7 +418,9 @@ class FakeSequence(_FakeArray):
self._lazy_context_list = lazy_context_list
def py__getitem__(self, index):
return self._lazy_context_list[index].infer()
with reraise_as_evaluator(IndexError, TypeError):
lazy_context = self._lazy_context_list[index]
return lazy_context.infer()
def py__iter__(self):
return self._lazy_context_list
@@ -450,7 +457,9 @@ class FakeDict(_FakeArray):
except KeyError:
pass
return self._dct[index].infer()
with reraise_as_evaluator(KeyError):
lazy_context = self._dct[index]
return lazy_context.infer()
@publish_method('values')
def _values(self):

View File

@@ -9,7 +9,6 @@ from parso.python import tree
from jedi._compatibility import unicode
from jedi.parser_utils import get_parent_scope
from jedi.evaluate.compiled import CompiledObject
def is_stdlib_path(path):
@@ -184,6 +183,7 @@ def predefine_names(context, flow_scope, dct):
def is_compiled(context):
from jedi.evaluate.compiled import CompiledObject
return isinstance(context, CompiledObject)
@@ -212,3 +212,24 @@ def get_int_or_none(context):
def is_number(context):
return _get_safe_value_or_none(context, (int, float)) is not None
class EvaluatorTypeError(Exception):
pass
class EvaluatorIndexError(Exception):
pass
class EvaluatorKeyError(Exception):
pass
@contextmanager
def reraise_as_evaluator(*exception_classes):
try:
yield
except exception_classes as e:
new_exc_cls = globals()['Evaluator' + e.__class__.__name__]
raise new_exc_cls(e)

View File

@@ -29,6 +29,9 @@ b = [6,7]
#? int()
b[8-7]
# Something unreasonable:
#?
b['']
# -----------------
# Slices