diff --git a/numpydoc/docscrape.py b/numpydoc/docscrape.py index 3c7017bc..a38bc1e7 100644 --- a/numpydoc/docscrape.py +++ b/numpydoc/docscrape.py @@ -124,10 +124,11 @@ class NumpyDocString(collections.Mapping): 'index': {} } - def __init__(self, docstring, config={}): + def __init__(self, docstring, config={}, obj_info=(None, None)): orig_docstring = docstring docstring = textwrap.dedent(docstring).split('\n') + self._module, self._name = obj_info self._doc = Reader(docstring) self._parsed_data = copy.deepcopy(self.sections) @@ -337,9 +338,8 @@ def _parse(self): section = (s.capitalize() for s in section.split(' ')) section = ' '.join(section) if self.get(section): - self._error_location("The section %s appears twice" - % section) - + self._error_location("The section {} appears twice" + .format(section)) if section in ('Parameters', 'Returns', 'Yields', 'Raises', 'Warns', 'Other Parameters', 'Attributes', 'Methods'): @@ -352,14 +352,8 @@ def _parse(self): self[section] = content def _error_location(self, msg, error=True): - if hasattr(self, '_obj'): - # we know where the docs came from: - try: - filename = inspect.getsourcefile(self._obj) - except TypeError: - filename = None - msg = msg + (" in the docstring of %s in %s." - % (self._obj, filename)) + msg = msg + (" in the docstring of {} in {}." + .format(self._name, self._module)) if error: raise ValueError(msg) else: @@ -487,7 +481,7 @@ def header(text, style='-'): class FunctionDoc(NumpyDocString): - def __init__(self, func, role='func', doc=None, config={}): + def __init__(self, func, role='func', doc=None, config={}, funcname=''): self._f = func self._role = role # e.g. "func" or "meth" @@ -495,7 +489,10 @@ def __init__(self, func, role='func', doc=None, config={}): if func is None: raise ValueError("No function or docstring given") doc = inspect.getdoc(func) or '' - NumpyDocString.__init__(self, doc) + + module = getattr(func, '__module__', None) + qualname = getattr(func, '__qualname__', funcname) + NumpyDocString.__init__(self, doc, obj_info=(module, qualname)) if not self['Signature'] and func is not None: func, func_name = self.get_func() @@ -563,7 +560,9 @@ def __init__(self, cls, doc=None, modulename='', func_doc=FunctionDoc, raise ValueError("No class or documentation string given") doc = pydoc.getdoc(cls) - NumpyDocString.__init__(self, doc) + module = getattr(cls, '__module__', None) + qualname = getattr(cls, '__qualname__', modulename) + NumpyDocString.__init__(self, doc, obj_info=(module, qualname)) if config.get('show_class_members', True): def splitlines_x(s): diff --git a/numpydoc/docscrape_sphinx.py b/numpydoc/docscrape_sphinx.py index a555ed06..4c29f564 100644 --- a/numpydoc/docscrape_sphinx.py +++ b/numpydoc/docscrape_sphinx.py @@ -22,8 +22,9 @@ class SphinxDocString(NumpyDocString): - def __init__(self, docstring, config={}): - NumpyDocString.__init__(self, docstring, config=config) + def __init__(self, docstring, config={}, obj_info=(None, None)): + NumpyDocString.__init__(self, docstring, config=config, + obj_info=obj_info) self.load_config(config) def load_config(self, config): @@ -376,25 +377,30 @@ def __str__(self, indent=0, func_role="obj"): class SphinxFunctionDoc(SphinxDocString, FunctionDoc): - def __init__(self, obj, doc=None, config={}): + def __init__(self, obj, doc=None, config={}, name=''): self.load_config(config) - FunctionDoc.__init__(self, obj, doc=doc, config=config) + FunctionDoc.__init__(self, obj, doc=doc, config=config, + funcname=name) class SphinxClassDoc(SphinxDocString, ClassDoc): - def __init__(self, obj, doc=None, func_doc=None, config={}): + def __init__(self, obj, doc=None, func_doc=None, config={}, name=''): self.load_config(config) - ClassDoc.__init__(self, obj, doc=doc, func_doc=None, config=config) + ClassDoc.__init__(self, obj, doc=doc, func_doc=func_doc, config=config, + modulename=name) class SphinxObjDoc(SphinxDocString): - def __init__(self, obj, doc=None, config={}): + def __init__(self, obj, doc=None, config={}, name=''): self._f = obj self.load_config(config) - SphinxDocString.__init__(self, doc, config=config) + module = getattr(obj, '__module__', None) + qualname = getattr(obj, '__qualname__', name) + SphinxDocString.__init__(self, doc, config=config, + obj_info=(module, qualname)) -def get_doc_object(obj, what=None, doc=None, config={}, builder=None): +def get_doc_object(obj, what=None, doc=None, config={}, builder=None, name=None): if what is None: if inspect.isclass(obj): what = 'class' @@ -416,10 +422,10 @@ def get_doc_object(obj, what=None, doc=None, config={}, builder=None): if what == 'class': return SphinxClassDoc(obj, func_doc=SphinxFunctionDoc, doc=doc, - config=config) + config=config, name=name) elif what in ('function', 'method'): - return SphinxFunctionDoc(obj, doc=doc, config=config) + return SphinxFunctionDoc(obj, doc=doc, config=config, name=name) else: if doc is None: doc = pydoc.getdoc(obj) - return SphinxObjDoc(obj, doc, config=config) + return SphinxObjDoc(obj, doc, config=config, name=name) diff --git a/numpydoc/numpydoc.py b/numpydoc/numpydoc.py index 7deecc55..9d718794 100644 --- a/numpydoc/numpydoc.py +++ b/numpydoc/numpydoc.py @@ -78,7 +78,7 @@ def mangle_docstrings(app, what, name, obj, options, lines): lines[:] = title_re.sub(sixu(''), u_NL.join(lines)).split(u_NL) else: doc = get_doc_object(obj, what, u_NL.join(lines), config=cfg, - builder=app.builder) + builder=app.builder, name=name) if sys.version_info[0] >= 3: doc = str(doc) else: @@ -113,7 +113,10 @@ def mangle_signature(app, what, name, obj, options, sig, retann): if not hasattr(obj, '__doc__'): return - doc = SphinxDocString(pydoc.getdoc(obj)) + + module = getattr(obj, '__module__', None) + qualname = getattr(obj, '__qualname__', name) + doc = SphinxDocString(pydoc.getdoc(obj), obj_info=(module, qualname)) sig = doc['Signature'] or getattr(obj, '__text_signature__', None) if sig: sig = re.sub(sixu("^[^(]*"), sixu(""), sig)