diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2019-06-30 12:23:23 -0700 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2019-07-14 11:31:57 -0700 |
commit | d14632c603fc290207e38a10c2d9716ef1567666 (patch) | |
tree | d2515b15426f93e21f44fa2da20ab66b1c7a7e79 /numpy/core/function_base.py | |
parent | 45c4a8dc09ecaff6352a2e17cb242f7ae5ca11a9 (diff) | |
download | numpy-d14632c603fc290207e38a10c2d9716ef1567666.tar.gz |
MAINT: Warn on the use of `_add_newdocs.py` to add docstrings to pure-python objects
This caught the duplication of docstrings between multiarray.py and _add_newdocs
Diffstat (limited to 'numpy/core/function_base.py')
-rw-r--r-- | numpy/core/function_base.py | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/numpy/core/function_base.py b/numpy/core/function_base.py index a316e072f..3964fff53 100644 --- a/numpy/core/function_base.py +++ b/numpy/core/function_base.py @@ -3,6 +3,7 @@ from __future__ import division, absolute_import, print_function import functools import warnings import operator +import types from . import numeric as _nx from .numeric import (result_type, NaN, shares_memory, MAY_SHARE_BOUNDS, @@ -427,15 +428,39 @@ def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0): return result.astype(dtype, copy=False) -#always succeed -def _add_docstring(obj, doc): +def _needs_add_docstring(obj): + """ + Returns true if the only way to set the docstring of `obj` from python is + via add_docstring. + + This function errs on the side of being overly conservative. + """ + Py_TPFLAGS_HEAPTYPE = 1 << 9 + + if isinstance(obj, (types.FunctionType, types.MethodType, property)): + return False + + if isinstance(obj, type) and obj.__flags__ & Py_TPFLAGS_HEAPTYPE: + return False + + return True + + +def _add_docstring(obj, doc, warn_on_python): + if warn_on_python and not _needs_add_docstring(obj): + warnings.warn( + "add_newdoc was used on a pure-python object {}. " + "Prefer to attach it directly to the source." + .format(obj), + UserWarning, + stacklevel=3) try: add_docstring(obj, doc) except Exception: pass -def add_newdoc(place, obj, doc): +def add_newdoc(place, obj, doc, warn_on_python=True): """ Add documentation to an existing object, typically one defined in C @@ -457,6 +482,9 @@ def add_newdoc(place, obj, doc): If a list, then each element of the list should be a tuple of length two - ``[(method1, docstring1), (method2, docstring2), ...]`` + warn_on_python : bool + If True, the default, emit `UserWarning` if this is used to attach + documentation to a pure-python object. Notes ----- @@ -480,10 +508,10 @@ def add_newdoc(place, obj, doc): """ new = getattr(__import__(place, globals(), {}, [obj]), obj) if isinstance(doc, str): - _add_docstring(new, doc.strip()) + _add_docstring(new, doc.strip(), warn_on_python) elif isinstance(doc, tuple): attr, docstring = doc - _add_docstring(getattr(new, attr), docstring.strip()) + _add_docstring(getattr(new, attr), docstring.strip(), warn_on_python) elif isinstance(doc, list): for attr, docstring in doc: - _add_docstring(getattr(new, attr), docstring.strip()) + _add_docstring(getattr(new, attr), docstring.strip(), warn_on_python) |