-
Notifications
You must be signed in to change notification settings - Fork 21
Description
The linting for decorators could be improved. Here is an example:
from typing import Callable
from functools import wraps
def foo(func:Callable[[], None])->Callable[[], None]:
"""Print things decorator.
:raises ValueError: Something went bad
"""
@wraps(func)
def wrapper()->None:
print("a")
func()
raise ValueError("Oops")
return wrapper
@foo
def bar():
print("b")
bar()This is how I would expect to have to document this decorator. But I get the following error:
4: DOC101: Function `foo`: Docstring contains fewer arguments than in function signature.
4: DOC103: Function `foo`: Docstring arguments are different from function arguments. (Or could be other formatting issues: https://jsh9.github.io/pydoclint/violation_codes.html#notes-on-doc103 ). Arguments in the function signature but not in the docstring: [func: Callable[[], None]].
4: DOC201: Function `foo` does not have a return section in docstring
4: DOC502: Function `foo` has a "Raises" section in the docstring, but there are not "raise" statements in the body
Another example with a decorator with an argument
from functools import wraps
from typing import Callable, ParamSpec, TypeVar
P = ParamSpec("P")
R = TypeVar("R")
def foo(nb: int) -> Callable[[Callable[P, R]], Callable[P, R]]:
"""The foo decorator.
:param nb: a valid number
:raises ValueError: some `nb`s are illegal
:return: unchanged return value of wrapped function
"""
def decorator(func: Callable[P, R]) -> Callable[P, R]:
@wraps(func)
def wrapper(*args: P.args, **kwargs: P.kwargs) -> R:
if nb == 2:
raise ValueError()
return func(*args, **kwargs)
return wrapper
return decorator
@foo(3)
def bar(val: str) -> int:
return 3
print(bar("2"))With this I get the following error:
8: DOC502: Function `foo` has a "Raises" section in the docstring, but there are not "raise" statements in the body
There is no return warning because the function returns the decorator function, but in reality, it is not checking for the correct return statement
Idea to fix
I don't know if it possible, but pydoclint could check if the function returns another function and in this case append the Exception and change the return to what the sub function returns.
I'm not sure how you would handle the func argument in the first case, because in the second case, we would like to document the decorator parameters.
There is also the fact that we could have a function, which is not intended to be a decorator, that returns another callable. In this case, it might be good to have both the current linting and the updated behavior to be valid.
There might be other cases to consider.
This is based on how I would document these decorators but I might be doing things wrong.
Decorators are a bit niche but it would be nice to have good documentation for them :)