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