Skip to content

Commit

Permalink
Support for listing properties and attributes of classes separately. (#…
Browse files Browse the repository at this point in the history
…1567)

Signed-off-by: Stefan Habel <19556655+StefanHabel@users.noreply.github.com>
  • Loading branch information
StefanHabel committed Oct 31, 2023
1 parent 28fd863 commit 74872ea
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 13 deletions.
64 changes: 51 additions & 13 deletions documents/_templates/autosummary/class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
.. currentmodule:: {{ module }}

.. autoclass:: {{ objname }}
:members:
:show-inheritance:

{% block methods %}
Expand All @@ -12,19 +11,58 @@

.. autosummary::
{% for item in methods %}
{%- if has_member(module, objname, item) %}
~{{ name }}.{{ item }}
{%- endif %}
{%- endfor %}
{% endif %}
{% endblock %}
{%- endif %}
{%- endblock %}

{% block attributes %}
{% if attributes %}
.. rubric:: {{ _('Attributes') }}
{%- block attributes %}
{%- if attributes %}
{# Check whether attributes and/or properties are present #}
{%- set ns = namespace(attributes_present=false, properties_present=false) %}
{%- for item in attributes %}
{# Only consider attributes that are local to the current object #}
{%- if has_member(module, objname, item) %}
{# Consider the current item an attribute if it contains "_" in #}
{# its name, e.g. "INTERFACE_NAME_ATTRIBUTE" #}
{%- if "_" in item %}
{%- set ns.attributes_present = true %}
{%- else %}
{%- set ns.properties_present = true %}
{%- endif %}
{%- endif %}
{%- endfor %}

{% if ns.attributes_present %}
Attributes
----------

{%- for item in attributes %}
{%- if "_" in item and has_member(module, objname, item) %}
.. autoattribute:: {{ module }}.{{ objname }}.{{ item }}

{{ getDocstring(module, objname, item) }}
{%- endif %}

{%- endfor %}
{%- endif %}

{% if ns.properties_present %}
Properties
----------

{%- for item in attributes %}
{%- if has_member(module, objname, item) %}
{%- if not "_" in item %}
.. autoproperty:: {{ module }}.{{ objname }}.{{ item }}
{%- endif %}
{%- endif %}

{%- endfor %}
{%- endif %}

.. autosummary::
{% for item in attributes %}
~{{ name }}.{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}

Expand All @@ -34,10 +72,10 @@
Methods
-------

.. automethod:: __init__
.. autosummary::
{% for item in methods %}
.. automethod:: ~{{ name }}.{{ item }}
{%- if has_member(module, objname, item) %}
.. automethod:: {{ module }}.{{ objname }}.{{ item }}
{%- endif %}
{%- endfor %}
{% endif %}
{% endblock %}
48 changes: 48 additions & 0 deletions documents/sphinx-conf.py.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# For the full list of built-in configuration values, see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

import sphinx.ext.autosummary.generate
import sphinx.util.logging


Expand Down Expand Up @@ -44,6 +45,53 @@ pygments_style = 'monokai'
templates_path = ['${CMAKE_CURRENT_SOURCE_DIR}/_templates']


# Override the `render()` method of the `AutosummaryRenderer` class in order to
# add a custom filter for extracting docstrings of attributes from their
# corresponding properties
_original_render = sphinx.ext.autosummary.generate.AutosummaryRenderer.render


def get_docstring(module_name, class_name, attribute_name):
module = sys.modules.get(module_name)
if module:
class_object = getattr(module, class_name)
if class_object:
attr = getattr(class_object, attribute_name)
if isinstance(attr, str):
prop = class_object.__dict__.get(attribute_name)
if prop:
return prop.__doc__.strip().replace("\n ", "\n ")
for base_class in class_object.__bases__:
prop = base_class.__dict__.get(attribute_name)
if prop:
return "Inherited from `{}`.\n\n {}".format(
base_class.__name__,
prop.__doc__.strip().replace("\n ", "\n "))

return "No docstring available for {}.{}.{}".format(module_name, class_name, attribute_name)


def has_member(module_name, class_name, member_name):
module = sys.modules.get(module_name)
if module:
class_object = getattr(module, class_name)
if class_object:
member = class_object.__dict__.get(member_name)
if member:
return True

return False


def render(self, template_name: str, context: dict) -> str:
self.env.globals['has_member'] = has_member
self.env.globals['getDocstring'] = get_docstring
return _original_render(self, template_name, context)


sphinx.ext.autosummary.generate.AutosummaryRenderer.render = render


# -- Autodoc Configuration ---------------------------------------------------

add_module_names = False
Expand Down

0 comments on commit 74872ea

Please sign in to comment.