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

Support sphinx 4.3#62 #72

Merged
merged 10 commits into from
Nov 10, 2021
5 changes: 4 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,12 @@ jobs:
- python_version: 3.9
pydantic_version: "18"
sphinx_version: "42"
- python_version: 3.9
pydantic_version: "18"
sphinx_version: "43"
- python_version: "3.10"
pydantic_version: "18"
sphinx_version: "42"
sphinx_version: "43"
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
Expand Down
13 changes: 13 additions & 0 deletions changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,33 @@ Bugfix
``numpy.typing.NDArray`` caused autodoc_pydantic to experience
an uncaught exception. (Issue #57)

Internal
~~~~~~~~

- Account for modified method signature in ``get_signature_prefix`` in sphinx
4.3 `#62 <https://github.com/mansenfranzen/autodoc_pydantic/issues/62>`__.

Testing
~~~~~~~

- Fix broken CI for sphinx 3.4 due to unpinned versions of ``docutils``. This
generates new sphinx loggings which have not been present before that in turn
cause tests to fail which are dependent on inspecting sphinx loggings
`#68 <https://github.com/mansenfranzen/autodoc_pydantic/issues/68>`__.
- Add sphinx 4.3 to CI matrix.
- Add compatibility module to abstract away minor implementation differences
between sphinx versions 4.3 and prior.

Contributors
~~~~~~~~~~~~

- Thanks to `j-carson <https://github.com/j-carson>`__ for reporting a bug
related autodoc_pydantic's inspection module
`#57 <https://github.com/mansenfranzen/autodoc_pydantic/issues/57>`__.
- Thanks to `Yoshanuikabundi <https://github.com/Yoshanuikabundi>`__ and
`jakobandersen <https://github.com/jakobandersen>`__ for reporting and
mitigating a compatibility issue with sphinx 4.3
`#62 <https://github.com/mansenfranzen/autodoc_pydantic/issues/62>`__.

v1.5.0 - 2021-10-10
-------------------
Expand Down
14 changes: 11 additions & 3 deletions sphinxcontrib/autodoc_pydantic/directives/directives.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

"""

from typing import Tuple
from typing import Tuple, Union, List

import sphinx
from docutils.nodes import Text
from docutils.parsers.rst.directives import unchanged
from sphinx.addnodes import (
desc_signature,
Expand Down Expand Up @@ -34,15 +36,21 @@ def __init__(self, *args):
super().__init__(*args)
self.pyautodoc = DirectiveOptions(self)

def get_signature_prefix(self, sig: str) -> str:
def get_signature_prefix(self, sig: str) -> Union[str, List[Text]]:
"""Overwrite original signature prefix with custom pydantic ones.

"""

config_name = f"{self.config_name}-signature-prefix"
prefix = self.pyautodoc.get_value(config_name)
value = prefix or self.default_prefix
return f"{value} "

# account for changed signature in sphinx 4.3, see #62
if sphinx.version_info >= (4, 3):
from sphinx.addnodes import desc_sig_space
return [Text(value), desc_sig_space()]
else:
return f"{value} "


class PydanticModel(PydanticDirectiveBase, PyClasslike):
Expand Down
Empty file added tests/__init__.py
Empty file.
52 changes: 52 additions & 0 deletions tests/compatability.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""This module contains compatibility functions to abstract away implementation
differences between different sphinx versions.

"""

from typing import Tuple

import sphinx
from sphinx.addnodes import desc_sig_punctuation, desc_annotation, pending_xref


def desc_annotation_default_value(value: str):
"""Provides compatibility abstraction for `desc_annotation` for default
values for sphinx version smaller and greater equal sphinx 4.3.

"""

if sphinx.version_info >= (4, 3):
from sphinx.addnodes import desc_sig_space
return (desc_sig_space,
[desc_sig_punctuation, "="],
desc_sig_space,
value)
else:
return [desc_annotation, f" = {value}"]


def desc_annotation_type_annotation(type_str: str) -> Tuple:
"""Provides compatibility abstraction for `desc_annotation` for type
annotation for sphinx version smaller and greater equal sphinx 4.3.

"""

if sphinx.version_info >= (4, 3):
from sphinx.addnodes import desc_sig_space
return ([desc_sig_punctuation, ":"],
desc_sig_space,
[pending_xref, type_str])
else:
return (": ", [pending_xref, type_str])


def desc_annotation_directive_prefix(prefix: str):
"""Provides compatibility abstraction for `desc_annotation` for directive
prefix for sphinx version smaller and greater equal sphinx 4.3.

"""

if sphinx.version_info >= (4, 3):
from sphinx.addnodes import desc_sig_space
return (prefix, desc_sig_space)
return prefix + " "
9 changes: 7 additions & 2 deletions tests/test_autosummary.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
import sphinx
from sphinx.ext.autosummary import FakeDirective

from sphinxcontrib.autodoc_pydantic import (
Expand Down Expand Up @@ -41,6 +42,10 @@ def test_autosummary_imported_objects(parse_rst):
]

nodes = parse_rst(input_rst)
ref = nodes[1][0][0][2][0][0][0][0][0]
node = nodes[1][0][0][2][0][0][0][0]

assert ref == ':obj:`target.AutoSummaryModel <target.AutoSummaryModel>`'
if sphinx.version_info >= (4, 3):
assert node["reftarget"] == "target.AutoSummaryModel"
assert node.astext() == "target.AutoSummaryModel"
else:
assert node[0] == ':obj:`target.AutoSummaryModel <target.AutoSummaryModel>`'
10 changes: 7 additions & 3 deletions tests/test_configuration_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import sphinx

from sphinxcontrib.autodoc_pydantic import PydanticConfigClassDocumenter
from tests.compatability import desc_annotation_directive_prefix

KWARGS = dict(documenter=PydanticConfigClassDocumenter.directivetype,
deactivate_all=True)
Expand Down Expand Up @@ -146,12 +147,14 @@ def test_autodoc_pydantic_config_signature_prefix_directive(parse_rst):
]

doctree = parse_rst(input_rst)
assert_node(doctree[1][0][0], [desc_annotation, "model "])
prefix = desc_annotation_directive_prefix("model")
assert_node(doctree[1][0][0], [desc_annotation, prefix])

# empty
doctree = parse_rst(input_rst,
conf={"autodoc_pydantic_config_signature_prefix": ""})
assert_node(doctree[1][0][0], [desc_annotation, "class "])
prefix = desc_annotation_directive_prefix("class")
assert_node(doctree[1][0][0], [desc_annotation, prefix])

# custom
input_rst = [
Expand All @@ -165,4 +168,5 @@ def test_autodoc_pydantic_config_signature_prefix_directive(parse_rst):
]

doctree = parse_rst(input_rst)
assert_node(doctree[1][0][0], [desc_annotation, "foobar "])
prefix = desc_annotation_directive_prefix("foobar")
assert_node(doctree[1][0][0], [desc_annotation, prefix])
31 changes: 22 additions & 9 deletions tests/test_configuration_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
)
from sphinx.testing.util import assert_node
from sphinxcontrib.autodoc_pydantic import PydanticFieldDocumenter
from .compatability import desc_annotation_default_value, \
desc_annotation_directive_prefix

KWARGS = dict(documenter=PydanticFieldDocumenter.directivetype,
deactivate_all=True)
Expand Down Expand Up @@ -346,12 +348,15 @@ def test_autodoc_pydantic_field_show_alias_true_directive(parse_rst):

"""

default_value = desc_annotation_default_value("1")
prefix = desc_annotation_directive_prefix("field")

output_nodes = (
index,
[desc, ([desc_signature, ([desc_annotation, "field "],
[desc, ([desc_signature, ([desc_annotation, prefix],
[desc_addname, "FieldShowAlias."],
[desc_name, "field"],
[desc_annotation, " = 1"],
default_value,
[desc_annotation, " (alias 'field2')"])],
[desc_content, ()])
]
Expand Down Expand Up @@ -385,12 +390,15 @@ def test_autodoc_pydantic_field_show_alias_false_directive(parse_rst):

"""

default_value = desc_annotation_default_value("1")
prefix = desc_annotation_directive_prefix("field")

output_nodes = (
index,
[desc, ([desc_signature, ([desc_annotation, "field "],
[desc, ([desc_signature, ([desc_annotation, prefix],
[desc_addname, "FieldShowAlias."],
[desc_name, "field"],
[desc_annotation, " = 1"])],
default_value)],
[desc_content, ()])
]
)
Expand Down Expand Up @@ -562,12 +570,14 @@ def test_autodoc_pydantic_field_signature_prefix_directive(parse_rst):
]

doctree = parse_rst(input_rst)
assert_node(doctree[1][0][0], [desc_annotation, "field "])
prefix = desc_annotation_directive_prefix("field")
assert_node(doctree[1][0][0], [desc_annotation, prefix])

# empty
doctree = parse_rst(input_rst,
conf={"autodoc_pydantic_field_signature_prefix": ""})
assert_node(doctree[1][0][0], [desc_annotation, "attribute "])
prefix = desc_annotation_directive_prefix("attribute")
assert_node(doctree[1][0][0], [desc_annotation, prefix])

# custom
input_rst = [
Expand All @@ -581,7 +591,8 @@ def test_autodoc_pydantic_field_signature_prefix_directive(parse_rst):
]

doctree = parse_rst(input_rst)
assert_node(doctree[1][0][0], [desc_annotation, "foobar "])
prefix = desc_annotation_directive_prefix("foobar")
assert_node(doctree[1][0][0], [desc_annotation, prefix])


@pytest.mark.parametrize("field", ["field1", "field2", "field3"])
Expand Down Expand Up @@ -708,9 +719,10 @@ def test_autodoc_pydantic_field_show_required_true_directive(parse_rst):

"""

prefix = desc_annotation_directive_prefix("field")
output_nodes = (
index,
[desc, ([desc_signature, ([desc_annotation, "field "],
[desc, ([desc_signature, ([desc_annotation, prefix],
[desc_addname, "FieldShowRequired."],
[desc_name, "field"],
[desc_annotation, " [Required]"],
Expand Down Expand Up @@ -743,9 +755,10 @@ def test_autodoc_pydantic_field_show_required_false_directive(parse_rst):

"""

prefix = desc_annotation_directive_prefix("field")
output_nodes = (
index,
[desc, ([desc_signature, ([desc_annotation, "field "],
[desc, ([desc_signature, ([desc_annotation, prefix],
[desc_addname, "FieldShowRequired."],
[desc_name, "field"],
[desc_annotation, " (alias 'field2')"])],
Expand Down
10 changes: 7 additions & 3 deletions tests/test_configuration_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from sphinx.testing.util import assert_node

from sphinxcontrib.autodoc_pydantic import PydanticModelDocumenter
from .compatability import desc_annotation_directive_prefix

KWARGS = dict(documenter=PydanticModelDocumenter.objtype,
deactivate_all=True)
Expand Down Expand Up @@ -1049,12 +1050,14 @@ def test_autodoc_pydantic_model_signature_prefix_directive(parse_rst):
]

doctree = parse_rst(input_rst)
assert_node(doctree[1][0][0], [desc_annotation, "pydantic model "])
prefix = desc_annotation_directive_prefix("pydantic model")
assert_node(doctree[1][0][0], [desc_annotation, prefix])

# empty
doctree = parse_rst(input_rst,
conf={"autodoc_pydantic_model_signature_prefix": ""})
assert_node(doctree[1][0][0], [desc_annotation, "class "])
prefix = desc_annotation_directive_prefix("class")
assert_node(doctree[1][0][0], [desc_annotation, prefix])

# custom
input_rst = [
Expand All @@ -1068,4 +1071,5 @@ def test_autodoc_pydantic_model_signature_prefix_directive(parse_rst):
]

doctree = parse_rst(input_rst)
assert_node(doctree[1][0][0], [desc_annotation, "foobar "])
prefix = desc_annotation_directive_prefix("foobar")
assert_node(doctree[1][0][0], [desc_annotation, prefix])
10 changes: 7 additions & 3 deletions tests/test_configuration_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from sphinx.testing.util import assert_node

from sphinxcontrib.autodoc_pydantic import PydanticSettingsDocumenter
from .compatability import desc_annotation_directive_prefix

KWARGS = dict(documenter=PydanticSettingsDocumenter.objtype,
deactivate_all=True)
Expand Down Expand Up @@ -1064,12 +1065,14 @@ def test_autodoc_pydantic_settings_signature_prefix_directive(parse_rst):
]

doctree = parse_rst(input_rst)
assert_node(doctree[1][0][0], [desc_annotation, "pydantic settings "])
prefix = desc_annotation_directive_prefix("pydantic settings")
assert_node(doctree[1][0][0], [desc_annotation, prefix])

# empty
doctree = parse_rst(input_rst,
conf={"autodoc_pydantic_settings_signature_prefix": ""})
assert_node(doctree[1][0][0], [desc_annotation, "class "])
prefix = desc_annotation_directive_prefix("class")
assert_node(doctree[1][0][0], [desc_annotation, prefix])

# custom
input_rst = [
Expand All @@ -1083,4 +1086,5 @@ def test_autodoc_pydantic_settings_signature_prefix_directive(parse_rst):
]

doctree = parse_rst(input_rst)
assert_node(doctree[1][0][0], [desc_annotation, "foobar "])
prefix = desc_annotation_directive_prefix("foobar")
assert_node(doctree[1][0][0], [desc_annotation, prefix])