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.
5 A ValueSet is typically used to specify the return of a function or any other
6 static analysis operation. In jedi there are always multiple returns and not
9 from functools
import reduce
10 from operator
import add
11 from itertools
import zip_longest
13 from parso
.python
.tree
import Name
15 from jedi
import debug
16 from jedi
.parser_utils
import clean_scope_docstring
17 from jedi
.inference
.helpers
import SimpleGetItemNotFound
18 from jedi
.inference
.utils
import safe_property
19 from jedi
.inference
.cache
import inference_state_as_method_param_cache
20 from jedi
.cache
import memoize_method
25 class HasNoContext(Exception):
29 class HelperValueMixin
:
30 def get_root_context(self
):
32 if value
.parent_context
is None:
33 return value
.as_context()
36 if value
.parent_context
is None:
38 value
= value
.parent_context
40 def execute(self
, arguments
):
41 return self
.inference_state
.execute(self
, arguments
=arguments
)
43 def execute_with_values(self
, *value_list
):
44 from jedi
.inference
.arguments
import ValuesArguments
45 arguments
= ValuesArguments([ValueSet([value
]) for value
in value_list
])
46 return self
.inference_state
.execute(self
, arguments
)
48 def execute_annotation(self
):
49 return self
.execute_with_values()
51 def gather_annotation_classes(self
):
52 return ValueSet([self
])
54 def merge_types_of_iterate(self
, contextualized_node
=None, is_async
=False):
55 return ValueSet
.from_sets(
57 for lazy_value
in self
.iterate(contextualized_node
, is_async
)
60 def _get_value_filters(self
, name_or_str
):
61 origin_scope
= name_or_str
if isinstance(name_or_str
, Name
) else None
62 yield from self
.get_filters(origin_scope
=origin_scope
)
63 # This covers the case where a stub files are incomplete.
65 from jedi
.inference
.gradual
.conversion
import convert_values
66 for c
in convert_values(ValueSet({self}
)):
67 yield from c
.get_filters()
69 def goto(self
, name_or_str
, name_context
=None, analysis_errors
=True):
70 from jedi
.inference
import finder
71 filters
= self
._get
_value
_filters
(name_or_str
)
72 names
= finder
.filter_name(filters
, name_or_str
)
73 debug
.dbg('context.goto %s in (%s): %s', name_or_str
, self
, names
)
76 def py__getattribute__(self
, name_or_str
, name_context
=None, position
=None,
77 analysis_errors
=True):
79 :param position: Position of the last statement -> tuple of line, column
81 if name_context
is None:
83 names
= self
.goto(name_or_str
, name_context
, analysis_errors
)
84 values
= ValueSet
.from_sets(name
.infer() for name
in names
)
86 n
= name_or_str
.value
if isinstance(name_or_str
, Name
) else name_or_str
87 values
= self
.py__getattribute__alternatives(n
)
89 if not names
and not values
and analysis_errors
:
90 if isinstance(name_or_str
, Name
):
91 from jedi
.inference
import analysis
92 analysis
.add_attribute_error(
93 name_context
, self
, name_or_str
)
94 debug
.dbg('context.names_to_types: %s -> %s', names
, values
)
97 def py__await__(self
):
98 await_value_set
= self
.py__getattribute__("__await__")
99 if not await_value_set
:
100 debug
.warning('Tried to run __await__ on value %s', self
)
101 return await_value_set
.execute_with_values()
103 def py__name__(self
):
104 return self
.name
.string_name
106 def iterate(self
, contextualized_node
=None, is_async
=False):
107 debug
.dbg('iterate %s', self
)
109 from jedi
.inference
.lazy_value
import LazyKnownValues
110 # TODO if no __aiter__ values are there, error should be:
111 # TypeError: 'async for' requires an object with __aiter__ method, got int
114 self
.py__getattribute__('__aiter__').execute_with_values()
115 .py__getattribute__('__anext__').execute_with_values()
116 .py__getattribute__('__await__').execute_with_values()
117 .py__stop_iteration_returns()
120 return self
.py__iter__(contextualized_node
)
122 def is_sub_class_of(self
, class_value
):
123 with debug
.increase_indent_cm('subclass matching of %s <=> %s' % (self
, class_value
),
125 for cls
in self
.py__mro__():
126 if cls
.is_same_class(class_value
):
127 debug
.dbg('matched subclass True', color
='BLUE')
129 debug
.dbg('matched subclass False', color
='BLUE')
132 def is_same_class(self
, class2
):
133 # Class matching should prefer comparisons that are not this function.
134 if type(class2
).is_same_class
!= HelperValueMixin
.is_same_class
:
135 return class2
.is_same_class(self
)
136 return self
== class2
139 def as_context(self
, *args
, **kwargs
):
140 return self
._as
_context
(*args
, **kwargs
)
143 class Value(HelperValueMixin
):
145 To be implemented by subclasses.
148 # Possible values: None, tuple, list, dict and set. Here to deal with these
149 # very important containers.
151 api_type
= 'not_defined_please_report_bug'
153 def __init__(self
, inference_state
, parent_context
=None):
154 self
.inference_state
= inference_state
155 self
.parent_context
= parent_context
157 def py__getitem__(self
, index_value_set
, contextualized_node
):
158 from jedi
.inference
import analysis
159 # TODO this value is probably not right.
161 contextualized_node
.context
,
162 'type-error-not-subscriptable',
163 contextualized_node
.node
,
164 message
="TypeError: '%s' object is not subscriptable" % self
168 def py__simple_getitem__(self
, index
):
169 raise SimpleGetItemNotFound
171 def py__iter__(self
, contextualized_node
=None):
172 if contextualized_node
is not None:
173 from jedi
.inference
import analysis
175 contextualized_node
.context
,
176 'type-error-not-iterable',
177 contextualized_node
.node
,
178 message
="TypeError: '%s' object is not iterable" % self
)
181 def py__next__(self
, contextualized_node
=None):
182 return self
.py__iter__(contextualized_node
)
184 def get_signatures(self
):
190 def is_class_mixin(self
):
193 def is_instance(self
):
196 def is_function(self
):
202 def is_namespace(self
):
205 def is_compiled(self
):
208 def is_bound_method(self
):
211 def is_builtins_module(self
):
214 def py__bool__(self
):
216 Since Wrapper is a super class for classes, functions and modules,
217 the return value will always be true.
223 self
.tree_node
.get_doc_node
224 except AttributeError:
227 return clean_scope_docstring(self
.tree_node
)
229 def get_safe_value(self
, default
=sentinel
):
230 if default
is sentinel
:
231 raise ValueError("There exists no safe value for value %s" % self
)
234 def execute_operation(self
, other
, operator
):
235 debug
.warning("%s not possible between %s and %s", operator
, self
, other
)
238 def py__call__(self
, arguments
):
239 debug
.warning("no execution possible %s", self
)
242 def py__stop_iteration_returns(self
):
243 debug
.warning("Not possible to return the stop iterations of %s", self
)
246 def py__getattribute__alternatives(self
, name_or_str
):
248 For now a way to add values in cases like __getattr__.
252 def py__get__(self
, instance
, class_value
):
253 debug
.warning("No __get__ defined on %s", self
)
254 return ValueSet([self
])
256 def py__get__on_class(self
, calling_instance
, instance
, class_value
):
257 return NotImplemented
259 def get_qualified_names(self
):
260 # Returns Optional[Tuple[str, ...]]
264 # The root value knows if it's a stub or not.
265 return self
.parent_context
.is_stub()
267 def _as_context(self
):
272 raise NotImplementedError
274 def get_type_hint(self
, add_class_info
=True):
277 def infer_type_vars(self
, value_set
):
279 When the current instance represents a type annotation, this method
280 tries to find information about undefined type vars and returns a dict
281 from type var name to value set.
283 This is for example important to understand what `iter([1])` returns.
284 According to typeshed, `iter` returns an `Iterator[_T]`:
286 def iter(iterable: Iterable[_T]) -> Iterator[_T]: ...
288 This functions would generate `int` for `_T` in this case, because it
289 unpacks the `Iterable`.
294 `self`: represents the annotation of the current parameter to infer the
295 value for. In the above example, this would initially be the
296 `Iterable[_T]` of the `iterable` parameter and then, when recursing,
297 just the `_T` generic parameter.
299 `value_set`: represents the actual argument passed to the parameter
300 we're inferred for, or (for recursive calls) their types. In the
301 above example this would first be the representation of the list
302 `[1]` and then, when recursing, just of `1`.
307 def iterate_values(values
, contextualized_node
=None, is_async
=False):
309 Calls `iterate`, on all values but ignores the ordering and just returns
310 all values that the iterate functions yield.
312 return ValueSet
.from_sets(
314 for lazy_value
in values
.iterate(contextualized_node
, is_async
=is_async
)
318 class _ValueWrapperBase(HelperValueMixin
):
321 from jedi
.inference
.names
import ValueName
322 wrapped_name
= self
._wrapped
_value
.name
323 if wrapped_name
.tree_name
is not None:
324 return ValueName(self
, wrapped_name
.tree_name
)
326 from jedi
.inference
.compiled
import CompiledValueName
327 return CompiledValueName(self
, wrapped_name
.string_name
)
330 @inference_state_as_method_param_cache()
331 def create_cached(cls
, inference_state
, *args
, **kwargs
):
332 return cls(*args
, **kwargs
)
334 def __getattr__(self
, name
):
335 assert name
!= '_wrapped_value', 'Problem with _get_wrapped_value'
336 return getattr(self
._wrapped
_value
, name
)
339 class LazyValueWrapper(_ValueWrapperBase
):
342 def _wrapped_value(self
):
343 with debug
.increase_indent_cm('Resolve lazy value wrapper'):
344 return self
._get
_wrapped
_value
()
347 return '<%s>' % (self
.__class
__.__name
__)
349 def _get_wrapped_value(self
):
350 raise NotImplementedError
353 class ValueWrapper(_ValueWrapperBase
):
354 def __init__(self
, wrapped_value
):
355 self
._wrapped
_value
= wrapped_value
358 return '%s(%s)' % (self
.__class
__.__name
__, self
._wrapped
_value
)
361 class TreeValue(Value
):
362 def __init__(self
, inference_state
, parent_context
, tree_node
):
363 super().__init
__(inference_state
, parent_context
)
364 self
.tree_node
= tree_node
367 return '<%s: %s>' % (self
.__class
__.__name
__, self
.tree_node
)
370 class ContextualizedNode
:
371 def __init__(self
, context
, node
):
372 self
.context
= context
375 def get_root_context(self
):
376 return self
.context
.get_root_context()
379 return self
.context
.infer_node(self
.node
)
382 return '<%s: %s in %s>' % (self
.__class
__.__name
__, self
.node
, self
.context
)
385 def _getitem(value
, index_values
, contextualized_node
):
386 # The actual getitem call.
388 unused_values
= set()
389 for index_value
in index_values
:
390 index
= index_value
.get_safe_value(default
=None)
391 if type(index
) in (float, int, str, slice, bytes
):
393 result |
= value
.py__simple_getitem__(index
)
395 except SimpleGetItemNotFound
:
398 unused_values
.add(index_value
)
400 # The index was somehow not good enough or simply a wrong type.
401 # Therefore we now iterate through all the values and just take
403 if unused_values
or not index_values
:
404 result |
= value
.py__getitem__(
405 ValueSet(unused_values
),
408 debug
.dbg('py__getitem__ result: %s', result
)
413 def __init__(self
, iterable
):
414 self
._set
= frozenset(iterable
)
415 for value
in iterable
:
416 assert not isinstance(value
, ValueSet
)
419 def _from_frozen_set(cls
, frozenset_
):
420 self
= cls
.__new
__(cls
)
421 self
._set
= frozenset_
425 def from_sets(cls
, sets
):
427 Used to work with an iterable of set.
431 if isinstance(set_
, ValueSet
):
432 aggregated |
= set_
._set
434 aggregated |
= frozenset(set_
)
435 return cls
._from
_frozen
_set
(frozenset(aggregated
))
437 def __or__(self
, other
):
438 return self
._from
_frozen
_set
(self
._set | other
._set
)
440 def __and__(self
, other
):
441 return self
._from
_frozen
_set
(self
._set
& other
._set
)
444 return iter(self
._set
)
447 return bool(self
._set
)
450 return len(self
._set
)
453 return 'S{%s}' % (', '.join(str(s
) for s
in self
._set
))
455 def filter(self
, filter_func
):
456 return self
.__class
__(filter(filter_func
, self
._set
))
458 def __getattr__(self
, name
):
459 def mapper(*args
, **kwargs
):
460 return self
.from_sets(
461 getattr(value
, name
)(*args
, **kwargs
)
462 for value
in self
._set
466 def __eq__(self
, other
):
467 return self
._set
== other
._set
469 def __ne__(self
, other
):
470 return not self
.__eq
__(other
)
473 return hash(self
._set
)
475 def py__class__(self
):
476 return ValueSet(c
.py__class__() for c
in self
._set
)
478 def iterate(self
, contextualized_node
=None, is_async
=False):
479 from jedi
.inference
.lazy_value
import get_merged_lazy_value
480 type_iters
= [c
.iterate(contextualized_node
, is_async
=is_async
) for c
in self
._set
]
481 for lazy_values
in zip_longest(*type_iters
):
482 yield get_merged_lazy_value(
483 [l
for l
in lazy_values
if l
is not None]
486 def execute(self
, arguments
):
487 return ValueSet
.from_sets(c
.inference_state
.execute(c
, arguments
) for c
in self
._set
)
489 def execute_with_values(self
, *args
, **kwargs
):
490 return ValueSet
.from_sets(c
.execute_with_values(*args
, **kwargs
) for c
in self
._set
)
492 def goto(self
, *args
, **kwargs
):
493 return reduce(add
, [c
.goto(*args
, **kwargs
) for c
in self
._set
], [])
495 def py__getattribute__(self
, *args
, **kwargs
):
496 return ValueSet
.from_sets(c
.py__getattribute__(*args
, **kwargs
) for c
in self
._set
)
498 def get_item(self
, *args
, **kwargs
):
499 return ValueSet
.from_sets(_getitem(c
, *args
, **kwargs
) for c
in self
._set
)
501 def try_merge(self
, function_name
):
502 value_set
= self
.__class
__([])
505 method
= getattr(c
, function_name
)
506 except AttributeError:
509 value_set |
= method()
512 def gather_annotation_classes(self
):
513 return ValueSet
.from_sets([c
.gather_annotation_classes() for c
in self
._set
])
515 def get_signatures(self
):
516 return [sig
for c
in self
._set
for sig
in c
.get_signatures()]
518 def get_type_hint(self
, add_class_info
=True):
519 t
= [v
.get_type_hint(add_class_info
=add_class_info
) for v
in self
._set
]
520 type_hints
= sorted(filter(None, t
))
521 if len(type_hints
) == 1:
524 optional
= 'None' in type_hints
526 type_hints
.remove('None')
528 if len(type_hints
) == 0:
530 elif len(type_hints
) == 1:
533 s
= 'Union[%s]' % ', '.join(type_hints
)
535 s
= 'Optional[%s]' % s
538 def infer_type_vars(self
, value_set
):
540 from jedi
.inference
.gradual
.annotation
import merge_type_var_dicts
543 for value
in self
._set
:
544 merge_type_var_dicts(
546 value
.infer_type_vars(value_set
),
551 NO_VALUES
= ValueSet([])
554 def iterator_to_value_set(func
):
555 def wrapper(*args
, **kwargs
):
556 return ValueSet(func(*args
, **kwargs
))