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