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

1# cython: language_level = 3 # noqa: ERA001 

2 

3 

4""" 

5数值类型配置数据实现 

6 

7.. versionadded:: 0.2.0 

8""" 

9 

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 

18 

19from ._generate_operators import generate 

20from ._generate_operators import operate 

21from .core import BasicSingleConfigData 

22 

23 

24@generate 

25class NumberConfigData[D: int | float | Number](BasicSingleConfigData[D]): 

26 """ 

27 数值配置数据 

28 

29 .. versionadded:: 0.1.5 

30 """ 

31 

32 _data: D 

33 

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)) 

45 

46 @property 

47 @override 

48 def data_read_only(self) -> Literal[False]: 

49 """ 

50 配置数据是否为只读 

51 

52 :return: 配置数据是否为只读 

53 :rtype: Literal[False] 

54 

55 .. note:: 

56 该配置数据类始终认为配置数据非只读,使其能正确作为配置数据容器使用 

57 """ # noqa: RUF002 

58 return False 

59 

60 @property # type: ignore[explicit-override] # mypy抽风 

61 @override 

62 def data(self) -> D: 

63 """ 

64 配置的原始数据 

65 

66 .. caution:: 

67 未默认做深拷贝,可能导致非预期的行为 

68 

69 .. versionchanged:: 0.3.0 

70 现在是可写属性 

71 """ # noqa: RUF002 

72 return self._data 

73 

74 @data.setter 

75 def data(self, data: D) -> None: 

76 self._data = data 

77 

78 def __int__(self) -> int: 

79 return int(self._data) # type: ignore[arg-type] 

80 

81 def __float__(self) -> float: 

82 return float(self._data) # type: ignore[arg-type] 

83 

84 @operate(operator.add, operator.iadd) 

85 def __add__(self, other: Any) -> Self: # type: ignore[empty-body] 

86 ... 

87 

88 @operate(operator.sub, operator.isub) 

89 def __sub__(self, other: Any) -> Self: # type: ignore[empty-body] 

90 ... 

91 

92 @operate(operator.mul, operator.imul) 

93 def __mul__(self, other: Any) -> Self: # type: ignore[empty-body] 

94 ... 

95 

96 @operate(operator.truediv, operator.itruediv) 

97 def __truediv__(self, other: Any) -> Self: # type: ignore[empty-body] 

98 ... 

99 

100 @operate(operator.floordiv, operator.ifloordiv) 

101 def __floordiv__(self, other: Any) -> Self: # type: ignore[empty-body] 

102 ... 

103 

104 @operate(operator.mod, operator.imod) 

105 def __mod__(self, other: Any) -> Self: # type: ignore[empty-body] 

106 ... 

107 

108 @operate(operator.pow, operator.ipow) 

109 def __pow__(self, other: Any) -> Self: # type: ignore[empty-body] 

110 ... 

111 

112 @operate(operator.and_, operator.iand) 

113 def __and__(self, other: Any) -> Self: # type: ignore[empty-body] 

114 ... 

115 

116 @operate(operator.or_, operator.ior) 

117 def __or__(self, other: Any) -> Self: # type: ignore[empty-body] 

118 ... 

119 

120 @operate(operator.xor, operator.ixor) 

121 def __xor__(self, other: Any) -> Self: # type: ignore[empty-body] 

122 ... 

123 

124 @operate(operator.matmul, operator.imatmul) 

125 def __matmul__(self, other: Any) -> Self: # type: ignore[empty-body] 

126 ... 

127 

128 @operate(operator.lshift, operator.ilshift) 

129 def __lshift__(self, other: Any) -> Self: # type: ignore[empty-body] 

130 ... 

131 

132 @operate(operator.rshift, operator.irshift) 

133 def __rshift__(self, other: Any) -> Self: # type: ignore[empty-body] 

134 ... 

135 

136 def __radd__(self, other: Any) -> Self: # type: ignore[empty-body] 

137 ... 

138 

139 def __rsub__(self, other: Any) -> Self: # type: ignore[empty-body] 

140 ... 

141 

142 def __rmul__(self, other: Any) -> Self: # type: ignore[empty-body] 

143 ... 

144 

145 def __rtruediv__(self, other: Any) -> Self: # type: ignore[empty-body] 

146 ... 

147 

148 def __rfloordiv__(self, other: Any) -> Self: # type: ignore[empty-body] 

149 ... 

150 

151 def __rmod__(self, other: Any) -> Self: # type: ignore[empty-body] 

152 ... 

153 

154 def __rpow__(self, other: Any) -> Self: # type: ignore[empty-body] 

155 ... 

156 

157 def __rand__(self, other: Any) -> Self: # type: ignore[empty-body] 

158 ... 

159 

160 def __ror__(self, other: Any) -> Self: # type: ignore[empty-body] 

161 ... 

162 

163 def __rxor__(self, other: Any) -> Self: # type: ignore[empty-body] 

164 ... 

165 

166 def __rmatmul__(self, other: Any) -> Self: # type: ignore[empty-body] 

167 ... 

168 

169 def __rlshift__(self, other: Any) -> Self: # type: ignore[empty-body] 

170 ... 

171 

172 def __rrshift__(self, other: Any) -> Self: # type: ignore[empty-body] 

173 ... 

174 

175 def __invert__(self) -> Any: 

176 return ~self._data # type: ignore[operator] 

177 

178 def __neg__(self) -> Any: 

179 return -self._data # type: ignore[operator] 

180 

181 def __pos__(self) -> Any: 

182 return +self._data # type: ignore[operator] 

183 

184 def __abs__(self) -> D: 

185 return abs(self._data) # type: ignore[return-value,arg-type] 

186 

187 # noinspection SpellCheckingInspection 

188 def __round__(self, ndigits: int | None = None) -> Any: 

189 return round(self._data, ndigits) # type: ignore[arg-type] 

190 

191 def __trunc__(self) -> Any: 

192 return math.trunc(self._data) # type: ignore[arg-type] 

193 

194 def __floor__(self) -> Any: 

195 return math.floor(self._data) # type: ignore[arg-type] 

196 

197 def __ceil__(self) -> Any: 

198 return math.ceil(self._data) # type: ignore[arg-type] 

199 

200 def __index__(self) -> Any: 

201 return self._data.__index__() # type: ignore[union-attr] 

202 

203 

204class BoolConfigData[D: bool](NumberConfigData[D]): 

205 # noinspection GrazieInspection 

206 """ 

207 布尔值配置数据 

208 

209 .. versionadded:: 0.1.5 

210 

211 .. versionchanged:: 0.2.0 

212 直接对参数调用 :py:class:`bool` 

213 """ 

214 

215 _data: D 

216 data: D 

217 

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))) 

224 

225 

226__all__ = ( 

227 "BoolConfigData", 

228 "NumberConfigData", 

229)