mkdocstrings / pytkdocs

Load Python objects documentation.
https://mkdocstrings.github.io/pytkdocs
ISC License
50 stars 32 forks source link

[BUG] Error displaying wrapped Python functions where wrapper is from another module #143

Open roastduck opened 2 years ago

roastduck commented 2 years ago

Describe the bug I am using a function wrapper to produce multiple functions from a stub one, and set the produced function with different names and docs. However, the produced functions are not displayed in the page generated from mkdocstrings. If I set show_if_no_docstring, it appears but without any document.

The function wrapper mypartial is as below.

def mypartial(name: str, doc: str, f, *args, **kvs):

    def g(*_args, **_kvs):
        return f(*args, *_args, **kvs, **_kvs)

    g.__name__ = name
    g.__doc__ = doc
    g.__wrapped__ = f  # Whether to set __wrapped__ does not change the result
    return g

xxx = mypartial("xxx", "xxx", lambda x, y: x + y, 1)

Surprisingly to me, this piece of code works. But if I import mypartial from another module (just another file aside), it does not. I am wondering what is the difference whether mypartial is defined in another module.

I noticed there is some discussions in https://github.com/mkdocstrings/mkdocstrings/issues/162. But my case is a little bit different, because my decorated function has a different name and doc from the original one.

To Reproduce Run the code above, but define mypartial in a separated file.

Expected behavior Function xxx should be documented

Screenshots The function xxx just disappears.

System (please complete the following information):

pawamoy commented 2 years ago

Hi, thanks for the report. I think setting __name__, __doc__ and __wrapped__ attributes should be enough, but maybe it's not. Did you try using functools.wraps instead?

roastduck commented 2 years ago

functools.wraps does not meet my use case well. The reason is that I am generating multiple functions from one stub function, instead of replacing an original function with a new one, so the generated functions should have different meta data from the original one, but functools.wraps just sets the original function's meta data to the new one.

Besides, I have also tried setting __module__. It does not work either.

pawamoy commented 2 years ago

I see, thanks. I'll to have to run a debug session to see exactly what's going wrong (I'm on mobile right now, will have time next week).