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