From be21d377d085bde35ac608e68d79b1fe3d70ddf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franz=20W=C3=B6llert?= Date: Fri, 26 Apr 2024 14:57:00 +0200 Subject: [PATCH] feat: Allow empty strings for directive prefixes (#285) docs: Add hint mentioning that pydantic directive prefixes allow empty strings --- docs/source/users/configuration.rst | 32 ++++++++++++++++--- .../autodoc_pydantic/directives/directives.py | 14 ++++---- tests/test_configuration_fields.py | 3 +- tests/test_configuration_model.py | 5 ++- tests/test_configuration_settings.py | 10 +++--- tests/test_configuration_validator.py | 17 +++++----- 6 files changed, 51 insertions(+), 30 deletions(-) diff --git a/docs/source/users/configuration.rst b/docs/source/users/configuration.rst index 7d36013d..a43d7d95 100644 --- a/docs/source/users/configuration.rst +++ b/docs/source/users/configuration.rst @@ -178,7 +178,13 @@ Contains all modifications for pydantic `BaseModel`. :directive_option: model-signature-prefix :values: pydantic model, class, foobar - Define the signature prefix for pydantic models. + Define the signature prefix for pydantic model. This is especially useful + when you want to distinguish pydantic models from other classes. + + .. hint:: + + An empty string is also a valid value. This will remove the prefix + completely. .. config_description:: autopydantic_model @@ -395,7 +401,13 @@ Contains all modifications for pydantic `BaseSettings`. :directive_option: settings-signature-prefix :values: pydantic settings, class, foobar - Define the signature prefix for pydantic settings. + Define the signature prefix for pydantic settings. This is especially useful + when you want to distinguish pydantic settings from other classes. + + .. hint:: + + An empty string is also a valid value. This will remove the prefix + completely. .. config_description:: autopydantic_settings @@ -575,7 +587,13 @@ Fields :enable: members, field-doc-policy=docstring :values: field, attribute, foobar - Define the signature prefix for pydantic field. + Define the signature prefix for pydantic fields. This is especially useful + when you want to distinguish pydantic fields from other attributes. + + .. hint:: + + An empty string is also a valid value. This will remove the prefix + completely. ---------- @@ -621,7 +639,13 @@ Validators :enable: members, model-show-validator-members, undoc-members :values: validator, classmethod, foobar - Define the signature prefix for pydantic validator. + Define the signature prefix for pydantic validators. This is especially useful + when you want to distinguish pydantic validators from other attributes. + + .. hint:: + + An empty string is also a valid value. This will remove the prefix + completely. ------- diff --git a/sphinxcontrib/autodoc_pydantic/directives/directives.py b/sphinxcontrib/autodoc_pydantic/directives/directives.py index febe6e17..40b0e849 100644 --- a/sphinxcontrib/autodoc_pydantic/directives/directives.py +++ b/sphinxcontrib/autodoc_pydantic/directives/directives.py @@ -33,7 +33,6 @@ class PydanticDirectiveMixin: """Base class for pydantic directive providing common functionality.""" config_name: str - default_prefix: str def __init__(self, *args) -> None: # noqa: ANN002 super().__init__(*args) @@ -44,15 +43,18 @@ def get_signature_prefix(self, *_) -> list[Node]: # noqa: ANN002 config_name = f'{self.config_name}-signature-prefix' prefix = self.pyautodoc.get_value(config_name) - value = prefix or self.default_prefix + + # empty prefix should not add any nodes + if prefix == '': + return [] # account for changed signature in sphinx 4.3, see #62 if sphinx.version_info < (4, 3): - return f'{value} ' # type: ignore[return-value] + return f'{prefix} ' # type: ignore[return-value] from sphinx.addnodes import desc_sig_space - return [Text(value), desc_sig_space()] + return [Text(prefix), desc_sig_space()] class PydanticModel(PydanticDirectiveMixin, PyClasslike): @@ -67,7 +69,6 @@ class PydanticModel(PydanticDirectiveMixin, PyClasslike): ) config_name = 'model' - default_prefix = 'class' class PydanticSettings(PydanticDirectiveMixin, PyClasslike): @@ -82,7 +83,6 @@ class PydanticSettings(PydanticDirectiveMixin, PyClasslike): ) config_name = 'settings' - default_prefix = 'class' class PydanticField(PydanticDirectiveMixin, PyAttribute): @@ -102,7 +102,6 @@ class PydanticField(PydanticDirectiveMixin, PyAttribute): ) config_name = 'field' - default_prefix = 'attribute' def get_field_name(self, sig: str) -> str: """Get field name from signature. Borrows implementation from @@ -218,7 +217,6 @@ class PydanticValidator(PydanticDirectiveMixin, PyMethod): ) config_name = 'validator' - default_prefix = 'classmethod' def get_field_href_from_mapping( self, inspector: ModelInspector, mapping: ValidatorFieldMap diff --git a/tests/test_configuration_fields.py b/tests/test_configuration_fields.py index d009ece2..1d390792 100644 --- a/tests/test_configuration_fields.py +++ b/tests/test_configuration_fields.py @@ -885,8 +885,7 @@ def test_autodoc_pydantic_field_signature_prefix_directive(parse_rst): # empty doctree = parse_rst(input_rst, conf={'autodoc_pydantic_field_signature_prefix': ''}) - prefix = desc_annotation_directive_prefix('attribute') - assert_node(doctree[1][0][0], [desc_annotation, prefix]) + assert_node(doctree[1][0][0], [desc_addname, 'FieldSignaturePrefix.']) # custom input_rst = [ diff --git a/tests/test_configuration_model.py b/tests/test_configuration_model.py index b29e6999..f8befc55 100644 --- a/tests/test_configuration_model.py +++ b/tests/test_configuration_model.py @@ -1,7 +1,7 @@ """This module contains tests for pydantic model configurations.""" import pytest -from sphinx.addnodes import desc_annotation +from sphinx.addnodes import desc_annotation, desc_addname from sphinx.testing.util import assert_node from sphinxcontrib.autodoc_pydantic.directives.autodocumenters import ( @@ -1271,8 +1271,7 @@ def test_autodoc_pydantic_model_signature_prefix_directive(parse_rst): # empty doctree = parse_rst(input_rst, conf={'autodoc_pydantic_model_signature_prefix': ''}) - prefix = desc_annotation_directive_prefix('class') - assert_node(doctree[1][0][0], [desc_annotation, prefix]) + assert_node(doctree[1][0][0], [desc_addname, 'target.configuration.']) # custom input_rst = [ diff --git a/tests/test_configuration_settings.py b/tests/test_configuration_settings.py index f3451770..0db1fe43 100644 --- a/tests/test_configuration_settings.py +++ b/tests/test_configuration_settings.py @@ -2,12 +2,13 @@ from typing import List -from sphinx.addnodes import desc_annotation +from sphinx.addnodes import desc_addname, desc_annotation from sphinx.testing.util import assert_node from sphinxcontrib.autodoc_pydantic.directives.autodocumenters import ( PydanticSettingsDocumenter, ) + from .compatibility import desc_annotation_directive_prefix KWARGS = dict(documenter=PydanticSettingsDocumenter.objtype, deactivate_all=True) @@ -1004,10 +1005,10 @@ def test_autodoc_pydantic_settings_signature_prefix(autodocument, parse_rst): actual = autodocument(options_doc={'settings-signature-prefix': ''}, **kwargs) assert result == actual - -def test_autodoc_pydantic_settings_signature_prefix_directive(parse_rst): """Tests pydantic_settings directive.""" + +def test_autodoc_pydantic_settings_signature_prefix_directive(parse_rst): # default input_rst = [ '', @@ -1026,8 +1027,7 @@ def test_autodoc_pydantic_settings_signature_prefix_directive(parse_rst): doctree = parse_rst( input_rst, conf={'autodoc_pydantic_settings_signature_prefix': ''} ) - prefix = desc_annotation_directive_prefix('class') - assert_node(doctree[1][0][0], [desc_annotation, prefix]) + assert_node(doctree[1][0][0], [desc_addname, 'target.configuration.']) # custom input_rst = [ diff --git a/tests/test_configuration_validator.py b/tests/test_configuration_validator.py index c8420ed5..7d81f20f 100644 --- a/tests/test_configuration_validator.py +++ b/tests/test_configuration_validator.py @@ -1,23 +1,25 @@ """This module contains tests for pydantic validator configurations.""" from docutils.nodes import ( - paragraph, emphasis, + paragraph, ) from sphinx.addnodes import ( desc, - desc_signature, - desc_name, - desc_content, - desc_annotation, desc_addname, - pending_xref, + desc_annotation, + desc_content, + desc_name, + desc_signature, index, + pending_xref, ) from sphinx.testing.util import assert_node + from sphinxcontrib.autodoc_pydantic.directives.autodocumenters import ( PydanticValidatorDocumenter, ) + from .compatibility import desc_annotation_directive_prefix KWARGS = dict(documenter=PydanticValidatorDocumenter.objtype, deactivate_all=True) @@ -449,8 +451,7 @@ def test_autodoc_pydantic_validator_signature_prefix_directive(parse_rst): doctree = parse_rst( input_rst, conf={'autodoc_pydantic_validator_signature_prefix': ''} ) - prefix = desc_annotation_directive_prefix('classmethod') - assert_node(doctree[1][0][0], [desc_annotation, prefix]) + assert_node(doctree[1][0][0], [desc_addname, 'ValidatorSignaturePrefix.']) # custom input_rst = [