Skip to content

Commit f33f891

Browse files
mivanitkernc
andauthored
BUG: Fix git_link_template not showing for property, cached_property (#451)
* fix properties and cached_properties failing when adding git links see #450 * fix whitespace for flake8 * special case for namedtuple fields * add special case for member_descriptor * Extend existing _unwrap_descriptor() function --------- Co-authored-by: Kernc <[email protected]>
1 parent 6330d7e commit f33f891

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

pdoc/__init__.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
import typing
2020
from contextlib import contextmanager
2121
from copy import copy
22-
from functools import lru_cache, reduce, partial, wraps
22+
from functools import cached_property, lru_cache, reduce, partial, wraps
2323
from itertools import tee, groupby
24-
from types import ModuleType
24+
from types import FunctionType, ModuleType
2525
from typing import ( # noqa: F401
2626
cast, Any, Callable, Dict, Generator, Iterable, List, Literal, Mapping, NewType,
2727
Optional, Set, Tuple, Type, TypeVar, Union,
@@ -429,11 +429,22 @@ def _is_descriptor(obj):
429429
inspect.ismemberdescriptor(obj))
430430

431431

432-
def _unwrap_descriptor(obj):
432+
def _unwrap_descriptor(dobj):
433+
obj = dobj.obj
433434
if isinstance(obj, property):
434435
return (getattr(obj, 'fget', False) or
435436
getattr(obj, 'fset', False) or
436437
getattr(obj, 'fdel', obj))
438+
if isinstance(obj, cached_property):
439+
return obj.func
440+
if isinstance(obj, FunctionType):
441+
return obj
442+
if (inspect.ismemberdescriptor(obj) or
443+
getattr(getattr(obj, '__class__', 0), '__name__', 0) == '_tuplegetter'):
444+
class_name = dobj.qualname.rsplit('.', 1)[0]
445+
obj = getattr(dobj.module.obj, class_name)
446+
return obj
447+
# XXX: Follow descriptor protocol? Already proved buggy in conditions above
437448
return getattr(obj, '__get__', obj)
438449

439450

@@ -558,7 +569,7 @@ def source(self) -> str:
558569
available, an empty string.
559570
"""
560571
try:
561-
lines, _ = inspect.getsourcelines(_unwrap_descriptor(self.obj))
572+
lines, _ = inspect.getsourcelines(_unwrap_descriptor(self))
562573
except (ValueError, TypeError, OSError):
563574
return ''
564575
return inspect.cleandoc(''.join(['\n'] + lines))
@@ -1432,7 +1443,7 @@ def return_annotation(self, *, link=None) -> str:
14321443
# global variables
14331444
lambda: _get_type_hints(not self.cls and self.module.obj)[self.name],
14341445
# properties
1435-
lambda: inspect.signature(_unwrap_descriptor(self.obj)).return_annotation,
1446+
lambda: inspect.signature(_unwrap_descriptor(self)).return_annotation,
14361447
# Use raw annotation strings in unmatched forward declarations
14371448
lambda: cast(Class, self.cls).obj.__annotations__[self.name],
14381449
# Extract annotation from the docstring for C builtin function

pdoc/html_helpers.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -564,20 +564,21 @@ def format_git_link(template: str, dobj: pdoc.Doc):
564564
try:
565565
if 'commit' in _str_template_fields(template):
566566
commit = _git_head_commit()
567-
abs_path = inspect.getfile(inspect.unwrap(dobj.obj))
567+
obj = pdoc._unwrap_descriptor(dobj)
568+
abs_path = inspect.getfile(inspect.unwrap(obj))
568569
path = _project_relative_path(abs_path)
569570

570571
# Urls should always use / instead of \\
571572
if os.name == 'nt':
572573
path = path.replace('\\', '/')
573574

574-
lines, start_line = inspect.getsourcelines(dobj.obj)
575+
lines, start_line = inspect.getsourcelines(obj)
575576
start_line = start_line or 1 # GH-296
576577
end_line = start_line + len(lines) - 1
577578
url = template.format(**locals())
578579
return url
579580
except Exception:
580-
warn(f'format_git_link for {dobj.obj} failed:\n{traceback.format_exc()}')
581+
warn(f'format_git_link for {obj} failed:\n{traceback.format_exc()}')
581582
return None
582583

583584

0 commit comments

Comments
 (0)