]>
crepu.dev Git - config.git/blob - djavu-asus/elpy/rpc-venv/lib/python3.11/site-packages/jedi/inference/finder.py
2 Searching for names with given scope and name. This is very central in Jedi and
3 Python. The name resolution is quite complicated with descripter,
4 ``__getattribute__``, ``__getattr__``, ``global``, etc.
6 If you want to understand name resolution, please read the first few chapters
7 in http://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/.
12 Flow checks are not really mature. There's only a check for ``isinstance``. It
13 would check whether a flow has the form of ``if isinstance(a, type_or_tuple)``.
14 Unfortunately every other thing is being ignored (e.g. a == '' would be easy to
15 check for -> a is a string). There's big potential in these checks.
18 from parso
.tree
import search_ancestor
19 from parso
.python
.tree
import Name
21 from jedi
import settings
22 from jedi
.inference
.arguments
import TreeArguments
23 from jedi
.inference
.value
import iterable
24 from jedi
.inference
.base_value
import NO_VALUES
25 from jedi
.parser_utils
import is_scope
28 def filter_name(filters
, name_or_str
):
30 Searches names that are defined in a scope (the different
31 ``filters``), until a name fits.
33 string_name
= name_or_str
.value
if isinstance(name_or_str
, Name
) else name_or_str
35 for filter in filters
:
36 names
= filter.get(string_name
)
40 return list(_remove_del_stmt(names
))
43 def _remove_del_stmt(names
):
44 # Catch del statements and remove them from results.
46 if name
.tree_name
is not None:
47 definition
= name
.tree_name
.get_definition()
48 if definition
is not None and definition
.type == 'del_stmt':
53 def check_flow_information(value
, flow
, search_name
, pos
):
54 """ Try to find out the type of a variable just with the information that
55 is given by the flows: e.g. It is also responsible for assert checks.::
57 if isinstance(k, str):
58 k. # <- completion here
60 ensures that `k` is a string.
62 if not settings
.dynamic_flow_information
:
68 module_node
= flow
.get_root_node()
70 names
= module_node
.get_used_names()[search_name
.value
]
75 if flow
.start_pos
<= n
.start_pos
< (pos
or flow
.end_pos
)
79 ass
= search_ancestor(name
, 'assert_stmt')
81 result
= _check_isinstance_type(value
, ass
.assertion
, search_name
)
82 if result
is not None:
85 if flow
.type in ('if_stmt', 'while_stmt'):
86 potential_ifs
= [c
for c
in flow
.children
[1::4] if c
!= ':']
87 for if_test
in reversed(potential_ifs
):
88 if search_name
.start_pos
> if_test
.end_pos
:
89 return _check_isinstance_type(value
, if_test
, search_name
)
93 def _get_isinstance_trailer_arglist(node
):
94 if node
.type in ('power', 'atom_expr') and len(node
.children
) == 2:
95 # This might be removed if we analyze and, etc
96 first
, trailer
= node
.children
97 if first
.type == 'name' and first
.value
== 'isinstance' \
98 and trailer
.type == 'trailer' and trailer
.children
[0] == '(':
103 def _check_isinstance_type(value
, node
, search_name
):
105 trailer
= _get_isinstance_trailer_arglist(node
)
106 if trailer
is not None and len(trailer
.children
) == 3:
107 arglist
= trailer
.children
[1]
108 args
= TreeArguments(value
.inference_state
, value
, arglist
, trailer
)
109 param_list
= list(args
.unpack())
110 # Disallow keyword arguments
111 if len(param_list
) == 2 and len(arglist
.children
) == 3:
112 (key1
, _
), (key2
, lazy_value_cls
) = param_list
113 if key1
is None and key2
is None:
114 call
= _get_call_string(search_name
)
115 is_instance_call
= _get_call_string(arglist
.children
[0])
116 # Do a simple get_code comparison of the strings . They should
117 # just have the same code, and everything will be all right.
118 # There are ways that this is not correct, if some stuff is
119 # redefined in between. However here we don't care, because
120 # it's a heuristic that works pretty well.
121 if call
== is_instance_call
:
122 lazy_cls
= lazy_value_cls
126 value_set
= NO_VALUES
127 for cls_or_tup
in lazy_cls
.infer():
128 if isinstance(cls_or_tup
, iterable
.Sequence
) and cls_or_tup
.array_type
== 'tuple':
129 for lazy_value
in cls_or_tup
.py__iter__():
130 value_set |
= lazy_value
.infer().execute_with_values()
132 value_set |
= cls_or_tup
.execute_with_values()
136 def _get_call_string(node
):
137 if node
.parent
.type == 'atom_expr':
138 return _get_call_string(node
.parent
)
141 leaf
= node
.get_first_leaf()
142 end
= node
.get_last_leaf().end_pos
143 while leaf
.start_pos
< end
:
145 leaf
= leaf
.get_next_leaf()