如何在Sphinx中记录带有@dataclass注释的可调用类?

huangapple go评论111阅读模式
英文:

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

问题

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,

  1. @final
  2. @dataclass(frozen=True, slots=True)
  3. class Casting(object):
  4. _int_converter_function = int
  5. _float_converter_function = float
  6. def __call__(self, casting, value_to_cast):
  7. if casting['type'] == 'integer':
  8. return self._int_converter_function(value_to_cast)
  9. return self._float_converter_function(value_to_cast)

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

  1. class Casting(object):
  2. def __init__(
  3. self,
  4. int_converter_function = int,
  5. float_converter_function = float,
  6. ):
  7. self.int_converter_function = int_converter_function
  8. self.float_converter_function = float_converter_function
  9. def converter(self, casting, value):
  10. self.value = value
  11. yield
  12. type = casting['type']
  13. if type == 'integer':
  14. yield self.int_converter_function(value)
  15. else:
  16. 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:

  1. .. autoclass:: package.Casting
  2. :members:
  3. .. 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:

  1. """Cast one type of code to another.
  2. Constructor arguments:
  3. :param int_converter_function: function to convert to int
  4. :param float_converter_function: function to convert to float
  5. Callable arguments:
  6. :param casting: :term:`casting` object
  7. :type casting: dict
  8. :param value_to_cast: input value
  9. :return: Casted value
  10. Example
  11. >>> cast = Casting(int)
  12. >>> cast({'type': 'integer'}, '123')
  13. 123
  14. >>> cast({'type': 'decimal'}, '123.12')
  15. Decimal('123.12')
  16. """

UPDATE 2:

The full class as it is below:

  1. # -*- coding: utf-8 -*-
  2. from attr import dataclass
  3. from typing_extensions import final
  4. @final
  5. @dataclass(frozen=True, slots=True)
  6. class Casting(object):
  7. """Cast one type of code to another.
  8. Constructor arguments:
  9. :param int_converter_function: function to convert to int
  10. :param float_converter_function: function to convert to float
  11. Callable arguments:
  12. :param casting: :term:`casting` object
  13. :type casting: dict
  14. :param value_to_cast: input value
  15. :return: Casted value
  16. Example
  17. >>> cast = Casting(int)
  18. >>> cast({'type': 'integer'}, '123')
  19. 123
  20. >>> cast({'type': 'decimal'}, '123.12')
  21. Decimal('123.12')
  22. """
  23. _int_converter_function = int
  24. _float_converter_function = float
  25. def __call__(self, casting, value_to_cast):
  26. if casting['type'] == 'integer':
  27. return self._int_converter_function(value_to_cast)
  28. return self._float_converter_function(value_to_cast)

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

英文:

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,

  1. @final
  2. @dataclass(frozen=True, slots=True)
  3. class Casting(object):
  4. _int_converter_function = int
  5. _float_converter_function = float
  6. def __call__(self, casting, value_to_cast):
  7. if casting['type'] == 'integer':
  8. return self._int_converter_function(value_to_cast)
  9. return self._float_converter_function(value_to_cast)

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

  1. class Casting(object):
  2. def __init__(
  3. self,
  4. int_converter_function = int,
  5. float_converter_function = float,
  6. ):
  7. self.int_converter_function = int_converter_function
  8. self.float_converter_function = float_converter_function
  9. def converter(self, casting, value):
  10. self.value = value
  11. yield
  12. type = casting['type']
  13. if type == 'integer':
  14. yield self.int_converter_function(value)
  15. else:
  16. 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:

  1. .. autoclass:: package.Casting
  2. :members:
  3. .. 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:

  1. """Cast one type of code to another.
  2. Constructor arguments:
  3. :param int_converter_function: function to convert to int
  4. :param float_converter_function: function to convert to float
  5. Callable arguments:
  6. :param casting: :term:`casting` object
  7. :type casting: dict
  8. :param value_to_cast: input value
  9. :return: Casted value
  10. Example
  11. >>> cast = Casting(int)
  12. >>> cast({'type': 'integer'}, '123')
  13. 123
  14. >>> cast({'type': 'decimal'}, '123.12')
  15. Decimal('123.12')
  16. """

UPDATE 2:

The full class as it is below:

  1. # -*- coding: utf-8 -*-
  2. from attr import dataclass
  3. from typing_extensions import final
  4. @final
  5. @dataclass(frozen=True, slots=True)
  6. class Casting(object):
  7. """Cast one type of code to another.
  8. Constructor arguments:
  9. :param int_converter_function: function to convert to int
  10. :param float_converter_function: function to convert to float
  11. Callable arguments:
  12. :param casting: :term:`casting` object
  13. :type casting: dict
  14. :param value_to_cast: input value
  15. :return: Casted value
  16. Example
  17. >>> cast = Casting(int)
  18. >>> cast({'type': 'integer'}, '123')
  19. 123
  20. >>> cast({'type': 'decimal'}, '123.12')
  21. Decimal('123.12')
  22. """
  23. _int_converter_function = int
  24. _float_converter_function = float
  25. def __call__(self, casting, value_to_cast):
  26. if casting['type'] == 'integer':
  27. return self._int_converter_function(value_to_cast)
  28. return self._float_converter_function(value_to_cast)

如何在Sphinx中记录带有@dataclass注释的可调用类?

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

答案1

得分: 2

如 @mzjn 在评论中提到的,如果 automodule 配置正确,:exclude-members: dataclass 应该能够完成任务。

我犯了一个愚蠢的错误,很难追踪。如果你将 :exclude-members:<name-of-module> 写在不同的行上,那么文件中的所有类都将被忽略。

与创建构造函数和可调用函数相关的另一部分看起来很不错,我将其提取到了单独的SO问题中。

英文:

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 &lt;name-of-module&gt; 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.

huangapple
  • 本文由 发表于 2020年1月3日 22:43:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/59580517.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定