DOC: Fix creation of [source] links in the doc creation
State: closed

See this issue: https://github.com/pandas-dev/pandas/issues/23046

A simple fix is to add `inspect.unwrap(obj)` before `getsourcefile`. This follows the `__wrapped__` attributes of the functions "all the way to the bottom" and then returns the object found.

One problem with this is that `unwrap` function was only introduced in Python 3.4. This means that compiling the documentation will now fail on Python versions older than that. I do not know if this is acceptable.

Labels:
name: Bug
name: Docs
name: CI
description: Continuous Integration

Comments:
Hello @vkk800! Thanks for submitting the PR.

 - There are no PEP8 issues in the file [`doc/source/conf.py`](https://github.com/vkk800/pandas/blob/b67aafd8bb5d9c69bc1dc16592f2767b2dc616bb/doc/source/conf.py) !


# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/23129?src=pr&el=h1) Report
> Merging [#23129](https://codecov.io/gh/pandas-dev/pandas/pull/23129?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/f6e1a0a5eab4b40832b3766831d3e354b10f0ee7?src=pr&el=desc) will **increase** coverage by `0.09%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/23129/graphs/tree.svg?width=650&token=eZ4WkYLtcO&height=150&src=pr)](https://codecov.io/gh/pandas-dev/pandas/pull/23129?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #23129      +/-   ##
==========================================
+ Coverage   92.13%   92.23%   +0.09%     
==========================================
  Files         170      161       -9     
  Lines       51073    51197     +124     
==========================================
+ Hits        47056    47220     +164     
+ Misses       4017     3977      -40
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `90.61% <ø> (+0.05%)` | :arrow_up: |
| #single | `42.27% <ø> (-0.02%)` | :arrow_down: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/23129?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/util/\_depr\_module.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL3V0aWwvX2RlcHJfbW9kdWxlLnB5) | `0% <0%> (-65.12%)` | :arrow_down: |
| [pandas/plotting/\_compat.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL3Bsb3R0aW5nL19jb21wYXQucHk=) | `87.5% <0%> (-3.81%)` | :arrow_down: |
| [pandas/core/dtypes/concat.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZHR5cGVzL2NvbmNhdC5weQ==) | `96.34% <0%> (-1.35%)` | :arrow_down: |
| [pandas/core/indexes/period.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9wZXJpb2QucHk=) | `92.15% <0%> (-1.09%)` | :arrow_down: |
| [pandas/compat/numpy/\_\_init\_\_.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL2NvbXBhdC9udW1weS9fX2luaXRfXy5weQ==) | `92.85% <0%> (-1.09%)` | :arrow_down: |
| [pandas/core/dtypes/common.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZHR5cGVzL2NvbW1vbi5weQ==) | `94.37% <0%> (-0.74%)` | :arrow_down: |
| [pandas/core/arrays/categorical.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvYXJyYXlzL2NhdGVnb3JpY2FsLnB5) | `95.21% <0%> (-0.41%)` | :arrow_down: |
| [pandas/core/dtypes/cast.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZHR5cGVzL2Nhc3QucHk=) | `88.92% <0%> (-0.31%)` | :arrow_down: |
| [pandas/io/common.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2NvbW1vbi5weQ==) | `70.76% <0%> (-0.28%)` | :arrow_down: |
| [pandas/io/formats/format.py](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree#diff-cGFuZGFzL2lvL2Zvcm1hdHMvZm9ybWF0LnB5) | `97.88% <0%> (-0.24%)` | :arrow_down: |
| ... and [106 more](https://codecov.io/gh/pandas-dev/pandas/pull/23129/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/23129?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/23129?src=pr&el=footer). Last update [f6e1a0a...e0cd676](https://codecov.io/gh/pandas-dev/pandas/pull/23129?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

In the CI we're building the documentation in Python 3.6, and in couple of months we'll only support Python 3.5+, so I think it's acceptable.

Could you test the broken links locally?

Btw, unrelated to this PR, in `scripts/validate_docstrings.py` we've got some tricky things to solve the same problem. May be you can take a look and see if they can be simplified with `inspect.unwrap`? We'are probably reinventing the wheel there.
Yes, I tried locally re-compiling the docs and the links were fixed by this change. However, maybe it's better, just to be sure, if someone else also verifies that this patch doesn't break anything before merging since the doc creation scripts are currently not tested at all by the automated tests.

I can also try to take a look at the other file you mentioned. Is there an open issue somewhere describing specifically what the problem is?
@vkk800 there is no problem with the script, it's just that it's possible that we reimplemented `inspect.unwrap` here: https://github.com/pandas-dev/pandas/blob/master/scripts/validate_docstrings.py#L169

As you already worked with that function, I thought it'd be useful if you can take a look, see if that's the case, and if we can delete that method and simply use `inspect.unwrap`, a PR would be great too. No issue, but feel free to create one.
@jorisvandenbossche I think you mmay want to take a look at this PR
For now, we can still call the `unwrap` conditionally on the python version?
> For now, we can still call the `unwrap` conditionally on the python version?

We could do something like `if "unwrap" in dir(inspect)`, but this is a bit ugly (and confusing years from now when no-one remembers why it was originally added). If no-one is compiling the docs with Python older than 3.4, I don't really see the point.

I took a look at the `validate_docstrings` and it looks that `_to_original_callable` could probably be improved by adding `unwrap`, but not removed completely, because `unwrap()` still wouldn't find the functions hidden behind `functools.partial` or class methods as `_to_original_callable` is trying to do. Also, the only thing that `unwrap()` achieves better than using `@functools.wraps` decorator is finding the original source file; docstrings, etc. are handled just fine with `@functools.wraps`.
@datapythonista 
@vkk800 if you can simply add a `if sys.version_info >= (3, 5):` that would be great. For such a small change let's keep the doc building working on Python 2.
thanks @vkk800