pdoc
pdoc copied to clipboard
pdoc3 skips a decorated function (callable object)
Expected Behavior
Generate the documentation for add3
Actual Behavior
Nothing is generated
Steps to Reproduce
- Create a script "pdoc_tt.py" as follows
from numba import cuda
@cuda.jit
def add3(a: int, b: int) -> int:
"""Add two integers
Args:
a (int): one integer
b (int): the other integer
Returns:
int: the sum
"""
return a + b
# add3 is a callable object of type 'numba.cuda.compiler.AutoJitCUDAKernel`
# set the two attributes below manually, since `AutoJitCUDAKernel` does not preserve them
add3.__module__ = __name__
add3.__doc__ = add3.py_func.__doc__ # the right hand side is just the original __doc__
print(callable(add3))
print(add3.__module__)
print(add3.__doc__)
The package numba is found here
- run command
pdoc3 --html pdoc_tt.py - We see the following output in the terminal
True
pdoc_tt
Add two integers
Args:
a (int): one integer
b (int): the other integer
Returns:
int: the sum
As we see, add3 is indeed callable, and its __module__ and __doc__ are also right. However, there is no documentation generated for add3 in the Html "pdoc_tt.html".
Additional info
Adding __pdoc__ = {'add3': True} makes no difference.
- pdoc version: pdoc.exe 0.8.1 (on Windows 10)
Well, it seems the reason is the following method in pdoc3:
def _is_function(obj):
return inspect.isroutine(obj) and callable(obj)
Here, for the above add3 of type numba.cuda.compiler.AutoJitCUDAKernel, callable yields true while inspect.isroutine gives false. My question is why and is used here for the two conditions. That is, what is the problem if we use or instead?
My question is why
andis used here for the two conditions. That is, what is the problem if we useorinstead?
When in doubt, best to flip the line and see what, if any, tests it breaks. (Hint: all of them.) The line was introduces as part of https://github.com/pdoc3/pdoc/pull/77, addressing read-only value descriptors (https://github.com/pdoc3/pdoc/issues/76).
The function ensures the passed object is callable and indeed a routine, as opposed to an arbitrary object which just happens to be callable (its class defines __call__), as is the case here.
If you can think of a way to adapt this condition check to also cover your case, a PR is welcome! https://github.com/pdoc3/pdoc/blob/64405338c0b58207f80d264b07cd7fe17694e2d5/pdoc/init.py#L611-L613
Pdoc3, though, diligently calls inspect.unwrap() on detected objects:
https://github.com/pdoc3/pdoc/blob/64405338c0b58207f80d264b07cd7fe17694e2d5/pdoc/init.py#L604
so really it's numba at fault, for they should update_wrapper(). This way, you also wouldn't need to manually preserve __module__ and __doc__. I see this is already filed as https://github.com/numba/numba/issues/5902. :+1: It also seems to be an easy, good first issue, so welcome to give them a hand!
Hi, kernc,
Thank you for your help. I have tried the or logic instead as follows:
def _is_function(obj):
return inspect.isroutine(obj) or callable(obj)
aside from setting __module__ and __doc__ manually.
However, it still failed to generate the documentation. I guess more changes are needed for this workaround, which is a little beyond my capability. For now, I will wait for the update from numba.