Coverage for fpdf2_textindex/interface/label_path.py: 68.75%
36 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-01 14:22 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-06-01 14:22 +0000
1"""Label Path."""
3from __future__ import annotations
5from collections.abc import Iterable
6from typing import SupportsIndex, TypeAlias, overload
8from typing_extensions import Self
10from fpdf2_textindex import constants as const
11from fpdf2_textindex.utils import remove_quotes
14class LabelPath(tuple[str, ...]):
15 """Label Path."""
17 def __new__(cls, labels: Self | Iterable[str] | str = ()) -> Self:
18 """Initializes the `LabelPath`.
20 Args:
21 labels: The labels composing the label path.
23 Raises:
24 TypeError: If `labels` does not have type `LabelPath`,
25 `Iterable[str]` or `str`.
26 """
27 if isinstance(labels, cls):
28 return labels
29 elif isinstance(labels, Iterable): 29 ↛ 31line 29 didn't jump to line 31 because the condition on line 29 was always true
30 labels_ = tuple(labels)
31 elif isinstance(labels, str):
32 labels_ = (labels,)
33 elif labels is None:
34 labels_ = tuple()
35 else:
36 msg = f"invalid type of `labels`: {type(labels).__name__:s}"
37 raise TypeError(msg)
38 if not all(isinstance(la, str) for la in labels_): 38 ↛ 39line 38 didn't jump to line 39 because the condition on line 38 was never true
39 msg = "invalid type of `labels`-elements: all must be `str`"
40 raise TypeError(msg)
41 return super().__new__(cls, (remove_quotes(la) for la in labels_))
43 @overload
44 def __getitem__(self, i: SupportsIndex) -> str: ...
46 @overload
47 def __getitem__(self, i: slice) -> Self: ...
49 def __getitem__(self, i: SupportsIndex | slice) -> Self | str:
50 result = super().__getitem__(i)
51 if isinstance(result, tuple):
52 return type(self)(result)
53 return result
55 def __repr__(self) -> str:
56 return f"{type(self).__name__:s}({super().__repr__()[1:-1]:s})"
58 def __str__(self) -> str:
59 return self.join()
61 def join(self) -> str:
62 """Returns the joined label path.
64 Returns:
65 The label path, joined by the path delimiter.
66 """
67 return f" {const.PATH_DELIMITER:s} ".join(f'"{la:s}"' for la in self)
69 @classmethod
70 def split_str(cls, label_path_str: str) -> Self:
71 """Splits a label path string by the path delimiter, removes quotes
72 from its elements and returns the corresponding label path.
74 Args:
75 label_path_str: The label path string to split.
77 Returns:
78 The corresponding label path.
79 """
80 return cls(label_path_str.split(const.PATH_DELIMITER))
83LabelPathT: TypeAlias = LabelPath | Iterable[str] | str
84"""Label Path Type."""