def docstring(self, fast=True, raw=True): """ The docstring ``__doc__`` for any object. See :attr:`doc` for example. """ full_doc = '' # Using the first docstring that we see. for value in self._get_values(fast=fast): if full_doc: # In case we have multiple values, just return all of them # separated by a few dashes. full_doc += '\n' + '-' * 30 + '\n' doc = value.py__doc__() signature_text = '' if self._name.is_value_name: if not raw: signature_text = _format_signatures(value) if not doc and value.is_stub(): for c in convert_values(ValueSet({value}), ignore_compiled=False): doc = c.py__doc__() if doc: break if signature_text and doc: full_doc += signature_text + '\n\n' + doc else: full_doc += signature_text + doc return full_doc
def definition(correct, correct_start, path): should_be = set() for match in re.finditer('(?:[^ ]+)', correct): string = match.group(0) parser = grammar36.parse(string, start_symbol='eval_input', error_recovery=False) parser_utils.move(parser.get_root_node(), self.line_nr) node = parser.get_root_node() module_context = script._get_module_context() user_context = get_user_context(module_context, (self.line_nr, 0)) node.parent = user_context.tree_node results = convert_values(user_context.infer_node(node)) if not results: raise Exception('Could not resolve %s on line %s' % (match.string, self.line_nr - 1)) should_be |= set( Definition(inference_state, r.name) for r in results) debug.dbg('Finished getting types', color='YELLOW') # Because the objects have different ids, `repr`, then compare. should = set(comparison(r) for r in should_be) return should
def _get_value_filters(self, name_or_str): origin_scope = name_or_str if isinstance(name_or_str, Name) else None yield from self.get_filters(origin_scope=origin_scope) # This covers the case where a stub files are incomplete. if self.is_stub(): from jedi.inference.gradual.conversion import convert_values for c in convert_values(ValueSet({self})): yield from c.get_filters()
def completion_names(self, inference_state, only_modules=False): """ :param only_modules: Indicates wheter it's possible to import a definition that is not defined in a module. """ if not self._infer_possible: return [] names = [] if self.import_path: # flask if self._str_import_path == ('flask', 'ext'): # List Flask extensions like ``flask_foo`` for mod in self._get_module_names(): modname = mod.string_name if modname.startswith('flask_'): extname = modname[len('flask_'):] names.append(ImportName(self._module_context, extname)) # Now the old style: ``flaskext.foo`` for dir in self._sys_path_with_modifications( is_completion=True): flaskext = os.path.join(dir, 'flaskext') if os.path.isdir(flaskext): names += self._get_module_names([flaskext]) values = self.follow() for value in values: # Non-modules are not completable. if value.api_type not in ('module', 'namespace'): # not a module continue if not value.is_compiled(): # sub_modules_dict is not implemented for compiled modules. names += value.sub_modules_dict().values() if not only_modules: from jedi.inference.gradual.conversion import convert_values both_values = values | convert_values(values) for c in both_values: for filter in c.get_filters(): names += filter.values() else: if self.level: # We only get here if the level cannot be properly calculated. names += self._get_module_names(self._fixed_sys_path) else: # This is just the list of global imports. names += self._get_module_names() return names
def complete_trailer(user_context, values): completion_names = [] for value in values: for filter in value.get_filters(origin_scope=user_context.tree_node): completion_names += filter.values() if not value.is_stub() and isinstance(value, TreeInstance): completion_names += _complete_getattr(user_context, value) python_values = convert_values(values) for c in python_values: if c not in values: for filter in c.get_filters(origin_scope=user_context.tree_node): completion_names += filter.values() return completion_names
def _trailer_completions(self, previous_leaf): user_value = get_user_context(self._module_context, self._position) inferred_context = self._module_context.create_context(previous_leaf) values = infer_call_of_leaf(inferred_context, previous_leaf) completion_names = [] debug.dbg('trailer completion values: %s', values, color='MAGENTA') for value in values: for filter in value.get_filters(origin_scope=user_value.tree_node): completion_names += filter.values() python_values = convert_values(values) for c in python_values: if c not in values: for filter in c.get_filters(origin_scope=user_value.tree_node): completion_names += filter.values() return completion_names
def _complete_trailer_for_values(self, values): user_value = get_user_context(self._module_context, self._position) completion_names = [] for value in values: for filter in value.get_filters(origin_scope=user_value.tree_node): completion_names += filter.values() if not value.is_stub() and isinstance(value, TreeInstance): completion_names += self._complete_getattr(value) python_values = convert_values(values) for c in python_values: if c not in values: for filter in c.get_filters(origin_scope=user_value.tree_node): completion_names += filter.values() return completion_names
def infer(self, line=None, column=None, *, only_stubs=False, prefer_stubs=False): """ Return the definitions of under the cursor. It is basically a wrapper around Jedi's type inference. This method follows complicated paths and returns the end, not the first definition. The big difference between :meth:`goto` and :meth:`infer` is that :meth:`goto` doesn't follow imports and statements. Multiple objects may be returned, because depending on an option you can have two different versions of a function. :param only_stubs: Only return stubs for this method. :param prefer_stubs: Prefer stubs to Python objects for this method. :rtype: list of :class:`.Name` """ pos = line, column leaf = self._module_node.get_name_of_position(pos) if leaf is None: leaf = self._module_node.get_leaf_for_position(pos) if leaf is None or leaf.type == 'string': return [] if leaf.end_pos == (line, column) and leaf.type == 'operator': next_ = leaf.get_next_leaf() if next_.start_pos == leaf.end_pos \ and next_.type in ('number', 'string', 'keyword'): leaf = next_ context = self._get_module_context().create_context(leaf) values = helpers.infer(self._inference_state, context, leaf) values = convert_values( values, only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) defs = [classes.Name(self._inference_state, c.name) for c in values] # The additional set here allows the definitions to become unique in an # API sense. In the internals we want to separate more things than in # the API. return helpers.sorted_definitions(set(defs))
def _infer(self, only_stubs=False, prefer_stubs=False): assert not (only_stubs and prefer_stubs) if not self._name.is_value_name: return [] # First we need to make sure that we have stub names (if possible) that # we can follow. If we don't do that, we can end up with the inferred # results of Python objects instead of stubs. names = convert_names([self._name], prefer_stubs=True) values = convert_values( ValueSet.from_sets(n.infer() for n in names), only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) resulting_names = [c.name for c in values] return [self if n == self._name else Definition(self._inference_state, n) for n in resulting_names]
def _infer(self, line, column, only_stubs=False, prefer_stubs=False): pos = line, column leaf = self._module_node.get_name_of_position(pos) if leaf is None: leaf = self._module_node.get_leaf_for_position(pos) if leaf is None or leaf.type == 'string': return [] context = self._get_module_context().create_context(leaf) values = helpers.infer(self._inference_state, context, leaf) values = convert_values( values, only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) defs = [classes.Name(self._inference_state, c.name) for c in values] # The additional set here allows the definitions to become unique in an # API sense. In the internals we want to separate more things than in # the API. return helpers.sorted_definitions(set(defs))
def infer(self, *, only_stubs=False, prefer_stubs=False): """ Like :meth:`.Script.infer`, it can be useful to understand which type the current name has. Return the actual definitions. I strongly recommend not using it for your completions, because it might slow down |jedi|. If you want to read only a few objects (<=20), it might be useful, especially to get the original docstrings. The basic problem of this function is that it follows all results. This means with 1000 completions (e.g. numpy), it's just very, very slow. :param only_stubs: Only return stubs for this goto call. :param prefer_stubs: Prefer stubs to Python objects for this type inference call. :rtype: list of :class:`Name` """ assert not (only_stubs and prefer_stubs) if not self._name.is_value_name: return [] # First we need to make sure that we have stub names (if possible) that # we can follow. If we don't do that, we can end up with the inferred # results of Python objects instead of stubs. names = convert_names([self._name], prefer_stubs=True) values = convert_values( ValueSet.from_sets(n.infer() for n in names), only_stubs=only_stubs, prefer_stubs=prefer_stubs, ) resulting_names = [c.name for c in values] return [ self if n == self._name else Name(self._inference_state, n) for n in resulting_names ]