Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- `TextStyle` type alias (`Literal["without_comments", "merged", "with_comments"]`) for
the `style` parameter on `HConfigChild.cisco_style_text()` and
`RemediationReporter.to_text()`, replacing the unconstrained `str` type (#189).

- Performance benchmarks for parsing, remediation, and iteration (#202).
Skipped by default; run with `poetry run pytest -m benchmark -v -s`.

Expand Down
3 changes: 2 additions & 1 deletion hier_config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
get_hconfig_from_dump,
get_hconfig_view,
)
from .models import ChangeDetail, MatchRule, Platform, ReportSummary, TagRule
from .models import ChangeDetail, MatchRule, Platform, ReportSummary, TagRule, TextStyle
from .reporting import RemediationReporter
from .root import HConfig
from .workflows import WorkflowRemediation
Expand All @@ -20,6 +20,7 @@
"RemediationReporter",
"ReportSummary",
"TagRule",
"TextStyle",
"WorkflowRemediation",
"get_hconfig",
"get_hconfig_driver",
Expand Down
4 changes: 2 additions & 2 deletions hier_config/child.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import TYPE_CHECKING, Any

from .base import HConfigBase
from .models import Instance, MatchRule, SetLikeOfStr
from .models import Instance, MatchRule, SetLikeOfStr, TextStyle

if TYPE_CHECKING:
from collections.abc import Iterable, Iterator
Expand Down Expand Up @@ -181,7 +181,7 @@ def path(self) -> Iterator[str]:

def cisco_style_text(
self,
style: str = "without_comments",
style: TextStyle = "without_comments",
tag: str | None = None,
) -> str:
"""Return a Cisco style formated line i.e. indentation_level + text ! comments."""
Expand Down
3 changes: 3 additions & 0 deletions hier_config/models.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from enum import Enum, auto
from typing import Literal

from pydantic import BaseModel as PydanticBaseModel
from pydantic import ConfigDict, NonNegativeInt, PositiveInt

TextStyle = Literal["without_comments", "merged", "with_comments"]


class BaseModel(PydanticBaseModel):
"""Pydantic.BaseModel with a safe config applied."""
Expand Down
4 changes: 2 additions & 2 deletions hier_config/reporting.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from typing import Any

from hier_config.child import HConfigChild
from hier_config.models import ChangeDetail, ReportSummary, TagRule
from hier_config.models import ChangeDetail, ReportSummary, TagRule, TextStyle
from hier_config.root import HConfig


Expand Down Expand Up @@ -637,7 +637,7 @@ def to_text(
self,
file_path: str | Path,
*,
style: str = "merged",
style: TextStyle = "merged",
include_tags: Iterable[str] = (),
exclude_tags: Iterable[str] = (),
) -> None:
Expand Down
13 changes: 13 additions & 0 deletions tests/test_hier_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2187,3 +2187,16 @@ def test_children_extend() -> None:
assert len(interface1.children) == 2
assert "description test" in interface1.children
assert "ip address 192.0.2.1 255.255.255.0" in interface1.children


def test_cisco_style_text_literal_styles(platform_a: Platform) -> None:
"""Verify cisco_style_text works with each valid TextStyle literal value (#189)."""
config = get_hconfig(platform_a)
child = config.add_child("interface Vlan2")
child.add_child("ip address 10.0.0.1 255.255.255.0")

# Each valid style should produce a non-empty string without raising
for style in ("without_comments", "merged", "with_comments"):
result = child.cisco_style_text(style=style)
assert isinstance(result, str)
assert "interface Vlan2" in result
Loading