问题描述
在 Python 3.14 下,实例化任何 _Base 子类(StatusInfo、AppInfo、DeviceInfo、BatteryInfo 等)都会抛:
TypeError: '<StatusInfo > does not have annotations'
这会导致所有依赖这些类型的接口失效。最典型的是 AppiumClient.status():它内部调用 StatusInfo.value_of() → StatusInfo() → _Base.__init__,于是连接 WDA 时一直报:
<StatusInfo > does not have annotations
实际上 WDA 是连上了的,只是客户端解析不了 status 响应。
环境
- wdapy:
1.0.0
- Python:
3.14.6
- OS:macOS arm64
复现
import wdapy._types as t
t.StatusInfo()
# TypeError: '<StatusInfo > does not have annotations'
传类而不是实例则正常:
import typing, wdapy._types as t
print(typing.get_type_hints(t.StatusInfo))
# {'ip': <class 'str'>, 'session_id': <class 'str'>, 'message': <class 'str'>}
根因
wdapy/_types.py 的 _Base.__init__ 把实例 self 传给了 typing.get_type_hints:
class _Base:
def __init__(self):
# set default value
for k, _ in typing.get_type_hints(self).items(): # 传的是实例
if not hasattr(self, k):
setattr(self, k, None)
- Python ≤ 3.13:
get_type_hints 内部走 getattr(obj, '__annotations__'),实例属性查找会回退到类,所以能拿到注解。
- Python 3.14:
get_type_hints 改基于 annotationlib.get_annotations(PEP 649 延迟注解),__annotations__ 变成 type 上的数据描述符,实例不再回退到类,直接抛 TypeError: '<StatusInfo > does not have annotations'。
验证:
s = object.__new__(StatusInfo)
getattr(s, '__annotations__', 'DEFAULT') # -> 'DEFAULT'(3.14 下实例不再回退到类)
hasattr(s, '__annotations__') # -> False
建议修复
改成传类即可,语义不变,兼容 3.8 ~ 3.14:
class _Base:
def __init__(self):
# set default value
for k, _ in typing.get_type_hints(type(self)).items():
if not hasattr(self, k):
setattr(self, k, None)
type(self) 解析为实际子类(如 StatusInfo),get_type_hints 会按预期读取该类的注解;value_of(调用 cls())及所有 _Base 子类均不受影响。
问题描述
在 Python 3.14 下,实例化任何
_Base子类(StatusInfo、AppInfo、DeviceInfo、BatteryInfo等)都会抛:这会导致所有依赖这些类型的接口失效。最典型的是
AppiumClient.status():它内部调用StatusInfo.value_of()→StatusInfo()→_Base.__init__,于是连接 WDA 时一直报:实际上 WDA 是连上了的,只是客户端解析不了
status响应。环境
1.0.03.14.6复现
传类而不是实例则正常:
根因
wdapy/_types.py的_Base.__init__把实例self传给了typing.get_type_hints:get_type_hints内部走getattr(obj, '__annotations__'),实例属性查找会回退到类,所以能拿到注解。get_type_hints改基于annotationlib.get_annotations(PEP 649 延迟注解),__annotations__变成type上的数据描述符,实例不再回退到类,直接抛TypeError: '<StatusInfo > does not have annotations'。验证:
建议修复
改成传类即可,语义不变,兼容 3.8 ~ 3.14:
type(self)解析为实际子类(如StatusInfo),get_type_hints会按预期读取该类的注解;value_of(调用cls())及所有_Base子类均不受影响。