Add the Script.help function, fixes #392

This commit is contained in:
Dave Halter
2019-12-21 12:46:51 +01:00
parent 341d79681a
commit 536fd8c7c0
4 changed files with 82 additions and 32 deletions

View File

@@ -110,6 +110,11 @@ def names(Script):
return lambda code, **kwargs: Script(code).names(**kwargs)
@pytest.fixture(scope='session', params=['goto', 'infer'])
def goto_or_infer(request, Script):
return lambda code, *args, **kwargs: getattr(Script(code), request.param)(*args, **kwargs)
@pytest.fixture(scope='session')
def has_typing(environment):
if environment.version_info >= (3, 5, 0):

View File

@@ -12,6 +12,7 @@ arguments.
import os
import sys
import warnings
import keyword
import parso
from parso.python import tree
@@ -27,6 +28,7 @@ from jedi.api import interpreter
from jedi.api import helpers
from jedi.api.helpers import validate_line_column
from jedi.api.completion import Completion
from jedi.api.keywords import KeywordName
from jedi.api.environment import InterpreterEnvironment
from jedi.api.project import get_default_project, Project
from jedi.inference import InferenceState
@@ -272,9 +274,6 @@ class Script(object):
dynamic language, which means depending on an option you can have two
different versions of a function.
.. note:: It is deprecated to use follow_imports and follow_builtin_imports as
positional arguments. Will be a keyword argument in 0.16.0.
:param follow_imports: The goto call will follow imports.
:param follow_builtin_imports: If follow_imports is True will decide if
it follow builtin imports.
@@ -324,6 +323,29 @@ class Script(object):
defs = [classes.Definition(self._inference_state, d) for d in set(names)]
return helpers.sorted_definitions(defs)
@validate_line_column
def help(self, line=None, column=None):
"""
Works like goto and returns a list of Definition objects. Returns
additional definitions for keywords and operators.
The additional definitions are of ``Definition(...).type == 'keyword'``.
These definitions do not have a lot of value apart from their docstring
attribute, which contains the output of Python's ``help()`` function.
:rtype: list of :class:`classes.Definition`
"""
definitions = self.goto(line, column)
if definitions:
return definitions
leaf = self._module_node.get_leaf_for_position((line, column))
if leaf.type in ('keyword', 'operator', 'error_leaf'):
reserved = self._grammar._pgen_grammar.reserved_syntax_strings.keys()
if leaf.value in reserved:
name = KeywordName(self._inference_state, leaf.value)
return [classes.Definition(self._inference_state, name)]
return []
def usages(self, **kwargs):
# Deprecated, will be removed.
return self.find_references(*self._pos, **kwargs)

View File

@@ -1,29 +0,0 @@
def test_keyword_doc(Script):
r = list(Script("or").infer(1, 1))
assert len(r) == 1
assert len(r[0].doc) > 100
r = list(Script("asfdasfd").infer(1, 1))
assert len(r) == 0
k = Script("fro").complete()[0]
imp_start = '\nThe ``import'
assert k.raw_doc.startswith(imp_start)
assert k.doc.startswith(imp_start)
def test_blablabla(Script):
defs = Script("import").infer()
assert len(defs) == 1 and [1 for d in defs if d.doc]
# unrelated to #44
def test_operator_doc(Script):
r = list(Script("a == b").infer(1, 3))
assert len(r) == 1
assert len(r[0].doc) > 100
def test_lambda(Script):
defs = Script('lambda x: x').infer(column=0)
assert [d.type for d in defs] == ['keyword']

View File

@@ -0,0 +1,52 @@
import pytest
def test_error_leaf_keyword_doc(Script):
d, = Script("or").help(1, 1)
assert len(d.docstring()) > 100
assert d.name == 'or'
def test_error_leaf_operator_doc(Script):
d, = Script("==").help()
assert len(d.docstring()) > 100
assert d.name == '=='
def test_keyword_completion(Script):
k = Script("fro").complete()[0]
imp_start = 'The "import'
assert k.docstring(raw=True).startswith(imp_start)
assert k.docstring().startswith(imp_start)
def test_import_keyword(Script):
d, = Script("import x").help(column=0)
assert d.docstring().startswith('The "import" statement')
# unrelated to #44
def test_import_keyword_with_gotos(goto_or_infer):
assert not goto_or_infer("import x", column=0)
def test_operator_doc(Script):
d, = Script("a == b").help(1, 3)
assert len(d.docstring()) > 100
def test_lambda(Script):
d, = Script('lambda x: x').help(column=0)
assert d.type == 'keyword'
assert d.docstring().startswith('Lambdas\n*******')
@pytest.mark.parametrize(
'code, kwargs', [
('?', {}),
('""', {}),
('"', {}),
]
)
def test_help_no_returns(Script, code, kwargs):
assert not Script(code).help(**kwargs)