-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
DOC: Make doc decorator a class and replace Appender by doc #33160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
6e4b036
21fa045
363f1be
5b5508d
eb7d12a
1caee82
4c9dc28
4ebd97b
d3dbe5d
b4bf49b
faaf564
cc2be1a
08a0744
11de122
34829bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -245,13 +245,13 @@ def wrapper(*args, **kwargs) -> Callable[..., Any]: | |
return decorate | ||
|
||
|
||
def doc(*args: Union[str, Callable], **kwargs: str) -> Callable[[F], F]: | ||
def doc(*args: Union[str, Callable], **kwargs: str) -> Callable[[Callable], Callable]: | ||
""" | ||
A decorator take docstring templates, concatenate them and perform string | ||
substitution on it. | ||
|
||
This decorator will add a variable "_docstring_components" to the wrapped | ||
function to keep track the original docstring template for potential usage. | ||
callable to keep track the original docstring template for potential usage. | ||
If it should be consider as a template, it will be saved as a string. | ||
Otherwise, it will be saved as callable, and later user __doc__ and dedent | ||
to get docstring. | ||
|
@@ -260,40 +260,37 @@ def doc(*args: Union[str, Callable], **kwargs: str) -> Callable[[F], F]: | |
---------- | ||
*args : str or callable | ||
The string / docstring / docstring template to be appended in order | ||
after default docstring under function. | ||
after default docstring under callable. | ||
**kwags : str | ||
The string which would be used to format docstring template. | ||
""" | ||
|
||
def decorator(func: F) -> F: | ||
@wraps(func) | ||
def wrapper(*args, **kwargs) -> Callable: | ||
return func(*args, **kwargs) | ||
|
||
def decorator(call: Callable) -> Callable: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Is a class of type There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC then this seems OK since we are passing a class type not instance, and a class type is callable in order to instantiate.
gives and no errors. The class type seems to be treated as a function that returns an instance by mypy. |
||
# collecting docstring and docstring templates | ||
docstring_components: List[Union[str, Callable]] = [] | ||
if func.__doc__: | ||
docstring_components.append(dedent(func.__doc__)) | ||
if call.__doc__: | ||
docstring_components.append(dedent(call.__doc__)) | ||
|
||
for arg in args: | ||
if hasattr(arg, "_docstring_components"): | ||
docstring_components.extend(arg._docstring_components) # type: ignore | ||
elif isinstance(arg, str) or arg.__doc__: | ||
docstring_components.append(arg) | ||
for appender in args: | ||
if hasattr(appender, "_docstring_components"): | ||
docstring_components.extend( | ||
appender._docstring_components # type: ignore | ||
) | ||
elif isinstance(appender, str) or appender.__doc__: | ||
docstring_components.append(appender) | ||
|
||
# formatting templates and concatenating docstring | ||
wrapper.__doc__ = "".join( | ||
call.__doc__ = "".join( | ||
[ | ||
arg.format(**kwargs) | ||
if isinstance(arg, str) | ||
else dedent(arg.__doc__ or "") | ||
for arg in docstring_components | ||
component.format(**kwargs) | ||
if isinstance(component, str) | ||
else dedent(component.__doc__ or "") | ||
for component in docstring_components | ||
] | ||
) | ||
|
||
wrapper._docstring_components = docstring_components # type: ignore | ||
|
||
return cast(F, wrapper) | ||
call._docstring_components = docstring_components # type: ignore | ||
return call | ||
|
||
return decorator | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the names of the parameters, I think a descriptive name is better in this case. I think
args
andkwargs
are great names when they are generic, you can pass whatever, and they are passed to another function mostly.But in this case, they have very specific usage, and they are very different between them.
I think something like
*docs
or*docs_or_objs
and**params
could be ok. May be you think of something better.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the names, I think
docs
andparams
are good. I also want to add some other candidates here:supplements
to replaceargs
fillers
to replacekwargs
I am not a native English speaker, so I am not sure if those words also make sense to you and other developers. Please let me know which one you like and I will be more than happy to make the change.