Make Slice a proper LazyValueWrapper

This commit is contained in:
Dave Halter
2019-08-21 09:51:47 +02:00
parent 02c96b37db
commit 9d34df2fed
2 changed files with 17 additions and 29 deletions

View File

@@ -19,7 +19,7 @@ from jedi.inference.utils import safe_property
from jedi.inference.cache import inference_state_as_method_param_cache from jedi.inference.cache import inference_state_as_method_param_cache
from jedi.cache import memoize_method from jedi.cache import memoize_method
_sentinel = object() sentinel = object()
class HelperValueMixin(object): class HelperValueMixin(object):
@@ -205,8 +205,8 @@ class Value(HelperValueMixin, BaseValue):
return clean_scope_docstring(self.tree_node) return clean_scope_docstring(self.tree_node)
return None return None
def get_safe_value(self, default=_sentinel): def get_safe_value(self, default=sentinel):
if default is _sentinel: if default is sentinel:
raise ValueError("There exists no safe value for value %s" % self) raise ValueError("There exists no safe value for value %s" % self)
return default return default
@@ -360,8 +360,6 @@ class ContextualizedName(ContextualizedNode):
def _getitem(value, index_values, contextualized_node): def _getitem(value, index_values, contextualized_node):
from jedi.inference.value.iterable import Slice
# The actual getitem call. # The actual getitem call.
simple_getitem = getattr(value, 'py__simple_getitem__', None) simple_getitem = getattr(value, 'py__simple_getitem__', None)
@@ -369,17 +367,8 @@ def _getitem(value, index_values, contextualized_node):
unused_values = set() unused_values = set()
for index_value in index_values: for index_value in index_values:
if simple_getitem is not None: if simple_getitem is not None:
index = index_value
if isinstance(index_value, Slice):
index = index.obj
try:
method = index.get_safe_value
except AttributeError:
pass
else:
index = method(default=None)
index = index_value.get_safe_value(default=None)
if type(index) in (float, int, str, unicode, slice, bytes): if type(index) in (float, int, str, unicode, slice, bytes):
try: try:
result |= simple_getitem(index) result |= simple_getitem(index)

View File

@@ -37,7 +37,8 @@ from jedi.inference.utils import safe_property, to_list
from jedi.inference.cache import inference_state_method_cache from jedi.inference.cache import inference_state_method_cache
from jedi.inference.filters import LazyAttributeOverwrite, publish_method from jedi.inference.filters import LazyAttributeOverwrite, publish_method
from jedi.inference.base_value import ValueSet, Value, NO_VALUES, \ from jedi.inference.base_value import ValueSet, Value, NO_VALUES, \
ContextualizedNode, iterate_values, HelperValueMixin, _sentinel ContextualizedNode, iterate_values, HelperValueMixin, sentinel, \
LazyValueWrapper
from jedi.parser_utils import get_sync_comp_fors from jedi.parser_utils import get_sync_comp_fors
from jedi.inference.context import CompForContext from jedi.inference.context import CompForContext
@@ -54,8 +55,8 @@ class IterableMixin(object):
# typeshed. # typeshed.
if sys.version_info[0] == 2: if sys.version_info[0] == 2:
# Python 2........... # Python 2...........
def get_safe_value(self, default=_sentinel): def get_safe_value(self, default=sentinel):
if default is _sentinel: if default is sentinel:
raise ValueError("There exists no safe value for value %s" % self) raise ValueError("There exists no safe value for value %s" % self)
return default return default
else: else:
@@ -771,23 +772,21 @@ class _ArrayInstance(HelperValueMixin):
return self.py__iter__(contextualized_node) return self.py__iter__(contextualized_node)
class Slice(object): class Slice(LazyValueWrapper):
def __init__(self, python_context, start, stop, step): def __init__(self, python_context, start, stop, step):
self._python_context = python_context self.inference_state = python_context.inference_state
self._slice_object = None self._context = python_context
# All of them are either a Precedence or None. # All of them are either a Precedence or None.
self._start = start self._start = start
self._stop = stop self._stop = stop
self._step = step self._step = step
def __getattr__(self, name): def _get_wrapped_value(self):
if self._slice_object is None: value = compiled.builtin_from_name(self._context.inference_state, 'slice')
value = compiled.builtin_from_name(self._python_context.inference_state, 'slice') slice_value, = value.execute_with_values()
self._slice_object, = value.execute_with_values() return slice_value
return getattr(self._slice_object, name)
@property def get_safe_value(self, default=sentinel):
def obj(self):
""" """
Imitate CompiledObject.obj behavior and return a ``builtin.slice()`` Imitate CompiledObject.obj behavior and return a ``builtin.slice()``
object. object.
@@ -796,7 +795,7 @@ class Slice(object):
if element is None: if element is None:
return None return None
result = self._python_context.infer_node(element) result = self._context.infer_node(element)
if len(result) != 1: if len(result) != 1:
# For simplicity, we want slices to be clear defined with just # For simplicity, we want slices to be clear defined with just
# one type. Otherwise we will return an empty slice object. # one type. Otherwise we will return an empty slice object.