ВЕРСИИ: sphinx 8.1.3, pydantic 2.9.2, autodoc-pydantic 2.2.0
схема .py
Код: Выделить всё
from __future__ import annotations
from pydantic import (
BaseModel,
Field,
TypeAdapter,
)
from pydantic.functional_validators import BeforeValidator
import typing as t
from typing_extensions import Annotated
from typing import List
T = t.TypeVar("T")
def create_optionally_discriminant_union(union: T, discriminator: str) -> T:
def allow_missing_discriminator(v):
if discriminator not in v:
return TypeAdapter(union).validate_python(v)
return v
return Annotated[
union,
Field(discriminator=discriminator),
BeforeValidator(allow_missing_discriminator),
]
class ClassA(BaseModel):
r"""An example class"""
discriminator1: t.Literal["A"] = "A"
r"""Used by the API for model-type discrimination, can be ignored"""
a: float
r"""A float field"""
class ClassB(BaseModel):
r"""An example class"""
discriminator1: t.Literal["B"] = "B"
r"""Used by the API for model-type discrimination, can be ignored"""
a: float
r"""A float field"""
DiscriminantUnion = create_optionally_discriminant_union(
t.Union[ClassA, ClassB], discriminator="discriminator1"
)
class ClassC(BaseModel):
r"""Another example class"""
discriminating_field: DiscriminantUnion
r"""A sub-model to represent some smaller part"""
a: t.Optional[float]
r"""An optional field"""
Код: Выделить всё
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinxcontrib.autodoc_pydantic",
]
intersphinx_mapping = {
"python": ("https://docs.python.org/3", None),
}
templates_path = ["_templates"]
exclude_patterns = []
autodoc_member_order = "bysource"
add_module_names = False
autodoc_typehints = "both"
html_static_path = ["_static"]
autodoc_pydantic_model_show_json = False
autodoc_pydantic_model_show_config_summary = False
autodoc_pydantic_model_show_validator_members = False
autodoc_pydantic_model_show_validator_summary = False
autodoc_pydantic_field_list_validators = False
autodoc_pydantic_model_show_field_summary = False
autodoc_pydantic_field_show_constraints = False
autodoc_pydantic_model_signature_prefix = "class"
autodoc_pydantic_field_show_required = True
autodoc_pydantic_model_member_order = "bysource"
Код: Выделить всё
Schema
----------------------
.. automodule:: schema.py
:members:
:inherited-members: BaseModel, str
Первоначальный рендеринг
... /schema.ClassA.discriminator1:1: ПРЕДУПРЕЖДЕНИЕ: py:цель ссылки на класс не найден: t.Literal [ref.class]
... /schema.ClassB.discriminator1 :1: ПРЕДУПРЕЖДЕНИЕ: py:цель ссылки на класс не найден: t.Literal [ref.class]
... /schema.ClassC.discrimination_field:1: ПРЕДУПРЕЖДЕНИЕ: py:цель ссылки на класс не найден : DiscriminantUnion [ref.class]
... /schema.ClassC.a:1: ПРЕДУПРЕЖДЕНИЕ: цель ссылки py:class не найдена: t.Optional [ref.class]Здесь несколько вещей нежелательны:
- правильно связан, но Literal и необязательный отображаются неправильно и вызывают предупреждения.
Код: Выделить всё
float
- Тип ClassC.discrimination_field отображается как DiscriminantUnion без ссылки, поэтому пользователь, попадающий в ClassC, не сможет узнать, что DiscriminantUnion является объединением ClassA и ClassB
Чтобы лучше понять, что происходит, я также создал документы без расширения "sphinxcontrib.autodoc_pydantic", и это был результат (для ясности показаны только ClassB и ClassC:
Код: Выделить всё
ClassB
Код: Выделить всё
ClassC
Я надеюсь это проблемы с autodoc, и как только они будут решены, я смогу продолжать использовать autodoc-pydantic, поскольку он отлично справляется с созданием чистой и читаемой документации для классов pydantic.
Итак:
- Как мне получить гиперссылки подсказок типа (особенно для аннотированных типов и т. д.) для правильной визуализации строк документации атрибутов класса (а не только разделов сигнатуры класса или параметров)?
- Есть ли способ аккуратно документировать аннотированные типы и не включать дополнительные метаданные, добавленные с помощью create_optionally_discriminant_union?
Подробнее здесь: https://stackoverflow.com/questions/791 ... and-autodo