Source code for attr_utils.docstrings

#!/usr/bin/env python
#
#  docstrings.py
"""
Add better docstrings to attrs_ generated functions.

.. _attrs: https://www.attrs.org/en/stable/
"""
#
#  Copyright © 2020-2021 Dominic Davis-Foster <dominic@davis-foster.co.uk>
#
#  Permission is hereby granted, free of charge, to any person obtaining a copy
#  of this software and associated documentation files (the "Software"), to deal
#  in the Software without restriction, including without limitation the rights
#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#  copies of the Software, and to permit persons to whom the Software is
#  furnished to do so, subject to the following conditions:
#
#  The above copyright notice and this permission notice shall be included in all
#  copies or substantial portions of the Software.
#
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
#  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
#  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
#  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
#  OR OTHER DEALINGS IN THE SOFTWARE.
#

# stdlib
import re
import sys
from types import MethodType
from typing import Optional, Pattern, Type, TypeVar

# 3rd party
from domdf_python_tools.compat import PYPY
from domdf_python_tools.doctools import base_new_docstrings, prettify_docstrings
from domdf_python_tools.typing import MethodDescriptorType, MethodWrapperType, WrapperDescriptorType

__all__ = ["add_attrs_doc", "_T"]

attrs_docstring = "Automatically created by attrs."
ne_default = "Check equality and either forward a NotImplemented or return the result\n    negated."
attrs_20_1_docstring: Pattern = re.compile(r"^\s*Method generated by attrs for class .*\.\s*")
repr_doc_template = "Return a string representation of the :class:`~.{name}`."
pickle_state_template = "Used for `pickling <https://docs.python.org/3/library/pickle.html>`_.\n\n{doc}"

_T = TypeVar("_T", bound=Type)


[docs]def add_attrs_doc(obj: _T) -> _T: """ Add better docstrings to attrs generated functions. :param obj: The class to improve the docstrings for. """ obj = prettify_docstrings(obj) new_docstrings = { **base_new_docstrings, "__repr__": repr_doc_template.format(name=obj.__name__), "__setstate__": pickle_state_template.format(doc=attrs_docstring), "__getstate__": pickle_state_template.format(doc=attrs_docstring), } if hasattr(obj, "__ne__"): if PYPY or not isinstance(obj.__ne__, (WrapperDescriptorType, MethodDescriptorType, MethodWrapperType)): if obj.__ne__.__doc__ is None or obj.__ne__.__doc__.strip() in {object.__ne__.__doc__, ne_default}: obj.__ne__.__doc__ = new_docstrings["__ne__"] if hasattr(obj, "__repr__"): if ( obj.__repr__.__doc__ is None or obj.__repr__.__doc__.strip() == attrs_docstring or attrs_20_1_docstring.match(obj.__repr__.__doc__) ): _new_doc = f"{new_docstrings['__repr__']}" # \n\n{attrs_docstring} obj.__repr__.__doc__ = _new_doc # prevents strange formatting in pycharm for attr_name in new_docstrings: if not hasattr(obj, attr_name): continue attribute = getattr(obj, attr_name) if not PYPY and isinstance( attribute, (WrapperDescriptorType, MethodDescriptorType, MethodWrapperType, MethodType), ): continue # pragma: no cover (!PyPy) elif PYPY and isinstance(attribute, MethodType): continue # pragma: no cover elif PYPY and sys.version_info >= (3, 7): # pragma: no cover (not (PyPy and py37+)) if attribute is getattr(object, attr_name, None): continue elif attribute is getattr(float, attr_name, None): continue elif attribute is getattr(str, attr_name, None): continue if attribute is None: continue doc: Optional[str] = attribute.__doc__ if doc is None or doc.strip() == attrs_docstring or attrs_20_1_docstring.match(doc): _new_doc = f"{new_docstrings[attr_name]}" # \n\n{attrs_docstring} attribute.__doc__ = _new_doc # prevents strange formatting in pycharm return obj