1from jedi.inference.base_value import ValueSet, NO_VALUES
2from jedi.common import monkeypatch
3
4
5class AbstractLazyValue:
6    def __init__(self, data, min=1, max=1):
7        self.data = data
8        self.min = min
9        self.max = max
10
11    def __repr__(self):
12        return '<%s: %s>' % (self.__class__.__name__, self.data)
13
14    def infer(self):
15        raise NotImplementedError
16
17
18class LazyKnownValue(AbstractLazyValue):
19    """data is a Value."""
20    def infer(self):
21        return ValueSet([self.data])
22
23
24class LazyKnownValues(AbstractLazyValue):
25    """data is a ValueSet."""
26    def infer(self):
27        return self.data
28
29
30class LazyUnknownValue(AbstractLazyValue):
31    def __init__(self, min=1, max=1):
32        super().__init__(None, min, max)
33
34    def infer(self):
35        return NO_VALUES
36
37
38class LazyTreeValue(AbstractLazyValue):
39    def __init__(self, context, node, min=1, max=1):
40        super().__init__(node, min, max)
41        self.context = context
42        # We need to save the predefined names. It's an unfortunate side effect
43        # that needs to be tracked otherwise results will be wrong.
44        self._predefined_names = dict(context.predefined_names)
45
46    def infer(self):
47        with monkeypatch(self.context, 'predefined_names', self._predefined_names):
48            return self.context.infer_node(self.data)
49
50
51def get_merged_lazy_value(lazy_values):
52    if len(lazy_values) > 1:
53        return MergedLazyValues(lazy_values)
54    else:
55        return lazy_values[0]
56
57
58class MergedLazyValues(AbstractLazyValue):
59    """data is a list of lazy values."""
60    def infer(self):
61        return ValueSet.from_sets(l.infer() for l in self.data)
62