{"id":16519201,"url":"https://github.com/rsokl/custom_inherit","last_synced_at":"2025-10-24T02:55:39.501Z","repository":{"id":9886051,"uuid":"63664805","full_name":"rsokl/custom_inherit","owner":"rsokl","description":"A Python package that provides tools for inheriting docstrings in customizable ways.","archived":false,"fork":false,"pushed_at":"2023-12-27T14:28:19.000Z","size":177,"stargazers_count":63,"open_issues_count":8,"forks_count":14,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-10T01:08:55.039Z","etag":null,"topics":["decorator","docstring-inheritance","documentation-tool","inheritance-styles","metaclass","numpy-styled-docstrings","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rsokl.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-19T05:52:12.000Z","updated_at":"2025-02-01T18:54:44.000Z","dependencies_parsed_at":"2024-06-18T18:25:29.844Z","dependency_job_id":"f011deca-f83b-4b7b-a93e-f85b48d65049","html_url":"https://github.com/rsokl/custom_inherit","commit_stats":{"total_commits":175,"total_committers":10,"mean_commits":17.5,"dds":"0.26857142857142857","last_synced_commit":"173650fcf30b5927e89659ec70f5466f4054fb9d"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsokl%2Fcustom_inherit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsokl%2Fcustom_inherit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsokl%2Fcustom_inherit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rsokl%2Fcustom_inherit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rsokl","download_url":"https://codeload.github.com/rsokl/custom_inherit/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137887,"owners_count":21053775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decorator","docstring-inheritance","documentation-tool","inheritance-styles","metaclass","numpy-styled-docstrings","python"],"created_at":"2024-10-11T16:45:46.487Z","updated_at":"2025-10-24T02:55:34.455Z","avatar_url":"https://github.com/rsokl.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# custom_inherit\n\n[![Automated tests status](https://github.com/rsokl/custom_inherit/workflows/Tests/badge.svg)](https://github.com/rsokl/custom_inherit/actions?query=workflow%3ATests+branch%3Amaster)\n[![PyPi version](https://img.shields.io/pypi/v/custom_inherit.svg)](https://pypi.python.org/pypi/custom_inherit)\n [![Conda Version](https://img.shields.io/conda/vn/conda-forge/custom-inherit.svg)](https://anaconda.org/conda-forge/custom-inherit)\n[![Python version support](https://img.shields.io/badge/python-2.7,%20%20%203.4%20%20%20--%203.11-blue.svg)](https://img.shields.io/pypi/v/custom_inherit.svg)\n\n## Contents\n- [custom\\_inherit](#custom_inherit)\n  - [Contents](#contents)\n  - [Overview](#overview)\n    - [Features](#features)\n    - [Implementation Notes](#implementation-notes)\n    - [Projects That Use `custom_inherit`](#projects-that-use-custom_inherit)\n  - [Basic Usage](#basic-usage)\n    - [Inheriting Docstrings Using a Metaclass](#inheriting-docstrings-using-a-metaclass)\n    - [Inheriting Docstrings Using a Decorator](#inheriting-docstrings-using-a-decorator)\n  - [Advanced Usage](#advanced-usage)\n  - [Built-in Styles](#built-in-styles)\n  - [Making New Inheritance Styles](#making-new-inheritance-styles)\n  - [Installation and Getting Started](#installation-and-getting-started)\n  - [Documentation](#documentation)\n    - [Go Back To:](#go-back-to)\n\n## Overview\nThe Python package `custom_inherit` provides convenient, light-weight tools for inheriting docstrings in customizeable ways.\n\n### Features\n- A metaclass that instructs children to inherit docstrings for their attributes from their parents, using custom docstring inheritance styles. This works for all varieties of methods (instance, static, class) and properties, including abstract ones.\n- A decorator that merges a string/docstring with the docstring of the decorated object using custom styles. This can decorate functions as well as all varieties of class attributes.\n- Built-in docstring merging styles for popular docstring specifications:\n    - [NumPy docstring specification](https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt#docstring-standard)\n    - [Napoleon docstring specifications](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/index.html#id1) (for both [Google](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html#example-google-style-python-docstrings) and [NumPy](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html#example-numpy) styles)\n    - Merging based on [reST sections](http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#sections)\n    - Simple inheritance from a parent, if the docstring is not overwritten ([deprecated in Python 3.5](https://docs.python.org/3/library/inspect.html#inspect.getdoc))\n- A simple interface for using your own docstring inheritance style.\n\n### Implementation Notes\n- These tools are compatible with [Sphinx](http://www.sphinx-doc.org/en/1.5.1/) - the inherited docstrings will be rendered by this package.\n- These tools do not obfuscate function signatures or error traceback messages, nor do they affect performance beyond the initial construction process.\n- No dependencies.\n\n### Projects That Use `custom_inherit`\n- [Toyplot](https://toyplot.readthedocs.io/en/stable/)\n- [p2p-project](https://github.com/p2p-today/p2p-project)\n- [Data Driven Discovery](https://gitlab.com/datadrivendiscovery)\n\n## Basic Usage\n### Inheriting Docstrings Using a Metaclass\n`custom_inherit` exposes a  [metaclass](https://docs.python.org/3/reference/datamodel.html#customizing-class-creation), `DocInheritMeta()`, that, when derived from by a class, will automatically mediate docstring inheritance for all subsequent derived classes of that parent. Thus a child's attributes (methods, classmethods, staticmethods, properties, and their abstract counterparts) will inherit documentation from its parent's attribute, and the resulting docstring is synthesized according to a customizable style.\n\nThe style of the inheritance scheme can be specified explicitly when passing `DocInheritMeta` its arguments. Here is a simple usage example using the built-in \"numpy\" style of inheritance:\n\n```python\nfrom custom_inherit import DocInheritMeta\n\nclass Parent(metaclass=DocInheritMeta(style=\"numpy\")):\n   def meth(self, x, y=None):\n       \"\"\" Parameters\n           ----------\n           x: int\n              blah-x\n\n           y: Optional[int]\n              blah-y\n\n           Raises\n           ------\n           NotImplementedError\"\"\"\n       raise NotImplementedError\n\nclass Child(Parent):\n    def meth(self, x, y=None):\n        \"\"\" Method description\n\n            Returns\n            -------\n            int\n\n            Notes\n            -----\n            Some notes here.\"\"\"\n        return 0\n```\n\nBecause we specified `style=\"numpy\"` in `DocInheritMeta`, the inherited docstring of `Child.meth` will be:\n\n```python\n  \"\"\" Method description\n\n      Parameters\n      ----------\n      x: int\n         blah-x\n\n      y: Optional[int]\n         blah-y\n\n      Returns\n      -------\n      int\n\n      Notes\n      -----\n      Some notes here.\"\"\"\n```\n(note the special case where the \"Raises\" section of the parent's method is left out, because the child\n class implements a \"Returns\" section instead. Jump [ahead](#builtin) for a detailed description\n of the \"numpy\" style)\n\nKeep in mind that the syntax for deriving from a meta class is slightly different in Python 2:\n\n```python\nfrom custom_inherit import DocInheritMeta\n\nclass Parent(object):\n   __metaclass__ = DocInheritMeta(style=\"numpy\")\n   ...\n```\n\n### Inheriting Docstrings Using a Decorator\n`custom_inherit` also exposes a decorator capable of mediating docstring inheritance on an individual function (or property, method, etc.) level. In this example, we provide our own custom inheritance style-function on the fly (rather than using a built-in style):\n\n```python\nfrom custom_inherit import doc_inherit\n\ndef my_style(prnt_doc, child_doc): return \"\\n-----\".join([prnt_doc, child_doc])\n\ndef parent():  # parent can be any object with a docstring, or simply a string itself\n   \"\"\" docstring to inherit from\"\"\"\n\n@doc_inherit(parent, style=my_style)\ndef child():\n   \"\"\" docstring to inherit into\"\"\"\n```\n\nGiven the customized (albeit stupid) inheritance style specified in this example, the inherited docsting of `child`, in this instance, will be:\n\n```python\n\"\"\"docstring to inherit from\n  -----\n  docstring to inherit into\"\"\"\n```\n\n## Advanced Usage\nA very natural, but more advanced use case for docstring inheritance is to define an [abstract base class](https://docs.python.org/3/library/abc.html#abc.ABCMeta) that has detailed docstrings for its abstract methods/properties. This class can be passed `DocInheritMeta(abstract_base_class=True)`, and it will have inherited from [abc.ABCMeta](https://docs.python.org/3/library/abc.html#abc.ABCMeta), plus all of its derived classes will inherit the docstrings for the methods/properties that they implement:\n\n```python\n# Parent is now an abstract base class\nclass Parent(metaclass=DocInheritMeta(style=\"numpy\", abstract_base_class=True)):\n   ...\n```\n\nFor the \"numpy\", \"google\", and \"napoleon_numpy\" inheritance styles, one then only needs to specify the \"Returns\" or \"Yields\" section in the derived class' attribute docstring for it to have a fully-detailed docstring.\n\nAnother option is to be able to decide whether to include all special methods, meaning methods that start and\nend by \"__\" such as \"__init__\" method, or not in the doctstring inheritance process. Such an option can be pass\nto the `DocInheritMeta` metaclass constructor:\n\n```python\n# Each child class will also merge the special methods' docstring of its parent class\nclass Parent(metaclass=DocInheritMeta(style=\"numpy\", include_special_methods=True)):\n   ...\n```\n\nSpecial methods are not included by default.\n\n## Built-in Styles\n\nUtilize a built-in style by specifying any of the following names (as a string), wherever the `style` parameter is to be specified. The built-in styles are:\n\n- `\"parent\"`: Wherever the docstring for a child-class' attribute (or for the class itself) is\n\t`None`, inherit the corresponding docstring from the parent. (Deprecated in Python 3.5)\n\n- `\"numpy\"`: [NumPy-styled docstrings](https://github.com/numpy/numpy/blob/master/doc/HOWTO_DOCUMENT.rst.txt#docstring-standard)\n        from the parent and child are merged gracefully with nice formatting. The child's docstring sections take precedence\n\tin the case of overlap.\n\n- `\"numpy_with_merge\"`: Behaves identically to the \"numpy\" style, but also merges - with de-duplication - sections that overlap,\n    instead of only keeping the child's section. The sections that are merged are \"Attributes\", \"Parameters\",\n    \"Methods\", \"Other Parameters\", and \"Keyword Arguments\".\n\n- `\"google\"`: Google-styled docstrings from the parent and child are merged gracefully\n\twith nice formatting. The child's docstring sections take precedence in the case of overlap.\n\tThis adheres to the [napoleon specification for the Google style](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html#example-google-style-python-docstrings).\n\n- `\"google_with_merge\"`: Behaves identically to the \"google\" style, but also merges - with de-duplication - sections that overlap,\n    instead of only keeping the child's section. The sections that are merged are \"Attributes\", \"Parameters\",\n    \"Methods\", \"Other Parameters\", and \"Keyword Arguments\" (or their [aliases](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/index.html#docstring-sections)).\n\n- `\"numpy_napoleon\"`: NumPy-styled docstrings from the parent and child are merged gracefully\n\twith nice formatting. The child's docstring sections take precedence in the case of overlap.\n\tThis adheres to the [napoleon specification for the NumPy style](http://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_numpy.html#example-numpy).\n\n- `\"numpy_napoleon_with_merge\"`: Behaves identically to the 'numpy_napoleon' style, but also merges - with de-duplication - sections\n    that overlap, instead of only keeping the child's section. The sections that are merged are \"Attributes\", \"Parameters\",\n    \"Methods\", \"Other Parameters\", and \"Keyword Arguments\" (or their [aliases](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/index.html#docstring-sections)).\n\n- `\"reST\"`: reST-styled docstrings from the parent and child are merged gracefully\n\twith nice formatting. Docstring sections are specified by\n\t[reST section titles](http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#sections).\n\tThe child's docstring sections take precedence in the case of overlap.\n\nFor the `numpy`, `numpy_with_merge`, `numpy_napoleon`, `numpy_napoleon_with_merge`, `google` and `google_with_merge` styles, if the parent's docstring contains a \"Raises\" section and the child's docstring implements a \"Returns\" or a \"Yields\" section instead, then the \"Raises\" section is not included in the resulting docstring. This is to accomodate for the relatively common use case in which an abstract method/property raises `NotImplementedError`. Child classes that implement this method/property clearly will not raise this. Of course, any \"Raises\" section that is explicitly included in the child's docstring will appear in the resulting docstring.\n\nDetailed documentation and example cases for the default styles can be found [here](https://github.com/rsokl/custom_inherit/blob/master/src/custom_inherit/_style_store.py)\n\n## Making New Inheritance Styles\nImplementing your inheritance style is simple.\n\n- Provide an inheritance style on the fly wherever a style parameter is specified:\n    - Supply any function of the form: `func(prnt_doc: str, child_doc: str) -\u003e str`\n\n- Log an inheritance style, and refer to it by name wherever a style parameter is specified, using either:\n    - `custom_inherit.store[\"my_style\"] = func`\n    - `custom_inherit.add_style(\"my_style\", func)`.\n\n## Installation and Getting Started\nInstall via pip:\n\n```\n    pip install custom_inherit\n```\nInstall via conda:\n\n```\n    conda install -c conda-forge custom-inherit\n```\n\nor\n\nDownload/clone this repository, go to its directory, and install custom_inherit by typing in your command line:\n\n```\n    python setup.py install\n```\n\nIf, instead, you want to install the package with links, so that edits you make to the code take\neffect immediately within your installed version of custom_inherit, type:\n\n```\n    python setup.py develop\n```\n\nand then get started with\n\n```python\nfrom custom_inherit import DocInheritMeta, doc_inherit, store\n# print(store) shows you the available styles\n```\n\n## Documentation\nDocumentation is available via `help(custom_inherit)`.\n\n```python\ncustom_inherit.DocInheritMeta(style=\"parent\", abstract_base_class=False):\n    \"\"\" A metaclass that merges the respective docstrings of a parent class and of its child, along with their\n        properties, methods (including classmethod, staticmethod, decorated methods).\n\n        Parameters\n        ----------\n        style: Union[Hashable, Callable[[str, str], str]], optional (default: \"parent\")\n            A valid inheritance-scheme style ID or function that merges two docstrings.\n\n        abstract_base_class: bool, optional(default: False)\n            If True, the returned metaclass inherits from abc.ABCMeta.\n\n            Thus a class that derives from DocInheritMeta(style=\"numpy\", abstract_base_class=True)\n            will be an abstract base class, whose derived classes will inherit docstrings\n            using the numpy-style inheritance scheme.\n\n\n        Returns\n        -------\n        custom_inherit.DocInheritorBase\"\"\"\n\n\ncustom_inherit.doc_inherit(parent, style=\"parent\"):\n    \"\"\" Returns a function/method decorator that, given `parent`, updates the docstring of the decorated\n        function/method based on the specified style and the corresponding attribute of `parent`.\n\n        Parameters\n        ----------\n        parent : Union[str, Any]\n            The object whose docstring, is utilized as the parent docstring\n\t    during the docstring merge. Or, a string can be provided directly.\n\n        style : Union[Hashable, Callable[[str, str], str]], optional (default: \"parent\")\n            A valid inheritance-scheme style ID or function that merges two docstrings.\n\n        Returns\n        -------\n        custom_inherit.DocInheritDecorator\n\n\n        Notes\n        -----\n        `doc_inherit` should always be the inner-most decorator when being used in\n        conjunction with other decorators, such as `@property`, `@staticmethod`, etc.\"\"\"\n\n\ncustom_inherit.remove_style(style):\n    \"\"\" Remove the specified style from the style store.\n\n        Parameters\n        ----------\n        style: Hashable\n            The inheritance-scheme style ID to be removed.\"\"\"\n\n\ncustom_inherit.add_style(style_name, style_func):\n    \"\"\" Make available a new function for merging a 'parent' and 'child' docstring.\n\n        Parameters\n        ----------\n        style_name : Hashable\n            The identifier of the style being logged\n        style_func: Callable[[Optional[str], Optional[str]], Optional[str]]\n            The style function that merges two docstrings into a single docstring.\"\"\"\n```\n\n### Go Back To:\n - [Overview](#overview)\n - [Basic Usage](#basic)\n - [Advanced Usage](#advanced)\n - [Built-in Styles](#builtin)\n - [Making New inheritance Styles](#new)\n - [Installation \u0026 Getting Started](#install)\n - [Documentation](#doc)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsokl%2Fcustom_inherit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frsokl%2Fcustom_inherit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frsokl%2Fcustom_inherit/lists"}