]> crepu.dev Git - config.git/blame - djavu-asus/elpy/rpc-venv/lib/python3.11/site-packages/jedi/inference/helpers.py
Actualizado el Readme
[config.git] / djavu-asus / elpy / rpc-venv / lib / python3.11 / site-packages / jedi / inference / helpers.py
CommitLineData
53e6db90
DC
1import copy
2import sys
3import re
4import os
5from itertools import chain
6from contextlib import contextmanager
7
8from parso.python import tree
9
10
11def is_stdlib_path(path):
12 # Python standard library paths look like this:
13 # /usr/lib/python3.9/...
14 # TODO The implementation below is probably incorrect and not complete.
15 parts = path.parts
16 if 'dist-packages' in parts or 'site-packages' in parts:
17 return False
18
19 base_path = os.path.join(sys.prefix, 'lib', 'python')
20 return bool(re.match(re.escape(base_path) + r'\d.\d', str(path)))
21
22
23def deep_ast_copy(obj):
24 """
25 Much, much faster than copy.deepcopy, but just for parser tree nodes.
26 """
27 # If it's already in the cache, just return it.
28 new_obj = copy.copy(obj)
29
30 # Copy children
31 new_children = []
32 for child in obj.children:
33 if isinstance(child, tree.Leaf):
34 new_child = copy.copy(child)
35 new_child.parent = new_obj
36 else:
37 new_child = deep_ast_copy(child)
38 new_child.parent = new_obj
39 new_children.append(new_child)
40 new_obj.children = new_children
41
42 return new_obj
43
44
45def infer_call_of_leaf(context, leaf, cut_own_trailer=False):
46 """
47 Creates a "call" node that consist of all ``trailer`` and ``power``
48 objects. E.g. if you call it with ``append``::
49
50 list([]).append(3) or None
51
52 You would get a node with the content ``list([]).append`` back.
53
54 This generates a copy of the original ast node.
55
56 If you're using the leaf, e.g. the bracket `)` it will return ``list([])``.
57
58 We use this function for two purposes. Given an expression ``bar.foo``,
59 we may want to
60 - infer the type of ``foo`` to offer completions after foo
61 - infer the type of ``bar`` to be able to jump to the definition of foo
62 The option ``cut_own_trailer`` must be set to true for the second purpose.
63 """
64 trailer = leaf.parent
65 if trailer.type == 'fstring':
66 from jedi.inference import compiled
67 return compiled.get_string_value_set(context.inference_state)
68
69 # The leaf may not be the last or first child, because there exist three
70 # different trailers: `( x )`, `[ x ]` and `.x`. In the first two examples
71 # we should not match anything more than x.
72 if trailer.type != 'trailer' or leaf not in (trailer.children[0], trailer.children[-1]):
73 if leaf == ':':
74 # Basically happens with foo[:] when the cursor is on the colon
75 from jedi.inference.base_value import NO_VALUES
76 return NO_VALUES
77 if trailer.type == 'atom':
78 return context.infer_node(trailer)
79 return context.infer_node(leaf)
80
81 power = trailer.parent
82 index = power.children.index(trailer)
83 if cut_own_trailer:
84 cut = index
85 else:
86 cut = index + 1
87
88 if power.type == 'error_node':
89 start = index
90 while True:
91 start -= 1
92 base = power.children[start]
93 if base.type != 'trailer':
94 break
95 trailers = power.children[start + 1:cut]
96 else:
97 base = power.children[0]
98 trailers = power.children[1:cut]
99
100 if base == 'await':
101 base = trailers[0]
102 trailers = trailers[1:]
103
104 values = context.infer_node(base)
105 from jedi.inference.syntax_tree import infer_trailer
106 for trailer in trailers:
107 values = infer_trailer(context, values, trailer)
108 return values
109
110
111def get_names_of_node(node):
112 try:
113 children = node.children
114 except AttributeError:
115 if node.type == 'name':
116 return [node]
117 else:
118 return []
119 else:
120 return list(chain.from_iterable(get_names_of_node(c) for c in children))
121
122
123def is_string(value):
124 return value.is_compiled() and isinstance(value.get_safe_value(default=None), str)
125
126
127def is_literal(value):
128 return is_number(value) or is_string(value)
129
130
131def _get_safe_value_or_none(value, accept):
132 value = value.get_safe_value(default=None)
133 if isinstance(value, accept):
134 return value
135
136
137def get_int_or_none(value):
138 return _get_safe_value_or_none(value, int)
139
140
141def get_str_or_none(value):
142 return _get_safe_value_or_none(value, str)
143
144
145def is_number(value):
146 return _get_safe_value_or_none(value, (int, float)) is not None
147
148
149class SimpleGetItemNotFound(Exception):
150 pass
151
152
153@contextmanager
154def reraise_getitem_errors(*exception_classes):
155 try:
156 yield
157 except exception_classes as e:
158 raise SimpleGetItemNotFound(e)
159
160
161def parse_dotted_names(nodes, is_import_from, until_node=None):
162 level = 0
163 names = []
164 for node in nodes[1:]:
165 if node in ('.', '...'):
166 if not names:
167 level += len(node.value)
168 elif node.type == 'dotted_name':
169 for n in node.children[::2]:
170 names.append(n)
171 if n is until_node:
172 break
173 else:
174 continue
175 break
176 elif node.type == 'name':
177 names.append(node)
178 if node is until_node:
179 break
180 elif node == ',':
181 if not is_import_from:
182 names = []
183 else:
184 # Here if the keyword `import` comes along it stops checking
185 # for names.
186 break
187 return level, names
188
189
190def values_from_qualified_names(inference_state, *names):
191 return inference_state.import_module(names[:-1]).py__getattribute__(names[-1])
192
193
194def is_big_annoying_library(context):
195 string_names = context.get_root_context().string_names
196 if string_names is None:
197 return False
198
199 # Especially pandas and tensorflow are huge complicated Python libraries
200 # that get even slower than they already are when Jedi tries to undrstand
201 # dynamic features like decorators, ifs and other stuff.
202 return string_names[0] in ('pandas', 'numpy', 'tensorflow', 'matplotlib')