names.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. from abc import abstractmethod
  2. from inspect import Parameter
  3. from typing import Optional, Tuple
  4. from parso.tree import search_ancestor
  5. from jedi.parser_utils import find_statement_documentation, clean_scope_docstring
  6. from jedi.inference.utils import unite
  7. from jedi.inference.base_value import ValueSet, NO_VALUES
  8. from jedi.inference.cache import inference_state_method_cache
  9. from jedi.inference import docstrings
  10. from jedi.cache import memoize_method
  11. from jedi.inference.helpers import deep_ast_copy, infer_call_of_leaf
  12. from jedi.plugins import plugin_manager
  13. def _merge_name_docs(names):
  14. doc = ''
  15. for name in names:
  16. if doc:
  17. # In case we have multiple values, just return all of them
  18. # separated by a few dashes.
  19. doc += '\n' + '-' * 30 + '\n'
  20. doc += name.py__doc__()
  21. return doc
  22. class AbstractNameDefinition:
  23. start_pos: Optional[Tuple[int, int]] = None
  24. string_name: str
  25. parent_context = None
  26. tree_name = None
  27. is_value_name = True
  28. """
  29. Used for the Jedi API to know if it's a keyword or an actual name.
  30. """
  31. @abstractmethod
  32. def infer(self):
  33. raise NotImplementedError
  34. @abstractmethod
  35. def goto(self):
  36. # Typically names are already definitions and therefore a goto on that
  37. # name will always result on itself.
  38. return {self}
  39. def get_qualified_names(self, include_module_names=False):
  40. qualified_names = self._get_qualified_names()
  41. if qualified_names is None or not include_module_names:
  42. return qualified_names
  43. module_names = self.get_root_context().string_names
  44. if module_names is None:
  45. return None
  46. return module_names + qualified_names
  47. def _get_qualified_names(self):
  48. # By default, a name has no qualified names.
  49. return None
  50. def get_root_context(self):
  51. return self.parent_context.get_root_context()
  52. def get_public_name(self):
  53. return self.string_name
  54. def __repr__(self):
  55. if self.start_pos is None:
  56. return '<%s: string_name=%s>' % (self.__class__.__name__, self.string_name)
  57. return '<%s: string_name=%s start_pos=%s>' % (self.__class__.__name__,
  58. self.string_name, self.start_pos)
  59. def is_import(self):
  60. return False
  61. def py__doc__(self):
  62. return ''
  63. @property
  64. def api_type(self):
  65. return self.parent_context.api_type
  66. def get_defining_qualified_value(self):
  67. """
  68. Returns either None or the value that is public and qualified. Won't
  69. return a function, because a name in a function is never public.
  70. """
  71. return None
  72. class AbstractArbitraryName(AbstractNameDefinition):
  73. """
  74. When you e.g. want to complete dicts keys, you probably want to complete
  75. string literals, which is not really a name, but for Jedi we use this
  76. concept of Name for completions as well.
  77. """
  78. is_value_name = False
  79. def __init__(self, inference_state, string):
  80. self.inference_state = inference_state
  81. self.string_name = string
  82. self.parent_context = inference_state.builtins_module
  83. def infer(self):
  84. return NO_VALUES
  85. class AbstractTreeName(AbstractNameDefinition):
  86. def __init__(self, parent_context, tree_name):
  87. self.parent_context = parent_context
  88. self.tree_name = tree_name
  89. def get_qualified_names(self, include_module_names=False):
  90. import_node = search_ancestor(self.tree_name, 'import_name', 'import_from')
  91. # For import nodes we cannot just have names, because it's very unclear
  92. # how they would look like. For now we just ignore them in most cases.
  93. # In case of level == 1, it works always, because it's like a submodule
  94. # lookup.
  95. if import_node is not None and not (import_node.level == 1
  96. and self.get_root_context().get_value().is_package()):
  97. # TODO improve the situation for when level is present.
  98. if include_module_names and not import_node.level:
  99. return tuple(n.value for n in import_node.get_path_for_name(self.tree_name))
  100. else:
  101. return None
  102. return super().get_qualified_names(include_module_names)
  103. def _get_qualified_names(self):
  104. parent_names = self.parent_context.get_qualified_names()
  105. if parent_names is None:
  106. return None
  107. return parent_names + (self.tree_name.value,)
  108. def get_defining_qualified_value(self):
  109. if self.is_import():
  110. raise NotImplementedError("Shouldn't really happen, please report")
  111. elif self.parent_context:
  112. return self.parent_context.get_value() # Might be None
  113. return None
  114. def goto(self):
  115. context = self.parent_context
  116. name = self.tree_name
  117. definition = name.get_definition(import_name_always=True)
  118. if definition is not None:
  119. type_ = definition.type
  120. if type_ == 'expr_stmt':
  121. # Only take the parent, because if it's more complicated than just
  122. # a name it's something you can "goto" again.
  123. is_simple_name = name.parent.type not in ('power', 'trailer')
  124. if is_simple_name:
  125. return [self]
  126. elif type_ in ('import_from', 'import_name'):
  127. from jedi.inference.imports import goto_import
  128. module_names = goto_import(context, name)
  129. return module_names
  130. else:
  131. return [self]
  132. else:
  133. from jedi.inference.imports import follow_error_node_imports_if_possible
  134. values = follow_error_node_imports_if_possible(context, name)
  135. if values is not None:
  136. return [value.name for value in values]
  137. par = name.parent
  138. node_type = par.type
  139. if node_type == 'argument' and par.children[1] == '=' and par.children[0] == name:
  140. # Named param goto.
  141. trailer = par.parent
  142. if trailer.type == 'arglist':
  143. trailer = trailer.parent
  144. if trailer.type != 'classdef':
  145. if trailer.type == 'decorator':
  146. value_set = context.infer_node(trailer.children[1])
  147. else:
  148. i = trailer.parent.children.index(trailer)
  149. to_infer = trailer.parent.children[:i]
  150. if to_infer[0] == 'await':
  151. to_infer.pop(0)
  152. value_set = context.infer_node(to_infer[0])
  153. from jedi.inference.syntax_tree import infer_trailer
  154. for trailer in to_infer[1:]:
  155. value_set = infer_trailer(context, value_set, trailer)
  156. param_names = []
  157. for value in value_set:
  158. for signature in value.get_signatures():
  159. for param_name in signature.get_param_names():
  160. if param_name.string_name == name.value:
  161. param_names.append(param_name)
  162. return param_names
  163. elif node_type == 'dotted_name': # Is a decorator.
  164. index = par.children.index(name)
  165. if index > 0:
  166. new_dotted = deep_ast_copy(par)
  167. new_dotted.children[index - 1:] = []
  168. values = context.infer_node(new_dotted)
  169. return unite(
  170. value.goto(name, name_context=context)
  171. for value in values
  172. )
  173. if node_type == 'trailer' and par.children[0] == '.':
  174. values = infer_call_of_leaf(context, name, cut_own_trailer=True)
  175. return values.goto(name, name_context=context)
  176. else:
  177. stmt = search_ancestor(
  178. name, 'expr_stmt', 'lambdef'
  179. ) or name
  180. if stmt.type == 'lambdef':
  181. stmt = name
  182. return context.goto(name, position=stmt.start_pos)
  183. def is_import(self):
  184. imp = search_ancestor(self.tree_name, 'import_from', 'import_name')
  185. return imp is not None
  186. @property
  187. def string_name(self):
  188. return self.tree_name.value
  189. @property
  190. def start_pos(self):
  191. return self.tree_name.start_pos
  192. class ValueNameMixin:
  193. def infer(self):
  194. return ValueSet([self._value])
  195. def py__doc__(self):
  196. doc = self._value.py__doc__()
  197. if not doc and self._value.is_stub():
  198. from jedi.inference.gradual.conversion import convert_names
  199. names = convert_names([self], prefer_stub_to_compiled=False)
  200. if self not in names:
  201. return _merge_name_docs(names)
  202. return doc
  203. def _get_qualified_names(self):
  204. return self._value.get_qualified_names()
  205. def get_root_context(self):
  206. if self.parent_context is None: # A module
  207. return self._value.as_context()
  208. return super().get_root_context()
  209. def get_defining_qualified_value(self):
  210. context = self.parent_context
  211. if context is not None and (context.is_module() or context.is_class()):
  212. return self.parent_context.get_value() # Might be None
  213. return None
  214. @property
  215. def api_type(self):
  216. return self._value.api_type
  217. class ValueName(ValueNameMixin, AbstractTreeName):
  218. def __init__(self, value, tree_name):
  219. super().__init__(value.parent_context, tree_name)
  220. self._value = value
  221. def goto(self):
  222. return ValueSet([self._value.name])
  223. class TreeNameDefinition(AbstractTreeName):
  224. _API_TYPES = dict(
  225. import_name='module',
  226. import_from='module',
  227. funcdef='function',
  228. param='param',
  229. classdef='class',
  230. )
  231. def infer(self):
  232. # Refactor this, should probably be here.
  233. from jedi.inference.syntax_tree import tree_name_to_values
  234. return tree_name_to_values(
  235. self.parent_context.inference_state,
  236. self.parent_context,
  237. self.tree_name
  238. )
  239. @property
  240. def api_type(self):
  241. definition = self.tree_name.get_definition(import_name_always=True)
  242. if definition is None:
  243. return 'statement'
  244. return self._API_TYPES.get(definition.type, 'statement')
  245. def assignment_indexes(self):
  246. """
  247. Returns an array of tuple(int, node) of the indexes that are used in
  248. tuple assignments.
  249. For example if the name is ``y`` in the following code::
  250. x, (y, z) = 2, ''
  251. would result in ``[(1, xyz_node), (0, yz_node)]``.
  252. When searching for b in the case ``a, *b, c = [...]`` it will return::
  253. [(slice(1, -1), abc_node)]
  254. """
  255. indexes = []
  256. is_star_expr = False
  257. node = self.tree_name.parent
  258. compare = self.tree_name
  259. while node is not None:
  260. if node.type in ('testlist', 'testlist_comp', 'testlist_star_expr', 'exprlist'):
  261. for i, child in enumerate(node.children):
  262. if child == compare:
  263. index = int(i / 2)
  264. if is_star_expr:
  265. from_end = int((len(node.children) - i) / 2)
  266. index = slice(index, -from_end)
  267. indexes.insert(0, (index, node))
  268. break
  269. else:
  270. raise LookupError("Couldn't find the assignment.")
  271. is_star_expr = False
  272. elif node.type == 'star_expr':
  273. is_star_expr = True
  274. elif node.type in ('expr_stmt', 'sync_comp_for'):
  275. break
  276. compare = node
  277. node = node.parent
  278. return indexes
  279. @property
  280. def inference_state(self):
  281. # Used by the cache function below
  282. return self.parent_context.inference_state
  283. @inference_state_method_cache(default='')
  284. def py__doc__(self):
  285. api_type = self.api_type
  286. if api_type in ('function', 'class', 'property'):
  287. if self.parent_context.get_root_context().is_stub():
  288. from jedi.inference.gradual.conversion import convert_names
  289. names = convert_names([self], prefer_stub_to_compiled=False)
  290. if self not in names:
  291. return _merge_name_docs(names)
  292. # Make sure the names are not TreeNameDefinitions anymore.
  293. return clean_scope_docstring(self.tree_name.get_definition())
  294. if api_type == 'module':
  295. names = self.goto()
  296. if self not in names:
  297. return _merge_name_docs(names)
  298. if api_type == 'statement' and self.tree_name.is_definition():
  299. return find_statement_documentation(self.tree_name.get_definition())
  300. return ''
  301. class _ParamMixin:
  302. def maybe_positional_argument(self, include_star=True):
  303. options = [Parameter.POSITIONAL_ONLY, Parameter.POSITIONAL_OR_KEYWORD]
  304. if include_star:
  305. options.append(Parameter.VAR_POSITIONAL)
  306. return self.get_kind() in options
  307. def maybe_keyword_argument(self, include_stars=True):
  308. options = [Parameter.KEYWORD_ONLY, Parameter.POSITIONAL_OR_KEYWORD]
  309. if include_stars:
  310. options.append(Parameter.VAR_KEYWORD)
  311. return self.get_kind() in options
  312. def _kind_string(self):
  313. kind = self.get_kind()
  314. if kind == Parameter.VAR_POSITIONAL: # *args
  315. return '*'
  316. if kind == Parameter.VAR_KEYWORD: # **kwargs
  317. return '**'
  318. return ''
  319. def get_qualified_names(self, include_module_names=False):
  320. return None
  321. class ParamNameInterface(_ParamMixin):
  322. api_type = 'param'
  323. def get_kind(self):
  324. raise NotImplementedError
  325. def to_string(self):
  326. raise NotImplementedError
  327. def get_executed_param_name(self):
  328. """
  329. For dealing with type inference and working around the graph, we
  330. sometimes want to have the param name of the execution. This feels a
  331. bit strange and we might have to refactor at some point.
  332. For now however it exists to avoid infering params when we don't really
  333. need them (e.g. when we can just instead use annotations.
  334. """
  335. return None
  336. @property
  337. def star_count(self):
  338. kind = self.get_kind()
  339. if kind == Parameter.VAR_POSITIONAL:
  340. return 1
  341. if kind == Parameter.VAR_KEYWORD:
  342. return 2
  343. return 0
  344. def infer_default(self):
  345. return NO_VALUES
  346. class BaseTreeParamName(ParamNameInterface, AbstractTreeName):
  347. annotation_node = None
  348. default_node = None
  349. def to_string(self):
  350. output = self._kind_string() + self.get_public_name()
  351. annotation = self.annotation_node
  352. default = self.default_node
  353. if annotation is not None:
  354. output += ': ' + annotation.get_code(include_prefix=False)
  355. if default is not None:
  356. output += '=' + default.get_code(include_prefix=False)
  357. return output
  358. def get_public_name(self):
  359. name = self.string_name
  360. if name.startswith('__'):
  361. # Params starting with __ are an equivalent to positional only
  362. # variables in typeshed.
  363. name = name[2:]
  364. return name
  365. def goto(self, **kwargs):
  366. return [self]
  367. class _ActualTreeParamName(BaseTreeParamName):
  368. def __init__(self, function_value, tree_name):
  369. super().__init__(
  370. function_value.get_default_param_context(), tree_name)
  371. self.function_value = function_value
  372. def _get_param_node(self):
  373. return search_ancestor(self.tree_name, 'param')
  374. @property
  375. def annotation_node(self):
  376. return self._get_param_node().annotation
  377. def infer_annotation(self, execute_annotation=True, ignore_stars=False):
  378. from jedi.inference.gradual.annotation import infer_param
  379. values = infer_param(
  380. self.function_value, self._get_param_node(),
  381. ignore_stars=ignore_stars)
  382. if execute_annotation:
  383. values = values.execute_annotation()
  384. return values
  385. def infer_default(self):
  386. node = self.default_node
  387. if node is None:
  388. return NO_VALUES
  389. return self.parent_context.infer_node(node)
  390. @property
  391. def default_node(self):
  392. return self._get_param_node().default
  393. def get_kind(self):
  394. tree_param = self._get_param_node()
  395. if tree_param.star_count == 1: # *args
  396. return Parameter.VAR_POSITIONAL
  397. if tree_param.star_count == 2: # **kwargs
  398. return Parameter.VAR_KEYWORD
  399. # Params starting with __ are an equivalent to positional only
  400. # variables in typeshed.
  401. if tree_param.name.value.startswith('__'):
  402. return Parameter.POSITIONAL_ONLY
  403. parent = tree_param.parent
  404. param_appeared = False
  405. for p in parent.children:
  406. if param_appeared:
  407. if p == '/':
  408. return Parameter.POSITIONAL_ONLY
  409. else:
  410. if p == '*':
  411. return Parameter.KEYWORD_ONLY
  412. if p.type == 'param':
  413. if p.star_count:
  414. return Parameter.KEYWORD_ONLY
  415. if p == tree_param:
  416. param_appeared = True
  417. return Parameter.POSITIONAL_OR_KEYWORD
  418. def infer(self):
  419. values = self.infer_annotation()
  420. if values:
  421. return values
  422. doc_params = docstrings.infer_param(self.function_value, self._get_param_node())
  423. return doc_params
  424. class AnonymousParamName(_ActualTreeParamName):
  425. @plugin_manager.decorate(name='goto_anonymous_param')
  426. def goto(self):
  427. return super().goto()
  428. @plugin_manager.decorate(name='infer_anonymous_param')
  429. def infer(self):
  430. values = super().infer()
  431. if values:
  432. return values
  433. from jedi.inference.dynamic_params import dynamic_param_lookup
  434. param = self._get_param_node()
  435. values = dynamic_param_lookup(self.function_value, param.position_index)
  436. if values:
  437. return values
  438. if param.star_count == 1:
  439. from jedi.inference.value.iterable import FakeTuple
  440. value = FakeTuple(self.function_value.inference_state, [])
  441. elif param.star_count == 2:
  442. from jedi.inference.value.iterable import FakeDict
  443. value = FakeDict(self.function_value.inference_state, {})
  444. elif param.default is None:
  445. return NO_VALUES
  446. else:
  447. return self.function_value.parent_context.infer_node(param.default)
  448. return ValueSet({value})
  449. class ParamName(_ActualTreeParamName):
  450. def __init__(self, function_value, tree_name, arguments):
  451. super().__init__(function_value, tree_name)
  452. self.arguments = arguments
  453. def infer(self):
  454. values = super().infer()
  455. if values:
  456. return values
  457. return self.get_executed_param_name().infer()
  458. def get_executed_param_name(self):
  459. from jedi.inference.param import get_executed_param_names
  460. params_names = get_executed_param_names(self.function_value, self.arguments)
  461. return params_names[self._get_param_node().position_index]
  462. class ParamNameWrapper(_ParamMixin):
  463. def __init__(self, param_name):
  464. self._wrapped_param_name = param_name
  465. def __getattr__(self, name):
  466. return getattr(self._wrapped_param_name, name)
  467. def __repr__(self):
  468. return '<%s: %s>' % (self.__class__.__name__, self._wrapped_param_name)
  469. class ImportName(AbstractNameDefinition):
  470. start_pos = (1, 0)
  471. _level = 0
  472. def __init__(self, parent_context, string_name):
  473. self._from_module_context = parent_context
  474. self.string_name = string_name
  475. def get_qualified_names(self, include_module_names=False):
  476. if include_module_names:
  477. if self._level:
  478. assert self._level == 1, "Everything else is not supported for now"
  479. module_names = self._from_module_context.string_names
  480. if module_names is None:
  481. return module_names
  482. return module_names + (self.string_name,)
  483. return (self.string_name,)
  484. return ()
  485. @property
  486. def parent_context(self):
  487. m = self._from_module_context
  488. import_values = self.infer()
  489. if not import_values:
  490. return m
  491. # It's almost always possible to find the import or to not find it. The
  492. # importing returns only one value, pretty much always.
  493. return next(iter(import_values)).as_context()
  494. @memoize_method
  495. def infer(self):
  496. from jedi.inference.imports import Importer
  497. m = self._from_module_context
  498. return Importer(m.inference_state, [self.string_name], m, level=self._level).follow()
  499. def goto(self):
  500. return [m.name for m in self.infer()]
  501. @property
  502. def api_type(self):
  503. return 'module'
  504. def py__doc__(self):
  505. return _merge_name_docs(self.goto())
  506. class SubModuleName(ImportName):
  507. _level = 1
  508. class NameWrapper:
  509. def __init__(self, wrapped_name):
  510. self._wrapped_name = wrapped_name
  511. def __getattr__(self, name):
  512. return getattr(self._wrapped_name, name)
  513. def __repr__(self):
  514. return '%s(%s)' % (self.__class__.__name__, self._wrapped_name)
  515. class StubNameMixin:
  516. def py__doc__(self):
  517. from jedi.inference.gradual.conversion import convert_names
  518. # Stubs are not complicated and we can just follow simple statements
  519. # that have an equals in them, because they typically make something
  520. # else public. See e.g. stubs for `requests`.
  521. names = [self]
  522. if self.api_type == 'statement' and '=' in self.tree_name.get_definition().children:
  523. names = [v.name for v in self.infer()]
  524. names = convert_names(names, prefer_stub_to_compiled=False)
  525. if self in names:
  526. return super().py__doc__()
  527. else:
  528. # We have signatures ourselves in stubs, so don't use signatures
  529. # from the implementation.
  530. return _merge_name_docs(names)
  531. # From here on down we make looking up the sys.version_info fast.
  532. class StubName(StubNameMixin, TreeNameDefinition):
  533. def infer(self):
  534. inferred = super().infer()
  535. if self.string_name == 'version_info' and self.get_root_context().py__name__() == 'sys':
  536. from jedi.inference.gradual.stub_value import VersionInfo
  537. return ValueSet(VersionInfo(c) for c in inferred)
  538. return inferred
  539. class ModuleName(ValueNameMixin, AbstractNameDefinition):
  540. start_pos = 1, 0
  541. def __init__(self, value, name):
  542. self._value = value
  543. self._name = name
  544. @property
  545. def string_name(self):
  546. return self._name
  547. class StubModuleName(StubNameMixin, ModuleName):
  548. pass