Thanks to visit codestin.com
Credit goes to github.com

Skip to content

MAINT: Warn if _add_newdocs.py is used to add docstrings to pure-python objects #13935

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 14, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 34 additions & 6 deletions numpy/core/function_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import functools
import warnings
import operator
import types

from . import numeric as _nx
from .numeric import (result_type, NaN, shares_memory, MAY_SHARE_BOUNDS,
Expand Down Expand Up @@ -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):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tests are complaining about the stack level of the warning.

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

Expand All @@ -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
-----
Expand All @@ -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)