Do not show signatures for properties, fixes #1695

This commit is contained in:
Dave Halter
2021-01-01 23:51:41 +01:00
parent 1ccc63e83d
commit 7d160f96f6
5 changed files with 43 additions and 4 deletions

View File

@@ -140,6 +140,11 @@ def goto_or_help_or_infer(request, Script):
return do
@pytest.fixture(scope='session', params=['goto', 'complete', 'help'])
def goto_or_complete(request, Script):
return lambda code, *args, **kwargs: getattr(Script(code), request.param)(*args, **kwargs)
@pytest.fixture(scope='session')
def has_django(environment):
script = jedi.Script('import django', environment=environment)

View File

@@ -550,6 +550,8 @@ class BaseName:
return ''.join(lines[start_index:index + after + 1])
def _get_signatures(self, for_docstring=False):
if self._name.api_type == 'property':
return []
if for_docstring and self._name.api_type == 'statement' and not self.is_stub():
# For docstrings we don't resolve signatures if they are simple
# statements and not stubs. This is a speed optimization.

View File

@@ -340,7 +340,7 @@ class TreeNameDefinition(AbstractTreeName):
@inference_state_method_cache(default='')
def py__doc__(self):
api_type = self.api_type
if api_type in ('function', 'class'):
if api_type in ('function', 'class', 'property'):
# Make sure the names are not TreeNameDefinitions anymore.
return clean_scope_docstring(self.tree_name.get_definition())

View File

@@ -306,7 +306,7 @@ def expr_is_dotted(node):
return node.type == 'name'
def _function_is_x_method(method_name):
def _function_is_x_method(*method_names):
def wrapper(function_node):
"""
This is a heuristic. It will not hold ALL the times, but it will be
@@ -316,7 +316,7 @@ def _function_is_x_method(method_name):
"""
for decorator in function_node.get_decorators():
dotted_name = decorator.children[1]
if dotted_name.get_code() == method_name:
if dotted_name.get_code() in method_names:
return True
return False
return wrapper
@@ -324,4 +324,4 @@ def _function_is_x_method(method_name):
function_is_staticmethod = _function_is_x_method('staticmethod')
function_is_classmethod = _function_is_x_method('classmethod')
function_is_property = _function_is_x_method('property')
function_is_property = _function_is_x_method('property', 'cached_property')

View File

@@ -507,3 +507,35 @@ def test_doctest_function_start(Script):
return
''')
assert Script(code).complete(7, 8)
@pytest.mark.parametrize(
"name, docstring", [
('prop1', 'Returns prop1.'),
('prop2', 'Returns None or ...'),
('prop3', 'Non-sense property.'),
('prop4', 'Django like property'),
]
)
def test_property(name, docstring, goto_or_complete):
code = dedent('''
from typing import Optional
class Test:
@property
def prop1(self) -> int:
"""Returns prop1."""
@property
def prop2(self) -> Optional[int]:
"""Returns None or ..."""
@property
def prop3(self) -> None:
"""Non-sense property."""
@cached_property # Not imported, but Jedi uses a heuristic
def prop4(self) -> None:
"""Django like property"""
''')
n, = goto_or_complete(code + 'Test().' + name)
assert n.docstring() == docstring