Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork10.9k
Description
Describe the issue:
Any class decorated using the the decoratorset_module('to_this_module')
, defined onnumpy/_utils/__init__.py
, is pointing the location of it's source code in the wrong place in externally generated docs. This error affects the automatically generated link appearing as a[source]
, in the function header in the documentation web site, and also in theFile:
attribute appearing in the footer of the helper shown by the IPython magic helper operator?
.
As an example, consider the poly1d class definition, which is located on filenumpy/lib/_polynomial_impl.py
, an screenshot of the documentation is shown below indicating that the code is located at `numpy/init.py
The same error appears while calling the? np.poly1d
helper on IPython, which results in
Init signature: np.poly1d(c_or_r, r=False, variable=None)Docstring: ... (omited)File: ~/mycode/numpy-aureliobarbosa/numpy-dev/lib/python3.12/site-packages/numpy/__init__.pyType: typeSubclasses:
This error currently affects at least 25 classes, which can be tracked in the repository with the regex@set_module\(['"].*?['"]\)\nclass
(I used VSCode for that). The full list of affected classes will complement this message. This problem doen't affect functions decorated with set_module as will become clear in the following
After some investigation I found that external tools (numpydoc
?,IPython
) automatically searching for where the source code of a certain object is located rely on the stdlib functioninpect.getfile(object)
(or another function on the module inspect which will call getfile) to recover theactual location of the code in the directory tree. This function is simple and it's code can be foundhere, and in the case of classes, it end up calling the following code:
module=sys.modules.get(object.__module__)ifgetattr(module,'__file__',None):returnmodule.__file__
which will return the__init__.py
file of the module passed using@set_module('module')
, since this decorator dynamically changes the the property__module__
of a class or a function. Using@set_module('module')
to decorate functions doesn't harm documentation because when callinginspect.getfile(object)
, whenobject
is a function, returnsobject.__code__.co_filename
, which wasn't affected by the set_module decorator.
My original intention was to try to fix the documentation but it turned it out that the problem is originating in the decorator@set_module
which, in my opinion, is breaking a contract that is commonly expected by other tools operating on a property of classes, as it also affects the behavior ofIPython
.
It should be possible to fix the online documentation (maybe changingnumpydoc
?) but the problem would continue to exist in any tool which automatically try to locate the source code of those classes in astandard
way. In order to fix this documentation/code issue a decision a decision should be made concerning the usage of the decorator@set_module
.
Although using numpy for some time, I am still new on its codebase, if someone can give me a hint on the reasons for using@set_module
it would help to implement a fix. Anyway, hope the current investigation helps when searching for a solution to this issue.
Regards
Reproduce the code example:
importsysimportnumpyasnpobject=np.poly1dmodule=sys.modules.get(object.__module__)print(module.__file__)# should be expecting '<codebase>/numpy/lib/_polynomial_impl.py'
Error message:
Python and NumPy Versions:
Python: 3.12.8
NumPy: 2.2.4
IPython: 9.0.4
Runtime Environment:
No response
Context for the issue:
No response