Skip to content
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

Updated "Use __dict__ and ignore __slots__ on classes #169 #181

Merged
merged 8 commits into from Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.rst
Expand Up @@ -4,6 +4,8 @@ Changes in sphinx-automodapi
0.17.0 (unreleased)
-------------------

- Fixes fixes issue where ``__slots__`` hides class variables [#168]
kylefawcett marked this conversation as resolved.
Show resolved Hide resolved

- Minimum supported Python version is now 3.8. [#177]

0.16.0 (2023-08-17)
Expand Down
19 changes: 2 additions & 17 deletions sphinx_automodapi/automodsumm.py
Expand Up @@ -83,7 +83,6 @@ class members that are inherited from a base class. This value can be
.. _sphinx.ext.inheritance_diagram: http://sphinx-doc.org/latest/ext/inheritance.html
"""

import abc
import inspect
import os
import re
Expand Down Expand Up @@ -555,25 +554,11 @@ def get_members_class(obj, typ, include_public=[],
items = []

# using dir gets all of the attributes, including the elements
# from the base class, otherwise use __slots__ or __dict__
# from the base class, otherwise use __dict__
if include_base:
names = dir(obj)
else:
# Classes deriving from an ABC using the `abc` module will
# have an empty `__slots__` attribute in Python 3, unless
# other slots were declared along the inheritance chain. If
# the ABC-derived class has empty slots, we'll use the
# class `__dict__` instead.
declares_slots = (
hasattr(obj, '__slots__') and
not (issubclass(type(obj), abc.ABCMeta) and
len(obj.__slots__) == 0)
)

if declares_slots:
names = tuple(getattr(obj, '__slots__'))
else:
names = getattr(obj, '__dict__').keys()
names = getattr(obj, '__dict__').keys()

for name in names:
try:
Expand Down
1 change: 1 addition & 0 deletions sphinx_automodapi/tests/cases/slots/README.md
@@ -0,0 +1 @@
Test classes that put attributes in `__slots__`.
1 change: 1 addition & 0 deletions sphinx_automodapi/tests/cases/slots/input/index.rst
@@ -0,0 +1 @@
.. automodapi:: sphinx_automodapi.tests.example_module.slots
@@ -0,0 +1,17 @@
DerivedParam
============

.. currentmodule:: sphinx_automodapi.tests.example_module.slots

.. autoclass:: DerivedParam
:show-inheritance:

.. rubric:: Methods Summary

.. autosummary::

~DerivedParam.derived_from_slot_class_method

.. rubric:: Methods Documentation

.. automethod:: derived_from_slot_class_method
@@ -0,0 +1,27 @@
DerivedSlotParam
================

.. currentmodule:: sphinx_automodapi.tests.example_module.slots

.. autoclass:: DerivedSlotParam
:show-inheritance:

.. rubric:: Attributes Summary

.. autosummary::

~DerivedSlotParam.extra_param

.. rubric:: Methods Summary

.. autosummary::

~DerivedSlotParam.derived_from_slot_class_method

.. rubric:: Attributes Documentation

.. autoattribute:: extra_param

.. rubric:: Methods Documentation

.. automethod:: derived_from_slot_class_method
@@ -0,0 +1,27 @@
SlotDict
========

.. currentmodule:: sphinx_automodapi.tests.example_module.slots

.. autoclass:: SlotDict
:show-inheritance:

.. rubric:: Attributes Summary

.. autosummary::

~SlotDict.param

.. rubric:: Methods Summary

.. autosummary::

~SlotDict.my_method

.. rubric:: Attributes Documentation

.. autoattribute:: param

.. rubric:: Methods Documentation

.. automethod:: my_method
19 changes: 19 additions & 0 deletions sphinx_automodapi/tests/cases/slots/output/index.rst.automodapi
@@ -0,0 +1,19 @@

sphinx_automodapi.tests.example_module.slots Module
---------------------------------------------------

.. automodule:: sphinx_automodapi.tests.example_module.slots

Classes
^^^^^^^

.. automodsumm:: sphinx_automodapi.tests.example_module.slots
:classes-only:
:toctree: api

Class Inheritance Diagram
^^^^^^^^^^^^^^^^^^^^^^^^^

.. automod-diagram:: sphinx_automodapi.tests.example_module.slots
:private-bases:
:parts: 1
@@ -0,0 +1,8 @@
.. currentmodule:: sphinx_automodapi.tests.example_module.slots

.. autosummary::
:toctree: api

SlotDict
DerivedParam
DerivedSlotParam
91 changes: 91 additions & 0 deletions sphinx_automodapi/tests/example_module/slots.py
@@ -0,0 +1,91 @@
"""Test classes containing slots"""
from __future__ import annotations

__all__ = ['SlotDict', 'DerivedParam', 'DerivedSlotParam',]


class SlotDict(object):
"""
A class that uses __slots__ and __dict__ for its attribute namespace.
"""
__slots__ = ('param', '__dict__',)

def __init__(self, param: str, other_param: str):
"""
Initializes a SlotDict object.

Parameters
----------
my_param : str
My parameter
"""
self.param = param
self.other_param = other_param

Check warning on line 23 in sphinx_automodapi/tests/example_module/slots.py

View check run for this annotation

Codecov / codecov/patch

sphinx_automodapi/tests/example_module/slots.py#L22-L23

Added lines #L22 - L23 were not covered by tests

def my_method(self):
"""
Prints the class's parameters.
"""
print(f"param: {self.param}")
print(f"other_param: {self.other_param}")

Check warning on line 30 in sphinx_automodapi/tests/example_module/slots.py

View check run for this annotation

Codecov / codecov/patch

sphinx_automodapi/tests/example_module/slots.py#L29-L30

Added lines #L29 - L30 were not covered by tests


class DerivedParam(SlotDict):
"""
Extends SlotDict by adding an extra parameter
"""
def __init__(self, param: str, other_param: str, extra_param: str):
"""
Initializes a DerivedParam object.

Parameters
----------
param : str
A parameter
other_param : str
Another parameter
extra_param : str
An extra parameter
"""
super(DerivedParam, self).__init__(param, other_param)
self.extra_param = extra_param

Check warning on line 51 in sphinx_automodapi/tests/example_module/slots.py

View check run for this annotation

Codecov / codecov/patch

sphinx_automodapi/tests/example_module/slots.py#L50-L51

Added lines #L50 - L51 were not covered by tests

def derived_from_slot_class_method(self):
"""
Prints the DerivedParam parameters.
"""
print(f"param: {self.param}")
print(f"other_param: {self.other_param}")
print(f"dict_param: {self.extra_param}")

Check warning on line 59 in sphinx_automodapi/tests/example_module/slots.py

View check run for this annotation

Codecov / codecov/patch

sphinx_automodapi/tests/example_module/slots.py#L57-L59

Added lines #L57 - L59 were not covered by tests


class DerivedSlotParam(SlotDict):
"""
Extends SlotDict by adding a slot parameter
"""

__slots__ = ('extra_param',)

def __init__(self, param: str, other_param: str, extra_param: str):
"""
Initializes a DerivedParam object.

Parameters
----------
param : str
A parameter
other_param : str
Another parameter
extra_param : str
An extra parameter
"""
super(DerivedSlotParam, self).__init__(param, other_param)
self.extra_param = extra_param

Check warning on line 83 in sphinx_automodapi/tests/example_module/slots.py

View check run for this annotation

Codecov / codecov/patch

sphinx_automodapi/tests/example_module/slots.py#L82-L83

Added lines #L82 - L83 were not covered by tests

def derived_from_slot_class_method(self):
"""
Prints the DerivedParam parameters.
"""
print(f"param: {self.param}")
print(f"other_param: {self.other_param}")
print(f"extra_param: {self.extra_param}")

Check warning on line 91 in sphinx_automodapi/tests/example_module/slots.py

View check run for this annotation

Codecov / codecov/patch

sphinx_automodapi/tests/example_module/slots.py#L89-L91

Added lines #L89 - L91 were not covered by tests