Format: text/x-python
⬇ Download File (3.1 KB)
   1  """
   2  This module is about generics, like the `int` in `List[int]`. It's not about
   3  the Generic class.
   4  """
   5  
   6  from jedi import debug
   7  from jedi.cache import memoize_method
   8  from jedi.inference.utils import to_tuple
   9  from jedi.inference.base_value import ValueSet, NO_VALUES
  10  from jedi.inference.value.iterable import SequenceLiteralValue
  11  from jedi.inference.helpers import is_string
  12  
  13  
  14  def _resolve_forward_references(context, value_set):
  15      for value in value_set:
  16          if is_string(value):
  17              from jedi.inference.gradual.annotation import _get_forward_reference_node
  18              node = _get_forward_reference_node(context, value.get_safe_value())
  19              if node is not None:
  20                  for c in context.infer_node(node):
  21                      yield c
  22          else:
  23              yield value
  24  
  25  
  26  class _AbstractGenericManager:
  27      def get_index_and_execute(self, index):
  28          try:
  29              return self[index].execute_annotation()
  30          except IndexError:
  31              debug.warning('No param #%s found for annotation %s', index, self)
  32              return NO_VALUES
  33  
  34      def get_type_hint(self):
  35          return '[%s]' % ', '.join(t.get_type_hint(add_class_info=False) for t in self.to_tuple())
  36  
  37  
  38  class LazyGenericManager(_AbstractGenericManager):
  39      def __init__(self, context_of_index, index_value):
  40          self._context_of_index = context_of_index
  41          self._index_value = index_value
  42  
  43      @memoize_method
  44      def __getitem__(self, index):
  45          return self._tuple()[index]()
  46  
  47      def __len__(self):
  48          return len(self._tuple())
  49  
  50      @memoize_method
  51      @to_tuple
  52      def _tuple(self):
  53          def lambda_scoping_in_for_loop_sucks(lazy_value):
  54              return lambda: ValueSet(_resolve_forward_references(
  55                  self._context_of_index,
  56                  lazy_value.infer()
  57              ))
  58  
  59          if isinstance(self._index_value, SequenceLiteralValue):
  60              for lazy_value in self._index_value.py__iter__(contextualized_node=None):
  61                  yield lambda_scoping_in_for_loop_sucks(lazy_value)
  62          else:
  63              yield lambda: ValueSet(_resolve_forward_references(
  64                  self._context_of_index,
  65                  ValueSet([self._index_value])
  66              ))
  67  
  68      @to_tuple
  69      def to_tuple(self):
  70          for callable_ in self._tuple():
  71              yield callable_()
  72  
  73      def is_homogenous_tuple(self):
  74          if isinstance(self._index_value, SequenceLiteralValue):
  75              entries = self._index_value.get_tree_entries()
  76              if len(entries) == 2 and entries[1] == '...':
  77                  return True
  78          return False
  79  
  80      def __repr__(self):
  81          return '<LazyG>[%s]' % (', '.join(repr(x) for x in self.to_tuple()))
  82  
  83  
  84  class TupleGenericManager(_AbstractGenericManager):
  85      def __init__(self, tup):
  86          self._tuple = tup
  87  
  88      def __getitem__(self, index):
  89          return self._tuple[index]
  90  
  91      def __len__(self):
  92          return len(self._tuple)
  93  
  94      def to_tuple(self):
  95          return self._tuple
  96  
  97      def is_homogenous_tuple(self):
  98          return False
  99  
 100      def __repr__(self):
 101          return '<TupG>[%s]' % (', '.join(repr(x) for x in self.to_tuple()))
 102