fix(config): 处理 _convert_field 函数中若干边界情况

1. 支持裸 list/set/tuple 注解(无类型参数)时的安全转换
2. 修复 tuple[T, ...] 不定长元组解析逻辑
3. 对非法 tuple 注解(如 tuple[str, int, ...])给出明确错误提示
4. 字符串"false"转换bool类型时不再转为True
pull/1517/head
suzmii 2026-02-19 23:27:50 +08:00
parent b63b7a7fb9
commit 65374685cc
1 changed files with 17 additions and 1 deletions

View File

@ -77,6 +77,8 @@ class ConfigBase:
# 检查提供的value是否为list # 检查提供的value是否为list
if not isinstance(value, list): if not isinstance(value, list):
raise TypeError(f"Expected an list for {field_type.__name__}, got {type(value).__name__}") raise TypeError(f"Expected an list for {field_type.__name__}, got {type(value).__name__}")
if field_type_args == () and field_origin_type:
return field_origin_type(value)
if field_origin_type is list: if field_origin_type is list:
# 如果列表元素类型是ConfigBase的子类则对每个元素调用from_dict # 如果列表元素类型是ConfigBase的子类则对每个元素调用from_dict
@ -90,8 +92,18 @@ class ConfigBase:
elif field_origin_type is set: elif field_origin_type is set:
return {cls._convert_field(item, field_type_args[0]) for item in value} return {cls._convert_field(item, field_type_args[0]) for item in value}
elif field_origin_type is tuple: elif field_origin_type is tuple:
# fix: support Tuple[int, ...]
if len(field_type_args) == 2 and field_type_args[1] is Ellipsis:
return tuple(cls._convert_field(item, field_type_args[0]) for item in value)
elif Ellipsis in field_type_args:
raise TypeError(
f"Invalid tuple annotation: {field_type}. "
"Only tuple[T, ...] (variadic homogeneous) or tuple[T1, T2, ...] (fixed length) is supported."
)
# 检查提供的value长度是否与类型参数一致 # 检查提供的value长度是否与类型参数一致
if len(value) != len(field_type_args): elif len(value) != len(field_type_args):
raise TypeError( raise TypeError(
f"Expected {len(field_type_args)} items for {field_type.__name__}, got {len(value)}" f"Expected {len(field_type_args)} items for {field_type.__name__}, got {len(value)}"
) )
@ -158,6 +170,10 @@ class ConfigBase:
if field_type is Any or isinstance(value, field_type): if field_type is Any or isinstance(value, field_type):
return value return value
# fix: bool("false") => True
if field_type is bool and type(value) is str and value.lower() in ("f", "false", "0"):
return False
# 其他类型,尝试直接转换 # 其他类型,尝试直接转换
try: try:
return field_type(value) return field_type(value)