1from abc import abstractproperty
2from typing import Any
3
4from jedi import debug
5from jedi import settings
6from jedi.inference import compiled
7from jedi.inference.compiled.value import CompiledValueFilter
8from jedi.inference.helpers import values_from_qualified_names, is_big_annoying_library
9from jedi.inference.filters import AbstractFilter, AnonymousFunctionExecutionFilter
10from jedi.inference.names import ValueName, TreeNameDefinition, ParamName, \
11 NameWrapper
12from jedi.inference.base_value import Value, NO_VALUES, ValueSet, \
13 iterator_to_value_set, ValueWrapper
14from jedi.inference.lazy_value import LazyKnownValue, LazyKnownValues
15from jedi.inference.cache import inference_state_method_cache
16from jedi.inference.arguments import ValuesArguments, TreeArgumentsWrapper
17from jedi.inference.value.function import \
18 FunctionValue, FunctionMixin, OverloadedFunctionValue, \
19 BaseFunctionExecutionContext, FunctionExecutionContext, FunctionNameInClass
20from jedi.inference.value.klass import ClassFilter, init_or_new_func
21from jedi.inference.value.dynamic_arrays import get_dynamic_array_instance
22from jedi.parser_utils import function_is_staticmethod, function_is_classmethod
23
24
25class InstanceExecutedParamName(ParamName):
26 def __init__(self, instance, function_value, tree_name):
27 super().__init__(
28 function_value, tree_name, arguments=None)
29 self._instance = instance
30
31 def infer(self):
32 return ValueSet([self._instance])
33
34 def matches_signature(self):
35 return True
36
37
38class AnonymousMethodExecutionFilter(AnonymousFunctionExecutionFilter):
39 def __init__(self, instance, *args, **kwargs):
40 super().__init__(*args, **kwargs)
41 self._instance = instance
42
43 def _convert_param(self, param, name):
44 if param.position_index == 0:
45 if function_is_classmethod(self._function_value.tree_node):
46 return InstanceExecutedParamName(
47 self._instance.py__class__(),
48 self._function_value,
49 name
50 )
51 elif not function_is_staticmethod(self._function_value.tree_node):
52 return InstanceExecutedParamName(
53 self._instance,
54 self._function_value,
55 name
56 )
57 return super()._convert_param(param, name)
58
59
60class AnonymousMethodExecutionContext(BaseFunctionExecutionContext):
61 def __init__(self, instance, value):
62 super().__init__(value)
63 self.instance = instance
64
65 def get_filters(self, until_position=None, origin_scope=None):
66 yield AnonymousMethodExecutionFilter(
67 self.instance, self, self._value,
68 until_position=until_position,
69 origin_scope=origin_scope,
70 )
71
72 def get_param_names(self):
73 param_names = list(self._value.get_param_names())
74 # set the self name
75 param_names[0] = InstanceExecutedParamName(
76 self.instance,
77 self._value,
78 param_names[0].tree_name
79 )
80 return param_names
81
82
83class MethodExecutionContext(FunctionExecutionContext):
84 def __init__(self, instance, *args, **kwargs):
85 super().__init__(*args, **kwargs)
86 self.instance = instance
87
88
89class AbstractInstanceValue(Value):
90 api_type = 'instance'
91
92 def __init__(self, inference_state, parent_context, class_value):
93 super().__init__(inference_state, parent_context)
94 # Generated instances are classes that are just generated by self
95 # (No arguments) used.
96 self.class_value = class_value
97
98 def is_instance(self):
99 return True
100
101 def get_qualified_names(self):
102 return self.class_value.get_qualified_names()
103
104 def get_annotated_class_object(self):
105 return self.class_value # This is the default.
106
107 def py__class__(self):
108 return self.class_value
109
110 def py__bool__(self):
111 # Signalize that we don't know about the bool type.
112 return None
113
114 @abstractproperty
115 def name(self):
116 raise NotImplementedError
117
118 def get_signatures(self):
119 call_funcs = self.py__getattribute__('__call__').py__get__(self, self.class_value)
120 return [s.bind(self) for s in call_funcs.get_signatures()]
121
122 def get_function_slot_names(self, name):
123 # Python classes don't look at the dictionary of the instance when
124 # looking up `__call__`. This is something that has to do with Python's
125 # internal slot system (note: not __slots__, but C slots).
126 for filter in self.get_filters(include_self_names=False):
127 names = filter.get(name)
128 if names:
129 return names
130 return []
131
132 def execute_function_slots(self, names, *inferred_args):
133 return ValueSet.from_sets(
134 name.infer().execute_with_values(*inferred_args)
135 for name in names
136 )
137
138 def get_type_hint(self, add_class_info=True):
139 return self.py__name__()
140
141 def py__getitem__(self, index_value_set, contextualized_node):
142 names = self.get_function_slot_names('__getitem__')
143 if not names:
144 return super().py__getitem__(
145 index_value_set,
146 contextualized_node,
147 )
148
149 args = ValuesArguments([index_value_set])
150 return ValueSet.from_sets(name.infer().execute(args) for name in names)
151
152 def py__iter__(self, contextualized_node=None):
153 iter_slot_names = self.get_function_slot_names('__iter__')
154 if not iter_slot_names:
155 return super().py__iter__(contextualized_node)
156
157 def iterate():
158 yield LazyKnownValues(
159 self.execute_function_slots(iter_slot_names).py__next__(contextualized_node).infer()
160 )
161 return iterate()
162
163 def __repr__(self):
164 return "<%s of %s>" % (self.__class__.__name__, self.class_value)
165
166
167class CompiledInstance(AbstractInstanceValue):
168 # This is not really a compiled class, it's just an instance from a
169 # compiled class.
170 def __init__(self, inference_state, parent_context, class_value, arguments):
171 super().__init__(inference_state, parent_context, class_value)
172 self._arguments = arguments
173
174 def get_filters(self, origin_scope=None, include_self_names=True):
175 class_value = self.get_annotated_class_object()
176 class_filters = class_value.get_filters(
177 origin_scope=origin_scope,
178 is_instance=True,
179 )
180 for f in class_filters:
181 yield CompiledInstanceClassFilter(self, f)
182
183 @property
184 def name(self):
185 return compiled.CompiledValueName(self, self.class_value.name.string_name)
186
187 def is_stub(self):
188 return False
189
190
191class _BaseTreeInstance(AbstractInstanceValue):
192 get_defined_names: Any
193 _arguments: Any
194
195 @property
196 def array_type(self):
197 name = self.class_value.py__name__()
198 if name in ['list', 'set', 'dict'] \
199 and self.parent_context.get_root_context().is_builtins_module():
200 return name
201 return None
202
203 @property
204 def name(self):
205 return ValueName(self, self.class_value.name.tree_name)
206
207 def get_filters(self, origin_scope=None, include_self_names=True):
208 class_value = self.get_annotated_class_object()
209 if include_self_names:
210 for cls in class_value.py__mro__():
211 if not cls.is_compiled():
212 # In this case we're excluding compiled objects that are
213 # not fake objects. It doesn't make sense for normal
214 # compiled objects to search for self variables.
215 yield SelfAttributeFilter(self, class_value, cls.as_context(), origin_scope)
216
217 class_filters = class_value.get_filters(
218 origin_scope=origin_scope,
219 is_instance=True,
220 )
221 for f in class_filters:
222 if isinstance(f, ClassFilter):
223 yield InstanceClassFilter(self, f)
224 elif isinstance(f, CompiledValueFilter):
225 yield CompiledInstanceClassFilter(self, f)
226 else:
227 # Propably from the metaclass.
228 yield f
229
230 @inference_state_method_cache()
231 def create_instance_context(self, class_context, node):
232 new = node
233 while True:
234 func_node = new
235 new = new.search_ancestor('funcdef', 'classdef')
236 if class_context.tree_node is new:
237 func = FunctionValue.from_context(class_context, func_node)
238 bound_method = BoundMethod(self, class_context, func)
239 if func_node.name.value == '__init__':
240 context = bound_method.as_context(self._arguments)
241 else:
242 context = bound_method.as_context()
243 break
244 return context.create_context(node)
245
246 def py__getattribute__alternatives(self, string_name):
247 '''
248 Since nothing was inferred, now check the __getattr__ and
249 __getattribute__ methods. Stubs don't need to be checked, because
250 they don't contain any logic.
251 '''
252 if self.is_stub():
253 return NO_VALUES
254
255 name = compiled.create_simple_object(self.inference_state, string_name)
256
257 # This is a little bit special. `__getattribute__` is in Python
258 # executed before `__getattr__`. But: I know no use case, where
259 # this could be practical and where Jedi would return wrong types.
260 # If you ever find something, let me know!
261 # We are inversing this, because a hand-crafted `__getattribute__`
262 # could still call another hand-crafted `__getattr__`, but not the
263 # other way around.
264 if is_big_annoying_library(self.parent_context):
265 return NO_VALUES
266 names = (self.get_function_slot_names('__getattr__')
267 or self.get_function_slot_names('__getattribute__'))
268 return self.execute_function_slots(names, name)
269
270 def py__next__(self, contextualized_node=None):
271 name = u'__next__'
272 next_slot_names = self.get_function_slot_names(name)
273 if next_slot_names:
274 yield LazyKnownValues(
275 self.execute_function_slots(next_slot_names)
276 )
277 else:
278 debug.warning('Instance has no __next__ function in %s.', self)
279
280 def py__call__(self, arguments):
281 names = self.get_function_slot_names('__call__')
282 if not names:
283 # Means the Instance is not callable.
284 return super().py__call__(arguments)
285
286 return ValueSet.from_sets(name.infer().execute(arguments) for name in names)
287
288 def py__get__(self, instance, class_value):
289 """
290 obj may be None.
291 """
292 # Arguments in __get__ descriptors are obj, class.
293 # `method` is the new parent of the array, don't know if that's good.
294 for cls in self.class_value.py__mro__():
295 result = cls.py__get__on_class(self, instance, class_value)
296 if result is not NotImplemented:
297 return result
298
299 names = self.get_function_slot_names('__get__')
300 if names:
301 if instance is None:
302 instance = compiled.builtin_from_name(self.inference_state, 'None')
303 return self.execute_function_slots(names, instance, class_value)
304 else:
305 return ValueSet([self])
306
307
308class TreeInstance(_BaseTreeInstance):
309 def __init__(self, inference_state, parent_context, class_value, arguments):
310 # I don't think that dynamic append lookups should happen here. That
311 # sounds more like something that should go to py__iter__.
312 if class_value.py__name__() in ['list', 'set'] \
313 and parent_context.get_root_context().is_builtins_module():
314 # compare the module path with the builtin name.
315 if settings.dynamic_array_additions:
316 arguments = get_dynamic_array_instance(self, arguments)
317
318 super().__init__(inference_state, parent_context, class_value)
319 self._arguments = arguments
320 self.tree_node = class_value.tree_node
321
322 # This can recurse, if the initialization of the class includes a reference
323 # to itself.
324 @inference_state_method_cache(default=None)
325 def _get_annotated_class_object(self):
326 from jedi.inference.gradual.annotation import py__annotations__, \
327 infer_type_vars_for_execution
328
329 args = InstanceArguments(self, self._arguments)
330 for signature in init_or_new_func(self.class_value).get_signatures():
331 # Just take the first result, it should always be one, because we
332 # control the typeshed code.
333 funcdef = signature.value.tree_node
334 if funcdef is None or funcdef.type != 'funcdef' \
335 or not signature.matches_signature(args):
336 # First check if the signature even matches, if not we don't
337 # need to infer anything.
338 continue
339 bound_method = BoundMethod(self, self.class_value.as_context(), signature.value)
340 all_annotations = py__annotations__(funcdef)
341 type_var_dict = infer_type_vars_for_execution(bound_method, args, all_annotations)
342 if type_var_dict:
343 defined, = self.class_value.define_generics(
344 infer_type_vars_for_execution(signature.value, args, all_annotations),
345 )
346 debug.dbg('Inferred instance value as %s', defined, color='BLUE')
347 return defined
348 return None
349
350 def get_annotated_class_object(self):
351 return self._get_annotated_class_object() or self.class_value
352
353 def get_key_values(self):
354 values = NO_VALUES
355 if self.array_type == 'dict':
356 for i, (key, instance) in enumerate(self._arguments.unpack()):
357 if key is None and i == 0:
358 values |= ValueSet.from_sets(
359 v.get_key_values()
360 for v in instance.infer()
361 if v.array_type == 'dict'
362 )
363 if key:
364 values |= ValueSet([compiled.create_simple_object(
365 self.inference_state,
366 key,
367 )])
368
369 return values
370
371 def py__simple_getitem__(self, index):
372 if self.array_type == 'dict':
373 # Logic for dict({'foo': bar}) and dict(foo=bar)
374 # reversed, because:
375 # >>> dict({'a': 1}, a=3)
376 # {'a': 3}
377 # TODO tuple initializations
378 # >>> dict([('a', 4)])
379 # {'a': 4}
380 for key, lazy_context in reversed(list(self._arguments.unpack())):
381 if key is None:
382 values = ValueSet.from_sets(
383 dct_value.py__simple_getitem__(index)
384 for dct_value in lazy_context.infer()
385 if dct_value.array_type == 'dict'
386 )
387 if values:
388 return values
389 else:
390 if key == index:
391 return lazy_context.infer()
392 return super().py__simple_getitem__(index)
393
394 def __repr__(self):
395 return "<%s of %s(%s)>" % (self.__class__.__name__, self.class_value,
396 self._arguments)
397
398
399class AnonymousInstance(_BaseTreeInstance):
400 _arguments = None
401
402
403class CompiledInstanceName(NameWrapper):
404 @iterator_to_value_set
405 def infer(self):
406 for result_value in self._wrapped_name.infer():
407 if result_value.api_type == 'function':
408 yield CompiledBoundMethod(result_value)
409 else:
410 yield result_value
411
412
413class CompiledInstanceClassFilter(AbstractFilter):
414 def __init__(self, instance, f):
415 self._instance = instance
416 self._class_filter = f
417
418 def get(self, name):
419 return self._convert(self._class_filter.get(name))
420
421 def values(self):
422 return self._convert(self._class_filter.values())
423
424 def _convert(self, names):
425 return [CompiledInstanceName(n) for n in names]
426
427
428class BoundMethod(FunctionMixin, ValueWrapper):
429 def __init__(self, instance, class_context, function):
430 super().__init__(function)
431 self.instance = instance
432 self._class_context = class_context
433
434 def is_bound_method(self):
435 return True
436
437 @property
438 def name(self):
439 return FunctionNameInClass(
440 self._class_context,
441 super().name
442 )
443
444 def py__class__(self):
445 c, = values_from_qualified_names(self.inference_state, 'types', 'MethodType')
446 return c
447
448 def _get_arguments(self, arguments):
449 assert arguments is not None
450 return InstanceArguments(self.instance, arguments)
451
452 def _as_context(self, arguments=None):
453 if arguments is None:
454 return AnonymousMethodExecutionContext(self.instance, self)
455
456 arguments = self._get_arguments(arguments)
457 return MethodExecutionContext(self.instance, self, arguments)
458
459 def py__call__(self, arguments):
460 if isinstance(self._wrapped_value, OverloadedFunctionValue):
461 return self._wrapped_value.py__call__(self._get_arguments(arguments))
462
463 function_execution = self.as_context(arguments)
464 return function_execution.infer()
465
466 def get_signature_functions(self):
467 return [
468 BoundMethod(self.instance, self._class_context, f)
469 for f in self._wrapped_value.get_signature_functions()
470 ]
471
472 def get_signatures(self):
473 return [sig.bind(self) for sig in super().get_signatures()]
474
475 def __repr__(self):
476 return '<%s: %s>' % (self.__class__.__name__, self._wrapped_value)
477
478
479class CompiledBoundMethod(ValueWrapper):
480 def is_bound_method(self):
481 return True
482
483 def get_signatures(self):
484 return [sig.bind(self) for sig in self._wrapped_value.get_signatures()]
485
486
487class SelfName(TreeNameDefinition):
488 """
489 This name calculates the parent_context lazily.
490 """
491 def __init__(self, instance, class_context, tree_name):
492 self._instance = instance
493 self.class_context = class_context
494 self.tree_name = tree_name
495
496 @property
497 def parent_context(self):
498 return self._instance.create_instance_context(self.class_context, self.tree_name)
499
500 def get_defining_qualified_value(self):
501 return self._instance
502
503 def infer(self):
504 stmt = self.tree_name.search_ancestor('expr_stmt')
505 if stmt is not None:
506 if stmt.children[1].type == "annassign":
507 from jedi.inference.gradual.annotation import infer_annotation
508 values = infer_annotation(
509 self.parent_context, stmt.children[1].children[1]
510 ).execute_annotation(None)
511 if values:
512 return values
513 return super().infer()
514
515
516class LazyInstanceClassName(NameWrapper):
517 def __init__(self, instance, class_member_name):
518 super().__init__(class_member_name)
519 self._instance = instance
520
521 @iterator_to_value_set
522 def infer(self):
523 for result_value in self._wrapped_name.infer():
524 yield from result_value.py__get__(self._instance, self._instance.py__class__())
525
526 def get_signatures(self):
527 return self.infer().get_signatures()
528
529 def get_defining_qualified_value(self):
530 return self._instance
531
532
533class InstanceClassFilter(AbstractFilter):
534 """
535 This filter is special in that it uses the class filter and wraps the
536 resulting names in LazyInstanceClassName. The idea is that the class name
537 filtering can be very flexible and always be reflected in instances.
538 """
539 def __init__(self, instance, class_filter):
540 self._instance = instance
541 self._class_filter = class_filter
542
543 def get(self, name):
544 return self._convert(self._class_filter.get(name))
545
546 def values(self):
547 return self._convert(self._class_filter.values())
548
549 def _convert(self, names):
550 return [
551 LazyInstanceClassName(self._instance, n)
552 for n in names
553 ]
554
555 def __repr__(self):
556 return '<%s for %s>' % (self.__class__.__name__, self._class_filter)
557
558
559class SelfAttributeFilter(ClassFilter):
560 """
561 This class basically filters all the use cases where `self.*` was assigned.
562 """
563 def __init__(self, instance, instance_class, node_context, origin_scope):
564 super().__init__(
565 class_value=instance_class,
566 node_context=node_context,
567 origin_scope=origin_scope,
568 is_instance=True,
569 )
570 self._instance = instance
571
572 def _filter(self, names):
573 start, end = self._parser_scope.start_pos, self._parser_scope.end_pos
574 names = [n for n in names if start < n.start_pos < end]
575 return self._filter_self_names(names)
576
577 def _filter_self_names(self, names):
578 for name in names:
579 trailer = name.parent
580 if trailer.type == 'trailer' \
581 and len(trailer.parent.children) == 2 \
582 and trailer.children[0] == '.':
583 if name.is_definition() and self._access_possible(name):
584 # TODO filter non-self assignments instead of this bad
585 # filter.
586 if self._is_in_right_scope(trailer.parent.children[0], name):
587 yield name
588
589 def _is_in_right_scope(self, self_name, name):
590 self_context = self._node_context.create_context(self_name)
591 names = self_context.goto(self_name, position=self_name.start_pos)
592 return any(
593 n.api_type == 'param'
594 and n.tree_name.get_definition().position_index == 0
595 and n.parent_context.tree_node is self._parser_scope
596 for n in names
597 )
598
599 def _convert_names(self, names):
600 return [SelfName(self._instance, self._node_context, name) for name in names]
601
602 def _check_flows(self, names):
603 return names
604
605
606class InstanceArguments(TreeArgumentsWrapper):
607 def __init__(self, instance, arguments):
608 super().__init__(arguments)
609 self.instance = instance
610
611 def unpack(self, func=None):
612 yield None, LazyKnownValue(self.instance)
613 yield from self._wrapped_arguments.unpack(func)