Coverage for src/c41811/config/basic/number.py: 100%
57 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 math
11import operator
12from numbers import Number
13from typing import Any
14from typing import Literal
15from typing import Self
16from typing import cast
17from typing import override
19from ._generate_operators import generate
20from ._generate_operators import operate
21from .core import BasicSingleConfigData
24@generate
25class NumberConfigData[D: int | float | Number](BasicSingleConfigData[D]):
26 """
27 数值配置数据
29 .. versionadded:: 0.1.5
30 """
32 _data: D
34 def __init__(self, data: D | None = None):
35 """
36 :param data: 数值数据
37 :type data: D | None
38 """ # noqa: D205
39 if data is None:
40 data = 0
41 if not isinstance(data, Number):
42 msg = f"must be number, not {type(data).__name__}"
43 raise TypeError(msg)
44 super().__init__(cast(D, data))
46 @property
47 @override
48 def data_read_only(self) -> Literal[False]:
49 """
50 配置数据是否为只读
52 :return: 配置数据是否为只读
53 :rtype: Literal[False]
55 .. note::
56 该配置数据类始终认为配置数据非只读,使其能正确作为配置数据容器使用
57 """ # noqa: RUF002
58 return False
60 @property # type: ignore[explicit-override] # mypy抽风
61 @override
62 def data(self) -> D:
63 """
64 配置的原始数据
66 .. caution::
67 未默认做深拷贝,可能导致非预期的行为
69 .. versionchanged:: 0.3.0
70 现在是可写属性
71 """ # noqa: RUF002
72 return self._data
74 @data.setter
75 def data(self, data: D) -> None:
76 self._data = data
78 def __int__(self) -> int:
79 return int(self._data) # type: ignore[arg-type]
81 def __float__(self) -> float:
82 return float(self._data) # type: ignore[arg-type]
84 @operate(operator.add, operator.iadd)
85 def __add__(self, other: Any) -> Self: # type: ignore[empty-body]
86 ...
88 @operate(operator.sub, operator.isub)
89 def __sub__(self, other: Any) -> Self: # type: ignore[empty-body]
90 ...
92 @operate(operator.mul, operator.imul)
93 def __mul__(self, other: Any) -> Self: # type: ignore[empty-body]
94 ...
96 @operate(operator.truediv, operator.itruediv)
97 def __truediv__(self, other: Any) -> Self: # type: ignore[empty-body]
98 ...
100 @operate(operator.floordiv, operator.ifloordiv)
101 def __floordiv__(self, other: Any) -> Self: # type: ignore[empty-body]
102 ...
104 @operate(operator.mod, operator.imod)
105 def __mod__(self, other: Any) -> Self: # type: ignore[empty-body]
106 ...
108 @operate(operator.pow, operator.ipow)
109 def __pow__(self, other: Any) -> Self: # type: ignore[empty-body]
110 ...
112 @operate(operator.and_, operator.iand)
113 def __and__(self, other: Any) -> Self: # type: ignore[empty-body]
114 ...
116 @operate(operator.or_, operator.ior)
117 def __or__(self, other: Any) -> Self: # type: ignore[empty-body]
118 ...
120 @operate(operator.xor, operator.ixor)
121 def __xor__(self, other: Any) -> Self: # type: ignore[empty-body]
122 ...
124 @operate(operator.matmul, operator.imatmul)
125 def __matmul__(self, other: Any) -> Self: # type: ignore[empty-body]
126 ...
128 @operate(operator.lshift, operator.ilshift)
129 def __lshift__(self, other: Any) -> Self: # type: ignore[empty-body]
130 ...
132 @operate(operator.rshift, operator.irshift)
133 def __rshift__(self, other: Any) -> Self: # type: ignore[empty-body]
134 ...
136 def __radd__(self, other: Any) -> Self: # type: ignore[empty-body]
137 ...
139 def __rsub__(self, other: Any) -> Self: # type: ignore[empty-body]
140 ...
142 def __rmul__(self, other: Any) -> Self: # type: ignore[empty-body]
143 ...
145 def __rtruediv__(self, other: Any) -> Self: # type: ignore[empty-body]
146 ...
148 def __rfloordiv__(self, other: Any) -> Self: # type: ignore[empty-body]
149 ...
151 def __rmod__(self, other: Any) -> Self: # type: ignore[empty-body]
152 ...
154 def __rpow__(self, other: Any) -> Self: # type: ignore[empty-body]
155 ...
157 def __rand__(self, other: Any) -> Self: # type: ignore[empty-body]
158 ...
160 def __ror__(self, other: Any) -> Self: # type: ignore[empty-body]
161 ...
163 def __rxor__(self, other: Any) -> Self: # type: ignore[empty-body]
164 ...
166 def __rmatmul__(self, other: Any) -> Self: # type: ignore[empty-body]
167 ...
169 def __rlshift__(self, other: Any) -> Self: # type: ignore[empty-body]
170 ...
172 def __rrshift__(self, other: Any) -> Self: # type: ignore[empty-body]
173 ...
175 def __invert__(self) -> Any:
176 return ~self._data # type: ignore[operator]
178 def __neg__(self) -> Any:
179 return -self._data # type: ignore[operator]
181 def __pos__(self) -> Any:
182 return +self._data # type: ignore[operator]
184 def __abs__(self) -> D:
185 return abs(self._data) # type: ignore[return-value,arg-type]
187 # noinspection SpellCheckingInspection
188 def __round__(self, ndigits: int | None = None) -> Any:
189 return round(self._data, ndigits) # type: ignore[arg-type]
191 def __trunc__(self) -> Any:
192 return math.trunc(self._data) # type: ignore[arg-type]
194 def __floor__(self) -> Any:
195 return math.floor(self._data) # type: ignore[arg-type]
197 def __ceil__(self) -> Any:
198 return math.ceil(self._data) # type: ignore[arg-type]
200 def __index__(self) -> Any:
201 return self._data.__index__() # type: ignore[union-attr]
204class BoolConfigData[D: bool](NumberConfigData[D]):
205 # noinspection GrazieInspection
206 """
207 布尔值配置数据
209 .. versionadded:: 0.1.5
211 .. versionchanged:: 0.2.0
212 直接对参数调用 :py:class:`bool`
213 """
215 _data: D
216 data: D
218 def __init__(self, data: D | None = None):
219 """
220 :param data: 布尔值数据
221 :type data: D | None
222 """ # noqa: D205
223 super().__init__(cast(D, bool(data)))
226__all__ = (
227 "BoolConfigData",
228 "NumberConfigData",
229)