Coverage for src / c41811 / config / basic / utils.py: 100%
23 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-06 06:04 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-06 06:04 +0000
1# cython: language_level = 3 # noqa: ERA001
4"""
5杂项实用程序
7.. versionadded:: 0.2.0
8"""
10from collections.abc import Callable
11from functools import update_wrapper
12from typing import Any
13from typing import cast
14from typing import overload
16import wrapt
18from ..abc import ABCConfigData
19from ..abc import ABCPath
20from ..abc import PathLike
21from ..errors import ConfigDataReadOnlyError
22from ..path import Path
25@overload
26def fmt_path(path: str) -> Path: ...
29@overload
30def fmt_path[P: ABCPath[Any]](path: P) -> P: ...
33def fmt_path(path: PathLike) -> ABCPath[Any] | Path:
34 """
35 格式化配置数据路径
37 :param path: 任意可转换为配置数据路径的对象
38 :type path: PathLike
40 :return: 配置数据
41 :rtype: ABCPath | Path
42 """
43 if isinstance(path, ABCPath):
44 return path
45 return Path.from_str(path)
48# noinspection PyNewStyleGenericSyntax
49def check_read_only[F: Callable[..., Any]](func: F) -> F:
50 """
51 装饰 :py:class:`ABCConfigData` 的方法提供 :py:attr:`ABCConfigData.read_only` 的便捷检查,当其不为 :py:const:`True`
52 时抛出 :py:exc:`TypeError`
54 :param func: 目标方法
55 :type func: F
57 :return: 装饰后方法
58 :rtype: F
59 """ # noqa: RUF002, D205
61 @wrapt.decorator # type: ignore[arg-type]
62 def wrapper(wrapped: F, instance: ABCConfigData | None, args: tuple[Any, ...], kwargs: dict[str, Any]) -> Any:
63 if instance is None: # pragma: no cover
64 msg = "must be called from an instance"
65 raise TypeError(msg)
66 if instance.read_only:
67 raise ConfigDataReadOnlyError
68 return wrapped(*args, **kwargs)
70 return cast(F, update_wrapper(wrapper(func), func))
73__all__ = (
74 "check_read_only",
75 "fmt_path",
76)