Karthikeyan Singaravelan <tir.kar...@gmail.com> added the comment:

Adding my analysis here which is also at related issue : issue30129. On the 
attached program written by @skip.montanaro both c.sum and Child.sum return 
None for inspect.getdocs thus docstrings in pydoc are empty which can be fixed 
in both functools and inspect module as below : 

1. When we do inspect.getdoc(c.sum) where c is a partialmethod it looks for 
obj.__doc__ (c.sum.__doc__) returning partialmethod.__doc__ ("new function with 
partial...") instead of checking if c.sum is a partial method and  returning 
obj.func.__doc__ which contains the relevant doc ("sum doc"). Thus getdoc needs 
to check before trying for obj.__doc__ if the obj is a partialmethod or partial 
object thus returning the original function object.

2. When we do inspect.getdoc(Child.sum) it looks for obj.__doc__ 
(Child.sum.__doc__) and since Child.sum is a partialmethod which has __get__ 
overridden it calls _make_unbound_method that returns a _method object with no 
doc and thus returning None. partialmethod object copies objects from the given 
function at [0] and the actual object is returned at [1] . Here self.func has 
the original function in this case Base.sum and _method._partialmethod has 
reference to Base.sum which contains the relevant docs but _method itself has 
no docs thus pydoc doesn't get any docs. So we can set _method.__doc__ = 
self.func.__doc__ and getdoc can pick up the docs.

[0] 
https://github.com/python/cpython/blob/f1b9ad3d38c11676b45edcbf2369239bae436e56/Lib/functools.py#L368
[1] 
https://github.com/python/cpython/blob/f1b9ad3d38c11676b45edcbf2369239bae436e56/Lib/functools.py#L401

Before patch partialmethod.__doc__ : 

$ ./python.exe
>>> import functools, inspect
>>> inspect.getdoc(functools.partial(int, base=2))
'partial(func, *args, **keywords) - new function with partial application\nof 
the given arguments and keywords.'

After patch returns int.__doc__ : 

./python.exe
>>> import functools, inspect
>>> inspect.getdoc(functools.partial(int, base=2))
"int([x]) -> integer\nint(x, base=10) -> integer\n\nConvert a number or string 
to an integer ..." # Trimmed

# Patch

diff --git a/Lib/functools.py b/Lib/functools.py
index ab7d71e126..751f67fcd0 100644
--- a/Lib/functools.py
+++ b/Lib/functools.py
@@ -398,6 +398,7 @@ class partialmethod(object):
             return self.func(*call_args, **call_keywords)
         _method.__isabstractmethod__ = self.__isabstractmethod__
         _method._partialmethod = self
+        _method.__doc__ = self.func.__doc__ or self.__doc__
         return _method

     def __get__(self, obj, cls):
diff --git a/Lib/inspect.py b/Lib/inspect.py
index b8a142232b..2c796546b2 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -600,6 +600,9 @@ def getdoc(object):
     All tabs are expanded to spaces.  To clean up docstrings that are
     indented to line up with blocks of code, any whitespace than can be
     uniformly removed from the second line onwards is removed."""
+    if isinstance(object, (functools.partialmethod, functools.partial)):
+        return object.func.__doc__
+
     try:
         doc = object.__doc__
     except AttributeError:

----------
nosy: +xtreak
Added file: https://bugs.python.org/file47910/bpo30129.py

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue12154>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to