diff --git a/jedi/inference/value/decorator.py b/jedi/inference/value/decorator.py index 3fe4be40..637f08f6 100644 --- a/jedi/inference/value/decorator.py +++ b/jedi/inference/value/decorator.py @@ -3,7 +3,7 @@ Decorators are not really values, however we need some wrappers to improve docstrings and other things around decorators. ''' -from jedi.inference.base_value import ValueWrapper +from jedi.inference.base_value import ValueWrapper, ValueSet class Decoratee(ValueWrapper): @@ -13,3 +13,9 @@ class Decoratee(ValueWrapper): def py__doc__(self): return self._original_value.py__doc__() + + def py__get__(self, instance, class_value): + return ValueSet( + Decoratee(v, self._original_value) + for v in self._wrapped_value.py__get__(instance, class_value) + ) diff --git a/jedi/plugins/stdlib.py b/jedi/plugins/stdlib.py index 8250b465..5e093e72 100644 --- a/jedi/plugins/stdlib.py +++ b/jedi/plugins/stdlib.py @@ -119,7 +119,9 @@ def execute(callback): else: return call() - if value.is_bound_method(): + if value.is_bound_method() or value.is_instance(): + # value can be an instance for example if it is a partial + # object. return call() # for now we just support builtin functions. diff --git a/test/test_inference/test_docstring.py b/test/test_inference/test_docstring.py index 4d371f3f..dd5a28eb 100644 --- a/test/test_inference/test_docstring.py +++ b/test/test_inference/test_docstring.py @@ -422,6 +422,27 @@ def test_decorator(Script): assert d.docstring(raw=True) == 'Nice docstring' +def test_method_decorator(Script): + code = dedent(''' + def decorator(func): + @wraps(func) + def wrapper(*args, **kwargs): + """wrapper docstring""" + return func(*args, **kwargs) + return wrapper + + class Foo(): + @decorator + def check_user(self, f): + """Nice docstring""" + pass + + Foo().check_user''') + + d, = Script(code).infer() + assert d.docstring() == 'check_user(f)\n\nNice docstring' + + def test_partial(Script): code = dedent(''' def foo():