How to document callable classes annotated with @dataclass in sphinx?
Asked Answered
J

1

7

I researched this topic and cannot see a clear solution. There is a similar SO question

My problem is that I have a class with attr.dataclass and typing_extensions.final annotations and I don't want them to be documented but I still want to describe the class from the point of how it would be called.

For instance,

@final
@dataclass(frozen=True, slots=True)
class Casting(object):

  _int_converter_function = int
  _float_converter_function = float

  def __call__(self, casting, value_to_cast):
    if casting['type'] == 'integer':
        return self._int_converter_function(value_to_cast)
    return self._float_converter_function(value_to_cast)

This is approximately equivalent to this (which is far away from being accurate):

class Casting(object):

  def __init__(
    self,
    int_converter_function = int,
    float_converter_function = float,
  ):
    self.int_converter_function = int_converter_function
    self.float_converter_function = float_converter_function

  def converter(self, casting, value):
    self.value = value
    yield
    type = casting['type']
    if type == 'integer':
      yield self.int_converter_function(value)
    else:
      yield self.float_converter_function(value)

and with the latest it is clear that I can document each method with docstrings and in Sphinx do:

.. autoclass:: package.Casting
  :members:
  .. automethod:: __init__(self, int_converter_function, float_converter_function)

How to do the same with annotations?

UPDATE:

I figured out that my questions should be more specific. I want to

  1. Eliminate dataclass completely from the doc but nevertheless, keep the class in the documentation. It messes classes so much that the docs are unreadable.

  2. Make a docstring on the __init__ but also keep it separate from the callable description. I left a comment.

Example of the doc:

"""Cast one type of code to another.

Constructor arguments:

    :param int_converter_function: function to convert to int

    :param float_converter_function: function to convert to float

Callable arguments:

:param casting: :term:`casting` object
:type casting: dict

:param value_to_cast: input value

:return: Casted value

Example
    >>> cast = Casting(int)
    >>> cast({'type': 'integer'}, '123')
    123
    >>> cast({'type': 'decimal'}, '123.12')
    Decimal('123.12')

"""

UPDATE 2:

The full class as it is below:

# -*- coding: utf-8 -*-

from attr import dataclass
from typing_extensions import final


@final
@dataclass(frozen=True, slots=True)
class Casting(object):
    """Cast one type of code to another.

    Constructor arguments:

        :param int_converter_function: function to convert to int

        :param float_converter_function: function to convert to float

    Callable arguments:

    :param casting: :term:`casting` object
    :type casting: dict

    :param value_to_cast: input value

    :return: Casted value

    Example
        >>> cast = Casting(int)
        >>> cast({'type': 'integer'}, '123')
        123
        >>> cast({'type': 'decimal'}, '123.12')
        Decimal('123.12')

    """

    _int_converter_function = int
    _float_converter_function = float

    def __call__(self, casting, value_to_cast):
        if casting['type'] == 'integer':
            return self._int_converter_function(value_to_cast)
        return self._float_converter_function(value_to_cast)

Example of docs

I want to eliminate package.casting.dataclass from the doc.

Jovanjove answered 3/1, 2020 at 14:43 Comment(6)
I'm not sure what the problem is, but have you seen this question? https://mcmap.net/q/278623/-how-do-i-document-a-constructor-for-a-class-using-python-dataclasses/407651Maria
@Maria I updated the question, so it reflects more accurately the issue I have.Jovanjove
@Maria Indeed, you are right. I adjusted the code, so it would be more understandable and less abstract as well.Jovanjove
@Maria I did 2nd update, hopefully, it will clear things and it makes sense for you.Jovanjove
When using automodule, I can reproduce the problem with getting "dataclass" documentation in the output. This can be fixed by using :exclude-members: dataclass.Maria
@Maria I tried it but for me, it excluded the whole class documentation not only dataclass partJovanjove
J
3

As @mzjn mentioned in comments :exclude-members: dataclass should do the job if automodule configured correctly.

I made a dumb mistake that was hard to track. If you write :exclude-members: and <name-of-module> on the separate lines then all classes in the file will be ignored.

Another part related to make constructor and callable function looks pretty I extracted into separate SO question.

Jovanjove answered 15/1, 2020 at 13:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.