Coverage for src/c41811/config/basic/sequence.py: 100%
105 statements
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-04 11:16 +0000
« prev ^ index » next coverage.py v7.15.0, created at 2026-07-04 11:16 +0000
1# cython: language_level = 3 # noqa: ERA001
4"""
5序列类型配置数据实现
7.. versionadded:: 0.2.0
8"""
10import operator
11from collections.abc import Iterable
12from collections.abc import Iterator
13from collections.abc import MutableSequence
14from collections.abc import Sequence
15from typing import Any
16from typing import Literal
17from typing import Self
18from typing import cast
19from typing import override
21from ._generate_operators import generate
22from ._generate_operators import operate
23from .core import BasicIndexedConfigData
24from .core import BasicSingleConfigData
25from .utils import check_read_only
28@generate
29class SequenceConfigData[D: Sequence[Any]](BasicIndexedConfigData[D], MutableSequence[Any]):
30 """
31 序列配置数据
33 .. versionadded:: 0.1.5
34 """
36 _data: D
37 data: D
39 def __init__(self, data: D | None = None): # type: ignore[var-annotated] # mypy抽风
40 """
41 :param data: 序列数据
42 :type data: D | None
43 """ # noqa: D205
44 if data is None:
45 data = []
46 if not isinstance(data, Sequence):
47 msg = f"must be sequence, not {type(data).__name__}"
48 raise TypeError(msg)
49 super().__init__(cast(D, data))
51 @property
52 @override
53 def data_read_only(self) -> bool:
54 return not isinstance(self._data, MutableSequence)
56 @override
57 @check_read_only
58 def append(self, value: Any) -> None:
59 self._data.append(value) # type: ignore[attr-defined]
61 @override
62 @check_read_only
63 def insert(self, index: int, value: Any) -> None:
64 self._data.insert(index, value) # type: ignore[attr-defined]
66 @override
67 @check_read_only
68 def extend(self, values: Iterable[Any]) -> None:
69 self._data.extend(values) # type: ignore[attr-defined]
71 @override
72 def index(self, *args: Any) -> int:
73 return self._data.index(*args)
75 @override
76 def count(self, value: Any) -> int:
77 return self._data.count(value)
79 @override
80 @check_read_only
81 def pop(self, index: int = -1) -> Any:
82 return self._data.pop(index) # type: ignore[attr-defined]
84 @override
85 @check_read_only
86 def remove(self, value: Any) -> None:
87 self._data.remove(value) # type: ignore[attr-defined]
89 @override
90 @check_read_only
91 def clear(self) -> None:
92 self._data.clear() # type: ignore[attr-defined]
94 @override
95 @check_read_only
96 def reverse(self) -> None:
97 self._data.reverse() # type: ignore[attr-defined]
99 @override
100 def __reversed__(self) -> Iterator[D]:
101 return reversed(self._data)
103 @operate(operator.mul, operator.imul)
104 def __mul__(self, other: Any) -> Self: # type: ignore[empty-body]
105 ...
107 @operate(operator.add, operator.iadd)
108 def __add__(self, other: Any) -> Self: # type: ignore[empty-body]
109 ...
111 def __rmul__(self, other: Any) -> Self: # type: ignore[empty-body]
112 ...
114 def __radd__(self, other: Any) -> Self: # type: ignore[empty-body]
115 ...
118@generate
119class StringConfigData[D: str | bytes](BasicSingleConfigData[D]):
120 """字符/字节串配置数据"""
122 _data: D
124 def __init__(self, data: D | None = None):
125 """
126 :param data: 配置数据
127 :type data: D | None
128 """ # noqa: D205
129 if data is None:
130 data = ""
131 if not isinstance(data, str | bytes):
132 msg = f"must be str or bytes, not {type(data).__name__}"
133 raise TypeError(msg)
134 super().__init__(cast(D, data))
136 @property
137 @override
138 def data_read_only(self) -> Literal[False]:
139 """
140 配置数据是否为只读
142 :return: 配置数据是否为只读
143 :rtype: Literal[False]
145 .. note::
146 该配置数据类始终认为配置数据非只读,使其能正确作为配置数据容器使用
147 """ # noqa: RUF002
148 return False
150 @property # type: ignore[explicit-override] # mypy抽风
151 @override
152 def data(self) -> D:
153 """
154 配置的原始数据
156 .. caution::
157 未默认做深拷贝,可能导致非预期的行为
159 .. versionchanged:: 0.3.0
160 现在是可写属性
161 """ # noqa: RUF002
162 return self._data
164 @data.setter
165 def data(self, data: D) -> None:
166 self._data = data
168 @override
169 def __format__(self, format_spec: str) -> str:
170 return self._data.__format__(format_spec)
172 @operate(operator.add, operator.iadd)
173 def __add__(self, other: Any) -> Self: # type: ignore[empty-body]
174 ...
176 @operate(operator.mul, operator.imul)
177 def __mul__(self, other: Any) -> Self: # type: ignore[empty-body]
178 ...
180 def __contains__(self, key: Any) -> bool:
181 return key in self._data
183 def __iter__(self) -> Iterator[D]:
184 return iter(cast(Iterable[D], self._data))
186 def __len__(self) -> int:
187 return len(self._data)
189 def __getitem__(self, item: Any) -> D:
190 return cast(D, self._data[item])
192 @check_read_only
193 def __setitem__(self, key: Any, value: D) -> None:
194 self._data[key] = value # type: ignore[index]
196 @check_read_only
197 def __delitem__(self, key: Any) -> None:
198 del self._data[key] # type: ignore[union-attr]
200 def __reversed__(self) -> Any: # 不支持reversed[D]语法
201 return reversed(self._data)
204__all__ = (
205 "SequenceConfigData",
206 "StringConfigData",
207)