PageRenderTime 28ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/vim_runtime/sources_non_forked/jedi-vim/pythonx/jedi/jedi/inference/gradual/typing.py

https://gitlab.com/lokiexinferis/vim-configs
Python | 341 lines | 250 code | 60 blank | 31 comment | 36 complexity | 2b0922b6f6aad0bbe4e8cd4573652f1a MD5 | raw file
  1. """
  2. We need to somehow work with the typing objects. Since the typing objects are
  3. pretty bare we need to add all the Jedi customizations to make them work as
  4. values.
  5. This file deals with all the typing.py cases.
  6. """
  7. from jedi import debug
  8. from jedi.inference.compiled import builtin_from_name
  9. from jedi.inference.base_value import ValueSet, NO_VALUES, Value, \
  10. LazyValueWrapper
  11. from jedi.inference.lazy_value import LazyKnownValues
  12. from jedi.inference.arguments import repack_with_argument_clinic
  13. from jedi.inference.filters import FilterWrapper
  14. from jedi.inference.names import NameWrapper, ValueName
  15. from jedi.inference.value.klass import ClassMixin
  16. from jedi.inference.gradual.base import BaseTypingValue, BaseTypingValueWithGenerics
  17. from jedi.inference.gradual.type_var import TypeVarClass
  18. from jedi.inference.gradual.generics import LazyGenericManager, TupleGenericManager
  19. _PROXY_CLASS_TYPES = 'Tuple Generic Protocol Callable Type'.split()
  20. _TYPE_ALIAS_TYPES = {
  21. 'List': 'builtins.list',
  22. 'Dict': 'builtins.dict',
  23. 'Set': 'builtins.set',
  24. 'FrozenSet': 'builtins.frozenset',
  25. 'ChainMap': 'collections.ChainMap',
  26. 'Counter': 'collections.Counter',
  27. 'DefaultDict': 'collections.defaultdict',
  28. 'Deque': 'collections.deque',
  29. }
  30. _PROXY_TYPES = 'Optional Union ClassVar'.split()
  31. class TypingModuleName(NameWrapper):
  32. def infer(self):
  33. return ValueSet(self._remap())
  34. def _remap(self):
  35. name = self.string_name
  36. inference_state = self.parent_context.inference_state
  37. try:
  38. actual = _TYPE_ALIAS_TYPES[name]
  39. except KeyError:
  40. pass
  41. else:
  42. yield TypeAlias.create_cached(
  43. inference_state, self.parent_context, self.tree_name, actual)
  44. return
  45. if name in _PROXY_CLASS_TYPES:
  46. yield ProxyTypingClassValue.create_cached(
  47. inference_state, self.parent_context, self.tree_name)
  48. elif name in _PROXY_TYPES:
  49. yield ProxyTypingValue.create_cached(
  50. inference_state, self.parent_context, self.tree_name)
  51. elif name == 'runtime':
  52. # We don't want anything here, not sure what this function is
  53. # supposed to do, since it just appears in the stubs and shouldn't
  54. # have any effects there (because it's never executed).
  55. return
  56. elif name == 'TypeVar':
  57. yield TypeVarClass.create_cached(
  58. inference_state, self.parent_context, self.tree_name)
  59. elif name == 'Any':
  60. yield Any.create_cached(
  61. inference_state, self.parent_context, self.tree_name)
  62. elif name == 'TYPE_CHECKING':
  63. # This is needed for e.g. imports that are only available for type
  64. # checking or are in cycles. The user can then check this variable.
  65. yield builtin_from_name(inference_state, u'True')
  66. elif name == 'overload':
  67. yield OverloadFunction.create_cached(
  68. inference_state, self.parent_context, self.tree_name)
  69. elif name == 'NewType':
  70. yield NewTypeFunction.create_cached(
  71. inference_state, self.parent_context, self.tree_name)
  72. elif name == 'cast':
  73. yield CastFunction.create_cached(
  74. inference_state, self.parent_context, self.tree_name)
  75. elif name == 'TypedDict':
  76. # TODO doesn't even exist in typeshed/typing.py, yet. But will be
  77. # added soon.
  78. pass
  79. elif name in ('no_type_check', 'no_type_check_decorator'):
  80. # This is not necessary, as long as we are not doing type checking.
  81. for c in self._wrapped_name.infer(): # Fuck my life Python 2
  82. yield c
  83. else:
  84. # Everything else shouldn't be relevant for type checking.
  85. for c in self._wrapped_name.infer(): # Fuck my life Python 2
  86. yield c
  87. class TypingModuleFilterWrapper(FilterWrapper):
  88. name_wrapper_class = TypingModuleName
  89. class TypingValueWithIndex(BaseTypingValueWithGenerics):
  90. def execute_annotation(self):
  91. string_name = self._tree_name.value
  92. if string_name == 'Union':
  93. # This is kind of a special case, because we have Unions (in Jedi
  94. # ValueSets).
  95. return self.gather_annotation_classes().execute_annotation()
  96. elif string_name == 'Optional':
  97. # Optional is basically just saying it's either None or the actual
  98. # type.
  99. return self.gather_annotation_classes().execute_annotation() \
  100. | ValueSet([builtin_from_name(self.inference_state, u'None')])
  101. elif string_name == 'Type':
  102. # The type is actually already given in the index_value
  103. return self._generics_manager[0]
  104. elif string_name == 'ClassVar':
  105. # For now don't do anything here, ClassVars are always used.
  106. return self._generics_manager[0].execute_annotation()
  107. mapped = {
  108. 'Tuple': Tuple,
  109. 'Generic': Generic,
  110. 'Protocol': Protocol,
  111. 'Callable': Callable,
  112. }
  113. cls = mapped[string_name]
  114. return ValueSet([cls(
  115. self.parent_context,
  116. self._tree_name,
  117. generics_manager=self._generics_manager,
  118. )])
  119. def gather_annotation_classes(self):
  120. return ValueSet.from_sets(self._generics_manager.to_tuple())
  121. def _create_instance_with_generics(self, generics_manager):
  122. return TypingValueWithIndex(
  123. self.parent_context,
  124. self._tree_name,
  125. generics_manager
  126. )
  127. class ProxyTypingValue(BaseTypingValue):
  128. index_class = TypingValueWithIndex
  129. def with_generics(self, generics_tuple):
  130. return self.index_class.create_cached(
  131. self.inference_state,
  132. self.parent_context,
  133. self._tree_name,
  134. generics_manager=TupleGenericManager(generics_tuple)
  135. )
  136. def py__getitem__(self, index_value_set, contextualized_node):
  137. return ValueSet(
  138. self.index_class.create_cached(
  139. self.inference_state,
  140. self.parent_context,
  141. self._tree_name,
  142. generics_manager=LazyGenericManager(
  143. context_of_index=contextualized_node.context,
  144. index_value=index_value,
  145. )
  146. ) for index_value in index_value_set
  147. )
  148. class _TypingClassMixin(ClassMixin):
  149. def py__bases__(self):
  150. return [LazyKnownValues(
  151. self.inference_state.builtins_module.py__getattribute__('object')
  152. )]
  153. def get_metaclasses(self):
  154. return []
  155. @property
  156. def name(self):
  157. return ValueName(self, self._tree_name)
  158. class TypingClassValueWithIndex(_TypingClassMixin, TypingValueWithIndex):
  159. pass
  160. class ProxyTypingClassValue(_TypingClassMixin, ProxyTypingValue):
  161. index_class = TypingClassValueWithIndex
  162. class TypeAlias(LazyValueWrapper):
  163. def __init__(self, parent_context, origin_tree_name, actual):
  164. self.inference_state = parent_context.inference_state
  165. self.parent_context = parent_context
  166. self._origin_tree_name = origin_tree_name
  167. self._actual = actual # e.g. builtins.list
  168. @property
  169. def name(self):
  170. return ValueName(self, self._origin_tree_name)
  171. def py__name__(self):
  172. return self.name.string_name
  173. def __repr__(self):
  174. return '<%s: %s>' % (self.__class__.__name__, self._actual)
  175. def _get_wrapped_value(self):
  176. module_name, class_name = self._actual.split('.')
  177. if self.inference_state.environment.version_info.major == 2 and module_name == 'builtins':
  178. module_name = '__builtin__'
  179. # TODO use inference_state.import_module?
  180. from jedi.inference.imports import Importer
  181. module, = Importer(
  182. self.inference_state, [module_name], self.inference_state.builtins_module
  183. ).follow()
  184. classes = module.py__getattribute__(class_name)
  185. # There should only be one, because it's code that we control.
  186. assert len(classes) == 1, classes
  187. cls = next(iter(classes))
  188. return cls
  189. def gather_annotation_classes(self):
  190. return ValueSet([self._get_wrapped_value()])
  191. class Callable(BaseTypingValueWithGenerics):
  192. def py__call__(self, arguments):
  193. """
  194. def x() -> Callable[[Callable[..., _T]], _T]: ...
  195. """
  196. # The 0th index are the arguments.
  197. try:
  198. param_values = self._generics_manager[0]
  199. result_values = self._generics_manager[1]
  200. except IndexError:
  201. debug.warning('Callable[...] defined without two arguments')
  202. return NO_VALUES
  203. else:
  204. from jedi.inference.gradual.annotation import infer_return_for_callable
  205. return infer_return_for_callable(arguments, param_values, result_values)
  206. class Tuple(LazyValueWrapper):
  207. def __init__(self, parent_context, name, generics_manager):
  208. self.inference_state = parent_context.inference_state
  209. self.parent_context = parent_context
  210. self._generics_manager = generics_manager
  211. def _is_homogenous(self):
  212. # To specify a variable-length tuple of homogeneous type, Tuple[T, ...]
  213. # is used.
  214. return self._generics_manager.is_homogenous_tuple()
  215. def py__simple_getitem__(self, index):
  216. if self._is_homogenous():
  217. return self._generics_manager.get_index_and_execute(0)
  218. else:
  219. if isinstance(index, int):
  220. return self._generics_manager.get_index_and_execute(index)
  221. debug.dbg('The getitem type on Tuple was %s' % index)
  222. return NO_VALUES
  223. def py__iter__(self, contextualized_node=None):
  224. if self._is_homogenous():
  225. yield LazyKnownValues(self._generics_manager.get_index_and_execute(0))
  226. else:
  227. for v in self._generics_manager.to_tuple():
  228. yield LazyKnownValues(v.execute_annotation())
  229. def py__getitem__(self, index_value_set, contextualized_node):
  230. if self._is_homogenous():
  231. return self._generics_manager.get_index_and_execute(0)
  232. return ValueSet.from_sets(
  233. self._generics_manager.to_tuple()
  234. ).execute_annotation()
  235. def _get_wrapped_value(self):
  236. tuple_, = self.inference_state.builtins_module \
  237. .py__getattribute__('tuple').execute_annotation()
  238. return tuple_
  239. class Generic(BaseTypingValueWithGenerics):
  240. pass
  241. class Protocol(BaseTypingValueWithGenerics):
  242. pass
  243. class Any(BaseTypingValue):
  244. def execute_annotation(self):
  245. debug.warning('Used Any - returned no results')
  246. return NO_VALUES
  247. class OverloadFunction(BaseTypingValue):
  248. @repack_with_argument_clinic('func, /')
  249. def py__call__(self, func_value_set):
  250. # Just pass arguments through.
  251. return func_value_set
  252. class NewTypeFunction(BaseTypingValue):
  253. def py__call__(self, arguments):
  254. ordered_args = arguments.unpack()
  255. next(ordered_args, (None, None))
  256. _, second_arg = next(ordered_args, (None, None))
  257. if second_arg is None:
  258. return NO_VALUES
  259. return ValueSet(
  260. NewType(
  261. self.inference_state,
  262. contextualized_node.context,
  263. contextualized_node.node,
  264. second_arg.infer(),
  265. ) for contextualized_node in arguments.get_calling_nodes())
  266. class NewType(Value):
  267. def __init__(self, inference_state, parent_context, tree_node, type_value_set):
  268. super(NewType, self).__init__(inference_state, parent_context)
  269. self._type_value_set = type_value_set
  270. self.tree_node = tree_node
  271. def py__call__(self, arguments):
  272. return self._type_value_set.execute_annotation()
  273. @property
  274. def name(self):
  275. from jedi.inference.compiled.value import CompiledValueName
  276. return CompiledValueName(self, 'NewType')
  277. class CastFunction(BaseTypingValue):
  278. @repack_with_argument_clinic('type, object, /')
  279. def py__call__(self, type_value_set, object_value_set):
  280. return type_value_set.execute_annotation()