Coverage for src / c41811 / config / utils.py: 100%
68 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-09 01:06 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-09 01:06 +0000
1# cython: language_level = 3 # noqa: ERA001
3"""
4杂项实用程序
6.. versionadded:: 0.2.0
7"""
9from collections import OrderedDict
10from collections.abc import Iterator
11from collections.abc import Mapping
12from collections.abc import Sequence
13from copy import deepcopy
14from functools import wraps
15from types import NotImplementedType
16from typing import Any
17from typing import Self
18from typing import cast
19from typing import override
22def singleton[C: type[Any]](target_cls: C, /) -> C:
23 """
24 单例模式类装饰器
26 :param target_cls: 目标类
27 :type target_cls: C
29 :return: 装饰后的类
30 :rtype: C
31 """
33 @wraps(target_cls.__new__)
34 def new_singleton(cls: C, /, *args: Any, **kwargs: Any) -> C:
35 if not hasattr(cls, "__singleton_instance__"):
36 # noinspection PyUnresolvedReferences
37 cls.__singleton_instance__ = cls.__singleton_new__(cls, *args, **kwargs)
39 # noinspection PyProtectedMember
40 return cast(C, cls.__singleton_instance__)
42 target_cls.__singleton_new__ = target_cls.__new__
43 target_cls.__new__ = staticmethod(new_singleton) # type: ignore[assignment]
45 return target_cls
48@singleton
49class UnsetType:
50 """用于填充默认值的特殊值"""
52 __slots__ = ()
54 @override
55 def __str__(self) -> str:
56 return "<Unset Argument>"
58 def __bool__(self) -> bool:
59 return False
62Unset = UnsetType()
63"""
64用于填充默认值的特殊值
65"""
68class Ref[T]:
69 """
70 间接持有对象引用的容器
72 .. versionchanged:: 0.3.0
73 重命名 ``CellType`` 为 ``Ref``
75 重命名字段 ``cell_contents`` 为 ``value``
76 """
78 __slots__ = ("value",)
80 def __init__(self, value: T):
81 """
82 :param value: 引用对象
83 :type value: T
84 """ # noqa: D205
85 self.value = value
87 @override
88 def __repr__(self) -> str:
89 return f"<{type(self).__name__} ({self.value!r})>"
92class FrozenArguments:
93 """
94 存储冻结的参数的容器
96 .. versionadded:: 0.3.0
97 """
99 def __init__(self, args: Sequence[Any] | None = None, kwargs: Mapping[str, Any] | None = None):
100 """
101 :param args: 位置参数
102 :type args: Sequence[Any]
103 :param kwargs: 关键字参数
104 :type kwargs: Mapping[str, Any]
105 """ # noqa: D205
106 self._args = () if args is None else tuple(args)
107 self._kwargs: tuple[tuple[str, Any], ...] = () if kwargs is None else tuple((k, v) for k, v in kwargs.items())
109 @property
110 def args(self) -> tuple[Any, ...]:
111 """
112 位置参数
114 :return: 位置参数
115 :rtype: tuple[Any]
116 """
117 return deepcopy(self._args)
119 @property
120 def kwargs(self) -> OrderedDict[str, Any]:
121 """
122 关键字参数
124 :return: 关键字参数
125 :rtype: OrderedDict[str, Any]
126 """
127 return OrderedDict(deepcopy(self._kwargs))
129 # noinspection PyTypeHints
130 def __or__(self, other: tuple[Sequence[Any], Mapping[str, Any]] | Self) -> Self | NotImplementedType:
131 if isinstance(other, tuple):
132 other = type(self)(*other)
133 if not isinstance(other, FrozenArguments):
134 return NotImplemented
135 merged_args = list(self._args)
136 merged_args[: len(other._args)] = other.args
138 merged_kwargs = self.kwargs | other.kwargs
139 return type(self)(merged_args, merged_kwargs)
141 def __iter__(self) -> Iterator[tuple[Any, ...] | OrderedDict[str, Any]]:
142 yield self.args
143 yield self.kwargs
145 @override
146 def __eq__(self, other: Any) -> bool:
147 if not isinstance(other, FrozenArguments):
148 return NotImplemented
149 return self._args == other._args and self._kwargs == other._kwargs
151 @override
152 def __hash__(self) -> int:
153 return hash(self._args) ^ hash(self._kwargs)
156__all__ = (
157 "FrozenArguments",
158 "Ref",
159 "Unset",
160 "UnsetType",
161 "singleton",
162)