base_value.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. """
  2. Values are the "values" that Python would return. However Values are at the
  3. same time also the "values" that a user is currently sitting in.
  4. A ValueSet is typically used to specify the return of a function or any other
  5. static analysis operation. In jedi there are always multiple returns and not
  6. just one.
  7. """
  8. from functools import reduce
  9. from operator import add
  10. from itertools import zip_longest
  11. from parso.python.tree import Name
  12. from jedi import debug
  13. from jedi.parser_utils import clean_scope_docstring
  14. from jedi.inference.helpers import SimpleGetItemNotFound
  15. from jedi.inference.utils import safe_property
  16. from jedi.inference.cache import inference_state_as_method_param_cache
  17. from jedi.cache import memoize_method
  18. sentinel = object()
  19. class HasNoContext(Exception):
  20. pass
  21. class HelperValueMixin:
  22. def get_root_context(self):
  23. value = self
  24. if value.parent_context is None:
  25. return value.as_context()
  26. while True:
  27. if value.parent_context is None:
  28. return value
  29. value = value.parent_context
  30. def execute(self, arguments):
  31. return self.inference_state.execute(self, arguments=arguments)
  32. def execute_with_values(self, *value_list):
  33. from jedi.inference.arguments import ValuesArguments
  34. arguments = ValuesArguments([ValueSet([value]) for value in value_list])
  35. return self.inference_state.execute(self, arguments)
  36. def execute_annotation(self):
  37. return self.execute_with_values()
  38. def gather_annotation_classes(self):
  39. return ValueSet([self])
  40. def merge_types_of_iterate(self, contextualized_node=None, is_async=False):
  41. return ValueSet.from_sets(
  42. lazy_value.infer()
  43. for lazy_value in self.iterate(contextualized_node, is_async)
  44. )
  45. def _get_value_filters(self, name_or_str):
  46. origin_scope = name_or_str if isinstance(name_or_str, Name) else None
  47. yield from self.get_filters(origin_scope=origin_scope)
  48. # This covers the case where a stub files are incomplete.
  49. if self.is_stub():
  50. from jedi.inference.gradual.conversion import convert_values
  51. for c in convert_values(ValueSet({self})):
  52. yield from c.get_filters()
  53. def goto(self, name_or_str, name_context=None, analysis_errors=True):
  54. from jedi.inference import finder
  55. filters = self._get_value_filters(name_or_str)
  56. names = finder.filter_name(filters, name_or_str)
  57. debug.dbg('context.goto %s in (%s): %s', name_or_str, self, names)
  58. return names
  59. def py__getattribute__(self, name_or_str, name_context=None, position=None,
  60. analysis_errors=True):
  61. """
  62. :param position: Position of the last statement -> tuple of line, column
  63. """
  64. if name_context is None:
  65. name_context = self
  66. names = self.goto(name_or_str, name_context, analysis_errors)
  67. values = ValueSet.from_sets(name.infer() for name in names)
  68. if not values:
  69. n = name_or_str.value if isinstance(name_or_str, Name) else name_or_str
  70. values = self.py__getattribute__alternatives(n)
  71. if not names and not values and analysis_errors:
  72. if isinstance(name_or_str, Name):
  73. from jedi.inference import analysis
  74. analysis.add_attribute_error(
  75. name_context, self, name_or_str)
  76. debug.dbg('context.names_to_types: %s -> %s', names, values)
  77. return values
  78. def py__await__(self):
  79. await_value_set = self.py__getattribute__("__await__")
  80. if not await_value_set:
  81. debug.warning('Tried to run __await__ on value %s', self)
  82. return await_value_set.execute_with_values()
  83. def py__name__(self):
  84. return self.name.string_name
  85. def iterate(self, contextualized_node=None, is_async=False):
  86. debug.dbg('iterate %s', self)
  87. if is_async:
  88. from jedi.inference.lazy_value import LazyKnownValues
  89. # TODO if no __aiter__ values are there, error should be:
  90. # TypeError: 'async for' requires an object with __aiter__ method, got int
  91. return iter([
  92. LazyKnownValues(
  93. self.py__getattribute__('__aiter__').execute_with_values()
  94. .py__getattribute__('__anext__').execute_with_values()
  95. .py__getattribute__('__await__').execute_with_values()
  96. .py__stop_iteration_returns()
  97. ) # noqa: E124
  98. ])
  99. return self.py__iter__(contextualized_node)
  100. def is_sub_class_of(self, class_value):
  101. with debug.increase_indent_cm('subclass matching of %s <=> %s' % (self, class_value),
  102. color='BLUE'):
  103. for cls in self.py__mro__():
  104. if cls.is_same_class(class_value):
  105. debug.dbg('matched subclass True', color='BLUE')
  106. return True
  107. debug.dbg('matched subclass False', color='BLUE')
  108. return False
  109. def is_same_class(self, class2):
  110. # Class matching should prefer comparisons that are not this function.
  111. if type(class2).is_same_class != HelperValueMixin.is_same_class:
  112. return class2.is_same_class(self)
  113. return self == class2
  114. @memoize_method
  115. def as_context(self, *args, **kwargs):
  116. return self._as_context(*args, **kwargs)
  117. class Value(HelperValueMixin):
  118. """
  119. To be implemented by subclasses.
  120. """
  121. tree_node = None
  122. # Possible values: None, tuple, list, dict and set. Here to deal with these
  123. # very important containers.
  124. array_type = None
  125. api_type = 'not_defined_please_report_bug'
  126. def __init__(self, inference_state, parent_context=None):
  127. self.inference_state = inference_state
  128. self.parent_context = parent_context
  129. def py__getitem__(self, index_value_set, contextualized_node):
  130. from jedi.inference import analysis
  131. # TODO this value is probably not right.
  132. analysis.add(
  133. contextualized_node.context,
  134. 'type-error-not-subscriptable',
  135. contextualized_node.node,
  136. message="TypeError: '%s' object is not subscriptable" % self
  137. )
  138. return NO_VALUES
  139. def py__simple_getitem__(self, index):
  140. raise SimpleGetItemNotFound
  141. def py__iter__(self, contextualized_node=None):
  142. if contextualized_node is not None:
  143. from jedi.inference import analysis
  144. analysis.add(
  145. contextualized_node.context,
  146. 'type-error-not-iterable',
  147. contextualized_node.node,
  148. message="TypeError: '%s' object is not iterable" % self)
  149. return iter([])
  150. def py__next__(self, contextualized_node=None):
  151. return self.py__iter__(contextualized_node)
  152. def get_signatures(self):
  153. return []
  154. def is_class(self):
  155. return False
  156. def is_class_mixin(self):
  157. return False
  158. def is_instance(self):
  159. return False
  160. def is_function(self):
  161. return False
  162. def is_module(self):
  163. return False
  164. def is_namespace(self):
  165. return False
  166. def is_compiled(self):
  167. return False
  168. def is_bound_method(self):
  169. return False
  170. def is_builtins_module(self):
  171. return False
  172. def py__bool__(self):
  173. """
  174. Since Wrapper is a super class for classes, functions and modules,
  175. the return value will always be true.
  176. """
  177. return True
  178. def py__doc__(self):
  179. try:
  180. self.tree_node.get_doc_node
  181. except AttributeError:
  182. return ''
  183. else:
  184. return clean_scope_docstring(self.tree_node)
  185. def get_safe_value(self, default=sentinel):
  186. if default is sentinel:
  187. raise ValueError("There exists no safe value for value %s" % self)
  188. return default
  189. def execute_operation(self, other, operator):
  190. debug.warning("%s not possible between %s and %s", operator, self, other)
  191. return NO_VALUES
  192. def py__call__(self, arguments):
  193. debug.warning("no execution possible %s", self)
  194. return NO_VALUES
  195. def py__stop_iteration_returns(self):
  196. debug.warning("Not possible to return the stop iterations of %s", self)
  197. return NO_VALUES
  198. def py__getattribute__alternatives(self, name_or_str):
  199. """
  200. For now a way to add values in cases like __getattr__.
  201. """
  202. return NO_VALUES
  203. def py__get__(self, instance, class_value):
  204. debug.warning("No __get__ defined on %s", self)
  205. return ValueSet([self])
  206. def py__get__on_class(self, calling_instance, instance, class_value):
  207. return NotImplemented
  208. def get_qualified_names(self):
  209. # Returns Optional[Tuple[str, ...]]
  210. return None
  211. def is_stub(self):
  212. # The root value knows if it's a stub or not.
  213. return self.parent_context.is_stub()
  214. def _as_context(self):
  215. raise HasNoContext
  216. @property
  217. def name(self):
  218. raise NotImplementedError
  219. def get_type_hint(self, add_class_info=True):
  220. return None
  221. def infer_type_vars(self, value_set):
  222. """
  223. When the current instance represents a type annotation, this method
  224. tries to find information about undefined type vars and returns a dict
  225. from type var name to value set.
  226. This is for example important to understand what `iter([1])` returns.
  227. According to typeshed, `iter` returns an `Iterator[_T]`:
  228. def iter(iterable: Iterable[_T]) -> Iterator[_T]: ...
  229. This functions would generate `int` for `_T` in this case, because it
  230. unpacks the `Iterable`.
  231. Parameters
  232. ----------
  233. `self`: represents the annotation of the current parameter to infer the
  234. value for. In the above example, this would initially be the
  235. `Iterable[_T]` of the `iterable` parameter and then, when recursing,
  236. just the `_T` generic parameter.
  237. `value_set`: represents the actual argument passed to the parameter
  238. we're inferred for, or (for recursive calls) their types. In the
  239. above example this would first be the representation of the list
  240. `[1]` and then, when recursing, just of `1`.
  241. """
  242. return {}
  243. def iterate_values(values, contextualized_node=None, is_async=False):
  244. """
  245. Calls `iterate`, on all values but ignores the ordering and just returns
  246. all values that the iterate functions yield.
  247. """
  248. return ValueSet.from_sets(
  249. lazy_value.infer()
  250. for lazy_value in values.iterate(contextualized_node, is_async=is_async)
  251. )
  252. class _ValueWrapperBase(HelperValueMixin):
  253. @safe_property
  254. def name(self):
  255. from jedi.inference.names import ValueName
  256. wrapped_name = self._wrapped_value.name
  257. if wrapped_name.tree_name is not None:
  258. return ValueName(self, wrapped_name.tree_name)
  259. else:
  260. from jedi.inference.compiled import CompiledValueName
  261. return CompiledValueName(self, wrapped_name.string_name)
  262. @classmethod
  263. @inference_state_as_method_param_cache()
  264. def create_cached(cls, inference_state, *args, **kwargs):
  265. return cls(*args, **kwargs)
  266. def __getattr__(self, name):
  267. assert name != '_wrapped_value', 'Problem with _get_wrapped_value'
  268. return getattr(self._wrapped_value, name)
  269. class LazyValueWrapper(_ValueWrapperBase):
  270. @safe_property
  271. @memoize_method
  272. def _wrapped_value(self):
  273. with debug.increase_indent_cm('Resolve lazy value wrapper'):
  274. return self._get_wrapped_value()
  275. def __repr__(self):
  276. return '<%s>' % (self.__class__.__name__)
  277. def _get_wrapped_value(self):
  278. raise NotImplementedError
  279. class ValueWrapper(_ValueWrapperBase):
  280. def __init__(self, wrapped_value):
  281. self._wrapped_value = wrapped_value
  282. def __repr__(self):
  283. return '%s(%s)' % (self.__class__.__name__, self._wrapped_value)
  284. class TreeValue(Value):
  285. def __init__(self, inference_state, parent_context, tree_node):
  286. super().__init__(inference_state, parent_context)
  287. self.tree_node = tree_node
  288. def __repr__(self):
  289. return '<%s: %s>' % (self.__class__.__name__, self.tree_node)
  290. class ContextualizedNode:
  291. def __init__(self, context, node):
  292. self.context = context
  293. self.node = node
  294. def get_root_context(self):
  295. return self.context.get_root_context()
  296. def infer(self):
  297. return self.context.infer_node(self.node)
  298. def __repr__(self):
  299. return '<%s: %s in %s>' % (self.__class__.__name__, self.node, self.context)
  300. def _getitem(value, index_values, contextualized_node):
  301. # The actual getitem call.
  302. result = NO_VALUES
  303. unused_values = set()
  304. for index_value in index_values:
  305. index = index_value.get_safe_value(default=None)
  306. if type(index) in (float, int, str, slice, bytes):
  307. try:
  308. result |= value.py__simple_getitem__(index)
  309. continue
  310. except SimpleGetItemNotFound:
  311. pass
  312. unused_values.add(index_value)
  313. # The index was somehow not good enough or simply a wrong type.
  314. # Therefore we now iterate through all the values and just take
  315. # all results.
  316. if unused_values or not index_values:
  317. result |= value.py__getitem__(
  318. ValueSet(unused_values),
  319. contextualized_node
  320. )
  321. debug.dbg('py__getitem__ result: %s', result)
  322. return result
  323. class ValueSet:
  324. def __init__(self, iterable):
  325. self._set = frozenset(iterable)
  326. for value in iterable:
  327. assert not isinstance(value, ValueSet)
  328. @classmethod
  329. def _from_frozen_set(cls, frozenset_):
  330. self = cls.__new__(cls)
  331. self._set = frozenset_
  332. return self
  333. @classmethod
  334. def from_sets(cls, sets):
  335. """
  336. Used to work with an iterable of set.
  337. """
  338. aggregated = set()
  339. for set_ in sets:
  340. if isinstance(set_, ValueSet):
  341. aggregated |= set_._set
  342. else:
  343. aggregated |= frozenset(set_)
  344. return cls._from_frozen_set(frozenset(aggregated))
  345. def __or__(self, other):
  346. return self._from_frozen_set(self._set | other._set)
  347. def __and__(self, other):
  348. return self._from_frozen_set(self._set & other._set)
  349. def __iter__(self):
  350. return iter(self._set)
  351. def __bool__(self):
  352. return bool(self._set)
  353. def __len__(self):
  354. return len(self._set)
  355. def __repr__(self):
  356. return 'S{%s}' % (', '.join(str(s) for s in self._set))
  357. def filter(self, filter_func):
  358. return self.__class__(filter(filter_func, self._set))
  359. def __getattr__(self, name):
  360. def mapper(*args, **kwargs):
  361. return self.from_sets(
  362. getattr(value, name)(*args, **kwargs)
  363. for value in self._set
  364. )
  365. return mapper
  366. def __eq__(self, other):
  367. return self._set == other._set
  368. def __ne__(self, other):
  369. return not self.__eq__(other)
  370. def __hash__(self):
  371. return hash(self._set)
  372. def py__class__(self):
  373. return ValueSet(c.py__class__() for c in self._set)
  374. def iterate(self, contextualized_node=None, is_async=False):
  375. from jedi.inference.lazy_value import get_merged_lazy_value
  376. type_iters = [c.iterate(contextualized_node, is_async=is_async) for c in self._set]
  377. for lazy_values in zip_longest(*type_iters):
  378. yield get_merged_lazy_value(
  379. [l for l in lazy_values if l is not None]
  380. )
  381. def execute(self, arguments):
  382. return ValueSet.from_sets(c.inference_state.execute(c, arguments) for c in self._set)
  383. def execute_with_values(self, *args, **kwargs):
  384. return ValueSet.from_sets(c.execute_with_values(*args, **kwargs) for c in self._set)
  385. def goto(self, *args, **kwargs):
  386. return reduce(add, [c.goto(*args, **kwargs) for c in self._set], [])
  387. def py__getattribute__(self, *args, **kwargs):
  388. return ValueSet.from_sets(c.py__getattribute__(*args, **kwargs) for c in self._set)
  389. def get_item(self, *args, **kwargs):
  390. return ValueSet.from_sets(_getitem(c, *args, **kwargs) for c in self._set)
  391. def try_merge(self, function_name):
  392. value_set = self.__class__([])
  393. for c in self._set:
  394. try:
  395. method = getattr(c, function_name)
  396. except AttributeError:
  397. pass
  398. else:
  399. value_set |= method()
  400. return value_set
  401. def gather_annotation_classes(self):
  402. return ValueSet.from_sets([c.gather_annotation_classes() for c in self._set])
  403. def get_signatures(self):
  404. return [sig for c in self._set for sig in c.get_signatures()]
  405. def get_type_hint(self, add_class_info=True):
  406. t = [v.get_type_hint(add_class_info=add_class_info) for v in self._set]
  407. type_hints = sorted(filter(None, t))
  408. if len(type_hints) == 1:
  409. return type_hints[0]
  410. optional = 'None' in type_hints
  411. if optional:
  412. type_hints.remove('None')
  413. if len(type_hints) == 0:
  414. return None
  415. elif len(type_hints) == 1:
  416. s = type_hints[0]
  417. else:
  418. s = 'Union[%s]' % ', '.join(type_hints)
  419. if optional:
  420. s = 'Optional[%s]' % s
  421. return s
  422. def infer_type_vars(self, value_set):
  423. # Circular
  424. from jedi.inference.gradual.annotation import merge_type_var_dicts
  425. type_var_dict = {}
  426. for value in self._set:
  427. merge_type_var_dicts(
  428. type_var_dict,
  429. value.infer_type_vars(value_set),
  430. )
  431. return type_var_dict
  432. NO_VALUES = ValueSet([])
  433. def iterator_to_value_set(func):
  434. def wrapper(*args, **kwargs):
  435. return ValueSet(func(*args, **kwargs))
  436. return wrapper