You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hypothesis构建int子类实例报错:TypeError问题求解

解决Hypothesis无法构建FixedUint子类实例的问题

问题根源

int是不可变类型,它的实例创建逻辑由__new__方法控制,而非__init__。你的FixedUint重写了__init__并添加了value参数,但int.__init__不接受value关键字参数——Hypothesis默认会用关键字参数传递构造参数,导致U64(value=xxx)调用触发TypeError。

方案一:将验证逻辑移至__new__方法

这是子类化不可变类型的标准做法,直接在实例创建阶段完成验证,同时避免关键字参数冲突:

from typing import ClassVar, TypeVar

from hypothesis import strategies as st

T = TypeVar("T", bound="FixedUint")


class FixedUint(int):
    MAX_VALUE: ClassVar["FixedUint"]

    def __new__(cls: type[T], value: int) -> T:
        # 先验证输入合法性
        if not isinstance(value, int):
            raise TypeError("值必须为整数")
        if value < 0 or value > cls.MAX_VALUE:
            raise OverflowError(f"值 {value} 超出范围 [0, {cls.MAX_VALUE}]")
        # 调用父类__new__创建实例,用位置参数传递value
        return super().__new__(cls, value)


class U256(FixedUint):
    MAX_VALUE: ClassVar[U256] = U256(2**256 - 1)


class U64(FixedUint):
    MAX_VALUE: ClassVar[U64] = U64(2**64 - 1)


# 现在可以正常生成实例
print(st.from_type(U64).example())

关键说明

  • 不可变类型的实例初始化逻辑必须放在__new__中,因为__init__是在实例已经创建后才执行的,此时修改属性没有意义。
  • 调用super().__new__(cls, value)时使用位置参数,完全符合int的构造规则,不会触发关键字参数错误。

方案二:注册Hypothesis自定义策略(无需修改类结构)

如果无法改动原有FixedUint的代码,可以给Hypothesis注册针对U64/U256的生成策略,绕过构造函数的参数问题:

# 在原有代码基础上添加以下注册逻辑
st.register_type_strategy(
    U64, 
    st.integers(min_value=0, max_value=U64.MAX_VALUE).map(U64)
)
st.register_type_strategy(
    U256, 
    st.integers(min_value=0, max_value=U256.MAX_VALUE).map(U256)
)

# 验证生成
print(st.from_type(U64).example())

关键说明

  • 该策略先生成合法范围内的整数,再通过map转换为U64/U256实例,避免了Hypothesis用关键字参数调用构造函数的行为。
  • 适合无法修改原有类定义的场景,快速适配Hypothesis的生成逻辑。

内容的提问来源于stack exchange,提问作者ClementWalter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 03:35:09