I have tried to somehow get a documentation for a partialmethod to work. My current code is
from functools import partialmethod
class Fun(object):
def test(self, num):
"""
I have a documentation
"""
return num
test2 = partialmethod(test, num=10)
test2.__doc__ = """Blub"""
test3 = partialmethod(test, num=20)
But if I run
a = Fun()
a.test2.__doc__ # only returns the partials documentation not "Blub"
Fun.test2.__doc__ # gives nothing
and Sphinx lists them using autoclass
as undocumented members
.
I have read https://docs.python.org/3/library/functools.html#partial-objects and https://docs.python.org/3/library/functools.html#functools.partialmethod but does that mean that there is no way of getting documentations into partialmethods or am I just too stupid about it?
It's not possible to set a docstring on a partialmethod
object. That's because partialmethod
is a class written in Python, and instances of classes get their docstring from the class's __doc__
, not from a __doc__
attribute on the instances. Functions behave differently, with the __doc__
attribute of the function object being looked at.
Depending on how complicated your use of partialmethod
is, you may be able to write your own version that returns a function, rather than an instance, thus allowing you to customize the documentation by assigning to the __doc__
attribute.
Here's a quick version I've thrown together with only basic testing. I think it works for common cases (e.g. where func
is an actual function), but it probably won't be as flexible as the regular partialmethod
type, so you should double check that it does everything you need it to do:
import functools
def my_partialmethod(func, *args1, **kwargs1):
@functools.wraps(func) # copy attributes to start, they can be overwritten later
def method(self, *args2, **kwargs2):
return func(self, *args1, *args2, **kwargs1, **kwargs2)
return method
The multiple unpacking in the call to func
is only legal in Python 3.5. In older Python versions, you'll have to merge the arguments yourself with something like this:
def method(self, *args2, **kwargs2):
kwargs = kwargs1.copy()
kwargs.update(kwargs2)
return func(self, *(args1+args2), **kwargs)
Here's an example use:
class Test(object):
def method1(self, arg):
"docstring1"
print(arg)
method2 = my_partial_method(method1, "foo")
method2.__name__ = "method2"
method2.__doc__ = "docstring2"
method3 = my_partial_method(method1, arg="bar")
method3.__name__ = "method3"
method3.__doc__ = "docstring3"
You can of course pick which attributes to overwrite. I'm not sure if using functools.wraps
is a good idea or not, as it may copy over a bunch of invalid attributes, beyond the ones I'm modifying in my example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With