Skip to content
This repository was archived by the owner on Sep 15, 2025. It is now read-only.

Commit 1259cb0

Browse files
committed
WIP: immutable nodes
1 parent 1c3a4a1 commit 1259cb0

File tree

1 file changed

+13
-9
lines changed

1 file changed

+13
-9
lines changed

html_tstring/nodes.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import typing as t
12
from dataclasses import dataclass, field
3+
from types import MappingProxyType
24

35
from markupsafe import escape
46

@@ -31,15 +33,15 @@
3133
# FUTURE: make nodes frozen (and have the parser work with mutable builders)
3234

3335

34-
@dataclass(slots=True)
36+
@dataclass(slots=True, frozen=True)
3537
class Node:
3638
def __html__(self) -> str:
3739
"""Return the HTML representation of the node."""
3840
# By default, just return the string representation
3941
return str(self)
4042

4143

42-
@dataclass(slots=False)
44+
@dataclass(slots=True, frozen=True)
4345
class Text(Node):
4446
text: str
4547

@@ -48,35 +50,37 @@ def __str__(self) -> str:
4850
return escape(self.text)
4951

5052

51-
@dataclass(slots=True)
53+
@dataclass(slots=True, frozen=True)
5254
class Fragment(Node):
53-
children: list[Node] = field(default_factory=list)
55+
children: t.Sequence[Node] = field(default_factory=tuple)
5456

5557
def __str__(self) -> str:
5658
return "".join(str(child) for child in self.children)
5759

5860

59-
@dataclass(slots=True)
61+
@dataclass(slots=True, frozen=True)
6062
class Comment(Node):
6163
text: str
6264

6365
def __str__(self) -> str:
6466
return f"<!--{self.text}-->"
6567

6668

67-
@dataclass(slots=True)
69+
@dataclass(slots=True, frozen=True)
6870
class DocumentType(Node):
6971
text: str = "html"
7072

7173
def __str__(self) -> str:
7274
return f"<!DOCTYPE {self.text}>"
7375

7476

75-
@dataclass(slots=True)
77+
@dataclass(slots=True, frozen=True)
7678
class Element(Node):
7779
tag: str
78-
attrs: dict[str, str | None] = field(default_factory=dict)
79-
children: list[Node] = field(default_factory=list)
80+
attrs: t.Mapping[str, str | None] = field(
81+
default_factory=lambda: MappingProxyType({})
82+
)
83+
children: t.Sequence[Node] = field(default_factory=tuple)
8084

8185
def __post_init__(self):
8286
"""Ensure all preconditions are met."""

0 commit comments

Comments
 (0)