diff --git a/jedi/inference/gradual/conversion.py b/jedi/inference/gradual/conversion.py index 3c05bb14..0700716d 100644 --- a/jedi/inference/gradual/conversion.py +++ b/jedi/inference/gradual/conversion.py @@ -4,6 +4,7 @@ from jedi.inference.base_value import ValueSet, \ from jedi.inference.utils import to_list from jedi.inference.gradual.stub_value import StubModuleValue from jedi.inference.gradual.typeshed import try_to_load_stub_cached +from jedi.inference.value.decorator import Decoratee def _stub_to_python_value_set(stub_value, ignore_compiled=False): @@ -11,6 +12,10 @@ def _stub_to_python_value_set(stub_value, ignore_compiled=False): if not stub_module_context.is_stub(): return ValueSet([stub_value]) + decorates = None + if isinstance(stub_value, Decoratee): + decorates = stub_value._original_value + was_instance = stub_value.is_instance() if was_instance: stub_value = stub_value.py__class__() @@ -37,6 +42,8 @@ def _stub_to_python_value_set(stub_value, ignore_compiled=False): # Now that the instance has been properly created, we can simply get # the method. values = values.py__getattribute__(method_name) + if decorates is not None: + values = ValueSet(Decoratee(v, decorates) for v in values) return values diff --git a/test/test_api/test_documentation.py b/test/test_api/test_documentation.py index 7f281b27..2aa6140a 100644 --- a/test/test_api/test_documentation.py +++ b/test/test_api/test_documentation.py @@ -97,3 +97,21 @@ def test_builtin_docstring(goto_or_help_or_infer, skip_python2): doc = d.docstring() assert doc.startswith('open(file: Union[') assert 'Open file' in doc + + +def test_docstring_decorator(goto_or_help_or_infer, skip_python2): + code = dedent(''' + import types + + def dec(func): + return types.FunctionType() + + @dec + def func(a, b): + "hello" + return + func''') + d, = goto_or_help_or_infer(code) + + doc = d.docstring() + assert doc == 'FunctionType(*args: Any, **kwargs: Any) -> Any\n\nhello'