NumPy-源码解析-八十六-

40 阅读1小时+

NumPy 源码解析(八十六)

.\numpy\numpy\_core\tests\test_scalarbuffer.py

"""
Test scalar buffer interface adheres to PEP 3118
"""
# 导入必要的库和模块
import numpy as np
from numpy._core._rational_tests import rational
from numpy._core._multiarray_tests import get_buffer_info
import pytest

from numpy.testing import assert_, assert_equal, assert_raises

# PEP3118 格式字符串,用于本机类型(标准对齐和字节顺序)
scalars_and_codes = [
    (np.bool, '?'),
    (np.byte, 'b'),
    (np.short, 'h'),
    (np.intc, 'i'),
    (np.long, 'l'),
    (np.longlong, 'q'),
    (np.ubyte, 'B'),
    (np.ushort, 'H'),
    (np.uintc, 'I'),
    (np.ulong, 'L'),
    (np.ulonglong, 'Q'),
    (np.half, 'e'),
    (np.single, 'f'),
    (np.double, 'd'),
    (np.longdouble, 'g'),
    (np.csingle, 'Zf'),
    (np.cdouble, 'Zd'),
    (np.clongdouble, 'Zg'),
]
scalars_only, codes_only = zip(*scalars_and_codes)

# 测试用例类,用于测试标量符合 PEP3118 的缓冲接口
class TestScalarPEP3118:

    # 参数化测试,对每种标量类型进行测试
    @pytest.mark.parametrize('scalar', scalars_only, ids=codes_only)
    def test_scalar_match_array(self, scalar):
        # 创建标量对象和相应的空数组
        x = scalar()
        a = np.array([], dtype=np.dtype(scalar))
        # 创建标量的内存视图
        mv_x = memoryview(x)
        mv_a = memoryview(a)
        # 断言两者的格式相同
        assert_equal(mv_x.format, mv_a.format)

    # 参数化测试,对每种标量类型进行测试
    @pytest.mark.parametrize('scalar', scalars_only, ids=codes_only)
    def test_scalar_dim(self, scalar):
        # 创建标量对象并获取其内存视图
        x = scalar()
        mv_x = memoryview(x)
        # 断言标量的字节大小与其 dtype 的字节大小相等
        assert_equal(mv_x.itemsize, np.dtype(scalar).itemsize)
        # 断言标量的维度为 0
        assert_equal(mv_x.ndim, 0)
        # 断言标量的形状为 ()
        assert_equal(mv_x.shape, ())
        # 断言标量的步幅为 ()
        assert_equal(mv_x.strides, ())
        # 断言标量的子偏移为 ()
        assert_equal(mv_x.suboffsets, ())

    # 参数化测试,对每种标量类型进行测试
    @pytest.mark.parametrize('scalar, code', scalars_and_codes, ids=codes_only)
    def test_scalar_code_and_properties(self, scalar, code):
        # 创建标量对象
        x = scalar()
        # 期望的内存视图属性字典
        expected = dict(strides=(), itemsize=x.dtype.itemsize, ndim=0,
                        shape=(), format=code, readonly=True)
        # 获取标量对象的内存视图
        mv_x = memoryview(x)
        # 断言内存视图的属性与期望的属性相等
        assert self._as_dict(mv_x) == expected

    # 参数化测试,对每种标量类型进行测试
    @pytest.mark.parametrize('scalar', scalars_only, ids=codes_only)
    def test_scalar_buffers_readonly(self, scalar):
        # 创建标量对象
        x = scalar()
        # 使用 pytest 断言捕获 BufferError 异常,确保标量缓冲区只读
        with pytest.raises(BufferError, match="scalar buffer is readonly"):
            get_buffer_info(x, ["WRITABLE"])
    def test_void_scalar_structured_data(self):
        # 定义一个结构化数据类型,包含一个长度为16的字符串和一个形状为(2,)的双精度浮点数数组
        dt = np.dtype([('name', np.str_, 16), ('grades', np.float64, (2,))])
        # 创建一个标量 ndarray,符合上述定义的数据类型,并取出其中的标量值
        x = np.array(('ndarray_scalar', (1.2, 3.0)), dtype=dt)[()]
        # 断言 x 是 np.void 类型的对象
        assert_(isinstance(x, np.void))
        # 从 x 中创建一个 memoryview 对象
        mv_x = memoryview(x)
        # 计算预期的 memoryview 大小,包括字符串和浮点数数组的大小
        expected_size = 16 * np.dtype((np.str_, 1)).itemsize
        expected_size += 2 * np.dtype(np.float64).itemsize
        # 断言 memoryview 的 itemsize 符合预期大小
        assert_equal(mv_x.itemsize, expected_size)
        # 断言 memoryview 的维度为 0
        assert_equal(mv_x.ndim, 0)
        # 断言 memoryview 的形状为空元组
        assert_equal(mv_x.shape, ())
        # 断言 memoryview 的 strides 为空元组
        assert_equal(mv_x.strides, ())
        # 断言 memoryview 的 suboffsets 为空元组
        assert_equal(mv_x.suboffsets, ())

        # 检查标量格式字符串与 ndarray 格式字符串是否匹配
        a = np.array([('Sarah', (8.0, 7.0)), ('John', (6.0, 7.0))], dtype=dt)
        # 断言 a 是 np.ndarray 类型的对象
        assert_(isinstance(a, np.ndarray))
        # 从 a 中创建一个 memoryview 对象
        mv_a = memoryview(a)
        # 断言 memoryview 的 itemsize 与 mv_x 的 itemsize 相等
        assert_equal(mv_x.itemsize, mv_a.itemsize)
        # 断言 memoryview 的 format 与 mv_a 的 format 相等

        # 检查不允许导出可写缓冲区(技术上有时可能会允许在此处...)
        with pytest.raises(BufferError, match="scalar buffer is readonly"):
            get_buffer_info(x, ["WRITABLE"])

    def _as_dict(self, m):
        # 返回 memoryview 对象 m 的属性字典
        return dict(strides=m.strides, shape=m.shape, itemsize=m.itemsize,
                    ndim=m.ndim, format=m.format, readonly=m.readonly)

    def test_datetime_memoryview(self):
        # gh-11656
        # 使用 np.datetime64 创建一个 datetime 对象 dt1
        dt1 = np.datetime64('2016-01-01')
        # 使用 np.datetime64 创建一个 datetime 对象 dt2
        dt2 = np.datetime64('2017-01-01')
        # 定义预期的 memoryview 属性字典,对于 dt1 和 dt2 都应相同
        expected = dict(strides=(1,), itemsize=1, ndim=1, shape=(8,),
                        format='B', readonly=True)
        # 创建 dt1 的 memoryview 对象 v,并断言其属性字典与预期相同
        v = memoryview(dt1)
        assert self._as_dict(v) == expected
        # 创建 dt2 - dt1 的 memoryview 对象 v,并断言其属性字典与预期相同
        v = memoryview(dt2 - dt1)
        assert self._as_dict(v) == expected

        # 创建一个 dtype,包含一个 'uint16' 类型的字段 'a' 和一个 'M8[s]' 类型的字段 'b'
        dt = np.dtype([('a', 'uint16'), ('b', 'M8[s]')])
        # 创建一个空的 dt 类型的 ndarray a
        a = np.empty(1, dt)
        # 尝试创建一个 PEP 3118 格式不合法的缓冲区,预期会失败
        assert_raises((ValueError, BufferError), memoryview, a[0])

        # 检查不允许导出可写缓冲区
        with pytest.raises(BufferError, match="scalar buffer is readonly"):
            get_buffer_info(dt1, ["WRITABLE"])

    @pytest.mark.parametrize('s', [
        pytest.param("\x32\x32", id="ascii"),
        pytest.param("\uFE0F\uFE0F", id="basic multilingual"),
        pytest.param("\U0001f4bb\U0001f4bb", id="non-BMP"),
    ])
    # 定义一个测试方法,用于测试 UCS4 字符串的特性
    def test_str_ucs4(self, s):
        # 将输入的字符串 s 转换为 numpy.str_ 类型,仅子类实现了缓冲区协议
        s = np.str_(s)  # only our subclass implements the buffer protocol

        # 预期结果,表示 UCS4 编码的字符串特性
        expected = dict(strides=(), itemsize=8, ndim=0, shape=(), format='2w',
                        readonly=True)

        # 创建内存视图对象 v
        v = memoryview(s)
        # 断言内存视图的属性与预期的字典 expected 相符
        assert self._as_dict(v) == expected

        # 将内存视图 v 视作 i4 类型的 numpy 数组,获取其对应的整数码点
        code_points = np.frombuffer(v, dtype='i4')

        # 断言获取的码点与字符串 s 中字符的 Unicode 编码相符
        assert_equal(code_points, [ord(c) for c in s])

        # 检查不允许导出可写缓冲区的情况
        with pytest.raises(BufferError, match="scalar buffer is readonly"):
            get_buffer_info(s, ["WRITABLE"])

    # 测试当用户自定义标量类型无法导出缓冲区时的情况
    def test_user_scalar_fails_buffer(self):
        # 创建一个有理数对象 r
        r = rational(1)
        # 使用 assert_raises 检查期望会抛出 TypeError 异常
        with assert_raises(TypeError):
            memoryview(r)

        # 再次检查不允许导出可写缓冲区的情况
        with pytest.raises(BufferError, match="scalar buffer is readonly"):
            get_buffer_info(r, ["WRITABLE"])

.\numpy\numpy\_core\tests\test_scalarinherit.py

""" Test printing of scalar types.

"""
# 引入 pytest 库,用于编写和运行测试
import pytest

# 引入 numpy 库及其子模块
import numpy as np
# 从 numpy.testing 模块中引入测试工具函数
from numpy.testing import assert_, assert_raises


# 定义类 A,作为基类
class A:
    pass

# 定义类 B,继承自 A 和 np.float64
class B(A, np.float64):
    pass

# 定义类 C,继承自 B
class C(B):
    pass

# 定义类 D,继承自 C 和 B
class D(C, B):
    pass

# 定义类 B0,继承自 np.float64 和 A
class B0(np.float64, A):
    pass

# 定义类 C0,继承自 B0
class C0(B0):
    pass

# 定义类 HasNew,重载 __new__ 方法
class HasNew:
    def __new__(cls, *args, **kwargs):
        return cls, args, kwargs

# 定义类 B1,继承自 np.float64 和 HasNew
class B1(np.float64, HasNew):
    pass


# 定义测试类 TestInherit
class TestInherit:
    # 定义测试方法 test_init
    def test_init(self):
        # 创建 B 类的实例 x
        x = B(1.0)
        # 断言 x 转换为字符串后结果为 '1.0'
        assert_(str(x) == '1.0')
        # 创建 C 类的实例 y
        y = C(2.0)
        # 断言 y 转换为字符串后结果为 '2.0'
        assert_(str(y) == '2.0')
        # 创建 D 类的实例 z
        z = D(3.0)
        # 断言 z 转换为字符串后结果为 '3.0'
        assert_(str(z) == '3.0')

    # 定义测试方法 test_init2
    def test_init2(self):
        # 创建 B0 类的实例 x
        x = B0(1.0)
        # 断言 x 转换为字符串后结果为 '1.0'
        assert_(str(x) == '1.0')
        # 创建 C0 类的实例 y
        y = C0(2.0)
        # 断言 y 转换为字符串后结果为 '2.0'
        assert_(str(y) == '2.0')

    # 定义测试方法 test_gh_15395
    def test_gh_15395(self):
        # 创建 B1 类的实例 x
        x = B1(1.0)
        # 断言 x 转换为字符串后结果为 '1.0'
        assert_(str(x) == '1.0')

        # 使用 pytest 检查以下代码是否引发 TypeError 异常
        with pytest.raises(TypeError):
            B1(1.0, 2.0)


# 定义测试类 TestCharacter
class TestCharacter:
    # 定义测试方法 test_char_radd
    def test_char_radd(self):
        # 测试 np.bytes_ 和 np.str_ 的加法操作
        # np.bytes_ 对象 np_s 和 np.str_ 对象 np_u
        np_s = np.bytes_('abc')
        np_u = np.str_('abc')
        # 字节串 b'def' 和 字符串 'def'
        s = b'def'
        u = 'def'
        # 断言 np_s 与 np_u 的右加操作结果为 NotImplemented
        assert_(np_s.__radd__(np_s) is NotImplemented)
        assert_(np_s.__radd__(np_u) is NotImplemented)
        assert_(np_s.__radd__(s) is NotImplemented)
        assert_(np_s.__radd__(u) is NotImplemented)
        assert_(np_u.__radd__(np_s) is NotImplemented)
        assert_(np_u.__radd__(np_u) is NotImplemented)
        assert_(np_u.__radd__(s) is NotImplemented)
        assert_(np_u.__radd__(u) is NotImplemented)
        # 断言 s + np_s 的结果为 b'defabc'
        assert_(s + np_s == b'defabc')
        # 断言 u + np_u 的结果为 'defabc'

        # 定义类 MyStr,继承自 str 和 np.generic
        class MyStr(str, np.generic):
            # 空类,用于测试特殊情况
            pass

        # 使用 assert_raises 检查以下代码是否引发 TypeError 异常
        with assert_raises(TypeError):
            ret = s + MyStr('abc')

        # 定义类 MyBytes,继承自 bytes 和 np.generic
        class MyBytes(bytes, np.generic):
            # 空类,用于测试特殊情况
            pass

        # 测试 MyBytes 类的加法操作
        ret = s + MyBytes(b'abc')
        # 断言 ret 的类型与 s 的类型相同
        assert(type(ret) is type(s))
        # 断言 ret 的值等于 b"defabc"

    # 定义测试方法 test_char_repeat
    def test_char_repeat(self):
        # np.bytes_ 对象 np_s 和 np.str_ 对象 np_u
        np_s = np.bytes_('abc')
        np_u = np.str_('abc')
        # 预期的重复结果
        res_s = b'abc' * 5
        res_u = 'abc' * 5
        # 断言 np_s 的重复 5 次结果等于 res_s
        assert_(np_s * 5 == res_s)
        # 断言 np_u 的重复 5 次结果等于 res_u
        assert_(np_u * 5 == res_u)

.\numpy\numpy\_core\tests\test_scalarmath.py

# 导入上下文管理模块
import contextlib
# 导入系统相关模块
import sys
# 导入警告处理模块
import warnings
# 导入迭代工具模块
import itertools
# 导入运算符模块
import operator
# 导入平台信息模块
import platform
# 导入 numpy 中的 PEP 440 版本处理工具
from numpy._utils import _pep440
# 导入 pytest 测试框架
import pytest
# 导入 hypothesis 中的给定测试策略和设置模块
from hypothesis import given, settings
# 导入 hypothesis 中的随机抽样策略模块
from hypothesis.strategies import sampled_from
# 导入 hypothesis.extra 中的 numpy 扩展模块
from hypothesis.extra import numpy as hynp

# 导入 numpy 库并重命名为 np
import numpy as np
# 导入 numpy 中的复数警告
from numpy.exceptions import ComplexWarning
# 导入 numpy 测试模块中的各种断言函数
from numpy.testing import (
    assert_, assert_equal, assert_raises, assert_almost_equal,
    assert_array_equal, IS_PYPY, suppress_warnings, _gen_alignment_data,
    assert_warns, _SUPPORTS_SVE,
    )

# 定义常见的数据类型列表
types = [np.bool, np.byte, np.ubyte, np.short, np.ushort, np.intc, np.uintc,
         np.int_, np.uint, np.longlong, np.ulonglong,
         np.single, np.double, np.longdouble, np.csingle,
         np.cdouble, np.clongdouble]

# 获取所有浮点类型的子类列表
floating_types = np.floating.__subclasses__()
# 获取所有复数浮点类型的子类列表
complex_floating_types = np.complexfloating.__subclasses__()

# 定义包含对象和 None 的列表
objecty_things = [object(), None]

# 合理的标量操作符列表
reasonable_operators_for_scalars = [
    operator.lt, operator.le, operator.eq, operator.ne, operator.ge,
    operator.gt, operator.add, operator.floordiv, operator.mod,
    operator.mul, operator.pow, operator.sub, operator.truediv,
]


# 这个类测试了不同类型的数值运算行为
class TestTypes:
    # 测试各种类型的初始化和比较
    def test_types(self):
        for atype in types:
            a = atype(1)
            assert_(a == 1, "error with %r: got %r" % (atype, a))

    # 测试不同类型的加法运算
    def test_type_add(self):
        # 遍历类型列表
        for k, atype in enumerate(types):
            # 创建标量和数组
            a_scalar = atype(3)
            a_array = np.array([3], dtype=atype)
            # 再次遍历类型列表
            for l, btype in enumerate(types):
                b_scalar = btype(1)
                b_array = np.array([1], dtype=btype)
                # 进行加法运算,比较结果的数据类型
                c_scalar = a_scalar + b_scalar
                c_array = a_array + b_array
                assert_equal(c_scalar.dtype, c_array.dtype,
                           "error with types (%d/'%c' + %d/'%c')" %
                            (k, np.dtype(atype).char, l, np.dtype(btype).char))

    # 测试不同类型的数组创建
    def test_type_create(self):
        for k, atype in enumerate(types):
            # 使用不同类型创建数组,并进行比较
            a = np.array([1, 2, 3], atype)
            b = atype([1, 2, 3])
            assert_equal(a, b)

    # 测试标量对象的内存泄漏
    def test_leak(self):
        # 模拟大量标量对象的创建,观察内存泄漏情况
        for i in range(200000):
            np.add(1, 1)


# 检查 ufunc 和标量等价性的函数
def check_ufunc_scalar_equivalence(op, arr1, arr2):
    scalar1 = arr1[()]
    scalar2 = arr2[()]
    assert isinstance(scalar1, np.generic)
    assert isinstance(scalar2, np.generic)
    # 检查 arr1 或 arr2 是否包含复数类型的数据
    if arr1.dtype.kind == "c" or arr2.dtype.kind == "c":
        # 定义支持复数类型的比较运算符集合
        comp_ops = {operator.ge, operator.gt, operator.le, operator.lt}
        # 如果操作是比较运算符,并且 scalar1 或 scalar2 是 NaN,则跳过测试
        if op in comp_ops and (np.isnan(scalar1) or np.isnan(scalar2)):
            pytest.xfail("complex comp ufuncs use sort-order, scalars do not.")

    # 如果操作是乘方运算符,并且 arr2 的值在 [-1, 0, 0.5, 1, 2] 中
    if op == operator.pow and arr2.item() in [-1, 0, 0.5, 1, 2]:
        # 对于 array**scalar 的特殊情况,可能会有不同的结果数据类型
        # (其他乘方可能也存在问题,但这里不涉及。)
        # TODO: 应该解决这个问题会比较好。
        pytest.skip("array**2 can have incorrect/weird result dtype")

    # 忽略浮点异常,因为对于整数来说,它们可能只是不匹配。
    with warnings.catch_warnings(), np.errstate(all="ignore"):
        # 从 2022 年 3 月开始,将比较警告(DeprecationWarning)转换为错误
        warnings.simplefilter("error", DeprecationWarning)
        try:
            # 尝试应用操作符 op 到 arr1 和 arr2 上
            res = op(arr1, arr2)
        except Exception as e:
            # 如果出现异常,验证应该抛出相同类型的异常
            with pytest.raises(type(e)):
                op(scalar1, scalar2)
        else:
            # 否则,对 scalar1 和 scalar2 应用操作符,并验证结果与 res 是否严格相等
            scalar_res = op(scalar1, scalar2)
            assert_array_equal(scalar_res, res, strict=True)
# 标记此测试为较慢的测试
@pytest.mark.slow
# 设置测试的策略,包括最大样本数和超时时间
@settings(max_examples=10000, deadline=2000)
# 使用 hypothesis 的 given 装饰器定义测试参数
@given(
    # 从 reasonable_operators_for_scalars 中随机选择一个操作符作为参数
    sampled_from(reasonable_operators_for_scalars),
    # 生成一个标量 dtype 的 NumPy 数组,形状为空
    hynp.arrays(dtype=hynp.scalar_dtypes(), shape=()),
    # 生成另一个标量 dtype 的 NumPy 数组,形状为空
    hynp.arrays(dtype=hynp.scalar_dtypes(), shape=())
)
def test_array_scalar_ufunc_equivalence(op, arr1, arr2):
    """
    This is a thorough test attempting to cover important promotion paths
    and ensuring that arrays and scalars stay as aligned as possible.
    However, if it creates troubles, it should maybe just be removed.
    """
    # 调用函数,检查数组和标量之间的等效性
    check_ufunc_scalar_equivalence(op, arr1, arr2)


# 标记此测试为较慢的测试
@pytest.mark.slow
# 使用 hypothesis 的 given 装饰器定义测试参数
@given(
    # 从 reasonable_operators_for_scalars 中随机选择一个操作符作为参数
    sampled_from(reasonable_operators_for_scalars),
    # 生成一个标量 dtype 作为参数
    hynp.scalar_dtypes(),
    # 生成另一个标量 dtype 作为参数
    hynp.scalar_dtypes()
)
def test_array_scalar_ufunc_dtypes(op, dt1, dt2):
    # Same as above, but don't worry about sampling weird values so that we
    # do not have to sample as much
    # 创建一个 NumPy 数组,包含单个元素 2,指定数据类型为 dt1
    arr1 = np.array(2, dtype=dt1)
    # 创建一个 NumPy 数组,包含单个元素 3,指定数据类型为 dt2
    arr2 = np.array(3, dtype=dt2)  # some power do weird things.
    
    # 调用函数,检查数组和标量之间的等效性
    check_ufunc_scalar_equivalence(op, arr1, arr2)


# 使用 pytest 的 parametrize 装饰器,为测试指定不同的 fscalar 参数
@pytest.mark.parametrize("fscalar", [np.float16, np.float32])
def test_int_float_promotion_truediv(fscalar):
    # Promotion for mixed int and float32/float16 must not go to float64
    # 创建一个 np.int8 类型的整数 i
    i = np.int8(1)
    # 创建一个指定类型的浮点数 f,根据参数 fscalar 不同而变化
    f = fscalar(1)
    # 期望的结果数据类型,根据 i 和 f 的类型计算得出
    expected = np.result_type(i, f)
    # 断言整数 i 除以浮点数 f 的结果数据类型符合预期
    assert (i / f).dtype == expected
    # 断言浮点数 f 除以整数 i 的结果数据类型符合预期
    assert (f / i).dtype == expected
    # 但是普通的整数除法(int / int)应该返回 float64:
    assert (i / i).dtype == np.dtype("float64")
    # 对于 int16,结果至少应该是 float32(采用 ufunc 路径):
    assert (np.int16(1) / f).dtype == np.dtype("float32")


# 创建一个名为 TestBaseMath 的测试类
class TestBaseMath:
    # 使用 pytest 的 mark 装饰器标记此测试为预期失败,并给出原因
    @pytest.mark.xfail(_SUPPORTS_SVE, reason="gh-22982")
    def test_blocked(self):
        # 测试对于 SIMD 指令的对齐偏移
        # 对于 vz + 2 * (vs - 1) + 1 的对齐
        for dt, sz in [(np.float32, 11), (np.float64, 7), (np.int32, 11)]:
            # 生成对齐数据,返回输出、输入1、输入2和消息
            for out, inp1, inp2, msg in _gen_alignment_data(dtype=dt,
                                                            type='binary',
                                                            max_size=sz):
                # 期望 inp1 的元素全为 1
                exp1 = np.ones_like(inp1)
                # 将 inp1 的元素设置为 1
                inp1[...] = np.ones_like(inp1)
                # 将 inp2 的元素设置为 0
                inp2[...] = np.zeros_like(inp2)
                # 断言 inp1 与 inp2 的元素相加结果接近 exp1,如果不是则输出错误消息 msg
                assert_almost_equal(np.add(inp1, inp2), exp1, err_msg=msg)
                # 断言 inp1 与 2 相加结果接近 exp1 + 2,如果不是则输出错误消息 msg
                assert_almost_equal(np.add(inp1, 2), exp1 + 2, err_msg=msg)
                # 断言 1 与 inp2 相加结果接近 exp1,如果不是则输出错误消息 msg
                assert_almost_equal(np.add(1, inp2), exp1, err_msg=msg)

                # 将 inp1 与 inp2 的相加结果存入 out
                np.add(inp1, inp2, out=out)
                # 断言 out 的结果接近 exp1,如果不是则输出错误消息 msg
                assert_almost_equal(out, exp1, err_msg=msg)

                # 将 inp2 的元素逐个加上从 1 开始的序列
                inp2[...] += np.arange(inp2.size, dtype=dt) + 1
                # 断言 inp2 的平方结果接近 inp2 自身与自身相乘的结果,如果不是则输出错误消息 msg
                assert_almost_equal(np.square(inp2),
                                    np.multiply(inp2, inp2),  err_msg=msg)
                # 对于非整数型数据,跳过真实除法的断言
                if dt != np.int32:
                    # 断言 inp2 的倒数接近 1 除以 inp2 的结果,如果不是则输出错误消息 msg
                    assert_almost_equal(np.reciprocal(inp2),
                                        np.divide(1, inp2),  err_msg=msg)

                # 将 inp1 的元素设置为 1
                inp1[...] = np.ones_like(inp1)
                # 将 inp1 与 2 相加结果存入 out
                np.add(inp1, 2, out=out)
                # 断言 out 的结果接近 exp1 + 2,如果不是则输出错误消息 msg
                assert_almost_equal(out, exp1 + 2, err_msg=msg)
                # 将 inp2 的元素设置为 1
                inp2[...] = np.ones_like(inp2)
                # 将 2 与 inp2 相加结果存入 out
                np.add(2, inp2, out=out)
                # 断言 out 的结果接近 exp1 + 2,如果不是则输出错误消息 msg
                assert_almost_equal(out, exp1 + 2, err_msg=msg)

    def test_lower_align(self):
        # 检查未对齐到元素大小的数据
        # 即在 i386 上,双精度浮点数按 4 字节对齐
        d = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
        o = np.zeros(23 * 8, dtype=np.int8)[4:-4].view(np.float64)
        # 断言 d 与 d 的和接近 d 的两倍
        assert_almost_equal(d + d, d * 2)
        # 将 d 与 d 的和存入 o
        np.add(d, d, out=o)
        # 将 np.ones_like(d) 与 d 的和存入 o
        np.add(np.ones_like(d), d, out=o)
        # 将 d 与 np.ones_like(d) 的和存入 o
        np.add(d, np.ones_like(d), out=o)
        # 将 np.ones_like(d) 与 d 相加,但不存入任何输出
        np.add(np.ones_like(d), d)
        # 将 d 与 np.ones_like(d) 相加,但不存入任何输出
        np.add(d, np.ones_like(d))
# 定义一个测试类 TestPower,用于测试不同数据类型的幂运算
class TestPower:

    # 测试小数据类型(np.int8, np.int16, np.float16)
    def test_small_types(self):
        # 遍历数据类型列表
        for t in [np.int8, np.int16, np.float16]:
            # 创建一个 t 类型的变量 a,并赋值为 3
            a = t(3)
            # 计算 a 的四次方,赋值给变量 b
            b = a ** 4
            # 断言 b 的值为 81,如果不是则输出错误信息
            assert_(b == 81, "error with %r: got %r" % (t, b))

    # 测试大数据类型(np.int32, np.int64, np.float32, np.float64, np.longdouble)
    def test_large_types(self):
        # 遍历数据类型列表
        for t in [np.int32, np.int64, np.float32, np.float64, np.longdouble]:
            # 创建一个 t 类型的变量 a,并赋值为 51
            a = t(51)
            # 计算 a 的四次方,赋值给变量 b
            b = a ** 4
            # 构造错误信息字符串
            msg = "error with %r: got %r" % (t, b)
            # 如果 t 是整数类型,则断言 b 的值为 6765201,否则使用近似值比较
            if np.issubdtype(t, np.integer):
                assert_(b == 6765201, msg)
            else:
                assert_almost_equal(b, 6765201, err_msg=msg)

    # 测试整数类型取负幂运算
    def test_integers_to_negative_integer_power(self):
        # 构建一个列表,其中包含与各个数据类型的组合可能导致的负幂结果
        exp = [np.array(-1, dt)[()] for dt in 'bhilq']

        # 1 ** -1 特殊情况
        base = [np.array(1, dt)[()] for dt in 'bhilqBHILQ']
        # 遍历基数和负幂结果的组合
        for i1, i2 in itertools.product(base, exp):
            # 如果 i1 的数据类型不是 uint64,则断言会引发 ValueError
            if i1.dtype != np.uint64:
                assert_raises(ValueError, operator.pow, i1, i2)
            else:
                # 计算 i1 的 i2 次幂,返回浮点数结果
                res = operator.pow(i1, i2)
                # 断言 res 的数据类型为 np.float64,并近似等于 1.0
                assert_(res.dtype.type is np.float64)
                assert_almost_equal(res, 1.)

        # -1 ** -1 特殊情况
        base = [np.array(-1, dt)[()] for dt in 'bhilq']
        # 遍历基数和负幂结果的组合
        for i1, i2 in itertools.product(base, exp):
            # 如果 i1 的数据类型不是 uint64,则断言会引发 ValueError
            if i1.dtype != np.uint64:
                assert_raises(ValueError, operator.pow, i1, i2)
            else:
                # 计算 i1 的 i2 次幂,返回浮点数结果
                res = operator.pow(i1, i2)
                # 断言 res 的数据类型为 np.float64,并近似等于 -1.0
                assert_(res.dtype.type is np.float64)
                assert_almost_equal(res, -1.)

        # 2 ** -1 一般情况
        base = [np.array(2, dt)[()] for dt in 'bhilqBHILQ']
        # 遍历基数和负幂结果的组合
        for i1, i2 in itertools.product(base, exp):
            # 如果 i1 的数据类型不是 uint64,则断言会引发 ValueError
            if i1.dtype != np.uint64:
                assert_raises(ValueError, operator.pow, i1, i2)
            else:
                # 计算 i1 的 i2 次幂,返回浮点数结果
                res = operator.pow(i1, i2)
                # 断言 res 的数据类型为 np.float64,并近似等于 0.5
                assert_(res.dtype.type is np.float64)
                assert_almost_equal(res, .5)

    # 测试混合类型的幂运算
    def test_mixed_types(self):
        # 定义一个包含各种数据类型的列表
        typelist = [np.int8, np.int16, np.float16,
                    np.float32, np.float64, np.int8,
                    np.int16, np.int32, np.int64]
        # 遍历两个数据类型的组合
        for t1 in typelist:
            for t2 in typelist:
                # 创建一个 t1 类型的变量 a,并赋值为 3
                a = t1(3)
                # 创建一个 t2 类型的变量 b,并赋值为 2
                b = t2(2)
                # 计算 a 的 b 次幂,结果赋值给 result
                result = a**b
                # 构造错误信息字符串
                msg = ("error with %r and %r:"
                       "got %r, expected %r") % (t1, t2, result, 9)
                # 如果 result 的数据类型是整数类型,则断言 result 等于 9
                if np.issubdtype(np.dtype(result), np.integer):
                    assert_(result == 9, msg)
                else:
                    # 否则使用近似值比较
                    assert_almost_equal(result, 9, err_msg=msg)
    def test_modular_power(self):
        # 模幂功能未实现,因此确保引发错误
        a = 5  # 设置基数为5
        b = 4  # 设置指数为4
        c = 10  # 设置模数为10
        expected = pow(a, b, c)  # 计算 a^b % c 的结果,但此行实际上未使用,用 noqa: F841 标记告知 linter 可以忽略未使用的变量警告
        for t in (np.int32, np.float32, np.complex64):
            # 注意,3元幂运算只根据第一个参数进行分派
            # 对于不同的数据类型 t(a),验证 pow 函数的调用是否会引发 TypeError
            assert_raises(TypeError, operator.pow, t(a), b, c)
            assert_raises(TypeError, operator.pow, np.array(t(a)), b, c)
# 定义一个函数,实现整数除法和取模操作,并返回商和余数
def floordiv_and_mod(x, y):
    return (x // y, x % y)


# 根据数据类型判断符号并返回一个或两个元素的元组
def _signs(dt):
    if dt in np.typecodes['UnsignedInteger']:
        return (+1,)
    else:
        return (+1, -1)


# 定义一个测试类 TestModulus
class TestModulus:

    # 测试整数除法和取模的基本情况
    def test_modulus_basic(self):
        # 获取所有整数和浮点数的数据类型编码
        dt = np.typecodes['AllInteger'] + np.typecodes['Float']
        # 遍历 floordiv_and_mod 和 divmod 函数
        for op in [floordiv_and_mod, divmod]:
            # 使用 itertools.product 生成数据类型的组合
            for dt1, dt2 in itertools.product(dt, dt):
                # 对于每一对数据类型,获取它们的符号组合
                for sg1, sg2 in itertools.product(_signs(dt1), _signs(dt2)):
                    # 格式化消息字符串,描述当前操作的参数
                    fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s'
                    msg = fmt % (op.__name__, dt1, dt2, sg1, sg2)
                    # 创建 np.array 数组,使用符号和数据类型创建数值
                    a = np.array(sg1*71, dtype=dt1)[()]
                    b = np.array(sg2*19, dtype=dt2)[()]
                    # 调用操作函数进行整数除法和取模运算
                    div, rem = op(a, b)
                    # 使用 assert_equal 断言确保恢复原始值
                    assert_equal(div*b + rem, a, err_msg=msg)
                    # 对于取模结果进行额外的断言,验证其符号和大小关系
                    if sg2 == -1:
                        assert_(b < rem <= 0, msg)
                    else:
                        assert_(b > rem >= 0, msg)

    # 测试浮点数取模的精确性
    def test_float_modulus_exact(self):
        # 测试小整数的浮点数取模结果的精确性,也适用于乘以二的幂的情况
        nlst = list(range(-127, 0))
        plst = list(range(1, 128))
        dividend = nlst + [0] + plst
        divisor = nlst + plst
        arg = list(itertools.product(dividend, divisor))
        tgt = list(divmod(*t) for t in arg)

        a, b = np.array(arg, dtype=int).T
        # 将 Python 的精确整数结果转换为浮点数,以支持使用有符号零进行检查
        tgtdiv, tgtrem = np.array(tgt, dtype=float).T
        tgtdiv = np.where((tgtdiv == 0.0) & ((b < 0) ^ (a < 0)), -0.0, tgtdiv)
        tgtrem = np.where((tgtrem == 0.0) & (b < 0), -0.0, tgtrem)

        # 再次遍历 floordiv_and_mod 和 divmod 函数
        for op in [floordiv_and_mod, divmod]:
            # 遍历所有浮点数数据类型
            for dt in np.typecodes['Float']:
                msg = 'op: %s, dtype: %s' % (op.__name__, dt)
                fa = a.astype(dt)
                fb = b.astype(dt)
                # 使用列表推导式确保 fa 和 fb 是标量
                div, rem = zip(*[op(a_, b_) for  a_, b_ in zip(fa, fb)])
                # 使用 assert_equal 断言检查结果与预期的精确整数结果
                assert_equal(div, tgtdiv, err_msg=msg)
                assert_equal(rem, tgtrem, err_msg=msg)
    def test_float_modulus_roundoff(self):
        # 测试用例函数:测试浮点数取模的舍入误差
        dt = np.typecodes['Float']
        # 循环测试不同操作和数据类型的组合
        for op in [floordiv_and_mod, divmod]:
            for dt1, dt2 in itertools.product(dt, dt):
                # 循环测试不同的符号组合
                for sg1, sg2 in itertools.product((+1, -1), (+1, -1)):
                    fmt = 'op: %s, dt1: %s, dt2: %s, sg1: %s, sg2: %s'
                    msg = fmt % (op.__name__, dt1, dt2, sg1, sg2)
                    # 创建浮点数数组 a 和 b
                    a = np.array(sg1*78*6e-8, dtype=dt1)[()]
                    b = np.array(sg2*6e-8, dtype=dt2)[()]
                    # 执行取整除法和取模操作
                    div, rem = op(a, b)
                    # 使用 fmod 操作进行相等断言
                    assert_equal(div*b + rem, a, err_msg=msg)
                    # 检查余数的符号和大小
                    if sg2 == -1:
                        assert_(b < rem <= 0, msg)
                    else:
                        assert_(b > rem >= 0, msg)

    def test_float_modulus_corner_cases(self):
        # 测试用例函数:测试浮点数取模的边界情况
        # 检查余数的大小
        for dt in np.typecodes['Float']:
            b = np.array(1.0, dtype=dt)
            a = np.nextafter(np.array(0.0, dtype=dt), -b)
            # 执行取模操作
            rem = operator.mod(a, b)
            assert_(rem <= b, 'dt: %s' % dt)
            rem = operator.mod(-a, -b)
            assert_(rem >= -b, 'dt: %s' % dt)

        # 检查 NaN 和 Inf
        with suppress_warnings() as sup:
            # 忽略特定的警告信息
            sup.filter(RuntimeWarning, "invalid value encountered in remainder")
            sup.filter(RuntimeWarning, "divide by zero encountered in remainder")
            sup.filter(RuntimeWarning, "divide by zero encountered in floor_divide")
            sup.filter(RuntimeWarning, "divide by zero encountered in divmod")
            sup.filter(RuntimeWarning, "invalid value encountered in divmod")
            for dt in np.typecodes['Float']:
                fone = np.array(1.0, dtype=dt)
                fzer = np.array(0.0, dtype=dt)
                finf = np.array(np.inf, dtype=dt)
                fnan = np.array(np.nan, dtype=dt)
                # 执行取模操作并进行断言
                rem = operator.mod(fone, fzer)
                assert_(np.isnan(rem), 'dt: %s' % dt)
                # MSVC 2008 在此返回 NaN,因此禁用此检查。
                # rem = operator.mod(fone, finf)
                # assert_(rem == fone, 'dt: %s' % dt)
                rem = operator.mod(fone, fnan)
                assert_(np.isnan(rem), 'dt: %s' % dt)
                rem = operator.mod(finf, fone)
                assert_(np.isnan(rem), 'dt: %s' % dt)
                # 循环测试不同操作的组合
                for op in [floordiv_and_mod, divmod]:
                    div, mod = op(fone, fzer)
                    assert_(np.isinf(div)) and assert_(np.isnan(mod))
    def test_inplace_floordiv_handling(self):
        # 定义一个测试函数,用于测试处理就地整除赋值操作的情况
        # 此测试仅适用于就地整除赋值 //=,因为输出类型会提升为 float,而 uint64 不适用于 float
        # 创建一个包含两个元素的 np.int64 数组 a
        a = np.array([1, 2], np.int64)
        # 创建一个包含两个元素的 np.uint64 数组 b
        b = np.array([1, 2], np.uint64)
        # 使用 pytest 检查是否会抛出 TypeError 异常,并匹配特定错误信息
        with pytest.raises(TypeError,
                match=r"Cannot cast ufunc 'floor_divide' output from"):
            # 对数组 a 执行就地整除赋值操作 //= b
            a //= b
class TestComplexDivision:
    def test_zero_division(self):
        # 忽略所有 NumPy 的错误和警告
        with np.errstate(all="ignore"):
            # 对于每种复数类型进行测试
            for t in [np.complex64, np.complex128]:
                # 创建复数类型对象a为0.0
                a = t(0.0)
                # 创建复数类型对象b为1.0
                b = t(1.0)
                # 断言 b/a 为无穷大
                assert_(np.isinf(b/a))
                # 将b设为复数类型,实部和虚部均为正无穷大
                b = t(complex(np.inf, np.inf))
                # 断言 b/a 为无穷大
                assert_(np.isinf(b/a))
                # 将b设为复数类型,实部为正无穷大,虚部为NaN
                b = t(complex(np.inf, np.nan))
                # 断言 b/a 为无穷大
                assert_(np.isinf(b/a))
                # 将b设为复数类型,实部为NaN,虚部为正无穷大
                b = t(complex(np.nan, np.inf))
                # 断言 b/a 为无穷大
                assert_(np.isinf(b/a))
                # 将b设为复数类型,实部和虚部均为NaN
                b = t(complex(np.nan, np.nan))
                # 断言 b/a 为NaN
                assert_(np.isnan(b/a))
                # 将b设为0.0
                b = t(0.)
                # 断言 b/a 为NaN
                assert_(np.isnan(b/a))

    def test_signed_zeros(self):
        # 忽略所有 NumPy 的错误和警告
        with np.errstate(all="ignore"):
            # 对于每种复数类型进行测试
            for t in [np.complex64, np.complex128]:
                # 定义测试数据:(分子实部, 分子虚部), (分母实部, 分母虚部), (期望结果实部, 期望结果虚部)
                data = (
                    (( 0.0,-1.0), ( 0.0, 1.0), (-1.0,-0.0)),
                    (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
                    (( 0.0,-1.0), (-0.0,-1.0), ( 1.0, 0.0)),
                    (( 0.0,-1.0), (-0.0, 1.0), (-1.0, 0.0)),
                    (( 0.0, 1.0), ( 0.0,-1.0), (-1.0, 0.0)),
                    (( 0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
                    ((-0.0,-1.0), ( 0.0,-1.0), ( 1.0,-0.0)),
                    ((-0.0, 1.0), ( 0.0,-1.0), (-1.0,-0.0))
                )
                # 对于每组测试数据
                for cases in data:
                    # 取出分子和分母
                    n = cases[0]
                    d = cases[1]
                    # 取出期望的实部和虚部
                    ex = cases[2]
                    # 计算结果
                    result = t(complex(n[0], n[1])) / t(complex(d[0], d[1]))
                    # 分别断言实部和虚部与期望值相等,以避免在数组环境下对符号零的比较问题
                    assert_equal(result.real, ex[0])
                    assert_equal(result.imag, ex[1])
    def test_branches(self):
        # 忽略 NumPy 中的所有错误(errorstate)
        with np.errstate(all="ignore"):
            # 对于每种复数类型进行迭代测试
            for t in [np.complex64, np.complex128]:
                # 定义用于测试的数据列表,每个元素是一个元组 (numerator, denominator, expected)
                data = list()

                # 触发条件分支:real(fabs(denom)) > imag(fabs(denom))
                # 然后执行 else 分支,因为两者都不等于 0
                data.append(((2.0, 1.0), (2.0, 1.0), (1.0, 0.0)))

                # 触发条件分支:real(fabs(denom)) > imag(fabs(denom))
                # 然后执行 if 分支,因为两者都等于 0
                # 这部分的测试被移至 test_zero_division(),因此在此跳过

                # 触发 else if 分支:real(fabs(denom)) < imag(fabs(denom))
                data.append(((1.0, 2.0), (1.0, 2.0), (1.0, 0.0)))

                # 遍历测试数据集合
                for cases in data:
                    # 分别取出 numerator、denominator 和 expected
                    n = cases[0]
                    d = cases[1]
                    ex = cases[2]
                    # 计算结果
                    result = t(complex(n[0], n[1])) / t(complex(d[0], d[1]))
                    # 分别检查实部和虚部,避免在数组上下文中比较,因为它不考虑有符号的零
                    assert_equal(result.real, ex[0])
                    assert_equal(result.imag, ex[1])
class TestConversion:
    # 测试从长浮点数到整数的转换
    def test_int_from_long(self):
        # 创建长浮点数列表
        l = [1e6, 1e12, 1e18, -1e6, -1e12, -1e18]
        # 创建预期整数列表
        li = [10**6, 10**12, 10**18, -10**6, -10**12, -10**18]
        # 对每种数据类型进行测试:None, np.float64, np.int64
        for T in [None, np.float64, np.int64]:
            # 使用指定数据类型创建 NumPy 数组
            a = np.array(l, dtype=T)
            # 断言转换后的每个元素与预期整数相等
            assert_equal([int(_m) for _m in a], li)

        # 使用 np.uint64 类型创建 NumPy 数组
        a = np.array(l[:3], dtype=np.uint64)
        # 断言转换后的每个元素与预期整数相等
        assert_equal([int(_m) for _m in a], li[:3])

    # 测试 np.iinfo 中的长整数值
    def test_iinfo_long_values(self):
        # 对于 'bBhH' 中的每个类型码,测试溢出错误
        for code in 'bBhH':
            with pytest.raises(OverflowError):
                np.array(np.iinfo(code).max + 1, dtype=code)

        # 对于所有整数类型码中的每个类型码,测试最大值与预期最大值相等
        for code in np.typecodes['AllInteger']:
            res = np.array(np.iinfo(code).max, dtype=code)
            tgt = np.iinfo(code).max
            assert_(res == tgt)

        # 对于所有整数类型码中的每个类型码,测试使用 np.dtype 创建的最大值与预期最大值相等
        for code in np.typecodes['AllInteger']:
            res = np.dtype(code).type(np.iinfo(code).max)
            tgt = np.iinfo(code).max
            assert_(res == tgt)

    # 测试整数溢出行为
    def test_int_raise_behaviour(self):
        # 定义溢出错误函数
        def overflow_error_func(dtype):
            dtype(np.iinfo(dtype).max + 1)

        # 对于指定的数据类型,测试是否抛出溢出错误
        for code in [np.int_, np.uint, np.longlong, np.ulonglong]:
            assert_raises(OverflowError, overflow_error_func, code)

    # 测试从无限长双精度浮点数到整数的转换
    def test_int_from_infinite_longdouble(self):
        # gh-627
        # 创建一个无限大的长双精度浮点数,预期抛出溢出错误
        x = np.longdouble(np.inf)
        assert_raises(OverflowError, int, x)
        # 使用抑制警告上下文管理器
        with suppress_warnings() as sup:
            sup.record(ComplexWarning)
            x = np.clongdouble(np.inf)
            assert_raises(OverflowError, int, x)
            assert_equal(len(sup.log), 1)

    # 仅在 PyPy 环境下运行的测试
    @pytest.mark.skipif(not IS_PYPY, reason="Test is PyPy only (gh-9972)")
    def test_int_from_infinite_longdouble___int__(self):
        # 创建一个无限大的长双精度浮点数,预期抛出溢出错误
        x = np.longdouble(np.inf)
        assert_raises(OverflowError, x.__int__)
        # 使用抑制警告上下文管理器
        with suppress_warnings() as sup:
            sup.record(ComplexWarning)
            x = np.clongdouble(np.inf)
            assert_raises(OverflowError, x.__int__)
            assert_equal(len(sup.log), 1)

    # 根据条件跳过测试
    @pytest.mark.skipif(np.finfo(np.double) == np.finfo(np.longdouble),
                        reason="long double is same as double")
    @pytest.mark.skipif(platform.machine().startswith("ppc"),
                        reason="IBM double double")
    def test_int_from_huge_longdouble(self):
        # 生成一个长双精度浮点数,其值将溢出一个双精度浮点数
        # 使用避免 Darwin pow 函数中的错误的指数
        exp = np.finfo(np.double).maxexp - 1
        huge_ld = 2 * 1234 * np.longdouble(2) ** exp
        huge_i = 2 * 1234 * 2 ** exp
        assert_(huge_ld != np.inf)
        assert_equal(int(huge_ld), huge_i)

    # 测试从长双精度浮点数到整数的转换
    def test_int_from_longdouble(self):
        # 创建一个长双精度浮点数,将其转换为整数并断言结果
        x = np.longdouble(1.5)
        assert_equal(int(x), 1)
        x = np.longdouble(-10.5)
        assert_equal(int(x), -10)
    def test_numpy_scalar_relational_operators(self):
        # 对所有整数类型进行测试
        for dt1 in np.typecodes['AllInteger']:
            # 断言 1 大于数组中的零,并给出失败类型信息
            assert_(1 > np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,))
            # 断言 1 不小于数组中的零,并给出失败类型信息
            assert_(not 1 < np.array(0, dtype=dt1)[()], "type %s failed" % (dt1,))

            # 嵌套循环,对第二个整数类型进行测试
            for dt2 in np.typecodes['AllInteger']:
                # 断言以 dt1 类型的数组中的 1 大于以 dt2 类型的数组中的 0,并给出失败类型信息
                assert_(np.array(1, dtype=dt1)[()] > np.array(0, dtype=dt2)[()],
                        "type %s and %s failed" % (dt1, dt2))
                # 断言以 dt1 类型的数组中的 1 不小于以 dt2 类型的数组中的 0,并给出失败类型信息
                assert_(not np.array(1, dtype=dt1)[()] < np.array(0, dtype=dt2)[()],
                        "type %s and %s failed" % (dt1, dt2))

        # 对无符号整数进行测试
        for dt1 in 'BHILQP':
            # 断言 -1 小于以 dt1 类型的数组中的 1,并给出失败类型信息
            assert_(-1 < np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
            # 断言 -1 不大于以 dt1 类型的数组中的 1,并给出失败类型信息
            assert_(not -1 > np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))
            # 断言 -1 不等于以 dt1 类型的数组中的 1,并给出失败类型信息
            assert_(-1 != np.array(1, dtype=dt1)[()], "type %s failed" % (dt1,))

            # 嵌套循环,测试无符号与有符号整数的比较
            for dt2 in 'bhilqp':
                # 断言以 dt1 类型的数组中的 1 大于以 dt2 类型的数组中的 -1,并给出失败类型信息
                assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()],
                        "type %s and %s failed" % (dt1, dt2))
                # 断言以 dt1 类型的数组中的 1 不小于以 dt2 类型的数组中的 -1,并给出失败类型信息
                assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()],
                        "type %s and %s failed" % (dt1, dt2))
                # 断言以 dt1 类型的数组中的 1 不等于以 dt2 类型的数组中的 -1,并给出失败类型信息
                assert_(np.array(1, dtype=dt1)[()] != np.array(-1, dtype=dt2)[()],
                        "type %s and %s failed" % (dt1, dt2))

        # 对有符号整数和浮点数进行测试
        for dt1 in 'bhlqp' + np.typecodes['Float']:
            # 断言 1 大于以 dt1 类型的数组中的 -1,并给出失败类型信息
            assert_(1 > np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
            # 断言 1 不小于以 dt1 类型的数组中的 -1,并给出失败类型信息
            assert_(not 1 < np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))
            # 断言 -1 等于以 dt1 类型的数组中的 -1,并给出失败类型信息
            assert_(-1 == np.array(-1, dtype=dt1)[()], "type %s failed" % (dt1,))

            # 嵌套循环,对第二个有符号整数和浮点数类型进行测试
            for dt2 in 'bhlqp' + np.typecodes['Float']:
                # 断言以 dt1 类型的数组中的 1 大于以 dt2 类型的数组中的 -1,并给出失败类型信息
                assert_(np.array(1, dtype=dt1)[()] > np.array(-1, dtype=dt2)[()],
                        "type %s and %s failed" % (dt1, dt2))
                # 断言以 dt1 类型的数组中的 1 不小于以 dt2 类型的数组中的 -1,并给出失败类型信息
                assert_(not np.array(1, dtype=dt1)[()] < np.array(-1, dtype=dt2)[()],
                        "type %s and %s failed" % (dt1, dt2))
                # 断言以 dt1 类型的数组中的 -1 等于以 dt2 类型的数组中的 -1,并给出失败类型信息
                assert_(np.array(-1, dtype=dt1)[()] == np.array(-1, dtype=dt2)[()],
                        "type %s and %s failed" % (dt1, dt2))
    def test_scalar_comparison_to_none(self):
        # 测试标量与 None 的比较行为
        # 标量应该返回 False 而不是产生警告。
        # 这些比较被 pep8 标记,我们忽略这一点。
        with warnings.catch_warnings(record=True) as w:
            warnings.filterwarnings('always', '', FutureWarning)
            # 断言:np.float32(1) 不等于 None
            assert_(not np.float32(1) == None)
            # 断言:np.str_('test') 不等于 None
            assert_(not np.str_('test') == None)
            # 这个比较可能不确定 (见下文):
            assert_(not np.datetime64('NaT') == None)

            # 断言:np.float32(1) 等于 None
            assert_(np.float32(1) != None)
            # 断言:np.str_('test') 等于 None
            assert_(np.str_('test') != None)
            # 这个比较可能不确定 (见下文):
            assert_(np.datetime64('NaT') != None)
        # 断言:警告的数量为 0
        assert_(len(w) == 0)

        # 为了文档目的,解释为什么 datetime 是不确定的。
        # 在弃用时没有行为变化,但在弃用时必须考虑这一点。
        assert_(np.equal(np.datetime64('NaT'), None))
# 测试类 TestRepr,用于验证数据类型的字符串表示和反向操作的正确性
class TestRepr:
    # 私有方法,测试给定数据类型 t 的字符串表示和反向操作
    def _test_type_repr(self, t):
        # 获取数据类型 t 的浮点数信息
        finfo = np.finfo(t)
        # 计算最后一个小数位索引
        last_fraction_bit_idx = finfo.nexp + finfo.nmant
        # 计算最后一个指数位索引
        last_exponent_bit_idx = finfo.nexp
        # 计算存储字节数
        storage_bytes = np.dtype(t).itemsize * 8
        
        # 在下面的循环中,处理两种情况:小的非规格化数和小的规格化数
        for which in ['small denorm', 'small norm']:
            # 创建一个存储字节数量的零数组,数据类型为 np.uint8
            constr = np.array([0x00] * storage_bytes, dtype=np.uint8)
            
            # 根据 which 的值设置特定位的值,来模拟特定的浮点数表示
            if which == 'small denorm':
                byte = last_fraction_bit_idx // 8
                bytebit = 7 - (last_fraction_bit_idx % 8)
                constr[byte] = 1 << bytebit
            elif which == 'small norm':
                byte = last_exponent_bit_idx // 8
                bytebit = 7 - (last_exponent_bit_idx % 8)
                constr[byte] = 1 << bytebit
            else:
                raise ValueError('hmm')
            
            # 将构造的数组视图转换为类型 t 的值
            val = constr.view(t)[0]
            # 获取值 val 的字符串表示
            val_repr = repr(val)
            # 通过 eval 将字符串表示转换回类型 t 的值
            val2 = t(eval(val_repr))
            
            # 断言原始值 val 和经过字符串表示转换后的值 val2 相等
            if not (val2 == 0 and val < 1e-100):
                assert_equal(val, val2)
    
    # 测试浮点数类型的字符串表示和反向操作
    def test_float_repr(self):
        # 对每种浮点数类型进行测试:单精度浮点数和双精度浮点数
        for t in [np.float32, np.float64]:
            self._test_type_repr(t)

# 如果不是在 PyPy 环境下执行以下代码
if not IS_PYPY:
    # 测试类 TestSizeOf,用于验证数据类型的字节大小与 sys.getsizeof() 方法的比较
    class TestSizeOf:
        
        # 测试每种数据类型的实际字节大小大于其 nbyte 属性的断言
        def test_equal_nbytes(self):
            # 对于 types 中的每种数据类型
            for type in types:
                # 创建类型为 type 的零值 x
                x = type(0)
                # 断言 x 的实际字节大小大于其 nbyte 属性
                assert_(sys.getsizeof(x) > x.nbytes)
        
        # 测试对非法输入的错误处理
        def test_error(self):
            # 创建一个 np.float32 类型的空对象 d
            d = np.float32()
            # 断言调用 d.__sizeof__("a") 时会引发 TypeError 异常
            assert_raises(TypeError, d.__sizeof__, "a")
    def test_no_seq_repeat_basic_array_like(self):
        # Test that an array-like which does not know how to be multiplied
        # does not attempt sequence repeat (raise TypeError).
        # See also gh-7428.
        class ArrayLike:
            def __init__(self, arr):
                self.arr = arr

            def __array__(self, dtype=None, copy=None):
                return self.arr
        
        # 对于每一个类似数组的对象(如ArrayLike和memoryview),进行测试
        for arr_like in (ArrayLike(np.ones(3)), memoryview(np.ones(3))):
            # 检查乘法操作是否能够正确进行
            assert_array_equal(arr_like * np.float32(3.), np.full(3, 3.))
            assert_array_equal(np.float32(3.) * arr_like, np.full(3, 3.))
            assert_array_equal(arr_like * np.int_(3), np.full(3, 3))
            assert_array_equal(np.int_(3) * arr_like, np.full(3, 3))
class TestNegative:
    def test_exceptions(self):
        # 创建一个布尔类型的 numpy 数组 a,值为 1.0
        a = np.ones((), dtype=np.bool)[()]
        # 断言调用 operator.neg(a) 会抛出 TypeError 异常
        assert_raises(TypeError, operator.neg, a)

    def test_result(self):
        # 获取所有整数和浮点数的 numpy 类型码
        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
        # 在抑制特定类型的警告的上下文中进行操作
        with suppress_warnings() as sup:
            # 过滤运行时警告
            sup.filter(RuntimeWarning)
            # 遍历每种数据类型
            for dt in types:
                # 创建一个包含单个元素的 numpy 数组 a,数据类型为 dt
                a = np.ones((), dtype=dt)[()]
                # 如果数据类型 dt 是无符号整数类型
                if dt in np.typecodes['UnsignedInteger']:
                    # 获取该数据类型的最大值
                    st = np.dtype(dt).type
                    max = st(np.iinfo(dt).max)
                    # 断言 operator.neg(a) 的结果等于最大值 max
                    assert_equal(operator.neg(a), max)
                else:
                    # 断言 operator.neg(a) + a 的结果等于 0
                    assert_equal(operator.neg(a) + a, 0)

class TestSubtract:
    def test_exceptions(self):
        # 创建一个布尔类型的 numpy 数组 a,值为 1.0
        a = np.ones((), dtype=np.bool)[()]
        # 断言调用 operator.sub(a, a) 会抛出 TypeError 异常
        assert_raises(TypeError, operator.sub, a, a)

    def test_result(self):
        # 获取所有整数和浮点数的 numpy 类型码
        types = np.typecodes['AllInteger'] + np.typecodes['AllFloat']
        # 在抑制特定类型的警告的上下文中进行操作
        with suppress_warnings() as sup:
            # 过滤运行时警告
            sup.filter(RuntimeWarning)
            # 遍历每种数据类型
            for dt in types:
                # 创建一个包含单个元素的 numpy 数组 a,数据类型为 dt
                a = np.ones((), dtype=dt)[()]
                # 断言 operator.sub(a, a) 的结果等于 0
                assert_equal(operator.sub(a, a), 0)


class TestAbs:
    def _test_abs_func(self, absfunc, test_dtype):
        # 创建一个 test_dtype 类型的对象 x,值为 -1.5
        x = test_dtype(-1.5)
        # 断言调用 absfunc(x) 的结果等于 1.5
        assert_equal(absfunc(x), 1.5)
        # 创建一个 test_dtype 类型的对象 x,值为 0.0
        x = test_dtype(0.0)
        # 调用 absfunc(x) 并将结果赋给变量 res
        res = absfunc(x)
        # 使用 assert_equal() 检查零的符号性
        assert_equal(res, 0.0)
        # 创建一个 test_dtype 类型的对象 x,值为 -0.0
        x = test_dtype(-0.0)
        # 调用 absfunc(x) 并将结果赋给变量 res
        res = absfunc(x)
        # 断言调用 absfunc(x) 的结果等于 0.0
        assert_equal(res, 0.0)

        # 创建一个 test_dtype 类型的对象 x,值为该类型的最大值
        x = test_dtype(np.finfo(test_dtype).max)
        # 断言调用 absfunc(x) 的结果等于 x 的实部
        assert_equal(absfunc(x), x.real)

        # 在抑制特定类型的警告的上下文中进行操作
        with suppress_warnings() as sup:
            # 过滤用户警告
            sup.filter(UserWarning)
            # 创建一个 test_dtype 类型的对象 x,值为该类型的最小非零数
            x = test_dtype(np.finfo(test_dtype).tiny)
            # 断言调用 absfunc(x) 的结果等于 x 的实部
            assert_equal(absfunc(x), x.real)

        # 创建一个 test_dtype 类型的对象 x,值为该类型的最小值
        x = test_dtype(np.finfo(test_dtype).min)
        # 断言调用 absfunc(x) 的结果等于 -x 的实部
        assert_equal(absfunc(x), -x.real)

    @pytest.mark.parametrize("dtype", floating_types + complex_floating_types)
    def test_builtin_abs(self, dtype):
        # 如果在 cygwin 平台上,并且 dtype 是 np.clongdouble 类型,并且运行时版本低于 3.3
        if (
                sys.platform == "cygwin" and dtype == np.clongdouble and
                (
                    _pep440.parse(platform.release().split("-")[0])
                    < _pep440.Version("3.3.0")
                )
        ):
            # 标记此测试为预期失败,原因是在 cygwin 平台上的 double 精度计算小数的情况
            pytest.xfail(
                reason="absl is computed in double precision on cygwin < 3.3"
            )
        # 调用 self._test_abs_func(abs, dtype)
        self._test_abs_func(abs, dtype)

    @pytest.mark.parametrize("dtype", floating_types + complex_floating_types)
    def test_numpy_abs(self, dtype):
        # 如果在 cygwin 平台上,并且 dtype 是 np.clongdouble 类型,并且运行时版本低于 3.3
        if (
                sys.platform == "cygwin" and dtype == np.clongdouble and
                (
                    _pep440.parse(platform.release().split("-")[0])
                    < _pep440.Version("3.3.0")
                )
        ):
            # 标记此测试为预期失败,原因是在 cygwin 平台上的 double 精度计算小数的情况
            pytest.xfail(
                reason="absl is computed in double precision on cygwin < 3.3"
            )
        # 调用 self._test_abs_func(np.abs, dtype)
        self._test_abs_func(np.abs, dtype)

class TestBitShifts:

    @pytest.mark.parametrize('type_code', np.typecodes['AllInteger'])
    # 使用 pytest 的参数化装饰器标记测试函数,对每个操作符进行测试
    @pytest.mark.parametrize('op',
        [operator.rshift, operator.lshift], ids=['>>', '<<'])
    # 定义测试函数,测试位移操作,参数包括类型码和操作符
    def test_shift_all_bits(self, type_code, op):
        """Shifts where the shift amount is the width of the type or wider """
        # 标题注释:测试位移操作,其中位移量等于类型宽度或更宽的情况
        # 从类型码创建 NumPy 数据类型对象
        dt = np.dtype(type_code)
        # 计算数据类型的位数
        nbits = dt.itemsize * 8
        # 对于每个值(5 和 -5)
        for val in [5, -5]:
            # 对于每个位移量(类型宽度和比类型宽度大 4 个单位)
            for shift in [nbits, nbits + 4]:
                # 将值转换为指定的 NumPy 标量类型
                val_scl = np.array(val).astype(dt)[()]
                # 创建指定类型的位移量
                shift_scl = dt.type(shift)
                # 执行位移操作
                res_scl = op(val_scl, shift_scl)
                # 如果值为负且操作为右移位操作
                if val_scl < 0 and op is operator.rshift:
                    # 断言结果保留了符号位
                    assert_equal(res_scl, -1)
                else:
                    # 否则断言结果为 0
                    assert_equal(res_scl, 0)

                # 对数组执行相同的位移操作,验证标量与数组结果一致性
                val_arr = np.array([val_scl]*32, dtype=dt)
                shift_arr = np.array([shift]*32, dtype=dt)
                res_arr = op(val_arr, shift_arr)
                assert_equal(res_arr, res_scl)
class TestHash:
    # 测试整数的哈希值
    @pytest.mark.parametrize("type_code", np.typecodes['AllInteger'])
    def test_integer_hashes(self, type_code):
        # 获取特定类型码的标量类型
        scalar = np.dtype(type_code).type
        # 对于范围内的整数,验证其哈希值与标量的哈希值一致
        for i in range(128):
            assert hash(i) == hash(scalar(i))

    # 测试浮点数和复数的哈希值
    @pytest.mark.parametrize("type_code", np.typecodes['AllFloat'])
    def test_float_and_complex_hashes(self, type_code):
        # 获取特定类型码的标量类型
        scalar = np.dtype(type_code).type
        # 对于给定的值列表,验证其转换后的哈希值与原始值的哈希值一致性
        for val in [np.pi, np.inf, 3, 6.]:
            numpy_val = scalar(val)
            # 如果是复数类型,将其转换为 Python 复数
            if numpy_val.dtype.kind == 'c':
                val = complex(numpy_val)
            else:
                val = float(numpy_val)
            assert val == numpy_val
            assert hash(val) == hash(numpy_val)

        if hash(float(np.nan)) != hash(float(np.nan)):
            # 如果 Python 区分不同的 NaN,则验证 NumPy 也做到了 (gh-18833)
            assert hash(scalar(np.nan)) != hash(scalar(np.nan))

    # 测试复数的哈希值
    @pytest.mark.parametrize("type_code", np.typecodes['Complex'])
    def test_complex_hashes(self, type_code):
        # 获取特定类型码的标量类型
        scalar = np.dtype(type_code).type
        # 验证特定复数值的哈希值
        for val in [np.pi+1j, np.inf-3j, 3j, 6.+1j]:
            numpy_val = scalar(val)
            assert hash(complex(numpy_val)) == hash(numpy_val)


# 管理递归限制的上下文管理器
@contextlib.contextmanager
def recursionlimit(n):
    # 获取当前递归限制
    o = sys.getrecursionlimit()
    try:
        # 设置新的递归限制
        sys.setrecursionlimit(n)
        yield
    finally:
        # 恢复原始的递归限制
        sys.setrecursionlimit(o)


# 使用假设来测试对象作为左操作数的运算符行为
@given(sampled_from(objecty_things),
       sampled_from(reasonable_operators_for_scalars),
       sampled_from(types))
def test_operator_object_left(o, op, type_):
    try:
        # 设置递归限制为200并测试操作
        with recursionlimit(200):
            op(o, type_(1))
    except TypeError:
        pass


# 使用假设来测试对象作为右操作数的运算符行为
@given(sampled_from(objecty_things),
       sampled_from(reasonable_operators_for_scalars),
       sampled_from(types))
def test_operator_object_right(o, op, type_):
    try:
        # 设置递归限制为200并测试操作
        with recursionlimit(200):
            op(type_(1), o)
    except TypeError:
        pass


# 使用假设来测试标量之间的运算符行为
@given(sampled_from(reasonable_operators_for_scalars),
       sampled_from(types),
       sampled_from(types))
def test_operator_scalars(op, type1, type2):
    try:
        # 测试标量操作并捕获可能的类型错误
        op(type1(1), type2(1))
    except TypeError:
        pass


# 使用假设来测试长双精度数与对象之间的运算符行为
@pytest.mark.parametrize("op", reasonable_operators_for_scalars)
@pytest.mark.parametrize("sctype", [np.longdouble, np.clongdouble])
def test_longdouble_operators_with_obj(sctype, op):
    # 这个测试曾经比较棘手,因为 NumPy 通常会通过 `np.asarray()` 使用 ufunc,可能会导致递归问题
    # 这里验证长双精度数与对象之间的运算是否正常
    pass  # 实际测试逻辑在代码注释中有详细说明,但这里不执行具体测试
    # 尝试执行 op(sctype(3), None),期望没有抛出 TypeError 异常
    try:
        op(sctype(3), None)
    # 如果抛出 TypeError 异常,则捕获并忽略
    except TypeError:
        pass
    
    # 尝试执行 op(None, sctype(3)),期望没有抛出 TypeError 异常
    try:
        op(None, sctype(3))
    # 如果抛出 TypeError 异常,则捕获并忽略
    except TypeError:
        pass
@pytest.mark.parametrize("op", reasonable_operators_for_scalars)
@pytest.mark.parametrize("sctype", [np.longdouble, np.clongdouble])
@np.errstate(all="ignore")
# 定义测试函数,测试长双精度和复长双精度的运算符,忽略所有错误状态
def test_longdouble_operators_with_large_int(sctype, op):
    # (See `test_longdouble_operators_with_obj` for why longdouble is special)
    # 根据 `test_longdouble_operators_with_obj` 查看为何 longdouble 特别
    # NEP 50 means that the result is clearly a (c)longdouble here:
    # NEP 50 意味着这里结果显然是 (复)长双精度
    if sctype == np.clongdouble and op in [operator.mod, operator.floordiv]:
        # The above operators are not support for complex though...
        # 但上述运算符不支持复数类型...
        with pytest.raises(TypeError):
            op(sctype(3), 2**64)
        with pytest.raises(TypeError):
            op(sctype(3), 2**64)
    else:
        assert op(sctype(3), -2**64) == op(sctype(3), sctype(-2**64))
        assert op(2**64, sctype(3)) == op(sctype(2**64), sctype(3))


@pytest.mark.parametrize("dtype", np.typecodes["AllInteger"])
@pytest.mark.parametrize("operation", [
        lambda min, max: max + max,
        lambda min, max: min - max,
        lambda min, max: max * max], ids=["+", "-", "*"])
# 测试整数类型的溢出操作,包括加法、减法和乘法
def test_scalar_integer_operation_overflow(dtype, operation):
    st = np.dtype(dtype).type
    min = st(np.iinfo(dtype).min)
    max = st(np.iinfo(dtype).max)

    with pytest.warns(RuntimeWarning, match="overflow encountered"):
        operation(min, max)


@pytest.mark.parametrize("dtype", np.typecodes["Integer"])
@pytest.mark.parametrize("operation", [
        lambda min, neg_1: -min,
        lambda min, neg_1: abs(min),
        lambda min, neg_1: min * neg_1,
        pytest.param(lambda min, neg_1: min // neg_1,
            marks=pytest.mark.skip(reason="broken on some platforms"))],
        ids=["neg", "abs", "*", "//"])
# 测试带符号整数的溢出情况,包括负数、绝对值、乘法和除法
def test_scalar_signed_integer_overflow(dtype, operation):
    # The minimum signed integer can "overflow" for some additional operations
    # 最小的有符号整数可能会在一些额外操作中"溢出"
    st = np.dtype(dtype).type
    min = st(np.iinfo(dtype).min)
    neg_1 = st(-1)

    with pytest.warns(RuntimeWarning, match="overflow encountered"):
        operation(min, neg_1)


@pytest.mark.parametrize("dtype", np.typecodes["UnsignedInteger"])
# 测试无符号整数的溢出情况
def test_scalar_unsigned_integer_overflow(dtype):
    val = np.dtype(dtype).type(8)
    with pytest.warns(RuntimeWarning, match="overflow encountered"):
        -val

    zero = np.dtype(dtype).type(0)
    -zero  # does not warn


@pytest.mark.parametrize("dtype", np.typecodes["AllInteger"])
@pytest.mark.parametrize("operation", [
        lambda val, zero: val // zero,
        lambda val, zero: val % zero, ], ids=["//", "%"])
# 测试整数除零操作,包括整数除法和取模
def test_scalar_integer_operation_divbyzero(dtype, operation):
    st = np.dtype(dtype).type
    val = st(100)
    zero = st(0)

    with pytest.warns(RuntimeWarning, match="divide by zero"):
        operation(val, zero)


ops_with_names = [
    ("__lt__", "__gt__", operator.lt, True),
    ("__le__", "__ge__", operator.le, True),
    ("__eq__", "__eq__", operator.eq, True),
    # Note __op__ and __rop__ may be identical here:
    # 注意这里 __op__ 和 __rop__ 可能是相同的:
    ("__ne__", "__ne__", operator.ne, True),
    # 创建元组,每个元组包含两个特殊方法名和对应的操作函数以及一个布尔值
    ("__gt__", "__lt__", operator.gt, True),
    # 创建元组,每个元组包含两个特殊方法名和对应的操作函数以及一个布尔值
    ("__ge__", "__le__", operator.ge, True),
    # 创建元组,每个元组包含两个特殊方法名和对应的操作函数以及一个布尔值
    ("__floordiv__", "__rfloordiv__", operator.floordiv, False),
    # 创建元组,每个元组包含两个特殊方法名和对应的操作函数以及一个布尔值
    ("__truediv__", "__rtruediv__", operator.truediv, False),
    # 创建元组,每个元组包含两个特殊方法名和对应的操作函数以及一个布尔值
    ("__add__", "__radd__", operator.add, False),
    # 创建元组,每个元组包含两个特殊方法名和对应的操作函数以及一个布尔值
    ("__mod__", "__rmod__", operator.mod, False),
    # 创建元组,每个元组包含两个特殊方法名和对应的操作函数以及一个布尔值
    ("__mul__", "__rmul__", operator.mul, False),
    # 创建元组,每个元组包含两个特殊方法名和对应的操作函数以及一个布尔值
    ("__pow__", "__rpow__", operator.pow, False),
    # 创建元组,每个元组包含两个特殊方法名和对应的操作函数以及一个布尔值
    ("__sub__", "__rsub__", operator.sub, False),
@pytest.mark.parametrize(["__op__", "__rop__", "op", "cmp"], ops_with_names)
# 使用pytest的@parametrize装饰器,对参数进行多组化,使用ops_with_names作为参数
@pytest.mark.parametrize("sctype", [np.float32, np.float64, np.longdouble])
# 使用pytest的@parametrize装饰器,对参数进行多组化,测试np.float32、np.float64和np.longdouble类型
def test_subclass_deferral(sctype, __op__, __rop__, op, cmp):
    """
    This test covers scalar subclass deferral.  Note that this is exceedingly
    complicated, especially since it tends to fall back to the array paths and
    these additionally add the "array priority" mechanism.

    The behaviour was modified subtly in 1.22 (to make it closer to how Python
    scalars work).  Due to its complexity and the fact that subclassing NumPy
    scalars is probably a bad idea to begin with.  There is probably room
    for adjustments here.
    """
    class myf_simple1(sctype):
        pass

    class myf_simple2(sctype):
        pass

    def op_func(self, other):
        return __op__
    # 定义一个函数op_func,返回参数__op__

    def rop_func(self, other):
        return __rop__
    # 定义一个函数rop_func,返回参数__rop__

    myf_op = type("myf_op", (sctype,), {__op__: op_func, __rop__: rop_func})
    # 创建一个名为myf_op的类型,继承自sctype,包含属性__op__和__rop__分别对应op_func和rop_func函数

    # inheritance has to override, or this is correctly lost:
    res = op(myf_simple1(1), myf_simple2(2))
    # 使用op函数对myf_simple1和myf_simple2实例进行操作
    assert type(res) == sctype or type(res) == np.bool
    # 断言res的类型为sctype或np.bool
    assert op(myf_simple1(1), myf_simple2(2)) == op(1, 2)  # inherited
    # 断言对myf_simple1和myf_simple2实例使用op函数的结果等于对1和2使用op函数的结果(继承)

    # Two independent subclasses do not really define an order.  This could
    # be attempted, but we do not since Python's `int` does neither:
    assert op(myf_op(1), myf_simple1(2)) == __op__
    # 断言对myf_op(1)和myf_simple1(2)使用op函数的结果等于__op__
    assert op(myf_simple1(1), myf_op(2)) == op(1, 2)  # inherited
    # 断言对myf_simple1(1)和myf_op(2)使用op函数的结果等于对1和2使用op函数的结果(继承)


def test_longdouble_complex():
    # Simple test to check longdouble and complex combinations, since these
    # need to go through promotion, which longdouble needs to be careful about.
    x = np.longdouble(1)
    # 创建一个np.longdouble类型的实例x
    assert x + 1j == 1+1j
    # 断言x加上虚数单位1j等于1加上1j
    assert 1j + x == 1+1j
    # 断言1j加上x等于1加上1j


@pytest.mark.parametrize(["__op__", "__rop__", "op", "cmp"], ops_with_names)
# 使用pytest的@parametrize装饰器,对参数进行多组化,使用ops_with_names作为参数
@pytest.mark.parametrize("subtype", [float, int, complex, np.float16])
# 使用pytest的@parametrize装饰器,对参数进行多组化,测试float、int、complex和np.float16类型
@np._no_nep50_warning()
def test_pyscalar_subclasses(subtype, __op__, __rop__, op, cmp):
    def op_func(self, other):
        return __op__
    # 定义一个函数op_func,返回参数__op__

    def rop_func(self, other):
        return __rop__
    # 定义一个函数rop_func,返回参数__rop__

    # Check that deferring is indicated using `__array_ufunc__`:
    myt = type("myt", (subtype,),
               {__op__: op_func, __rop__: rop_func, "__array_ufunc__": None})
    # 创建一个名为myt的类型,继承自subtype,包含属性__op__和__rop__分别对应op_func和rop_func函数,以及属性"__array_ufunc__"为None

    # Just like normally, we should never presume we can modify the float.
    assert op(myt(1), np.float64(2)) == __op__
    # 断言对myt(1)和np.float64(2)使用op函数的结果等于__op__
    assert op(np.float64(1), myt(2)) == __rop__
    # 断言对np.float64(1)和myt(2)使用op函数的结果等于__rop__

    if op in {operator.mod, operator.floordiv} and subtype == complex:
        return  # module is not support for complex.  Do not test.
    # 如果op函数是operator.mod或operator.floordiv,并且subtype是complex类型,则返回,因为模块不支持complex。不进行测试。

    if __rop__ == __op__:
        return
    # 如果__rop__等于__op__,则返回

    # When no deferring is indicated, subclasses are handled normally.
    myt = type("myt", (subtype,), {__rop__: rop_func})
    # 创建一个名为myt的类型,继承自subtype,包含属性__rop__对应rop_func函数

    # Check for float32, as a float subclass float64 may behave differently
    res = op(myt(1), np.float16(2))
    # 使用op函数对myt(1)和np.float16(2)进行操作
    expected = op(subtype(1), np.float16(2))
    # 计算subtype(1)和np.float16(2)使用op函数的结果
    assert res == expected
    # 断言res等于expected
    assert type(res) == type(expected)
    # 断言res的类型等于expected的类型
    # 使用 op 函数计算 np.float32(2) 和 myt(1) 的结果
    res = op(np.float32(2), myt(1))
    # 使用 op 函数计算 np.float32(2) 和 subtype(1) 的结果(期望结果)
    expected = op(np.float32(2), subtype(1))
    # 断言结果 res 等于期望值 expected
    assert res == expected
    # 断言结果 res 的类型等于 expected 的类型
    assert type(res) == type(expected)

    # 对 np.longdouble 类型进行相同的检查:
    # 使用 op 函数计算 myt(1) 和 np.longdouble(2) 的结果
    res = op(myt(1), np.longdouble(2))
    # 使用 op 函数计算 subtype(1) 和 np.longdouble(2) 的结果(期望结果)
    expected = op(subtype(1), np.longdouble(2))
    # 断言结果 res 等于期望值 expected
    assert res == expected
    # 断言结果 res 的类型等于 expected 的类型
    assert type(res) == type(expected)

    # 再次使用 op 函数进行不同类型的计算:
    # 使用 op 函数计算 np.float32(2) 和 myt(1) 的结果
    res = op(np.float32(2), myt(1))
    # 使用 op 函数计算 np.longdouble(2) 和 subtype(1) 的结果(期望结果)
    expected = op(np.longdouble(2), subtype(1))
    # 断言结果 res 等于期望值 expected
    assert res == expected
# 定义一个测试函数,用于测试整数除法的行为
def test_truediv_int():
    # 这个断言应该成功,因为结果是浮点数:
    assert np.uint8(3) / 123454 == np.float64(3) / 123454


# 将下面的测试函数标记为“slow”,表示它是一个比较慢的测试
@pytest.mark.slow
# 参数化测试,测试各种运算符(不包括幂运算符),这些运算符用于标量
@pytest.mark.parametrize("op", [op for op in reasonable_operators_for_scalars if op is not operator.pow])
# 参数化测试,测试各种数据类型
@pytest.mark.parametrize("sctype", types)
# 参数化测试,测试另一种数据类型,包括 float、int 和 complex
@pytest.mark.parametrize("other_type", [float, int, complex])
# 参数化测试,测试是否翻转操作数
@pytest.mark.parametrize("rop", [True, False])
def test_scalar_matches_array_op_with_pyscalar(op, sctype, other_type, rop):
    # 显式地将值转换为数组,以检查 ufunc 路径是否匹配
    val1 = sctype(2)
    val2 = other_type(2)

    # 如果需要翻转操作数,重新定义操作符函数
    if rop:
        _op = op
        op = lambda x, y: _op(y, x)

    try:
        res = op(val1, val2)
    except TypeError:
        try:
            # 如果 ufunc 没有引发 TypeError,则生成预期结果并引发 AssertionError
            expected = op(np.asarray(val1), val2)
            raise AssertionError("ufunc didn't raise.")
        except TypeError:
            # 如果预期引发了 TypeError,则直接返回
            return
    else:
        # 计算预期结果
        expected = op(np.asarray(val1), val2)

    # 注意,这里只检查 dtype 是否相等,因为如果等效,ufunc 可能会选择较低的 dtype
    assert res == expected

    # 特殊情况:如果 val1 是 float 且 other_type 是 complex 且需要翻转操作数
    if isinstance(val1, float) and other_type is complex and rop:
        # Python 中的 complex 类型接受 float 的子类,所以结果可能是 Python 的 complex 类型
        # 因此,使用 `np.array()` 来确保结果的 dtype 是预期的
        assert np.array(res).dtype == expected.dtype
    else:
        # 否则,检查结果的 dtype 是否与预期的 dtype 相同
        assert res.dtype == expected.dtype

.\numpy\numpy\_core\tests\test_scalarprint.py

# 导入所需的模块和库
import code
import platform
import pytest
import sys

# 导入临时文件对象
from tempfile import TemporaryFile

# 导入 NumPy 库并引入特定的函数和变量
import numpy as np
from numpy.testing import assert_, assert_equal, assert_raises, IS_MUSL

# 定义测试类 TestRealScalars,用于测试实数标量
class TestRealScalars:
    
    # 定义测试方法 test_str,测试实数标量的字符串表示
    def test_str(self):
        # 待测试的标量值
        svals = [0.0, -0.0, 1, -1, np.inf, -np.inf, np.nan]
        # 待测试的数据类型列表
        styps = [np.float16, np.float32, np.float64, np.longdouble]
        # 预期的字符串表示
        wanted = [
             ['0.0',  '0.0',  '0.0',  '0.0' ],
             ['-0.0', '-0.0', '-0.0', '-0.0'],
             ['1.0',  '1.0',  '1.0',  '1.0' ],
             ['-1.0', '-1.0', '-1.0', '-1.0'],
             ['inf',  'inf',  'inf',  'inf' ],
             ['-inf', '-inf', '-inf', '-inf'],
             ['nan',  'nan',  'nan',  'nan']]
        
        # 遍历待测试的标量和数据类型
        for wants, val in zip(wanted, svals):
            for want, styp in zip(wants, styps):
                # 构建测试消息
                msg = 'for str({}({}))'.format(np.dtype(styp).name, repr(val))
                # 断言标量的字符串表示符合预期
                assert_equal(str(styp(val)), want, err_msg=msg)

    # 定义测试方法 test_scalar_cutoffs,测试实数标量的截断情况
    def test_scalar_cutoffs(self):
        # 检查 np.float64 的字符串表示是否与 Python 浮点数相同
        def check(v):
            assert_equal(str(np.float64(v)), str(v))
            assert_equal(str(np.float64(v)), repr(v))
            assert_equal(repr(np.float64(v)), f"np.float64({v!r})")
            assert_equal(repr(np.float64(v)), f"np.float64({v})")
        
        # 检查保留相同的有效数字位数
        check(1.12345678901234567890)
        check(0.0112345678901234567890)
        
        # 检查科学计数法和定点表示之间的切换
        check(1e-5)
        check(1e-4)
        check(1e15)
        check(1e16)
    def test_py2_float_print(self):
        # 测试用例:验证 Python 2 中浮点数打印的行为
        # gh-10753
        # 在 Python 2 中,Python 浮点类型实现了一个过时的方法 tp_print,
        # 当使用 "print" 输出到一个“真实文件”(即不是 StringIO)时,
        # 它会覆盖 tp_repr 和 tp_str。确保我们不继承这种行为。
        x = np.double(0.1999999999999)
        
        # 使用临时文件对象 f 来捕获输出
        with TemporaryFile('r+t') as f:
            # 将 x 的值打印到文件 f 中
            print(x, file=f)
            # 将文件指针移到文件开头
            f.seek(0)
            # 读取文件中的输出内容
            output = f.read()
        
        # 断言捕获的输出与 x 的字符串表示加上换行符相等
        assert_equal(output, str(x) + '\n')
        
        # 在 Python 2 中,使用 float('0.1999999999999') 打印时会以 '0.2' 的
        # 形式显示,但是我们希望 numpy 的 np.double('0.1999999999999') 能够
        # 打印出唯一的值 '0.1999999999999'。

        # gh-11031
        # 只有在 Python 2 的交互式 shell 中,并且当 stdout 是一个“真实”
        # 文件时,最后一个命令的输出会直接打印到 stdout,而不像 print
        # 语句那样需要 Py_PRINT_RAW(不像 print 语句)。因此 `>>> x` 和
        # `>>> print x` 可能是不同的。确保它们是相同的。我发现的唯一获取
        # 到类似提示输出的方法是使用 'code' 模块的实际提示。同样,必须使
        # 用 tempfile 来获取一个“真实”文件。

        # dummy user-input which enters one line and then ctrl-Ds.
        # 定义一个虚拟的用户输入函数,输入一行 'np.sqrt(2)' 然后抛出 EOFError
        def userinput():
            yield 'np.sqrt(2)'
            raise EOFError
        gen = userinput()
        # 定义一个输入函数,用于交互时读取输入
        input_func = lambda prompt="": next(gen)

        # 使用两个临时文件对象 fo 和 fe 来捕获 stdout 和 stderr
        with TemporaryFile('r+t') as fo, TemporaryFile('r+t') as fe:
            orig_stdout, orig_stderr = sys.stdout, sys.stderr
            # 重定向 stdout 和 stderr 到 fo 和 fe
            sys.stdout, sys.stderr = fo, fe

            # 使用 code.interact 来进入交互模式,本地变量包括 np,输入函数为 input_func,banner 为空
            code.interact(local={'np': np}, readfunc=input_func, banner='')

            # 恢复原始的 stdout 和 stderr
            sys.stdout, sys.stderr = orig_stdout, orig_stderr

            # 将 fo 的文件指针移到开头,读取所有内容并去除首尾空白字符
            fo.seek(0)
            capture = fo.read().strip()

        # 断言捕获的输出与 np.sqrt(2) 的 repr 相等
        assert_equal(capture, repr(np.sqrt(2)))
    # 定义测试函数 test_dragon4_interface,用于测试浮点数格式化接口
    def test_dragon4_interface(self):
        # 定义浮点数类型列表,包括 np.float16, np.float32, np.float64
        tps = [np.float16, np.float32, np.float64]
        # 如果系统支持 np.float128 并且不是 musllinux 环境,则添加 np.float128 到测试类型列表
        if hasattr(np, 'float128') and not IS_MUSL:
            tps.append(np.float128)

        # 获取 numpy 中的浮点数格式化函数
        fpos = np.format_float_positional
        fsci = np.format_float_scientific

        # 遍历测试类型列表 tps
        for tp in tps:
            # 测试填充功能,使用 assert_equal 断言检查结果是否符合预期
            assert_equal(fpos(tp('1.0'), pad_left=4, pad_right=4), "   1.    ")
            assert_equal(fpos(tp('-1.0'), pad_left=4, pad_right=4), "  -1.    ")
            assert_equal(fpos(tp('-10.2'),
                         pad_left=4, pad_right=4), " -10.2   ")

            # 测试科学计数法格式化,使用 assert_equal 断言检查结果是否符合预期
            assert_equal(fsci(tp('1.23e1'), exp_digits=5), "1.23e+00001")

            # 测试固定位数模式下的格式化,使用 assert_equal 断言检查结果是否符合预期
            assert_equal(fpos(tp('1.0'), unique=False, precision=4), "1.0000")
            assert_equal(fsci(tp('1.0'), unique=False, precision=4),
                         "1.0000e+00")

            # 测试修剪功能,根据不同的 trim 参数进行测试,使用 assert_equal 断言检查结果是否符合预期
            assert_equal(fpos(tp('1.'), unique=False, precision=4, trim='k'),
                         "1.0000")

            assert_equal(fpos(tp('1.'), unique=False, precision=4, trim='.'),
                         "1.")
            assert_equal(fpos(tp('1.2'), unique=False, precision=4, trim='.'),
                         "1.2" if tp != np.float16 else "1.2002")

            assert_equal(fpos(tp('1.'), unique=False, precision=4, trim='0'),
                         "1.0")
            assert_equal(fpos(tp('1.2'), unique=False, precision=4, trim='0'),
                         "1.2" if tp != np.float16 else "1.2002")
            assert_equal(fpos(tp('1.'), trim='0'), "1.0")

            assert_equal(fpos(tp('1.'), unique=False, precision=4, trim='-'),
                         "1")
            assert_equal(fpos(tp('1.2'), unique=False, precision=4, trim='-'),
                         "1.2" if tp != np.float16 else "1.2002")
            assert_equal(fpos(tp('1.'), trim='-'), "1")
            assert_equal(fpos(tp('1.001'), precision=1, trim='-'), "1")

    # 使用 pytest.mark.skipif 装饰器标记测试用例,在非 ppc64 机器上跳过测试,给出原因说明
    @pytest.mark.skipif(not platform.machine().startswith("ppc64"),
                        reason="only applies to ppc float128 values")
    def test_ppc64_ibm_double_double128(self):
        # 测试函数,验证在子正常范围内精度降低的情况。
        # 不像 float64,这里从约 1e-292 开始而不是 1e-308,
        # 当第一个 double 是正常的,第二个是子正常的时候发生。
        
        # 定义一个 np.float128 类型的变量 x,初始值为 '2.123123123123123123123123123123123e-286'
        x = np.float128('2.123123123123123123123123123123123e-286')
        
        # 生成一个列表,包含 0 到 39 的字符串形式的 x 除以 np.float128('2e' + str(i)) 的结果
        got = [str(x/np.float128('2e' + str(i))) for i in range(0,40)]
        
        # 预期的结果列表
        expected = [
            "1.06156156156156156156156156156157e-286",
            "1.06156156156156156156156156156158e-287",
            "1.06156156156156156156156156156159e-288",
            "1.0615615615615615615615615615616e-289",
            "1.06156156156156156156156156156157e-290",
            "1.06156156156156156156156156156156e-291",
            "1.0615615615615615615615615615616e-292",
            "1.0615615615615615615615615615615e-293",
            "1.061561561561561561561561561562e-294",
            "1.06156156156156156156156156155e-295",
            "1.0615615615615615615615615615616e-296",
            "1.06156156156156156156156156156156e-297",
            "1.06156156156156156156156156156157e-298",
            "1.0615615615615615615615615615616e-299",
            "1.0615615615615615615615615615615e-300",
            "1.061561561561561561561561561562e-301",
            "1.06156156156156156156156156155e-302",
            "1.0615615615615615615615615616e-303",
            "1.061561561561561561561561562e-304",
            "1.0615615615615615615615615616e-305",
            "1.0615615615615615615615615616e-306",
            "1.06156156156156156156156156156e-307",
            "1.0615615615615615615615615615616e-308",
            "1.06156156156156156156156156156e-309",
            "1.06156156156156157e-310",
            "1.0615615615615616e-311",
            "1.06156156156156e-312",
            "1.06156156156157e-313",
            "1.0615615615616e-314",
            "1.06156156156e-315",
            "1.06156156155e-316",
            "1.061562e-317",
            "1.06156e-318",
            "1.06155e-319",
            "1.0617e-320",
            "1.06e-321",
            "1.04e-322",
            "1e-323",
            "0.0",
            "0.0"]
        
        # 使用 assert_equal 函数断言 got 和 expected 相等
        assert_equal(got, expected)

        # 注意:我们遵循 glibc 的行为,但它(或者 gcc)可能不正确。
        # 特别是我们可以得到两个打印相同但不相等的值:
        
        # 定义变量 a,值为 np.float128('2')/np.float128('3')
        a = np.float128('2')/np.float128('3')
        
        # 定义变量 b,值为 np.float128(str(a))
        b = np.float128(str(a))
        
        # 使用 assert_equal 函数断言变量 a 和 b 的字符串表示相等
        assert_equal(str(a), str(b))
        
        # 使用 assert_ 函数断言 a 不等于 b
        assert_(a != b)

    def float32_roundtrip(self):
        # 测试函数,验证 float32 的 roundtrip 行为
        # gh-9360
        
        # 定义变量 x,值为 np.float32(1024 - 2**-14)
        x = np.float32(1024 - 2**-14)
        
        # 定义变量 y,值为 np.float32(1024 - 2**-13)
        y = np.float32(1024 - 2**-13)
        
        # 使用 assert_ 函数断言 x 的字符串表示不等于 y 的字符串表示
        assert_(repr(x) != repr(y))
        
        # 使用 assert_equal 函数断言 np.float32(repr(x)) 等于 x
        assert_equal(np.float32(repr(x)), x)
        
        # 使用 assert_equal 函数断言 np.float32(repr(y)) 等于 y
        assert_equal(np.float32(repr(y)), y)

    def float64_vs_python(self):
        # 测试函数,验证 float64 与 Python 浮点数表示的比较行为
        # gh-2643, gh-6136, gh-6908
        
        # 使用 assert_equal 函数断言 np.float64(0.1) 的字符串表示等于 Python 浮点数 0.1 的字符串表示
        assert_equal(repr(np.float64(0.1)), repr(0.1))
        
        # 使用 assert_ 函数断言 np.float64(0.20000000000000004) 的字符串表示不等于 Python 浮点数 0.2 的字符串表示
        assert_(repr(np.float64(0.20000000000000004)) != repr(0.2))

.\numpy\numpy\_core\tests\test_scalar_ctors.py

"""
Test the scalar constructors, which also do type-coercion
"""
# 导入 pytest 库,用于测试
import pytest

# 导入 numpy 库,并引入测试函数
import numpy as np
from numpy.testing import (
    assert_equal, assert_almost_equal, assert_warns,
    )

# 定义一个测试类 TestFromString,用于测试从字符串构造浮点数的情况
class TestFromString:
    def test_floating(self):
        # Ticket #640, floats from string
        # 使用字符串构造不同精度的浮点数
        fsingle = np.single('1.234')
        fdouble = np.double('1.234')
        flongdouble = np.longdouble('1.234')
        # 断言各个浮点数与预期值的近似程度
        assert_almost_equal(fsingle, 1.234)
        assert_almost_equal(fdouble, 1.234)
        assert_almost_equal(flongdouble, 1.234)

    def test_floating_overflow(self):
        """ Strings containing an unrepresentable float overflow """
        # 测试字符串表示的浮点数超出范围的情况
        fhalf = np.half('1e10000')
        assert_equal(fhalf, np.inf)
        fsingle = np.single('1e10000')
        assert_equal(fsingle, np.inf)
        fdouble = np.double('1e10000')
        assert_equal(fdouble, np.inf)
        # 使用 assert_warns 检查超出范围时 longdouble 的情况
        flongdouble = assert_warns(RuntimeWarning, np.longdouble, '1e10000')
        assert_equal(flongdouble, np.inf)

        # 测试负无穷大的情况
        fhalf = np.half('-1e10000')
        assert_equal(fhalf, -np.inf)
        fsingle = np.single('-1e10000')
        assert_equal(fsingle, -np.inf)
        fdouble = np.double('-1e10000')
        assert_equal(fdouble, -np.inf)
        # 使用 assert_warns 检查负无穷大时 longdouble 的情况
        flongdouble = assert_warns(RuntimeWarning, np.longdouble, '-1e10000')
        assert_equal(flongdouble, -np.inf)


# 定义一个测试类 TestExtraArgs,用于测试特殊参数情况
class TestExtraArgs:
    def test_superclass(self):
        # try both positional and keyword arguments
        # 测试 str_ 函数使用不同编码方式转换字节串为字符串
        s = np.str_(b'\x61', encoding='unicode-escape')
        assert s == 'a'
        s = np.str_(b'\x61', 'unicode-escape')
        assert s == 'a'

        # 之前的版本会返回 '\\xx',现在应该抛出 UnicodeDecodeError
        with pytest.raises(UnicodeDecodeError):
            np.str_(b'\\xx', encoding='unicode-escape')
        with pytest.raises(UnicodeDecodeError):
            np.str_(b'\\xx', 'unicode-escape')

        # 测试 np.bytes_ 函数将整数转换为字节串
        # 先前会失败,但 numpy 现在能成功转换
        assert np.bytes_(-2) == b'-2'

    def test_datetime(self):
        # 测试 np.datetime64 函数的用法
        dt = np.datetime64('2000-01', ('M', 2))
        assert np.datetime_data(dt) == ('M', 2)

        # 检查 np.datetime64 函数使用无效参数时是否引发 TypeError
        with pytest.raises(TypeError):
            np.datetime64('2000', garbage=True)

    def test_bool(self):
        # 检查 np.bool 函数使用无效参数时是否引发 TypeError
        with pytest.raises(TypeError):
            np.bool(False, garbage=True)

    def test_void(self):
        # 检查 np.void 函数使用无效参数时是否引发 TypeError
        with pytest.raises(TypeError):
            np.void(b'test', garbage=True)


# 定义一个测试类 TestFromInt,用于测试从整数构造的情况
class TestFromInt:
    def test_intp(self):
        # Ticket #99
        # 测试 np.intp 函数的用法
        assert_equal(1024, np.intp(1024))

    def test_uint64_from_negative(self):
        # 检查 np.uint64 函数使用负数参数时是否引发 OverflowError
        with pytest.raises(OverflowError):
            np.uint64(-2)


# 定义几个类型列表,用于测试数组从标量构造的情况
int_types = [np.byte, np.short, np.intc, np.long, np.longlong]
uint_types = [np.ubyte, np.ushort, np.uintc, np.ulong, np.ulonglong]
float_types = [np.half, np.single, np.double, np.longdouble]
cfloat_types = [np.csingle, np.cdouble, np.clongdouble]


# 定义一个测试类 TestArrayFromScalar,用于测试从标量构造数组的情况
class TestArrayFromScalar:
    """ gh-15467 and gh-19125 """
    # 定义一个名为 _do_test 的方法,用于执行测试,接受 t1 和 t2 作为参数,arg 默认为 2
    def _do_test(self, t1, t2, arg=2):
        # 如果 arg 是 None,则调用 t1() 来获取结果
        if arg is None:
            x = t1()
        # 如果 arg 是一个元组,则根据 t1 的类型来调用相应的方法
        elif isinstance(arg, tuple):
            # 特殊情况:如果 t1 是 np.clongdouble,则标记测试为失败
            if t1 is np.clongdouble:
                pytest.xfail("creating a clongdouble from real and "
                             "imaginary parts isn't supported")
            x = t1(*arg)
        # 否则,使用 arg 作为参数调用 t1
        else:
            x = t1(arg)
        # 将结果转换为 numpy 数组,使用 t2 指定的数据类型
        arr = np.array(x, dtype=t2)
        # 断言:确保数据类型被精确地保留
        # 如果 t2 是 None,则检查数组的数据类型是否与 t1 的类型相同
        if t2 is None:
            assert arr.dtype.type is t1
        # 否则,检查数组的数据类型是否与 t2 相同
        else:
            assert arr.dtype.type is t2
    
    # 使用 pytest 的参数化装饰器,对整数类型进行测试
    @pytest.mark.parametrize('t1', int_types + uint_types)
    @pytest.mark.parametrize('t2', int_types + uint_types + [None])
    def test_integers(self, t1, t2):
        return self._do_test(t1, t2)
    
    # 使用 pytest 的参数化装饰器,对浮点数类型进行测试
    @pytest.mark.parametrize('t1', float_types)
    @pytest.mark.parametrize('t2', float_types + [None])
    def test_reals(self, t1, t2):
        return self._do_test(t1, t2)
    
    # 使用 pytest 的参数化装饰器,对复数类型进行测试,同时参数化 arg 参数
    @pytest.mark.parametrize('t1', cfloat_types)
    @pytest.mark.parametrize('t2', cfloat_types + [None])
    @pytest.mark.parametrize('arg', [2, 1 + 3j, (1, 2), None])
    def test_complex(self, t1, t2, arg):
        self._do_test(t1, t2, arg)
    
    # 使用 pytest 的参数化装饰器,对复数类型进行异常情况测试
    @pytest.mark.parametrize('t', cfloat_types)
    def test_complex_errors(self, t):
        # 断言:应该抛出 TypeError 异常
        with pytest.raises(TypeError):
            t(1j, 1j)
        with pytest.raises(TypeError):
            t(1, None)
        with pytest.raises(TypeError):
            t(None, 1)
@pytest.mark.parametrize("length",
        [5, np.int8(5), np.array(5, dtype=np.uint16)])
def test_void_via_length(length):
    # 使用给定的长度创建一个空的 np.void 对象
    res = np.void(length)
    # 断言返回结果的类型是 np.void
    assert type(res) is np.void
    # 断言返回结果的 item 是由长度个字节零组成的 bytes 对象
    assert res.item() == b"\0" * 5
    # 断言返回结果的数据类型是 "V5"
    assert res.dtype == "V5"

@pytest.mark.parametrize("bytes_",
        [b"spam", np.array(567.)])
def test_void_from_byteslike(bytes_):
    # 使用给定的字节数据创建一个 np.void 对象
    res = np.void(bytes_)
    expected = bytes(bytes_)
    # 断言返回结果的类型是 np.void
    assert type(res) is np.void
    # 断言返回结果的 item 与输入的 bytes 对象相同
    assert res.item() == expected

    # 通过传递 dtype 参数可以扩展 np.void 对象的长度
    res = np.void(bytes_, dtype="V100")
    assert type(res) is np.void
    # 断言返回结果的前部分与输入的 bytes 对象相同
    assert res.item()[:len(expected)] == expected
    # 断言返回结果的后部分是用零填充的,以使总长度为 res.nbytes
    assert res.item()[len(expected):] == b"\0" * (res.nbytes - len(expected))
    
    # 通过传递 dtype 参数可以缩短 np.void 对象的长度
    res = np.void(bytes_, dtype="V4")
    assert type(res) is np.void
    # 断言返回结果只包含输入 bytes 对象的前 4 个字节
    assert res.item() == expected[:4]

def test_void_arraylike_trumps_byteslike():
    # memoryview 对象被转换为一个形状为 (18,) 的数组,而不是一个长度为 18 的单个 bytes-like 对象。
    m = memoryview(b"just one mintleaf?")
    res = np.void(m)
    assert type(res) is np.ndarray
    # 断言返回结果的数据类型是 "V1"
    assert res.dtype == "V1"
    # 断言返回结果的形状是 (18,)
    assert res.shape == (18,)

def test_void_dtype_arg():
    # 测试 dtype 参数的基本用法(位置参数和关键字参数)
    res = np.void((1, 2), dtype="i,i")
    # 断言返回结果的 item 等于输入的元组 (1, 2)
    assert res.item() == (1, 2)
    res = np.void((2, 3), "i,i")
    # 断言返回结果的 item 等于输入的元组 (2, 3)
    assert res.item() == (2, 3)

@pytest.mark.parametrize("data",
        [5, np.int8(5), np.array(5, dtype=np.uint16)])
def test_void_from_integer_with_dtype(data):
    # "length" 的含义被忽略,使用 data 的值:
    res = np.void(data, dtype="i,i")
    assert type(res) is np.void
    # 断言返回结果的数据类型是 "i,i"
    assert res.dtype == "i,i"
    # 断言返回结果的字段 "f0" 和 "f1" 分别等于 data 的值
    assert res["f0"] == 5 and res["f1"] == 5

def test_void_from_structure():
    # 创建一个复合 dtype
    dtype = np.dtype([('s', [('f', 'f8'), ('u', 'U1')]), ('i', 'i2')])
    data = np.array(((1., 'a'), 2), dtype=dtype)
    # 使用复合数据类型创建 np.void 对象
    res = np.void(data[()], dtype=dtype)
    assert type(res) is np.void
    # 断言返回结果的数据类型与输入数据的 dtype 相同
    assert res.dtype == dtype
    # 断言返回结果与输入数据相同
    assert res == data[()]

def test_void_bad_dtype():
    with pytest.raises(TypeError,
            match="void: descr must be a `void.*int64"):
        # 传递不合法的 dtype 引发 TypeError 异常
        np.void(4, dtype="i8")

    # 不合法的子数组 dtype (形状为 `(4,)`) 被拒绝
    with pytest.raises(TypeError,
            match=r"void: descr must be a `void.*\(4,\)"):
        np.void(4, dtype="4i")

.\numpy\numpy\_core\tests\test_scalar_methods.py

"""
Test the scalar constructors, which also do type-coercion
"""
# 导入所需的模块和库
import fractions  # 导入 fractions 模块
import platform  # 导入 platform 模块
import types  # 导入 types 模块
from typing import Any, Type  # 从 typing 模块导入 Any 和 Type 类型

import pytest  # 导入 pytest 测试框架
import numpy as np  # 导入 NumPy 库

from numpy._core import sctypes  # 从 NumPy 内核中导入 sctypes
from numpy.testing import assert_equal, assert_raises, IS_MUSL  # 从 NumPy 测试模块导入断言和异常处理相关函数


class TestAsIntegerRatio:
    # derived in part from the cpython test "test_floatasratio"

    @pytest.mark.parametrize("ftype", [
        np.half, np.single, np.double, np.longdouble])
    @pytest.mark.parametrize("f, ratio", [
        (0.875, (7, 8)),
        (-0.875, (-7, 8)),
        (0.0, (0, 1)),
        (11.5, (23, 2)),
        ])
    def test_small(self, ftype, f, ratio):
        # 断言浮点数转化为分数的正确性
        assert_equal(ftype(f).as_integer_ratio(), ratio)

    @pytest.mark.parametrize("ftype", [
        np.half, np.single, np.double, np.longdouble])
    def test_simple_fractions(self, ftype):
        R = fractions.Fraction
        # 断言简单浮点数转化为分数的正确性
        assert_equal(R(0, 1),
                     R(*ftype(0.0).as_integer_ratio()))
        assert_equal(R(5, 2),
                     R(*ftype(2.5).as_integer_ratio()))
        assert_equal(R(1, 2),
                     R(*ftype(0.5).as_integer_ratio()))
        assert_equal(R(-2100, 1),
                     R(*ftype(-2100.0).as_integer_ratio()))

    @pytest.mark.parametrize("ftype", [
        np.half, np.single, np.double, np.longdouble])
    def test_errors(self, ftype):
        # 测试处理特定浮点数值时的错误情况
        assert_raises(OverflowError, ftype('inf').as_integer_ratio)
        assert_raises(OverflowError, ftype('-inf').as_integer_ratio)
        assert_raises(ValueError, ftype('nan').as_integer_ratio)

    def test_against_known_values(self):
        R = fractions.Fraction
        # 断言浮点数转化为分数的正确性,与已知值进行对比
        assert_equal(R(1075, 512),
                     R(*np.half(2.1).as_integer_ratio()))
        assert_equal(R(-1075, 512),
                     R(*np.half(-2.1).as_integer_ratio()))
        assert_equal(R(4404019, 2097152),
                     R(*np.single(2.1).as_integer_ratio()))
        assert_equal(R(-4404019, 2097152),
                     R(*np.single(-2.1).as_integer_ratio()))
        assert_equal(R(4728779608739021, 2251799813685248),
                     R(*np.double(2.1).as_integer_ratio()))
        assert_equal(R(-4728779608739021, 2251799813685248),
                     R(*np.double(-2.1).as_integer_ratio()))
        # longdouble is platform dependent
    @pytest.mark.parametrize("ftype, frac_vals, exp_vals", [
        # 定义测试参数化,包括数据类型、小数部分值和指数部分值
        # 使用假设生成的数据类型测试用例
        # 每种数据类型的前五个生成的情况
        (np.half, [0.0, 0.01154830649280303, 0.31082276347447274,
                   0.527350517124794, 0.8308562335072596],
                  [0, 1, 0, -8, 12]),
        (np.single, [0.0, 0.09248576989263226, 0.8160498218131407,
                     0.17389442853722373, 0.7956044195067877],
                    [0, 12, 10, 17, -26]),
        (np.double, [0.0, 0.031066908499895136, 0.5214135908877832,
                     0.45780736035689296, 0.5906586745934036],
                    [0, -801, 51, 194, -653]),
        # 使用 pytest.param 定义额外的测试参数
        pytest.param(
            np.longdouble,
            [0.0, 0.20492557202724854, 0.4277180662199366, 0.9888085019891495,
             0.9620175814461964],
            [0, -7400, 14266, -7822, -8721],
            marks=[
                # 添加跳过条件的标记,如果 np.double 和 np.longdouble 的信息相同,则跳过
                pytest.mark.skipif(
                    np.finfo(np.double) == np.finfo(np.longdouble),
                    reason="long double is same as double"),
                # 添加跳过条件的标记,如果平台机器名以 "ppc" 开头,则跳过,原因是 IBM 双倍精度
                pytest.mark.skipif(
                    platform.machine().startswith("ppc"),
                    reason="IBM double double"),
            ]
        )
    ])
    def test_roundtrip(self, ftype, frac_vals, exp_vals):
        # 遍历小数部分值和指数部分值
        for frac, exp in zip(frac_vals, exp_vals):
            # 使用 ldexp 函数创建浮点数
            f = np.ldexp(ftype(frac), exp)
            # 断言生成的浮点数的数据类型与预期的数据类型相同
            assert f.dtype == ftype
            # 将浮点数转换为分数形式
            n, d = f.as_integer_ratio()

            try:
                # 尝试将分子和分母转换为 longdouble 类型
                nf = np.longdouble(n)
                df = np.longdouble(d)
                # 如果分母不是有限的浮点数,则抛出溢出错误
                if not np.isfinite(df):
                    raise OverflowError
            except (OverflowError, RuntimeWarning):
                # 如果在此平台上 longdouble 太小,则跳过测试
                pytest.skip("longdouble too small on this platform")

            # 断言分数形式的值与原始浮点数相等
            assert_equal(nf / df, f, "{}/{}".format(n, d))
class TestIsInteger:
    # 定义测试类 TestIsInteger,用于测试浮点数和整数类型的方法 is_integer()

    @pytest.mark.parametrize("str_value", ["inf", "nan"])
    @pytest.mark.parametrize("code", np.typecodes["Float"])
    def test_special(self, code: str, str_value: str) -> None:
        # 测试特殊值,如无穷大和NaN,对应于浮点数类型
        cls = np.dtype(code).type
        # 根据类型码创建数据类型对象
        value = cls(str_value)
        # 使用类型对象创建具体数值对象
        assert not value.is_integer()
        # 断言该数值对象不是整数

    @pytest.mark.parametrize(
        "code", np.typecodes["Float"] + np.typecodes["AllInteger"]
    )
    def test_true(self, code: str) -> None:
        # 测试各种浮点数和整数类型的数据是否是整数
        float_array = np.arange(-5, 5).astype(code)
        # 创建一个指定类型码的数组,范围从-5到4
        for value in float_array:
            assert value.is_integer()
            # 断言每个数组元素是整数

    @pytest.mark.parametrize("code", np.typecodes["Float"])
    def test_false(self, code: str) -> None:
        # 测试浮点数类型的数据是否不是整数
        float_array = np.arange(-5, 5).astype(code)
        # 创建一个指定类型码的数组,范围从-5到4
        float_array *= 1.1
        # 数组中的每个元素乘以1.1
        for value in float_array:
            if value == 0:
                continue
            assert not value.is_integer()
            # 断言每个乘以1.1后的数组元素不是整数


class TestClassGetItem:
    # 定义测试类 TestClassGetItem,用于测试 numpy 类型别名和数据类型对象的行为

    @pytest.mark.parametrize("cls", [
        np.number,
        np.integer,
        np.inexact,
        np.unsignedinteger,
        np.signedinteger,
        np.floating,
    ])
    def test_abc(self, cls: Type[np.number]) -> None:
        # 测试 numpy 的类型别名的基本行为
        alias = cls[Any]
        # 使用 cls 创建泛型别名
        assert isinstance(alias, types.GenericAlias)
        # 断言别名是泛型别名类型
        assert alias.__origin__ is cls
        # 断言别名的原始类型是 cls

    def test_abc_complexfloating(self) -> None:
        # 测试 np.complexfloating 的类型别名行为
        alias = np.complexfloating[Any, Any]
        # 创建复数浮点数类型别名
        assert isinstance(alias, types.GenericAlias)
        # 断言别名是泛型别名类型
        assert alias.__origin__ is np.complexfloating
        # 断言别名的原始类型是 np.complexfloating

    @pytest.mark.parametrize("arg_len", range(4))
    def test_abc_complexfloating_subscript_tuple(self, arg_len: int) -> None:
        # 测试复数浮点数类型别名的下标元组行为
        arg_tup = (Any,) * arg_len
        # 创建由参数长度决定的 Any 元组
        if arg_len in (1, 2):
            assert np.complexfloating[arg_tup]
            # 如果参数长度为 1 或 2,断言能够使用参数元组索引复数浮点数类型
        else:
            match = f"Too {'few' if arg_len == 0 else 'many'} arguments"
            # 根据参数长度生成匹配错误消息
            with pytest.raises(TypeError, match=match):
                np.complexfloating[arg_tup]
                # 断言在其他情况下索引复数浮点数类型会引发类型错误异常

    @pytest.mark.parametrize("cls", [np.generic, np.flexible, np.character])
    def test_abc_non_numeric(self, cls: Type[np.generic]) -> None:
        # 测试非数值型别名的行为
        with pytest.raises(TypeError):
            cls[Any]
            # 断言创建非数值型别名会引发类型错误异常

    @pytest.mark.parametrize("code", np.typecodes["All"])
    def test_concrete(self, code: str) -> None:
        # 测试具体数据类型对象的行为
        cls = np.dtype(code).type
        # 创建指定类型码的数据类型对象
        with pytest.raises(TypeError):
            cls[Any]
            # 断言创建具体数据类型对象会引发类型错误异常

    @pytest.mark.parametrize("arg_len", range(4))
    def test_subscript_tuple(self, arg_len: int) -> None:
        # 测试数据类型对象的下标元组行为
        arg_tup = (Any,) * arg_len
        # 创建由参数长度决定的 Any 元组
        if arg_len == 1:
            assert np.number[arg_tup]
            # 断言能够使用参数元组索引数据类型对象
        else:
            with pytest.raises(TypeError):
                np.number[arg_tup]
                # 断言在其他情况下索引数据类型对象会引发类型错误异常

    def test_subscript_scalar(self) -> None:
        # 测试数据类型对象的标量下标行为
        assert np.number[Any]
        # 断言能够使用标量形式的 Any 索引数据类型对象


class TestBitCount:
    # 定义测试类 TestBitCount,部分派生自 cpython 的 "test_bit_count" 测试

    @pytest.mark.parametrize("itype", sctypes['int']+sctypes['uint'])
    # 参数化整数和无符号整数类型
    # 定义一个测试方法,用于对指定整数类型进行小规模测试
    def test_small(self, itype):
        # 使用整数类型的最小非负值和 0 之间的范围进行迭代
        for a in range(max(np.iinfo(itype).min, 0), 128):
            # 构建测试消息字符串,用于显示当前测试的信息
            msg = f"Smoke test for {itype}({a}).bit_count()"
            # 断言当前整数类型的位数计算结果等于其二进制表示中 '1' 的个数,若不等则输出消息
            assert itype(a).bit_count() == bin(a).count("1"), msg

    # 定义位数计算方法的测试方法
    def test_bit_count(self):
        # 对指定的指数列表进行迭代
        for exp in [10, 17, 63]:
            # 计算 2 的 exp 次方,并将结果转换为 np.uint64 类型的整数 a
            a = 2**exp
            # 断言 np.uint64 类型的 a 的位数计算结果等于 1,若不等则抛出异常
            assert np.uint64(a).bit_count() == 1
            # 断言 np.uint64 类型的 (a - 1) 的位数计算结果等于 exp,若不等则抛出异常
            assert np.uint64(a - 1).bit_count() == exp
            # 断言 np.uint64 类型的 (a ^ 63) 的位数计算结果等于 7,若不等则抛出异常
            assert np.uint64(a ^ 63).bit_count() == 7
            # 断言 np.uint64 类型的 ((a - 1) ^ 510) 的位数计算结果等于 exp - 8,若不等则抛出异常
            assert np.uint64((a - 1) ^ 510).bit_count() == exp - 8

.\numpy\numpy\_core\tests\test_shape_base.py

import pytest  # 导入 pytest 库,用于单元测试
import numpy as np  # 导入 NumPy 库,用于数值计算和数组操作
from numpy._core import (  # 导入 NumPy 的核心功能模块
    array, arange, atleast_1d, atleast_2d, atleast_3d, block, vstack, hstack,
    newaxis, concatenate, stack
    )
from numpy.exceptions import AxisError  # 导入 NumPy 异常处理模块中的 AxisError 异常
from numpy._core.shape_base import (_block_dispatcher, _block_setup,  # 导入 NumPy 核心的形状基础功能模块
                                   _block_concatenate, _block_slicing)
from numpy.testing import (  # 导入 NumPy 测试模块的一些测试函数和常量
    assert_, assert_raises, assert_array_equal, assert_equal,
    assert_raises_regex, assert_warns, IS_PYPY
    )


class TestAtleast1d:
    def test_0D_array(self):
        a = array(1)  # 创建一个标量数组
        b = array(2)  # 创建一个标量数组
        res = [atleast_1d(a), atleast_1d(b)]  # 将输入至少转换为 1 维数组
        desired = [array([1]), array([2])]  # 预期的结果数组
        assert_array_equal(res, desired)  # 断言 res 和 desired 数组相等

    def test_1D_array(self):
        a = array([1, 2])  # 创建一个一维数组
        b = array([2, 3])  # 创建一个一维数组
        res = [atleast_1d(a), atleast_1d(b)]  # 将输入至少转换为 1 维数组
        desired = [array([1, 2]), array([2, 3])]  # 预期的结果数组
        assert_array_equal(res, desired)  # 断言 res 和 desired 数组相等

    def test_2D_array(self):
        a = array([[1, 2], [1, 2]])  # 创建一个二维数组
        b = array([[2, 3], [2, 3]])  # 创建一个二维数组
        res = [atleast_1d(a), atleast_1d(b)]  # 将输入至少转换为 1 维数组
        desired = [a, b]  # 预期的结果数组
        assert_array_equal(res, desired)  # 断言 res 和 desired 数组相等

    def test_3D_array(self):
        a = array([[1, 2], [1, 2]])  # 创建一个二维数组
        b = array([[2, 3], [2, 3]])  # 创建一个二维数组
        a = array([a, a])  # 创建一个三维数组
        b = array([b, b])  # 创建一个三维数组
        res = [atleast_1d(a), atleast_1d(b)]  # 将输入至少转换为 1 维数组
        desired = [a, b]  # 预期的结果数组
        assert_array_equal(res, desired)  # 断言 res 和 desired 数组相等

    def test_r1array(self):
        """ Test to make sure equivalent Travis O's r1array function
        """
        assert_(atleast_1d(3).shape == (1,))  # 断言至少将标量 3 转换为 1 维数组后的形状
        assert_(atleast_1d(3j).shape == (1,))  # 断言至少将复数标量 3j 转换为 1 维数组后的形状
        assert_(atleast_1d(3.0).shape == (1,))  # 断言至少将浮点数标量 3.0 转换为 1 维数组后的形状
        assert_(atleast_1d([[2, 3], [4, 5]]).shape == (2, 2))  # 断言至少将二维数组转换为 1 维数组后的形状


class TestAtleast2d:
    def test_0D_array(self):
        a = array(1)  # 创建一个标量数组
        b = array(2)  # 创建一个标量数组
        res = [atleast_2d(a), atleast_2d(b)]  # 将输入至少转换为 2 维数组
        desired = [array([[1]]), array([[2]])]  # 预期的结果数组
        assert_array_equal(res, desired)  # 断言 res 和 desired 数组相等

    def test_1D_array(self):
        a = array([1, 2])  # 创建一个一维数组
        b = array([2, 3])  # 创建一个一维数组
        res = [atleast_2d(a), atleast_2d(b)]  # 将输入至少转换为 2 维数组
        desired = [array([[1, 2]]), array([[2, 3]])]  # 预期的结果数组
        assert_array_equal(res, desired)  # 断言 res 和 desired 数组相等

    def test_2D_array(self):
        a = array([[1, 2], [1, 2]])  # 创建一个二维数组
        b = array([[2, 3], [2, 3]])  # 创建一个二维数组
        res = [atleast_2d(a), atleast_2d(b)]  # 将输入至少转换为 2 维数组
        desired = [a, b]  # 预期的结果数组
        assert_array_equal(res, desired)  # 断言 res 和 desired 数组相等

    def test_3D_array(self):
        a = array([[1, 2], [1, 2]])  # 创建一个二维数组
        b = array([[2, 3], [2, 3]])  # 创建一个二维数组
        a = array([a, a])  # 创建一个三维数组
        b = array([b, b])  # 创建一个三维数组
        res = [atleast_2d(a), atleast_2d(b)]  # 将输入至少转换为 2 维数组
        desired = [a, b]  # 预期的结果数组
        assert_array_equal(res, desired)  # 断言 res 和 desired 数组相等

    def test_r2array(self):
        """ Test to make sure equivalent Travis O's r2array function
        """
        assert_(atleast_2d(3).shape == (1, 1))  # 断言至少将标量 3 转换为 2 维数组后的形状
        assert_(atleast_2d([3j, 1]).shape == (1, 2))  # 断言至少将一维数组转换为 2 维数组后的形状
        assert_(atleast_2d([[[3, 1], [4, 5]], [[3, 5], [1, 2]]]).shape == (2, 2, 2))  # 断言至少将三维数组转换为 2 维数组后的形状


class TestAtleast3d:
    pass  # TestAtleast3d 类还未实现,因此暂不添加任何代码
    # 定义测试函数,用于测试处理零维数组的情况
    def test_0D_array(self):
        # 创建包含单个元素的一维数组 a
        a = array(1)
        # 创建包含单个元素的一维数组 b
        b = array(2)
        # 对数组 a 和 b 分别应用 atleast_3d 函数,返回结果列表 res
        res = [atleast_3d(a), atleast_3d(b)]
        # 预期结果列表 desired,包含将单个元素转换为三维数组的结果
        desired = [array([[[1]]]), array([[[2]]])]
        # 使用 assert_array_equal 函数比较 res 和 desired 是否相等
        assert_array_equal(res, desired)

    # 定义测试函数,用于测试处理一维数组的情况
    def test_1D_array(self):
        # 创建包含两个元素的一维数组 a 和 b
        a = array([1, 2])
        b = array([2, 3])
        # 对数组 a 和 b 分别应用 atleast_3d 函数,返回结果列表 res
        res = [atleast_3d(a), atleast_3d(b)]
        # 预期结果列表 desired,包含将一维数组转换为三维数组的结果
        desired = [array([[[1], [2]]]), array([[[2], [3]]])]
        # 使用 assert_array_equal 函数比较 res 和 desired 是否相等
        assert_array_equal(res, desired)

    # 定义测试函数,用于测试处理二维数组的情况
    def test_2D_array(self):
        # 创建一个二维数组 a 和 b
        a = array([[1, 2], [1, 2]])
        b = array([[2, 3], [2, 3]])
        # 对数组 a 和 b 分别应用 atleast_3d 函数,返回结果列表 res
        res = [atleast_3d(a), atleast_3d(b)]
        # 预期结果列表 desired,包含将二维数组转换为三维数组的结果
        desired = [a[:,:, newaxis], b[:,:, newaxis]]
        # 使用 assert_array_equal 函数比较 res 和 desired 是否相等
        assert_array_equal(res, desired)

    # 定义测试函数,用于测试处理三维数组的情况
    def test_3D_array(self):
        # 创建一个二维数组 a 和 b
        a = array([[1, 2], [1, 2]])
        b = array([[2, 3], [2, 3]])
        # 将二维数组 a 和 b 分别存储为三维数组的元素
        a = array([a, a])
        b = array([b, b])
        # 对数组 a 和 b 分别应用 atleast_3d 函数,返回结果列表 res
        res = [atleast_3d(a), atleast_3d(b)]
        # 预期结果列表 desired,直接使用数组 a 和 b 作为三维数组的结果
        desired = [a, b]
        # 使用 assert_array_equal 函数比较 res 和 desired 是否相等
        assert_array_equal(res, desired)
class TestHstack:
    # 测试非可迭代输入的情况,期望抛出 TypeError 异常
    def test_non_iterable(self):
        assert_raises(TypeError, hstack, 1)

    # 测试空输入的情况,期望抛出 ValueError 异常
    def test_empty_input(self):
        assert_raises(ValueError, hstack, ())

    # 测试 0 维数组的堆叠
    def test_0D_array(self):
        a = array(1)
        b = array(2)
        res = hstack([a, b])
        desired = array([1, 2])
        assert_array_equal(res, desired)

    # 测试 1 维数组的堆叠
    def test_1D_array(self):
        a = array([1])
        b = array([2])
        res = hstack([a, b])
        desired = array([1, 2])
        assert_array_equal(res, desired)

    # 测试 2 维数组的堆叠
    def test_2D_array(self):
        a = array([[1], [2]])
        b = array([[1], [2]])
        res = hstack([a, b])
        desired = array([[1, 1], [2, 2]])
        assert_array_equal(res, desired)

    # 测试生成器作为输入的情况,期望抛出 TypeError 异常
    def test_generator(self):
        with pytest.raises(TypeError, match="arrays to stack must be"):
            hstack((np.arange(3) for _ in range(2)))
        with pytest.raises(TypeError, match="arrays to stack must be"):
            hstack(map(lambda x: x, np.ones((3, 2))))

    # 测试指定类型转换和数据类型的情况
    def test_casting_and_dtype(self):
        a = np.array([1, 2, 3])
        b = np.array([2.5, 3.5, 4.5])
        res = np.hstack((a, b), casting="unsafe", dtype=np.int64)
        expected_res = np.array([1, 2, 3, 2, 3, 4])
        assert_array_equal(res, expected_res)
    
    # 测试类型转换和数据类型错误的情况,期望抛出 TypeError 异常
    def test_casting_and_dtype_type_error(self):
        a = np.array([1, 2, 3])
        b = np.array([2.5, 3.5, 4.5])
        with pytest.raises(TypeError):
            hstack((a, b), casting="safe", dtype=np.int64)


class TestVstack:
    # 测试非可迭代输入的情况,期望抛出 TypeError 异常
    def test_non_iterable(self):
        assert_raises(TypeError, vstack, 1)

    # 测试空输入的情况,期望抛出 ValueError 异常
    def test_empty_input(self):
        assert_raises(ValueError, vstack, ())

    # 测试 0 维数组的堆叠
    def test_0D_array(self):
        a = array(1)
        b = array(2)
        res = vstack([a, b])
        desired = array([[1], [2]])
        assert_array_equal(res, desired)

    # 测试 1 维数组的堆叠
    def test_1D_array(self):
        a = array([1])
        b = array([2])
        res = vstack([a, b])
        desired = array([[1], [2]])
        assert_array_equal(res, desired)

    # 测试 2 维数组的堆叠
    def test_2D_array(self):
        a = array([[1], [2]])
        b = array([[1], [2]])
        res = vstack([a, b])
        desired = array([[1], [2], [1], [2]])
        assert_array_equal(res, desired)

    # 测试另一种 2 维数组的堆叠方式
    def test_2D_array2(self):
        a = array([1, 2])
        b = array([1, 2])
        res = vstack([a, b])
        desired = array([[1, 2], [1, 2]])
        assert_array_equal(res, desired)

    # 测试生成器作为输入的情况,期望抛出 TypeError 异常
    def test_generator(self):
        with pytest.raises(TypeError, match="arrays to stack must be"):
            vstack((np.arange(3) for _ in range(2)))

    # 测试指定类型转换和数据类型的情况
    def test_casting_and_dtype(self):
        a = np.array([1, 2, 3])
        b = np.array([2.5, 3.5, 4.5])
        res = np.vstack((a, b), casting="unsafe", dtype=np.int64)
        expected_res = np.array([[1, 2, 3], [2, 3, 4]])
        assert_array_equal(res, expected_res)
    # 定义一个测试函数,用于测试类型转换和数据类型错误的情况
    def test_casting_and_dtype_type_error(self):
        # 创建一个包含整数的 NumPy 数组 a
        a = np.array([1, 2, 3])
        # 创建一个包含浮点数的 NumPy 数组 b
        b = np.array([2.5, 3.5, 4.5])
        # 使用 pytest 模块检测是否会引发 TypeError 异常
        with pytest.raises(TypeError):
            # 尝试在类型安全且数据类型为 np.int64 的情况下堆叠数组 a 和 b
            vstack((a, b), casting="safe", dtype=np.int64)
class TestConcatenate:
    # 定义测试方法,验证 np.concatenate 返回的是副本而非引用
    def test_returns_copy(self):
        # 创建一个 3x3 的单位矩阵 a
        a = np.eye(3)
        # 对 a 进行沿 axis=0 方向的连接,得到 b
        b = np.concatenate([a])
        # 修改 b 的第一个元素为 2
        b[0, 0] = 2
        # 断言 b 的修改不影响原始矩阵 a 的相同位置元素
        assert b[0, 0] != a[0, 0]

    # 定义测试方法,验证 np.concatenate 对各种异常情况的处理
    def test_exceptions(self):
        # 测试 axis 超出范围的情况
        for ndim in [1, 2, 3]:
            # 创建 ndim 维度为 1 的全 1 数组 a
            a = np.ones((1,)*ndim)
            # 沿 axis=0 连接 a 和 a,预期不会抛出异常
            np.concatenate((a, a), axis=0)  # OK
            # 断言沿指定 axis 超出范围时会抛出 AxisError 异常
            assert_raises(AxisError, np.concatenate, (a, a), axis=ndim)
            assert_raises(AxisError, np.concatenate, (a, a), axis=-(ndim + 1))

        # 测试无法连接标量的情况
        assert_raises(ValueError, concatenate, (0,))
        assert_raises(ValueError, concatenate, (np.array(0),))

        # 测试连接的数组维度不匹配的情况
        assert_raises_regex(
            ValueError,
            r"all the input arrays must have same number of dimensions, but "
            r"the array at index 0 has 1 dimension\(s\) and the array at "
            r"index 1 has 2 dimension\(s\)",
            np.concatenate, (np.zeros(1), np.zeros((1, 1))))

        # 测试除连接轴外其他维度不匹配的情况
        a = np.ones((1, 2, 3))
        b = np.ones((2, 2, 3))
        axis = list(range(3))
        for i in range(3):
            # 沿 axis=i 连接 a 和 b,预期不会抛出异常
            np.concatenate((a, b), axis=axis[0])  # OK
            # 断言在指定轴上维度不匹配时会抛出 ValueError 异常
            assert_raises_regex(
                ValueError,
                "all the input array dimensions except for the concatenation axis "
                "must match exactly, but along dimension {}, the array at "
                "index 0 has size 1 and the array at index 1 has size 2"
                .format(i),
                np.concatenate, (a, b), axis=axis[1])
            assert_raises(ValueError, np.concatenate, (a, b), axis=axis[2])
            a = np.moveaxis(a, -1, 0)
            b = np.moveaxis(b, -1, 0)
            axis.append(axis.pop(0))

        # 测试空输入时抛出 ValueError 异常
        assert_raises(ValueError, concatenate, ())

    # 定义测试方法,验证 np.concatenate 在 axis=None 时的行为
    def test_concatenate_axis_None(self):
        # 创建一个 2x2 的浮点数矩阵 a
        a = np.arange(4, dtype=np.float64).reshape((2, 2))
        # 创建一个包含 [0, 1, 2] 的列表 b
        b = list(range(3))
        # 创建一个包含单个字符串 'x' 的列表 c
        c = ['x']
        
        # 测试在 axis=None 时,返回的数组类型与输入矩阵 a 的类型相同
        r = np.concatenate((a, a), axis=None)
        assert_equal(r.dtype, a.dtype)
        # 断言返回的数组维度为 1
        assert_equal(r.ndim, 1)
        
        # 测试在 axis=None 时,返回的数组大小为 a 的大小加上 b 的长度
        r = np.concatenate((a, b), axis=None)
        assert_equal(r.size, a.size + len(b))
        assert_equal(r.dtype, a.dtype)
        
        # 测试在 axis=None 时,使用 dtype="U" 连接 a、b、c
        r = np.concatenate((a, b, c), axis=None, dtype="U")
        d = np.array(['0.0', '1.0', '2.0', '3.0',
                      '0', '1', '2', 'x'])
        assert_array_equal(r, d)
        
        # 测试在 axis=None 时,使用 out 参数将结果连接到预先分配的数组
        out = np.zeros(a.size + len(b))
        r = np.concatenate((a, b), axis=None)
        rout = np.concatenate((a, b), axis=None, out=out)
        assert_(out is rout)
        assert_equal(r, rout)
    def test_large_concatenate_axis_None(self):
        # 当没有指定 axis 参数时,concatenate 函数会使用扁平化的版本。
        # 这个函数曾经在处理多个数组时存在 bug(参见 gh-5979)。
        x = np.arange(1, 100)
        # 将 x 数组按照 axis=None 进行连接
        r = np.concatenate(x, None)
        # 断言连接后的结果与原始数组 x 相等
        assert_array_equal(x, r)

        # 曾经这种写法等同于 `axis=None`,但现在会失败(由于多个问题导致的未指定错误)。
        with pytest.raises(ValueError):
            # 尝试使用一个非法的 axis 参数值来调用 concatenate
            np.concatenate(x, 100)

    def test_concatenate(self):
        # 测试 concatenate 函数的各种用法
        # 单个序列返回不变的数组
        r4 = list(range(4))
        assert_array_equal(concatenate((r4,)), r4)
        # 任何序列类型
        assert_array_equal(concatenate((tuple(r4),)), r4)
        assert_array_equal(concatenate((array(r4),)), r4)
        # 1D 默认连接
        r3 = list(range(3))
        assert_array_equal(concatenate((r4, r3)), r4 + r3)
        # 不同类型序列的混合连接
        assert_array_equal(concatenate((tuple(r4), r3)), r4 + r3)
        assert_array_equal(concatenate((array(r4), r3)), r4 + r3)
        # 明确指定 axis 参数进行连接
        assert_array_equal(concatenate((r4, r3), 0), r4 + r3)
        # 包括负数作为 axis 参数
        assert_array_equal(concatenate((r4, r3), -1), r4 + r3)
        # 2D 连接
        a23 = array([[10, 11, 12], [13, 14, 15]])
        a13 = array([[0, 1, 2]])
        res = array([[10, 11, 12], [13, 14, 15], [0, 1, 2]])
        assert_array_equal(concatenate((a23, a13)), res)
        assert_array_equal(concatenate((a23, a13), 0), res)
        assert_array_equal(concatenate((a23.T, a13.T), 1), res.T)
        assert_array_equal(concatenate((a23.T, a13.T), -1), res.T)
        # 数组必须匹配形状
        assert_raises(ValueError, concatenate, (a23.T, a13.T), 0)
        # 3D 连接
        res = arange(2 * 3 * 7).reshape((2, 3, 7))
        a0 = res[..., :4]
        a1 = res[..., 4:6]
        a2 = res[..., 6:]
        assert_array_equal(concatenate((a0, a1, a2), 2), res)
        assert_array_equal(concatenate((a0, a1, a2), -1), res)
        assert_array_equal(concatenate((a0.T, a1.T, a2.T), 0), res.T)

        # 测试使用输出参数 out 进行连接
        out = res.copy()
        rout = concatenate((a0, a1, a2), 2, out=out)
        assert_(out is rout)
        assert_equal(res, rout)

    @pytest.mark.skipif(IS_PYPY, reason="PYPY handles sq_concat, nb_add differently than cpython")
    def test_operator_concat(self):
        import operator
        a = array([1, 2])
        b = array([3, 4])
        n = [1,2]
        res = array([1, 2, 3, 4])
        assert_raises(TypeError, operator.concat, a, b)
        assert_raises(TypeError, operator.concat, a, n)
        assert_raises(TypeError, operator.concat, n, a)
        assert_raises(TypeError, operator.concat, a, 1)
        assert_raises(TypeError, operator.concat, 1, a)
    # 定义一个测试函数,用于测试不良的输出形状
    def test_bad_out_shape(self):
        # 创建两个numpy数组a和b
        a = array([1, 2])
        b = array([3, 4])

        # 断言:使用np.empty创建输出为5的空数组时,应该引发值错误异常
        assert_raises(ValueError, concatenate, (a, b), out=np.empty(5))
        # 断言:使用np.empty创建输出形状为(4,1)的空数组时,应该引发值错误异常
        assert_raises(ValueError, concatenate, (a, b), out=np.empty((4,1)))
        # 断言:使用np.empty创建输出形状为(1,4)的空数组时,应该引发值错误异常
        assert_raises(ValueError, concatenate, (a, b), out=np.empty((1,4)))
        # 使用np.empty创建输出形状为(4,)的空数组进行连接
        concatenate((a, b), out=np.empty(4))

    # 使用pytest的参数化标记,测试不同情况下的输出和数据类型
    @pytest.mark.parametrize("axis", [None, 0])
    @pytest.mark.parametrize("out_dtype", ["c8", "f4", "f8", ">f8", "i8", "S4"])
    @pytest.mark.parametrize("casting",
            ['no', 'equiv', 'safe', 'same_kind', 'unsafe'])
    def test_out_and_dtype(self, axis, out_dtype, casting):
        # 创建一个指定数据类型的空数组out
        out = np.empty(4, dtype=out_dtype)
        # 创建两个要连接的数组
        to_concat = (array([1.1, 2.2]), array([3.3, 4.4]))

        # 如果无法将to_concat[0]转换为指定的out_dtype,则应该引发类型错误异常
        if not np.can_cast(to_concat[0], out_dtype, casting=casting):
            with assert_raises(TypeError):
                concatenate(to_concat, out=out, axis=axis, casting=casting)
            with assert_raises(TypeError):
                concatenate(to_concat, dtype=out.dtype,
                            axis=axis, casting=casting)
        else:
            # 否则,使用指定的out和数据类型连接数组,并进行断言检查
            res_out = concatenate(to_concat, out=out,
                                  axis=axis, casting=casting)
            res_dtype = concatenate(to_concat, dtype=out.dtype,
                                    axis=axis, casting=casting)
            assert res_out is out
            assert_array_equal(out, res_dtype)
            assert res_dtype.dtype == out_dtype

        # 最后,应该引发类型错误异常,因为不能同时指定out和dtype参数
        with assert_raises(TypeError):
            concatenate(to_concat, out=out, dtype=out_dtype, axis=axis)

    # 使用pytest的参数化标记,测试不同情况下的字符串数据类型
    @pytest.mark.parametrize("axis", [None, 0])
    @pytest.mark.parametrize("string_dt", ["S", "U", "S0", "U0"])
    @pytest.mark.parametrize("arrs",
            [([0.],), ([0.], [1]), ([0], ["string"], [1.])])
    def test_dtype_with_promotion(self, arrs, string_dt, axis):
        # 执行连接操作,使用给定的字符串数据类型和不安全的类型转换方式
        res = np.concatenate(arrs, axis=axis, dtype=string_dt, casting="unsafe")
        # 断言:实际的数据类型应该与转换后的双精度数组的数据类型相同
        assert res.dtype == np.array(1.).astype(string_dt).dtype

    # 使用pytest的参数化标记,测试字符串数据类型不会检查的情况
    @pytest.mark.parametrize("axis", [None, 0])
    def test_string_dtype_does_not_inspect(self, axis):
        # 应该引发类型错误异常,因为不能将None和整数1连接为字符串数据类型"S"
        with pytest.raises(TypeError):
            np.concatenate(([None], [1]), dtype="S", axis=axis)
        # 应该引发类型错误异常,因为不能将None和整数1连接为Unicode字符串数据类型"U"
        with pytest.raises(TypeError):
            np.concatenate(([None], [1]), dtype="U", axis=axis)

    # 使用pytest的参数化标记,测试子数组错误的情况
    @pytest.mark.parametrize("axis", [None, 0])
    def test_subarray_error(self, axis):
        # 应该引发类型错误异常,因为不能将(1,)整数数组连接为子数组dtype
        with pytest.raises(TypeError, match=".*subarray dtype"):
            np.concatenate(([1], [1]), dtype="(2,)i", axis=axis)
# 定义测试函数 `test_stack()`,用于测试 `stack` 函数的各种输入情况和异常情况
def test_stack():
    # 针对非可迭代输入,验证是否会抛出 TypeError 异常
    assert_raises(TypeError, stack, 1)

    # 针对0维输入的测试用例
    for input_ in [(1, 2, 3),               # 元组形式
                   [np.int32(1), np.int32(2), np.int32(3)],  # 使用 np.int32 数组
                   [np.array(1), np.array(2), np.array(3)]]:  # 使用 np.array 数组
        assert_array_equal(stack(input_), [1, 2, 3])

    # 1维输入的测试用例
    a = np.array([1, 2, 3])
    b = np.array([4, 5, 6])
    r1 = array([[1, 2, 3], [4, 5, 6]])

    # 测试 np.stack 函数的不同参数组合和结果是否符合预期
    assert_array_equal(np.stack((a, b)), r1)
    assert_array_equal(np.stack((a, b), axis=1), r1.T)

    # 测试所有输入类型
    assert_array_equal(np.stack(list([a, b])), r1)
    assert_array_equal(np.stack(array([a, b])), r1)

    # 所有1维输入形状的测试用例
    arrays = [np.random.randn(3) for _ in range(10)]
    axes = [0, 1, -1, -2]
    expected_shapes = [(10, 3), (3, 10), (3, 10), (10, 3)]
    for axis, expected_shape in zip(axes, expected_shapes):
        assert_equal(np.stack(arrays, axis).shape, expected_shape)

    # 测试超出范围的轴异常
    assert_raises_regex(AxisError, 'out of bounds', stack, arrays, axis=2)
    assert_raises_regex(AxisError, 'out of bounds', stack, arrays, axis=-3)

    # 所有2维输入形状的测试用例
    arrays = [np.random.randn(3, 4) for _ in range(10)]
    axes = [0, 1, 2, -1, -2, -3]
    expected_shapes = [(10, 3, 4), (3, 10, 4), (3, 4, 10),
                       (3, 4, 10), (3, 10, 4), (10, 3, 4)]
    for axis, expected_shape in zip(axes, expected_shapes):
        assert_equal(np.stack(arrays, axis).shape, expected_shape)

    # 空数组的测试用例
    assert_(stack([[], [], []]).shape == (3, 0))
    assert_(stack([[], [], []], axis=1).shape == (0, 3))

    # 输出参数的测试用例
    out = np.zeros_like(r1)
    np.stack((a, b), out=out)
    assert_array_equal(out, r1)

    # 边界情况的异常测试
    assert_raises_regex(ValueError, 'need at least one array', stack, [])
    assert_raises_regex(ValueError, 'must have the same shape',
                        stack, [1, np.arange(3)])
    assert_raises_regex(ValueError, 'must have the same shape',
                        stack, [np.arange(3), 1])
    assert_raises_regex(ValueError, 'must have the same shape',
                        stack, [np.arange(3), 1], axis=1)
    assert_raises_regex(ValueError, 'must have the same shape',
                        stack, [np.zeros((3, 3)), np.zeros(3)], axis=1)
    assert_raises_regex(ValueError, 'must have the same shape',
                        stack, [np.arange(2), np.arange(3)])

    # 不接受生成器的测试用例
    with pytest.raises(TypeError, match="arrays to stack must be"):
        stack((x for x in range(3)))

    # 类型转换和数据类型测试
    a = np.array([1, 2, 3])
    b = np.array([2.5, 3.5, 4.5])
    res = np.stack((a, b), axis=1, casting="unsafe", dtype=np.int64)
    expected_res = np.array([[1, 2], [2, 3], [3, 4]])
    assert_array_equal(res, expected_res)

    # 类型转换和数据类型与 TypeError 的测试用例
    with assert_raises(TypeError):
        stack((a, b), dtype=np.int64, axis=1, casting="safe")
@pytest.mark.parametrize("out_dtype", ["c8", "f4", "f8", ">f8", "i8"])
# 参数化测试用例,测试不同的输出数据类型
@pytest.mark.parametrize("casting",
                         ['no', 'equiv', 'safe', 'same_kind', 'unsafe'])
# 参数化测试用例,测试不同的类型转换策略

def test_stack_out_and_dtype(axis, out_dtype, casting):
    # 准备要堆叠的数组
    to_concat = (array([1, 2]), array([3, 4]))
    # 预期的堆叠结果
    res = array([[1, 2], [3, 4]])
    # 创建一个与 res 相同形状的零数组
    out = np.zeros_like(res)

    # 如果无法将第一个数组转换为指定的输出数据类型,则抛出 TypeError 异常
    if not np.can_cast(to_concat[0], out_dtype, casting=casting):
        with assert_raises(TypeError):
            stack(to_concat, dtype=out_dtype,
                  axis=axis, casting=casting)
    else:
        # 测试指定输出数组的情况
        res_out = stack(to_concat, out=out,
                        axis=axis, casting=casting)
        # 测试指定输出数据类型的情况
        res_dtype = stack(to_concat, dtype=out_dtype,
                          axis=axis, casting=casting)
        # 确保使用指定输出数组时的返回结果是 out 数组本身
        assert res_out is out
        # 确保使用指定输出数据类型时的返回结果与 out 数组相等
        assert_array_equal(out, res_dtype)
        # 确保返回结果的数据类型与指定的输出数据类型相同
        assert res_dtype.dtype == out_dtype

    # 在指定输出数组的情况下,检查是否会抛出 TypeError 异常
    with assert_raises(TypeError):
        stack(to_concat, out=out, dtype=out_dtype, axis=axis)


class TestBlock:
    @pytest.fixture(params=['block', 'force_concatenate', 'force_slicing'])
    # 使用不同的参数化来设置测试块的行为
    def block(self, request):
        # 阻塞小数组和大数组会走不同的路径。
        # 算法的触发取决于所需元素的数量拷贝。
        # 定义一个测试夹具,强制大多数测试通过两个代码路径。
        # 如果找到单一算法对小数组和大数组都更快,应最终删除此部分。
        def _block_force_concatenate(arrays):
            arrays, list_ndim, result_ndim, _ = _block_setup(arrays)
            return _block_concatenate(arrays, list_ndim, result_ndim)

        def _block_force_slicing(arrays):
            arrays, list_ndim, result_ndim, _ = _block_setup(arrays)
            return _block_slicing(arrays, list_ndim, result_ndim)

        if request.param == 'force_concatenate':
            return _block_force_concatenate
        elif request.param == 'force_slicing':
            return _block_force_slicing
        elif request.param == 'block':
            return block
        else:
            raise ValueError('Unknown blocking request. There is a typo in the tests.')

    def test_returns_copy(self, block):
        # 创建一个单位矩阵
        a = np.eye(3)
        # 使用测试块对数组进行处理
        b = block(a)
        # 修改 b 的值
        b[0, 0] = 2
        # 确保修改后的值不等于原始数组 a 的值
        assert b[0, 0] != a[0, 0]

    def test_block_total_size_estimate(self, block):
        # 测试总大小估算
        _, _, _, total_size = _block_setup([1])
        assert total_size == 1

        _, _, _, total_size = _block_setup([[1]])
        assert total_size == 1

        _, _, _, total_size = _block_setup([[1, 1]])
        assert total_size == 2

        _, _, _, total_size = _block_setup([[1], [1]])
        assert total_size == 2

        _, _, _, total_size = _block_setup([[1, 2], [3, 4]])
        assert total_size == 4
    # 定义一个测试方法,测试简单的按行拼接的情况
    def test_block_simple_row_wise(self, block):
        # 创建一个2x2的全1数组
        a_2d = np.ones((2, 2))
        # 将a_2d中的每个元素乘以2,得到b_2d
        b_2d = 2 * a_2d
        # 预期结果,将a_2d和b_2d按行拼接
        desired = np.array([[1, 1, 2, 2],
                            [1, 1, 2, 2]])
        # 调用被测试的block方法,传入a_2d和b_2d,获取结果
        result = block([a_2d, b_2d])
        # 断言结果与预期相等
        assert_equal(desired, result)

    # 定义一个测试方法,测试简单的按列拼接的情况
    def test_block_simple_column_wise(self, block):
        # 创建一个2x2的全1数组
        a_2d = np.ones((2, 2))
        # 将a_2d中的每个元素乘以2,得到b_2d
        b_2d = 2 * a_2d
        # 预期结果,将a_2d和b_2d按列拼接
        expected = np.array([[1, 1],
                             [1, 1],
                             [2, 2],
                             [2, 2]])
        # 调用被测试的block方法,传入[a_2d]和[b_2d]的列表,获取结果
        result = block([[a_2d], [b_2d]])
        # 断言结果与预期相等
        assert_equal(expected, result)

    # 定义一个测试方法,测试包含1维数组按行拼接的情况
    def test_block_with_1d_arrays_row_wise(self, block):
        # 创建两个1维数组a和b
        a = np.array([1, 2, 3])
        b = np.array([2, 3, 4])
        # 预期结果,将a和b按行拼接
        expected = np.array([1, 2, 3, 2, 3, 4])
        # 调用被测试的block方法,传入a和b,获取结果
        result = block([a, b])
        # 断言结果与预期相等
        assert_equal(expected, result)

    # 定义一个测试方法,测试包含1维数组按行拼接的多行情况
    def test_block_with_1d_arrays_multiple_rows(self, block):
        # 创建两个1维数组a和b
        a = np.array([1, 2, 3])
        b = np.array([2, 3, 4])
        # 预期结果,将[a, b]和[a, b]按行拼接
        expected = np.array([[1, 2, 3, 2, 3, 4],
                             [1, 2, 3, 2, 3, 4]])
        # 调用被测试的block方法,传入[[a, b], [a, b]],获取结果
        result = block([[a, b], [a, b]])
        # 断言结果与预期相等
        assert_equal(expected, result)

    # 定义一个测试方法,测试包含1维数组按列拼接的情况
    def test_block_with_1d_arrays_column_wise(self, block):
        # 创建两个1维数组a_1d和b_1d
        a_1d = np.array([1, 2, 3])
        b_1d = np.array([2, 3, 4])
        # 预期结果,将[a_1d]和[b_1d]按列拼接
        expected = np.array([[1, 2, 3],
                             [2, 3, 4]])
        # 调用被测试的block方法,传入[[a_1d], [b_1d]],获取结果
        result = block([[a_1d], [b_1d]])
        # 断言结果与预期相等
        assert_equal(expected, result)

    # 定义一个测试方法,测试包含2维数组和1维数组混合拼接的情况
    def test_block_mixed_1d_and_2d(self, block):
        # 创建一个2x2的全1数组a_2d和一个1维数组b_1d
        a_2d = np.ones((2, 2))
        b_1d = np.array([2, 2])
        # 调用被测试的block方法,传入[[a_2d], [b_1d]],获取结果
        result = block([[a_2d], [b_1d]])
        # 预期结果,将a_2d和b_1d按列拼接
        expected = np.array([[1, 1],
                             [1, 1],
                             [2, 2]])
        # 断言结果与预期相等
        assert_equal(expected, result)

    # 定义一个测试方法,测试更复杂的拼接情况
    def test_block_complicated(self, block):
        # 创建多个不同维度和形状的数组
        one_2d = np.array([[1, 1, 1]])
        two_2d = np.array([[2, 2, 2]])
        three_2d = np.array([[3, 3, 3, 3, 3, 3]])
        four_1d = np.array([4, 4, 4, 4, 4, 4])
        five_0d = np.array(5)
        six_1d = np.array([6, 6, 6, 6, 6])
        zero_2d = np.zeros((2, 6))

        # 预期结果,按照给定的组合拼接这些数组
        expected = np.array([[1, 1, 1, 2, 2, 2],
                             [3, 3, 3, 3, 3, 3],
                             [4, 4, 4, 4, 4, 4],
                             [5, 6, 6, 6, 6, 6],
                             [0, 0, 0, 0, 0, 0],
                             [0, 0, 0, 0, 0, 0]])

        # 调用被测试的block方法,传入包含不同维度和形状数组的列表,获取结果
        result = block([[one_2d, two_2d],
                        [three_2d],
                        [four_1d],
                        [five_0d, six_1d],
                        [zero_2d]])
        # 断言结果与预期相等
        assert_equal(result, expected)
    # 定义一个测试方法,用于测试包含嵌套结构的块操作
    def test_nested(self, block):
        # 创建各种大小和形状的 NumPy 数组
        one = np.array([1, 1, 1])
        two = np.array([[2, 2, 2], [2, 2, 2], [2, 2, 2]])
        three = np.array([3, 3, 3])
        four = np.array([4, 4, 4])
        five = np.array(5)
        six = np.array([6, 6, 6, 6, 6])
        zero = np.zeros((2, 6))

        # 进行块操作,生成嵌套的数组结构
        result = block([
            [
                # 第一个子块,包含三个一维数组
                block([
                   [one],   # 第一个一维数组
                   [three], # 第二个一维数组
                   [four]   # 第三个一维数组
                ]),
                two  # 第二个子块,包含一个二维数组
            ],
            [five, six],  # 第三个子块,包含两个一维数组
            [zero]        # 第四个子块,包含一个二维数组
        ])
        # 预期的结果数组
        expected = np.array([[1, 1, 1, 2, 2, 2],
                             [3, 3, 3, 2, 2, 2],
                             [4, 4, 4, 2, 2, 2],
                             [5, 6, 6, 6, 6, 6],
                             [0, 0, 0, 0, 0, 0],
                             [0, 0, 0, 0, 0, 0]])

        # 断言结果数组与预期数组相等
        assert_equal(result, expected)

    # 定义一个测试方法,用于测试包含三维数组的块操作
    def test_3d(self, block):
        # 创建各种大小和形状的三维 NumPy 数组
        a000 = np.ones((2, 2, 2), int) * 1
        a100 = np.ones((3, 2, 2), int) * 2
        a010 = np.ones((2, 3, 2), int) * 3
        a001 = np.ones((2, 2, 3), int) * 4
        a011 = np.ones((2, 3, 3), int) * 5
        a101 = np.ones((3, 2, 3), int) * 6
        a110 = np.ones((3, 3, 2), int) * 7
        a111 = np.ones((3, 3, 3), int) * 8

        # 进行块操作,生成嵌套的三维数组结构
        result = block([
            [
                [a000, a001],  # 第一个子块,包含两个二维数组
                [a010, a011],  # 第二个子块,包含两个二维数组
            ],
            [
                [a100, a101],  # 第三个子块,包含两个二维数组
                [a110, a111],  # 第四个子块,包含两个二维数组
            ]
        ])
        # 预期的结果数组
        expected = np.array([[[1, 1, 4, 4, 4],
                              [1, 1, 4, 4, 4],
                              [3, 3, 5, 5, 5],
                              [3, 3, 5, 5, 5],
                              [3, 3, 5, 5, 5]],

                             [[1, 1, 4, 4, 4],
                              [1, 1, 4, 4, 4],
                              [3, 3, 5, 5, 5],
                              [3, 3, 5, 5, 5],
                              [3, 3, 5, 5, 5]],

                             [[2, 2, 6, 6, 6],
                              [2, 2, 6, 6, 6],
                              [7, 7, 8, 8, 8],
                              [7, 7, 8, 8, 8],
                              [7, 7, 8, 8, 8]],

                             [[2, 2, 6, 6, 6],
                              [2, 2, 6, 6, 6],
                              [7, 7, 8, 8, 8],
                              [7, 7, 8, 8, 8],
                              [7, 7, 8, 8, 8]],

                             [[2, 2, 6, 6, 6],
                              [2, 2, 6, 6, 6],
                              [7, 7, 8, 8, 8],
                              [7, 7, 8, 8, 8],
                              [7, 7, 8, 8, 8]]])

        # 断言结果数组与预期数组相等
        assert_array_equal(result, expected)

    # 定义一个测试方法,用于测试形状不匹配的块操作
    def test_block_with_mismatched_shape(self, block):
        # 创建不同形状的 NumPy 数组
        a = np.array([0, 0])
        b = np.eye(2)

        # 断言块操作会抛出 ValueError 异常,因为形状不匹配
        assert_raises(ValueError, block, [a, b])
        assert_raises(ValueError, block, [b, a])

        # 创建不同形状的二维数组列表
        to_block = [[np.ones((2,3)), np.ones((2,2))],
                    [np.ones((2,2)), np.ones((2,2))]]

        # 断言块操作会抛出 ValueError 异常,因为形状不匹配
        assert_raises(ValueError, block, to_block)
    # 测试函数:验证对于不包含列表的情况,block 函数能正确处理
    def test_no_lists(self, block):
        # 断言:当输入参数为1时,返回一个形状为(1,)的 NumPy 数组
        assert_equal(block(1),         np.array(1))
        # 断言:当输入参数为3阶单位矩阵时,返回相同的3阶单位矩阵
        assert_equal(block(np.eye(3)), np.eye(3))

    # 测试函数:验证对于不合法的嵌套列表的情况,block 函数能引发 ValueError 异常并包含指定错误消息
    def test_invalid_nesting(self, block):
        msg = 'depths are mismatched'
        # 断言:当嵌套列表的深度不匹配时,会引发 ValueError 异常,并包含指定错误消息
        assert_raises_regex(ValueError, msg, block, [1, [2]])
        assert_raises_regex(ValueError, msg, block, [1, []])
        assert_raises_regex(ValueError, msg, block, [[1], 2])
        assert_raises_regex(ValueError, msg, block, [[], 2])
        assert_raises_regex(ValueError, msg, block, [
            [[1], [2]],
            [[3, 4]],
            [5]  # 缺少括号
        ])

    # 测试函数:验证对于空列表的情况,block 函数能引发 ValueError 异常并包含指定错误消息
    def test_empty_lists(self, block):
        assert_raises_regex(ValueError, 'empty', block, [])
        assert_raises_regex(ValueError, 'empty', block, [[]])
        assert_raises_regex(ValueError, 'empty', block, [[1], []])

    # 测试函数:验证对于元组作为输入的情况,block 函数能引发 TypeError 异常并包含指定错误消息
    def test_tuple(self, block):
        assert_raises_regex(TypeError, 'tuple', block, ([1, 2], [3, 4]))
        assert_raises_regex(TypeError, 'tuple', block, [(1, 2), (3, 4)])

    # 测试函数:验证对于不同维度的数组作为输入的情况,block 函数能正确处理
    def test_different_ndims(self, block):
        a = 1.
        b = 2 * np.ones((1, 2))
        c = 3 * np.ones((1, 1, 3))

        # 调用 block 函数,并断言返回的结果与预期的结果相等
        result = block([a, b, c])
        expected = np.array([[[1., 2., 2., 3., 3., 3.]]])
        assert_equal(result, expected)

    # 测试函数:验证对于深度不同的多维数组作为输入的情况,block 函数能正确处理
    def test_different_ndims_depths(self, block):
        a = 1.
        b = 2 * np.ones((1, 2))
        c = 3 * np.ones((1, 2, 3))

        # 调用 block 函数,并断言返回的结果与预期的结果相等
        result = block([[a, b], [c]])
        expected = np.array([[[1., 2., 2.],
                              [3., 3., 3.],
                              [3., 3., 3.]]])
        assert_equal(result, expected)

    # 测试函数:验证对于不同存储顺序的多维数组作为输入的情况,block 函数能正确处理
    def test_block_memory_order(self, block):
        # 创建 C 和 Fortran 存储顺序的三维数组
        arr_c = np.zeros((3,)*3, order='C')
        arr_f = np.zeros((3,)*3, order='F')

        # 创建对应存储顺序的多层嵌套数组 b_c 和 b_f
        b_c = [[[arr_c, arr_c],
                [arr_c, arr_c]],
               [[arr_c, arr_c],
                [arr_c, arr_c]]]

        b_f = [[[arr_f, arr_f],
                [arr_f, arr_f]],
               [[arr_f, arr_f],
                [arr_f, arr_f]]]

        # 断言:block 函数处理后的数组保持 C 和 Fortran 的存储顺序
        assert block(b_c).flags['C_CONTIGUOUS']
        assert block(b_f).flags['F_CONTIGUOUS']

        # 更新为二维数组的情况
        arr_c = np.zeros((3, 3), order='C')
        arr_f = np.zeros((3, 3), order='F')

        b_c = [[arr_c, arr_c],
               [arr_c, arr_c]]

        b_f = [[arr_f, arr_f],
               [arr_f, arr_f]]

        # 断言:block 函数处理后的数组保持 C 和 Fortran 的存储顺序
        assert block(b_c).flags['C_CONTIGUOUS']
        assert block(b_f).flags['F_CONTIGUOUS']
# 定义一个测试函数 test_block_dispatcher,用于测试 _block_dispatcher 函数的行为
def test_block_dispatcher():
    # 定义一个内部类 ArrayLike,用于模拟类似数组的对象
    class ArrayLike:
        pass
    
    # 创建三个 ArrayLike 的实例对象 a, b, c
    a = ArrayLike()
    b = ArrayLike()
    c = ArrayLike()
    
    # 测试 _block_dispatcher 函数处理单个 ArrayLike 对象的情况,期望返回包含 a 的列表
    assert_equal(list(_block_dispatcher(a)), [a])
    
    # 测试 _block_dispatcher 函数处理包含单个 ArrayLike 对象的列表的情况,期望返回包含 a 的列表
    assert_equal(list(_block_dispatcher([a])), [a])
    
    # 测试 _block_dispatcher 函数处理包含多个 ArrayLike 对象的列表的情况,期望返回包含 a 和 b 的列表
    assert_equal(list(_block_dispatcher([a, b])), [a, b])
    
    # 测试 _block_dispatcher 函数处理包含嵌套列表的情况,期望返回包含 a, b 和 c 的列表
    assert_equal(list(_block_dispatcher([[a], [b, [c]]])), [a, b, c])
    
    # 测试 _block_dispatcher 函数不会递归处理非列表类型的情况,期望返回包含 (a, b) 的列表
    assert_equal(list(_block_dispatcher((a, b))), [(a, b)])

.\numpy\numpy\_core\tests\test_simd.py

# NOTE: Please avoid the use of numpy.testing since NPYV intrinsics
# may be involved in their functionality.
import pytest, math, re
import itertools
import operator
from numpy._core._simd import targets, clear_floatstatus, get_floatstatus
from numpy._core._multiarray_umath import __cpu_baseline__

class _Test_Utility:
    # submodule of the desired SIMD extension, e.g. targets["AVX512F"]
    npyv = None
    # the current data type suffix e.g. 's8'
    sfx  = None
    # target name can be 'baseline' or one or more of CPU features
    target_name = None

    def __getattr__(self, attr):
        """
        To call NPV intrinsics without the attribute 'npyv' and
        auto suffixing intrinsics according to class attribute 'sfx'
        """
        return getattr(self.npyv, attr + "_" + self.sfx)

    def _x2(self, intrin_name):
        """
        Returns the intrinsic function name suffixed with 'sfx' followed by 'x2'.
        """
        return getattr(self.npyv, f"{intrin_name}_{self.sfx}x2")

    def _data(self, start=None, count=None, reverse=False):
        """
        Create list of consecutive numbers according to number of vector's lanes.
        """
        if start is None:
            start = 1
        if count is None:
            count = self.nlanes
        rng = range(start, start + count)
        if reverse:
            rng = reversed(rng)
        if self._is_fp():
            return [x / 1.0 for x in rng]
        return list(rng)

    def _is_unsigned(self):
        """
        Checks if the current data type suffix indicates an unsigned integer type.
        """
        return self.sfx[0] == 'u'

    def _is_signed(self):
        """
        Checks if the current data type suffix indicates a signed integer type.
        """
        return self.sfx[0] == 's'

    def _is_fp(self):
        """
        Checks if the current data type suffix indicates a floating point type.
        """
        return self.sfx[0] == 'f'

    def _scalar_size(self):
        """
        Returns the size of the scalar in bytes based on the current data type suffix.
        """
        return int(self.sfx[1:])

    def _int_clip(self, seq):
        """
        Clips integer sequence 'seq' to fit within the valid range for the current data type suffix.
        """
        if self._is_fp():
            return seq
        max_int = self._int_max()
        min_int = self._int_min()
        return [min(max(v, min_int), max_int) for v in seq]

    def _int_max(self):
        """
        Returns the maximum representable integer value for the current data type suffix.
        """
        if self._is_fp():
            return None
        max_u = self._to_unsigned(self.setall(-1))[0]
        if self._is_signed():
            return max_u // 2
        return max_u

    def _int_min(self):
        """
        Returns the minimum representable integer value for the current data type suffix.
        """
        if self._is_fp():
            return None
        if self._is_unsigned():
            return 0
        return -(self._int_max() + 1)

    def _true_mask(self):
        """
        Returns the true mask for the current data type suffix.
        """
        max_unsig = getattr(self.npyv, "setall_u" + self.sfx[1:])(-1)
        return max_unsig[0]

def check_floatstatus(divbyzero=False, overflow=False,
                      underflow=False, invalid=False,
                      all=False):
    """
    Checks the floating point status flags against specified conditions.
    """
    #define NPY_FPE_DIVIDEBYZERO  1
    #define NPY_FPE_OVERFLOW      2
    #define NPY_FPE_UNDERFLOW     4
    #define NPY_FPE_INVALID       8
    err = get_floatstatus()
    ret = (all or divbyzero) and (err & 1) != 0
    ret |= (all or overflow) and (err & 2) != 0
    ret |= (all or underflow) and (err & 4) != 0
    ret |= (all or invalid) and (err & 8) != 0
    return ret
    # 将输入的向量转换为无符号数形式
    def _to_unsigned(self, vector):
        # 如果向量是列表或元组,调用对应的 numpy 加载函数来加载无符号数
        if isinstance(vector, (list, tuple)):
            return getattr(self.npyv, "load_u" + self.sfx[1:])(vector)
        else:
            # 否则,从向量对象中提取名称后缀并生成相应的转换函数名
            sfx = vector.__name__.replace("npyv_", "")
            if sfx[0] == "b":
                cvt_intrin = "cvt_u{0}_b{0}"  # 使用 b 开头的转换函数
            else:
                cvt_intrin = "reinterpret_u{0}_{1}"  # 使用 reinterpret 转换函数
            # 调用生成的转换函数来将向量转换为无符号数形式
            return getattr(self.npyv, cvt_intrin.format(sfx[1:], sfx))(vector)

    # 返回正无穷大
    def _pinfinity(self):
        return float("inf")

    # 返回负无穷大
    def _ninfinity(self):
        return -float("inf")

    # 返回 NaN(Not a Number)
    def _nan(self):
        return float("nan")

    # 返回 CPU 的特性信息
    def _cpu_features(self):
        target = self.target_name
        # 如果目标名称是 "baseline",则替换为 __cpu_baseline__ 的值
        if target == "baseline":
            target = __cpu_baseline__
        else:
            # 否则,按 '__' 进行分割目标名称,得到多个目标信息
            target = target.split('__')  # 多目标分隔符
        # 将目标信息用空格连接成字符串并返回
        return ' '.join(target)
    # _SIMD_BOOL 类,继承自 _Test_Utility 类,用于测试布尔向量类型的统一接口
    class _SIMD_BOOL(_Test_Utility):
        """
        To test all boolean vector types at once
        """
        
        # 获取向量长度(lanes 数量),通过获取属性的方式动态调用
        def _nlanes(self):
            return getattr(self.npyv, "nlanes_u" + self.sfx[1:])
        
        # 生成测试数据,返回一个布尔向量,可以选择是否反向生成
        def _data(self, start=None, count=None, reverse=False):
            # 获取真值掩码
            true_mask = self._true_mask()
            # 生成范围为 0 到 nlanes 的序列
            rng = range(self._nlanes())
            if reverse:
                rng = reversed(rng)
            # 生成布尔向量数据,奇数索引位置使用 true_mask,偶数索引位置使用 0
            return [true_mask if x % 2 else 0 for x in rng]
        
        # 加载数据并转换为布尔向量,依据数据长度动态调用 load 和 cvt 方法
        def _load_b(self, data):
            len_str = self.sfx[1:]
            load = getattr(self.npyv, "load_u" + len_str)
            cvt = getattr(self.npyv, f"cvt_b{len_str}_u{len_str}")
            return cvt(load(data))
        
        # 测试逻辑运算操作符,包括 and、or、xor 和 not,使用相应的向量操作方法
        def test_operators_logical(self):
            """
            Logical operations for boolean types.
            Test intrinsics:
                npyv_xor_##SFX, npyv_and_##SFX, npyv_or_##SFX, npyv_not_##SFX,
                npyv_andc_b8, npvy_orc_b8, nvpy_xnor_b8
            """
            # 获取正序和反序的数据和向量数据
            data_a = self._data()
            data_b = self._data(reverse=True)
            vdata_a = self._load_b(data_a)
            vdata_b = self._load_b(data_b)
            
            # 计算按位与的结果并断言相等
            data_and = [a & b for a, b in zip(data_a, data_b)]
            vand = getattr(self, "and")(vdata_a, vdata_b)
            assert vand == data_and
            
            # 计算按位或的结果并断言相等
            data_or = [a | b for a, b in zip(data_a, data_b)]
            vor = getattr(self, "or")(vdata_a, vdata_b)
            assert vor == data_or
            
            # 计算按位异或的结果并断言相等
            data_xor = [a ^ b for a, b in zip(data_a, data_b)]
            vxor = getattr(self, "xor")(vdata_a, vdata_b)
            assert vxor == data_xor
            
            # 计算按位取反的结果并断言相等
            vnot = getattr(self, "not")(vdata_a)
            assert vnot == data_b
            
            # 如果数据长度不是 b8,则不支持 andc、orc 和 xnor 操作,直接返回
            if self.sfx not in ("b8"):
                return
            
            # 计算按位与非的结果并断言相等
            data_andc = [(a & ~b) & 0xFF for a, b in zip(data_a, data_b)]
            vandc = getattr(self, "andc")(vdata_a, vdata_b)
            assert data_andc == vandc
            
            # 计算按位或非的结果并断言相等
            data_orc = [(a | ~b) & 0xFF for a, b in zip(data_a, data_b)]
            vorc = getattr(self, "orc")(vdata_a, vdata_b)
            assert data_orc == vorc
            
            # 计算按位异或非的结果并断言相等
            data_xnor = [~(a ^ b) & 0xFF for a, b in zip(data_a, data_b)]
            vxnor = getattr(self, "xnor")(vdata_a, vdata_b)
            assert data_xnor == vxnor
        
        # 测试将布尔向量转换为位数的操作
        def test_tobits(self):
            # 定义一个 lambda 函数将数据转换为位数
            data2bits = lambda data: sum([int(x != 0) << i for i, x in enumerate(data, 0)])
            # 对正序和反序的数据进行遍历
            for data in (self._data(), self._data(reverse=True)):
                vdata = self._load_b(data)
                # 计算数据的位表示
                data_bits = data2bits(data)
                # 进行 tobits 操作并断言结果与预期相等
                tobits = self.tobits(vdata)
                bin_tobits = bin(tobits)
                assert bin_tobits == bin(data_bits)
    def test_pack(self):
        """
        Pack multiple vectors into one
        Test intrinsics:
            npyv_pack_b8_b16
            npyv_pack_b8_b32
            npyv_pack_b8_b64
        """
        # 如果不是指定的后缀,则不执行测试
        if self.sfx not in ("b16", "b32", "b64"):
            return

        # 创建向量数据
        data = self._data()
        rdata = self._data(reverse=True)
        
        # 加载向量数据为 SIMD 变量
        vdata = self._load_b(data)
        vrdata = self._load_b(rdata)
        
        # 获取对应的打包函数
        pack_simd = getattr(self.npyv, f"pack_b8_{self.sfx}")

        # 根据后缀类型执行不同的打包操作
        if self.sfx == "b16":
            # 将 rdata 和 data 的元素取低8位并打包成 spack
            spack = [(i & 0xFF) for i in (list(rdata) + list(data))]
            # 使用 SIMD 函数打包 vrdata 和 vdata
            vpack = pack_simd(vrdata, vdata)
        elif self.sfx == "b32":
            # 将 rdata 和 data 的元素取低8位并扩展两倍后打包成 spack
            spack = [(i & 0xFF) for i in (2*list(rdata) + 2*list(data))]
            # 使用 SIMD 函数打包 vrdata, vrdata, vdata, vdata
            vpack = pack_simd(vrdata, vrdata, vdata, vdata)
        elif self.sfx == "b64":
            # 将 rdata 和 data 的元素取低8位并扩展四倍后打包成 spack
            spack = [(i & 0xFF) for i in (4*list(rdata) + 4*list(data))]
            # 使用 SIMD 函数打包 vrdata, vrdata, vrdata, vrdata, vdata, vdata, vdata, vdata
            vpack = pack_simd(vrdata, vrdata, vrdata, vrdata,
                               vdata,  vdata,  vdata,  vdata)
        
        # 断言打包结果与预期结果相同
        assert vpack == spack

    @pytest.mark.parametrize("intrin", ["any", "all"])
    @pytest.mark.parametrize("data", (
        [-1, 0],
        [0, -1],
        [-1],
        [0]
    ))
    def test_operators_crosstest(self, intrin, data):
        """
        Test intrinsics:
            npyv_any_##SFX
            npyv_all_##SFX
        """
        # 将数据乘以 SIMD 向量长度后加载为 SIMD 变量
        data_a = self._load_b(data * self._nlanes())
        
        # 动态执行函数名对应的函数
        func = eval(intrin)
        
        # 获取对象实例中的函数引用
        intrin = getattr(self, intrin)
        
        # 计算预期的标量操作结果
        desired = func(data_a)
        
        # 使用 SIMD 函数进行计算
        simd = intrin(data_a)
        
        # 断言 SIMD 计算结果与预期结果相等
        assert not not simd == desired
class _SIMD_INT(_Test_Utility):
    """
    To test all integer vector types at once
    """

    def test_operators_shift(self):
        # 如果数据类型是 'u8' 或 's8',则跳过测试
        if self.sfx in ("u8", "s8"):
            return

        # 创建包含接近整型最大值的数据集
        data_a = self._data(self._int_max() - self.nlanes)
        # 创建包含整型最小值的数据集,以相反顺序
        data_b = self._data(self._int_min(), reverse=True)
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)

        # 对于每个位移量进行循环测试
        for count in range(self._scalar_size()):
            # 创建左移后的数据集,用于加载并进行类型转换
            data_shl_a = self.load([a << count for a in data_a])
            # 左移操作
            shl = self.shl(vdata_a, count)
            assert shl == data_shl_a
            # 创建右移后的数据集,用于加载并进行类型转换
            data_shr_a = self.load([a >> count for a in data_a])
            # 右移操作
            shr = self.shr(vdata_a, count)
            assert shr == data_shr_a

        # 对于从 1 到标量大小的位移量进行循环测试
        for count in range(1, self._scalar_size()):
            # 创建左移后的数据集,用于加载并进行类型转换
            data_shl_a = self.load([a << count for a in data_a])
            # 左移常数位移量
            shli = self.shli(vdata_a, count)
            assert shli == data_shl_a
            # 创建右移后的数据集,用于加载并进行类型转换
            data_shr_a = self.load([a >> count for a in data_a])
            # 右移常数位移量
            shri = self.shri(vdata_a, count)
            assert shri == data_shr_a

    def test_arithmetic_subadd_saturated(self):
        # 如果数据类型是 'u32', 's32', 'u64', 或 's64',则跳过测试
        if self.sfx in ("u32", "s32", "u64", "s64"):
            return

        # 创建包含接近整型最大值的数据集
        data_a = self._data(self._int_max() - self.nlanes)
        # 创建包含整型最小值的数据集,以相反顺序
        data_b = self._data(self._int_min(), reverse=True)
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)

        # 计算加法结果并进行饱和运算
        data_adds = self._int_clip([a + b for a, b in zip(data_a, data_b)])
        adds = self.adds(vdata_a, vdata_b)
        assert adds == data_adds

        # 计算减法结果并进行饱和运算
        data_subs = self._int_clip([a - b for a, b in zip(data_a, data_b)])
        subs = self.subs(vdata_a, vdata_b)
        assert subs == data_subs

    def test_math_max_min(self):
        # 创建默认数据集
        data_a = self._data()
        # 创建带有 'nlanes' 元素的数据集
        data_b = self._data(self.nlanes)
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)

        # 计算最大值,并将结果存储在列表中
        data_max = [max(a, b) for a, b in zip(data_a, data_b)]
        simd_max = self.max(vdata_a, vdata_b)
        assert simd_max == data_max

        # 计算最小值,并将结果存储在列表中
        data_min = [min(a, b) for a, b in zip(data_a, data_b)]
        simd_min = self.min(vdata_a, vdata_b)
        assert simd_min == data_min

    @pytest.mark.parametrize("start", [-100, -10000, 0, 100, 10000])
    def test_reduce_max_min(self, start):
        """
        Test intrinsics:
            npyv_reduce_max_##sfx
            npyv_reduce_min_##sfx
        """
        # 加载具有 'start' 初始值的数据集
        vdata_a = self.load(self._data(start))
        # 验证减少操作后的最大值是否与预期一致
        assert self.reduce_max(vdata_a) == max(vdata_a)
        # 验证减少操作后的最小值是否与预期一致
        assert self.reduce_min(vdata_a) == min(vdata_a)
    def test_conversions(self):
        """
        Round to nearest even integer, assume CPU control register is set to rounding.
        Test intrinsics:
            npyv_round_s32_##SFX
        """
        # 获取当前 CPU 的特性信息
        features = self._cpu_features()
        # 如果不支持双精度 SIMD 并且 CPU 特性中包含 NEON 或 ASIMD,则条件成立
        if not self.npyv.simd_f64 and re.match(r".*(NEON|ASIMD)", features):
            # 在 Armv7 上模拟最近偶数舍入成本很高
            # 我们选择将半数向上舍入。例如 0.5 -> 1, -0.5 -> -1
            _round = lambda v: int(v + (0.5 if v >= 0 else -0.5))
        else:
            # 否则使用内置的 round 函数进行舍入
            _round = round
        # 载入数据集
        vdata_a = self.load(self._data())
        # 从数据集中减去 0.5
        vdata_a = self.sub(vdata_a, self.setall(0.5))
        # 对每个元素进行舍入操作,得到舍入后的数据列表
        data_round = [_round(x) for x in vdata_a]
        # 使用特定的 SIMD 函数对数据进行整数舍入
        vround = self.round_s32(vdata_a)
        # 断言舍入后的 SIMD 结果与手动舍入的结果相等
        assert vround == data_round
class _SIMD_FP64(_Test_Utility):
    """
    To only test double precision
    """
    def test_conversions(self):
        """
        Round to nearest even integer, assume CPU control register is set to rounding.
        Test intrinsics:
            npyv_round_s32_##SFX
        """
        # 加载测试数据
        vdata_a = self.load(self._data())
        # 对加载的数据减去0.5
        vdata_a = self.sub(vdata_a, self.setall(0.5))
        # 将数据乘以-1.5
        vdata_b = self.mul(vdata_a, self.setall(-1.5))
        # 将每个向量中的元素四舍五入到最近的偶数,得到一个列表
        data_round = [round(x) for x in list(vdata_a) + list(vdata_b)]
        # 使用 SIMD 指令进行整数舍入操作
        vround = self.round_s32(vdata_a, vdata_b)
        # 断言结果是否相等
        assert vround == data_round

class _SIMD_FP(_Test_Utility):
    """
    To test all float vector types at once
    """
    def test_arithmetic_fused(self):
        # 加载测试数据并复制三份
        vdata_a, vdata_b, vdata_c = [self.load(self._data())]*3
        # 计算 vdata_c 的两倍
        vdata_cx2 = self.add(vdata_c, vdata_c)
        # 计算 a*b + c
        data_fma = self.load([a * b + c for a, b, c in zip(vdata_a, vdata_b, vdata_c)])
        # 使用 SIMD 指令进行融合乘加运算
        fma = self.muladd(vdata_a, vdata_b, vdata_c)
        # 断言结果是否相等
        assert fma == data_fma
        # 计算 a*b - c
        fms = self.mulsub(vdata_a, vdata_b, vdata_c)
        # 计算 data_fma - vdata_cx2
        data_fms = self.sub(data_fma, vdata_cx2)
        # 断言结果是否相等
        assert fms == data_fms
        # 计算 -(a*b) + c
        nfma = self.nmuladd(vdata_a, vdata_b, vdata_c)
        # 计算 vdata_cx2 - data_fma
        data_nfma = self.sub(vdata_cx2, data_fma)
        # 断言结果是否相等
        assert nfma == data_nfma
        # 计算 -(a*b) - c
        nfms = self.nmulsub(vdata_a, vdata_b, vdata_c)
        # 将 data_fma 中的每个元素乘以-1
        data_nfms = self.mul(data_fma, self.setall(-1))
        # 断言结果是否相等
        assert nfms == data_nfms
        # 计算 a*b -+ c,其中奇数索引位置相加,偶数索引位置相减
        fmas = list(self.muladdsub(vdata_a, vdata_b, vdata_c))
        # 断言结果是否相等
        assert fmas[0::2] == list(data_fms)[0::2]
        assert fmas[1::2] == list(data_fma)[1::2]

    def test_abs(self):
        pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
        data = self._data()
        vdata = self.load(self._data())

        # 定义绝对值测试案例
        abs_cases = ((-0, 0), (ninf, pinf), (pinf, pinf), (nan, nan))
        for case, desired in abs_cases:
            # 根据 case 设置全部元素的绝对值
            data_abs = [desired]*self.nlanes
            vabs = self.abs(self.setall(case))
            # 断言结果是否近似相等,允许 NaN
            assert vabs == pytest.approx(data_abs, nan_ok=True)

        # 计算 vdata 中每个元素的相反数的绝对值
        vabs = self.abs(self.mul(vdata, self.setall(-1)))
        # 断言结果是否相等
        assert vabs == data

    def test_sqrt(self):
        pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
        data = self._data()
        vdata = self.load(self._data())

        # 定义平方根测试案例
        sqrt_cases = ((-0.0, -0.0), (0.0, 0.0), (-1.0, nan), (ninf, nan), (pinf, pinf))
        for case, desired in sqrt_cases:
            # 根据 case 设置全部元素的平方根
            data_sqrt = [desired]*self.nlanes
            sqrt  = self.sqrt(self.setall(case))
            # 断言结果是否近似相等,允许 NaN
            assert sqrt == pytest.approx(data_sqrt, nan_ok=True)

        # 计算 vdata 中每个元素的平方根并加载到降低精度
        data_sqrt = self.load([math.sqrt(x) for x in data]) # load to truncate precision
        sqrt = self.sqrt(vdata)
        # 断言结果是否相等
        assert sqrt == data_sqrt
    def test_square(self):
        # 获取正无穷、负无穷和 NaN 值
        pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
        # 载入测试数据
        data = self._data()
        vdata = self.load(self._data())
        # 测试平方函数
        square_cases = ((nan, nan), (pinf, pinf), (ninf, pinf))
        for case, desired in square_cases:
            # 生成期望的平方结果数组
            data_square = [desired]*self.nlanes
            # 计算给定 case 的平方
            square  = self.square(self.setall(case))
            # 断言计算结果与期望值近似相等
            assert square == pytest.approx(data_square, nan_ok=True)

        # 计算数据数组各元素的平方作为期望值
        data_square = [x*x for x in data]
        # 使用 vdata 计算平方
        square = self.square(vdata)
        # 断言计算结果与期望值相等
        assert square == data_square

    @pytest.mark.parametrize("intrin, func", [("ceil", math.ceil),
    ("trunc", math.trunc), ("floor", math.floor), ("rint", round)])
    def test_rounding(self, intrin, func):
        """
        Test intrinsics:
            npyv_rint_##SFX
            npyv_ceil_##SFX
            npyv_trunc_##SFX
            npyv_floor##SFX
        """
        # 获取指定的内在函数名称和函数对象
        intrin_name = intrin
        intrin = getattr(self, intrin)
        # 获取正无穷、负无穷和 NaN 值
        pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
        
        # 特殊情况
        round_cases = ((nan, nan), (pinf, pinf), (ninf, ninf))
        for case, desired in round_cases:
            # 生成期望的舍入结果数组
            data_round = [desired]*self.nlanes
            # 计算给定 case 的舍入值
            _round = intrin(self.setall(case))
            # 断言计算结果与期望值近似相等
            assert _round == pytest.approx(data_round, nan_ok=True)

        # 测试多种数值和权重的舍入行为
        for x in range(0, 2**20, 256**2):
            for w in (-1.05, -1.10, -1.15, 1.05, 1.10, 1.15):
                # 生成测试数据
                data = self.load([(x+a)*w for a in range(self.nlanes)])
                # 计算数据数组各元素的舍入值
                data_round = [func(x) for x in data]
                # 使用内在函数计算舍入
                _round = intrin(data)
                # 断言计算结果与期望值相等
                assert _round == data_round

        # 测试大数值
        for i in (
            1.1529215045988576e+18, 4.6116860183954304e+18,
            5.902958103546122e+20, 2.3611832414184488e+21
        ):
            x = self.setall(i)
            y = intrin(x)
            # 计算大数值的舍入结果
            data_round = [func(n) for n in x]
            # 断言计算结果与期望值相等
            assert y == data_round

        # 测试带符号零
        if intrin_name == "floor":
            data_szero = (-0.0,)
        else:
            data_szero = (-0.0, -0.25, -0.30, -0.45, -0.5)

        for w in data_szero:
            # 计算带符号零的舍入值并转为无符号数
            _round = self._to_unsigned(intrin(self.setall(w)))
            data_round = self._to_unsigned(self.setall(-0.0))
            # 断言计算结果与期望值相等
            assert _round == data_round

    @pytest.mark.parametrize("intrin", [
        "max", "maxp", "maxn", "min", "minp", "minn"
    ])
    def test_max_min(self, intrin):
        """
        Test intrinsics:
            npyv_max_##sfx
            npyv_maxp_##sfx
            npyv_maxn_##sfx
            npyv_min_##sfx
            npyv_minp_##sfx
            npyv_minn_##sfx
            npyv_reduce_max_##sfx
            npyv_reduce_maxp_##sfx
            npyv_reduce_maxn_##sfx
            npyv_reduce_min_##sfx
            npyv_reduce_minp_##sfx
            npyv_reduce_minn_##sfx
        """
        # 定义正无穷、负无穷和NaN
        pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
        
        # 根据当前指令类型确定是否有NaN的情况
        chk_nan = {"xp": 1, "np": 1, "nn": 2, "xn": 2}.get(intrin[-2:], 0)
        
        # 根据指令动态生成函数对象
        func = eval(intrin[:3])
        
        # 获取对应的 reduce 函数
        reduce_intrin = getattr(self, "reduce_" + intrin)
        
        # 获取指令对应的 intrin 函数
        intrin = getattr(self, intrin)
        
        # 计算半数通道数
        hf_nlanes = self.nlanes//2

        # 定义测试用例
        cases = (
            ([0.0, -0.0], [-0.0, 0.0]),
            ([10, -10],  [10, -10]),
            ([pinf, 10], [10, ninf]),
            ([10, pinf], [ninf, 10]),
            ([10, -10], [10, -10]),
            ([-10, 10], [-10, 10])
        )
        
        # 遍历测试用例
        for op1, op2 in cases:
            # 加载数据到向量 vdata_a 和 vdata_b
            vdata_a = self.load(op1*hf_nlanes)
            vdata_b = self.load(op2*hf_nlanes)
            
            # 计算标量数据并进行 SIMD 计算
            data = func(vdata_a, vdata_b)
            simd = intrin(vdata_a, vdata_b)
            
            # 断言 SIMD 结果与标量计算结果一致
            assert simd == data
            
            # 计算单个向量的结果并进行 reduce 操作
            data = func(vdata_a)
            simd = reduce_intrin(vdata_a)
            
            # 断言 SIMD reduce 结果与标量计算结果一致
            assert simd == data

        # 处理 NaN 的情况
        if not chk_nan:
            return
        
        # 定义处理 NaN 的匿名函数
        if chk_nan == 1:
            test_nan = lambda a, b: (
                b if math.isnan(a) else a if math.isnan(b) else b
            )
        else:
            test_nan = lambda a, b: (
                nan if math.isnan(a) or math.isnan(b) else b
            )
        
        # 针对 NaN 的测试用例
        cases = (
            (nan, 10),
            (10, nan),
            (nan, pinf),
            (pinf, nan),
            (nan, nan)
        )
        
        # 遍历 NaN 的测试用例
        for op1, op2 in cases:
            # 加载数据到向量 vdata_ab
            vdata_ab = self.load([op1, op2]*hf_nlanes)
            
            # 计算期望的数据
            data = test_nan(op1, op2)
            
            # 执行 reduce 操作并断言结果与预期一致
            simd = reduce_intrin(vdata_ab)
            assert simd == pytest.approx(data, nan_ok=True)
            
            # 设置所有向量数据为 op1 和 op2,计算期望结果并进行 SIMD 计算
            vdata_a = self.setall(op1)
            vdata_b = self.setall(op2)
            data = [data] * self.nlanes
            simd = intrin(vdata_a, vdata_b)
            
            # 断言 SIMD 计算结果与期望一致
            assert simd == pytest.approx(data, nan_ok=True)

    def test_reciprocal(self):
        # 获取正无穷、负无穷和NaN
        pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
        
        # 获取数据
        data = self._data()
        
        # 加载数据到向量 vdata
        vdata = self.load(self._data())

        # 计算 reciprocal 的测试用例
        recip_cases = ((nan, nan), (pinf, 0.0), (ninf, -0.0), (0.0, pinf), (-0.0, ninf))
        
        # 遍历 reciprocal 的测试用例
        for case, desired in recip_cases:
            # 计算期望的数据
            data_recip = [desired]*self.nlanes
            
            # 计算 reciprocal 并断言结果与期望一致
            recip = self.recip(self.setall(case))
            assert recip == pytest.approx(data_recip, nan_ok=True)

        # 计算所有数据的 reciprocal
        data_recip = self.load([1/x for x in data]) # load to truncate precision
        
        # 计算 reciprocal 并断言结果与期望一致
        recip = self.recip(vdata)
        assert recip == data_recip
    def test_special_cases(self):
        """
        Compare Not NaN. Test intrinsics:
            npyv_notnan_##SFX
        """
        # 调用 self.notnan 方法,将所有元素设置为 NaN,然后进行比较,期望结果为全零数组
        nnan = self.notnan(self.setall(self._nan()))
        # 断言 nnan 应该等于长度为 self.nlanes 的全零列表
        assert nnan == [0]*self.nlanes

    @pytest.mark.parametrize("intrin_name", [
        "rint", "trunc", "ceil", "floor"
    ])
    def test_unary_invalid_fpexception(self, intrin_name):
        # 获取当前测试的内置函数 intrin
        intrin = getattr(self, intrin_name)
        # 对于特定的无效浮点数值进行测试,包括 NaN、正无穷、负无穷
        for d in [float("nan"), float("inf"), -float("inf")]:
            v = self.setall(d)
            # 清除浮点数状态
            clear_floatstatus()
            # 调用 intrin 处理向量 v
            intrin(v)
            # 断言检查浮点数状态的 invalid 位是否为 False
            assert check_floatstatus(invalid=True) == False

    @pytest.mark.parametrize('py_comp,np_comp', [
        (operator.lt, "cmplt"),
        (operator.le, "cmple"),
        (operator.gt, "cmpgt"),
        (operator.ge, "cmpge"),
        (operator.eq, "cmpeq"),
        (operator.ne, "cmpneq")
    ])
    def test_comparison_with_nan(self, py_comp, np_comp):
        # 获取正、负无穷大和 NaN 的特定值
        pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
        # 获取所有真值的掩码
        mask_true = self._true_mask()

        def to_bool(vector):
            # 将向量转换为布尔值列表
            return [lane == mask_true for lane in vector]

        # 获取对应的 SIMD 操作函数
        intrin = getattr(self, np_comp)
        # 比较测试案例,包括 (0, nan), (nan, 0), (nan, nan), (pinf, nan), (ninf, nan), (-0.0, +0.0)
        cmp_cases = ((0, nan), (nan, 0), (nan, nan), (pinf, nan),
                     (ninf, nan), (-0.0, +0.0))
        for case_operand1, case_operand2 in cmp_cases:
            # 创建数据列表,长度为 self.nlanes,并设置为相应的操作数值
            data_a = [case_operand1]*self.nlanes
            data_b = [case_operand2]*self.nlanes
            # 将数据转换为 SIMD 向量
            vdata_a = self.setall(case_operand1)
            vdata_b = self.setall(case_operand2)
            # 获取 SIMD 操作后的布尔结果向量
            vcmp = to_bool(intrin(vdata_a, vdata_b))
            # 获取 Python 操作后的布尔结果列表
            data_cmp = [py_comp(a, b) for a, b in zip(data_a, data_b)]
            # 断言 SIMD 操作后的结果与 Python 操作后的结果相同
            assert vcmp == data_cmp

    @pytest.mark.parametrize("intrin", ["any", "all"])
    @pytest.mark.parametrize("data", (
        [float("nan"), 0],
        [0, float("nan")],
        [float("nan"), 1],
        [1, float("nan")],
        [float("nan"), float("nan")],
        [0.0, -0.0],
        [-0.0, 0.0],
        [1.0, -0.0]
    ))
    def test_operators_crosstest(self, intrin, data):
        """
        Test intrinsics:
            npyv_any_##SFX
            npyv_all_##SFX
        """
        # 加载测试数据并创建函数对象
        data_a = self.load(data * self.nlanes)
        func = eval(intrin)
        # 获取对应的 SIMD 操作函数
        intrin = getattr(self, intrin)
        # 计算 Python 函数的预期结果
        desired = func(data_a)
        # 执行 SIMD 操作
        simd = intrin(data_a)
        # 断言 SIMD 操作后的结果不为空(即非 False),且与 Python 函数的结果相同
        assert not not simd == desired
class _SIMD_ALL(_Test_Utility):
    """
    To test all vector types at once
    """
    # 测试内存加载功能
    def test_memory_load(self):
        # 获取测试数据
        data = self._data()
        # 不对齐加载
        load_data = self.load(data)
        assert load_data == data
        # 对齐加载
        loada_data = self.loada(data)
        assert loada_data == data
        # 流加载
        loads_data = self.loads(data)
        assert loads_data == data
        # 加载低位部分
        loadl = self.loadl(data)
        loadl_half = list(loadl)[:self.nlanes//2]
        data_half = data[:self.nlanes//2]
        assert loadl_half == data_half
        assert loadl != data # 检测溢出

    # 测试内存存储功能
    def test_memory_store(self):
        # 获取测试数据
        data = self._data()
        vdata = self.load(data)
        # 不对齐存储
        store = [0] * self.nlanes
        self.store(store, vdata)
        assert store == data
        # 对齐存储
        store_a = [0] * self.nlanes
        self.storea(store_a, vdata)
        assert store_a == data
        # 流存储
        store_s = [0] * self.nlanes
        self.stores(store_s, vdata)
        assert store_s == data
        # 存储低位部分
        store_l = [0] * self.nlanes
        self.storel(store_l, vdata)
        assert store_l[:self.nlanes//2] == data[:self.nlanes//2]
        assert store_l != vdata # 检测溢出
        # 存储高位部分
        store_h = [0] * self.nlanes
        self.storeh(store_h, vdata)
        assert store_h[:self.nlanes//2] == data[self.nlanes//2:]
        assert store_h != vdata  # 检测溢出

    @pytest.mark.parametrize("intrin, elsizes, scale, fill", [
        ("self.load_tillz, self.load_till", (32, 64), 1, [0xffff]),
        ("self.load2_tillz, self.load2_till", (32, 64), 2, [0xffff, 0x7fff]),
    ])
    # 测试部分加载功能
    def test_memory_partial_load(self, intrin, elsizes, scale, fill):
        if self._scalar_size() not in elsizes:
            return
        npyv_load_tillz, npyv_load_till = eval(intrin)
        data = self._data()
        lanes = list(range(1, self.nlanes + 1))
        lanes += [self.nlanes**2, self.nlanes**4] # 测试超出范围
        for n in lanes:
            load_till = npyv_load_till(data, n, *fill)
            load_tillz = npyv_load_tillz(data, n)
            n *= scale
            data_till = data[:n] + fill * ((self.nlanes-n) // scale)
            assert load_till == data_till
            data_tillz = data[:n] + [0] * (self.nlanes-n)
            assert load_tillz == data_tillz

    @pytest.mark.parametrize("intrin, elsizes, scale", [
        ("self.store_till", (32, 64), 1),
        ("self.store2_till", (32, 64), 2),
    ])
    # 测试部分存储功能,检查标量大小是否在指定的元素大小列表中
    def test_memory_partial_store(self, intrin, elsizes, scale):
        # 如果标量大小不在elsizes列表中,则退出测试
        if self._scalar_size() not in elsizes:
            return
        # 将intrin字符串转换为函数对象
        npyv_store_till = eval(intrin)
        # 获取数据
        data = self._data()
        # 获取反转后的数据
        data_rev = self._data(reverse=True)
        # 载入数据
        vdata = self.load(data)
        # 生成一个包含self.nlanes个元素的列表
        lanes = list(range(1, self.nlanes + 1))
        # 添加额外的两个元素到lanes列表中
        lanes += [self.nlanes**2, self.nlanes**4]
        # 遍历lanes列表
        for n in lanes:
            # 复制反转后的数据到data_till
            data_till = data_rev.copy()
            # 将data中的前n*scale个元素复制到data_till中的对应位置
            data_till[:n*scale] = data[:n*scale]
            # 获取反转后的数据
            store_till = self._data(reverse=True)
            # 调用npyv_store_till函数
            npyv_store_till(store_till, n, vdata)
            # 断言store_till与data_till相等
            assert store_till == data_till

    # 标记pytest参数化测试函数,用于非连续加载内存的测试
    @pytest.mark.parametrize("intrin, elsizes, scale", [
        ("self.loadn", (32, 64), 1),
        ("self.loadn2", (32, 64), 2),
    ])
    # 测试非连续加载内存功能
    def test_memory_noncont_load(self, intrin, elsizes, scale):
        # 如果标量大小不在elsizes列表中,则退出测试
        if self._scalar_size() not in elsizes:
            return
        # 将intrin字符串转换为函数对象
        npyv_loadn = eval(intrin)
        # 遍历stride从-64到63的范围
        for stride in range(-64, 64):
            # 如果stride小于0
            if stride < 0:
                # 获取反转后的数据,使用负的stride参数
                data = self._data(stride, -stride*self.nlanes)
                # 创建data_stride列表,将data中的部分元素交错连接起来
                data_stride = list(itertools.chain(
                    *zip(*[data[-i::stride] for i in range(scale, 0, -1)])
                ))
            # 如果stride等于0
            elif stride == 0:
                # 获取数据
                data = self._data()
                # 将数据的前scale个元素复制到data_stride中,重复self.nlanes//scale次
                data_stride = data[0:scale] * (self.nlanes//scale)
            # 如果stride大于0
            else:
                # 获取stride*self.nlanes个元素的数据
                data = self._data(count=stride*self.nlanes)
                # 创建data_stride列表,将data中的部分元素按照stride分组并交错连接起来
                data_stride = list(itertools.chain(
                    *zip(*[data[i::stride] for i in range(scale)]))
                )
            # 将data_stride转换为无符号整数类型
            data_stride = self.load(data_stride)  # cast unsigned
            # 使用npyv_loadn函数加载数据
            loadn = npyv_loadn(data, stride)
            # 断言loadn与data_stride相等
            assert loadn == data_stride

    # 标记pytest参数化测试函数,用于加载至特定边界值的内存测试
    @pytest.mark.parametrize("intrin, elsizes, scale, fill", [
        ("self.loadn_tillz, self.loadn_till", (32, 64), 1, [0xffff]),
        ("self.loadn2_tillz, self.loadn2_till", (32, 64), 2, [0xffff, 0x7fff]),
    ])
    # 定义一个测试函数,用于测试内存非连续部分加载的情况
    def test_memory_noncont_partial_load(self, intrin, elsizes, scale):
        # 如果标量大小不在给定的elsizes列表中,则直接返回
        if self._scalar_size() not in elsizes:
            return
        
        # 根据字符串intrin获取对应的函数或方法,并赋值给npyv_loadn_tillz和npyv_loadn_till
        npyv_loadn_tillz, npyv_loadn_till = eval(intrin)
        
        # 创建一个包含1到self.nlanes + 1的列表,并添加额外的两个元素
        lanes = list(range(1, self.nlanes + 1))
        lanes += [self.nlanes**2, self.nlanes**4]
        
        # 遍历从-64到63的步长值
        for stride in range(-64, 64):
            if stride < 0:
                # 如果步长为负数,则调用self._data方法获取数据
                data = self._data(stride, -stride*self.nlanes)
                # 通过列表推导式和zip函数,创建部分加载后的数据列表data_stride
                data_stride = list(itertools.chain(
                    *zip(*[data[-i::stride] for i in range(scale, 0, -1)])
                ))
            elif stride == 0:
                # 如果步长为0,则直接调用self._data方法获取数据,并复制scale个元素
                data = self._data()
                data_stride = data[0:scale] * (self.nlanes//scale)
            else:
                # 否则,根据步长调用self._data方法获取数据
                data = self._data(count=stride*self.nlanes)
                # 使用列表推导式和zip函数,创建部分加载后的数据列表data_stride
                data_stride = list(itertools.chain(
                    *zip(*[data[i::stride] for i in range(scale)])
                ))
            
            # 将data_stride转换为无符号整数形式的列表
            data_stride = list(self.load(data_stride))
            
            # 遍历lanes列表中的元素
            for n in lanes:
                # 计算nscale值
                nscale = n * scale
                # 计算llanes值
                llanes = self.nlanes - nscale
                
                # 构造部分加载后的数据列表data_stride_till
                data_stride_till = (
                    data_stride[:nscale] + fill * (llanes//scale)
                )
                
                # 调用npyv_loadn_till函数处理data数据,验证结果与data_stride_till是否相等
                loadn_till = npyv_loadn_till(data, stride, n, *fill)
                assert loadn_till == data_stride_till
                
                # 构造部分加载且填充为0的数据列表data_stride_tillz
                data_stride_tillz = data_stride[:nscale] + [0] * llanes
                
                # 调用npyv_loadn_tillz函数处理data数据,验证结果与data_stride_tillz是否相等
                loadn_tillz = npyv_loadn_tillz(data, stride, n)
                assert loadn_tillz == data_stride_tillz
    # 定义测试函数 test_memory_noncont_store,接受参数 intrin, elsizes, scale
    def test_memory_noncont_store(self, intrin, elsizes, scale):
        # 如果当前对象的标量大小不在 elsizes 中,则直接返回
        if self._scalar_size() not in elsizes:
            return
        # 根据字符串 intrin 动态评估得到 npyv_storen 函数
        npyv_storen = eval(intrin)
        # 获得当前对象的数据
        data = self._data()
        # 载入数据到向量数据 vdata
        vdata = self.load(data)
        # 计算每个向量的半长度
        hlanes = self.nlanes // scale
        
        # 循环不同的步长
        for stride in range(1, 64):
            # 初始化数据存储结构为一组特定值
            data_storen = [0xff] * stride * self.nlanes
            # 遍历数据索引范围以填充 data_storen
            for s in range(0, hlanes*stride, stride):
                i = (s//stride)*scale
                data_storen[s:s+scale] = data[i:i+scale]
            # 初始化 storen 为特定值组成的列表,后续追加额外值
            storen = [0xff] * stride * self.nlanes
            storen += [0x7f]*64
            # 使用 npyv_storen 函数存储数据到 storen 中
            npyv_storen(storen, stride, vdata)
            # 断言前部分数据与 data_storen 相等
            assert storen[:-64] == data_storen
            # 断言后 64 个元素为 [0x7f]
            assert storen[-64:] == [0x7f]*64  # detect overflow

        # 对于负的步长值
        for stride in range(-64, 0):
            # 初始化数据存储结构为一组特定值
            data_storen = [0xff] * -stride * self.nlanes
            # 遍历数据索引范围以填充 data_storen
            for s in range(0, hlanes*stride, stride):
                i = (s//stride)*scale
                data_storen[s-scale:s or None] = data[i:i+scale]
            # 初始化 storen 为 [0x7f] 组成的列表,后续追加特定值
            storen = [0x7f]*64
            storen += [0xff] * -stride * self.nlanes
            # 使用 npyv_storen 函数存储数据到 storen 中
            npyv_storen(storen, stride, vdata)
            # 断言后部分数据与 data_storen 相等
            assert storen[64:] == data_storen
            # 断言前 64 个元素为 [0x7f]
            assert storen[:64] == [0x7f]*64  # detect overflow
        
        # 对于步长为 0 的情况
        # 初始化数据存储结构为一组 [0x7f]
        data_storen = [0x7f] * self.nlanes
        storen = data_storen.copy()
        # 将数据的末尾部分复制到 data_storen 的前 scale 个位置
        data_storen[0:scale] = data[-scale:]
        # 使用 npyv_storen 函数存储数据到 storen 中
        npyv_storen(storen, 0, vdata)
        # 断言 storen 与 data_storen 相等
        assert storen == data_storen

    # 使用 pytest.mark.parametrize 运行参数化测试,参数为 intrin, elsizes, scale
    @pytest.mark.parametrize("intrin, elsizes, scale", [
        ("self.storen_till", (32, 64), 1),
        ("self.storen2_till", (32, 64), 2),
    ])
    def test_memory_noncont_partial_store(self, intrin, elsizes, scale):
        # 检查当前标量大小是否在给定的元素大小列表中,如果不在则直接返回
        if self._scalar_size() not in elsizes:
            return

        # 根据传入的指令名称,获取对应的函数对象
        npyv_storen_till = eval(intrin)

        # 获取当前对象的数据
        data = self._data()

        # 加载数据到向量数据对象中
        vdata = self.load(data)

        # 构建一个包含指定范围的 lane 数字的列表
        lanes = list(range(1, self.nlanes + 1))
        lanes += [self.nlanes**2, self.nlanes**4]

        # 计算缩放后的 lane 数量
        hlanes = self.nlanes // scale

        # 遍历不同的步长
        for stride in range(1, 64):
            for n in lanes:
                # 初始化数据直到指定位置
                data_till = [0xff] * stride * self.nlanes

                # 根据给定的 n 和缩放因子构建 tdata
                tdata = data[:n*scale] + [0xff] * (self.nlanes-n*scale)

                # 填充数据直到指定位置
                for s in range(0, hlanes*stride, stride)[:n]:
                    i = (s//stride)*scale
                    data_till[s:s+scale] = tdata[i:i+scale]

                # 初始化存储数据直到指定位置
                storen_till = [0xff] * stride * self.nlanes
                storen_till += [0x7f]*64

                # 调用指定的存储函数
                npyv_storen_till(storen_till, stride, n, vdata)

                # 断言存储数据直到指定位置与预期的数据相同
                assert storen_till[:-64] == data_till

                # 检测溢出
                assert storen_till[-64:] == [0x7f]*64  # detect overflow

        # 负步长情况下的遍历
        for stride in range(-64, 0):
            for n in lanes:
                # 初始化数据直到指定位置
                data_till = [0xff] * -stride * self.nlanes

                # 根据给定的 n 和缩放因子构建 tdata
                tdata = data[:n*scale] + [0xff] * (self.nlanes-n*scale)

                # 填充数据直到指定位置
                for s in range(0, hlanes*stride, stride)[:n]:
                    i = (s//stride)*scale
                    data_till[s-scale:s or None] = tdata[i:i+scale]

                # 初始化存储数据直到指定位置
                storen_till = [0x7f]*64
                storen_till += [0xff] * -stride * self.nlanes

                # 调用指定的存储函数
                npyv_storen_till(storen_till, stride, n, vdata)

                # 断言存储数据直到指定位置与预期的数据相同
                assert storen_till[64:] == data_till

                # 检测溢出
                assert storen_till[:64] == [0x7f]*64  # detect overflow

        # 步长为 0 的情况
        for n in lanes:
            # 初始化数据直到指定位置
            data_till = [0x7f] * self.nlanes

            # 复制数据直到指定位置
            storen_till = data_till.copy()

            # 从数据的末尾复制指定长度的数据到存储数据中
            data_till[0:scale] = data[:n*scale][-scale:]

            # 调用指定的存储函数
            npyv_storen_till(storen_till, 0, n, vdata)

            # 断言存储数据与预期的数据相同
            assert storen_till == data_till

    @pytest.mark.parametrize("intrin, table_size, elsize", [
        # 参数化测试不同的内联函数和表格大小
        ("self.lut32", 32, 32),
        ("self.lut16", 16, 64)
    ])
    def test_lut(self, intrin, table_size, elsize):
        """
        Test lookup table intrinsics:
            npyv_lut32_##sfx
            npyv_lut16_##sfx
        """
        # 检查元素大小是否与当前对象的标量大小相同,如果不同则直接返回
        if elsize != self._scalar_size():
            return

        # 根据传入的指令名称,获取对应的函数对象
        intrin = eval(intrin)

        # 获取设置所有元素的索引函数对象
        idx_itrin = getattr(self.npyv, f"setall_u{elsize}")

        # 创建一个指定范围的表格
        table = range(0, table_size)

        # 遍历表格中的每个索引
        for i in table:
            # 设置所有元素为当前索引值的向量
            broadi = self.setall(i)

            # 使用索引设置函数获取索引值
            idx = idx_itrin(i)

            # 调用内联函数处理表格和索引,返回结果
            lut = intrin(table, idx)

            # 断言内联函数返回的结果与预期的广播向量相同
            assert lut == broadi
    # 定义一个测试方法,用于测试各种杂项功能
    def test_misc(self):
        # 调用 self.zero() 方法,返回全零的列表,长度为 self.nlanes
        broadcast_zero = self.zero()
        # 断言 broadcast_zero 应该等于 [0] * self.nlanes
        assert broadcast_zero == [0] * self.nlanes
        
        # 遍历范围从 1 到 9
        for i in range(1, 10):
            # 调用 self.setall(i) 方法,返回所有元素为 i 的列表
            broadcasti = self.setall(i)
            # 断言 broadcasti 应该等于 [i] * self.nlanes
            assert broadcasti == [i] * self.nlanes

        # 分别获取两种数据:正常顺序和反向顺序的 self._data()
        data_a, data_b = self._data(), self._data(reverse=True)
        # 使用 self.load() 方法加载两种数据,得到 vdata_a 和 vdata_b
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)

        # 测试 self.set() 方法,传入 data_a,期望返回相同的数据
        vset = self.set(*data_a)
        assert vset == data_a
        # 测试 self.setf() 方法,传入 10 和 data_a,期望返回 data_a
        vsetf = self.setf(10, *data_a)
        assert vsetf == data_a

        # 测试 _simd 的类型向量的稳定性,
        # reinterpret* 内在本身通过编译器测试
        sfxes = ["u8", "s8", "u16", "s16", "u32", "s32", "u64", "s64"]
        # 如果支持 simd_f64,添加 "f64" 到 sfxes
        if self.npyv.simd_f64:
            sfxes.append("f64")
        # 如果支持 simd_f32,添加 "f32" 到 sfxes
        if self.npyv.simd_f32:
            sfxes.append("f32")
        # 遍历所有的后缀 sfxes
        for sfx in sfxes:
            # 构造 reinterpret_sfx 方法的名字,调用它并获取返回值的名称
            vec_name = getattr(self, "reinterpret_" + sfx)(vdata_a).__name__
            # 断言 vec_name 应该等于 "npyv_" + sfx
            assert vec_name == "npyv_" + sfx

        # select & mask 操作
        # 使用 self.cmpeq() 比较 self.zero() 和 self.zero(),得到掩码
        select_a = self.select(self.cmpeq(self.zero(), self.zero()), vdata_a, vdata_b)
        # 断言 select_a 应该等于 data_a
        assert select_a == data_a
        # 使用 self.cmpneq() 比较 self.zero() 和 self.zero(),得到掩码
        select_b = self.select(self.cmpneq(self.zero(), self.zero()), vdata_a, vdata_b)
        # 断言 select_b 应该等于 data_b
        assert select_b == data_b

        # 测试提取元素
        # 断言 self.extract0(vdata_b) 应该等于 vdata_b 的第一个元素
        assert self.extract0(vdata_b) == vdata_b[0]

        # cleanup 操作仅在 AVX 中用于清零寄存器,避免 AVX-SSE 过渡损失
        # 在这里没有需要测试的内容
        self.npyv.cleanup()
    def test_reorder(self):
        # 准备测试数据,一个正序,一个逆序
        data_a, data_b  = self._data(), self._data(reverse=True)
        # 载入数据到向量数据
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)
        
        # 取前半部分数据
        data_a_lo = data_a[:self.nlanes//2]
        data_b_lo = data_b[:self.nlanes//2]
        
        # 取后半部分数据
        data_a_hi = data_a[self.nlanes//2:]
        data_b_hi = data_b[self.nlanes//2:]
        
        # 合并两个低部分数据
        combinel = self.combinel(vdata_a, vdata_b)
        assert combinel == data_a_lo + data_b_lo
        
        # 合并两个高部分数据
        combineh = self.combineh(vdata_a, vdata_b)
        assert combineh == data_a_hi + data_b_hi
        
        # 合并两倍
        combine = self.combine(vdata_a, vdata_b)
        assert combine == (data_a_lo + data_b_lo, data_a_hi + data_b_hi)

        # zip(interleave)
        # 按交错顺序载入数据
        data_zipl = self.load([
            v for p in zip(data_a_lo, data_b_lo) for v in p
        ])
        data_ziph = self.load([
            v for p in zip(data_a_hi, data_b_hi) for v in p
        ])
        vzip = self.zip(vdata_a, vdata_b)
        assert vzip == (data_zipl, data_ziph)
        vzip = [0]*self.nlanes*2
        self._x2("store")(vzip, (vdata_a, vdata_b))
        assert vzip == list(data_zipl) + list(data_ziph)

        # unzip(deinterleave)
        # 按反交错顺序解压数据
        unzip = self.unzip(data_zipl, data_ziph)
        assert unzip == (data_a, data_b)
        unzip = self._x2("load")(list(data_zipl) + list(data_ziph))
        assert unzip == (data_a, data_b)

    def test_reorder_rev64(self):
        # 反转每个64位元素的顺序
        ssize = self._scalar_size()
        if ssize == 64:
            return
        data_rev64 = [
            y for x in range(0, self.nlanes, 64//ssize)
              for y in reversed(range(x, x + 64//ssize))
        ]
        rev64 = self.rev64(self.load(range(self.nlanes)))
        assert rev64 == data_rev64

    def test_reorder_permi128(self):
        """
        Test permuting elements for each 128-bit lane.
        npyv_permi128_##sfx
        """
        ssize = self._scalar_size()
        if ssize < 32:
            return
        data = self.load(self._data())
        permn = 128//ssize
        permd = permn-1
        nlane128 = self.nlanes//permn
        shfl = [0, 1] if ssize == 64 else [0, 2, 4, 6]
        for i in range(permn):
            # 计算排列索引
            indices = [(i >> shf) & permd for shf in shfl]
            vperm = self.permi128(data, *indices)
            # 验证排列后的数据是否正确
            data_vperm = [
                data[j + (e & -permn)]
                for e, j in enumerate(indices*nlane128)
            ]
            assert vperm == data_vperm

    @pytest.mark.parametrize('func, intrin', [
        (operator.lt, "cmplt"),
        (operator.le, "cmple"),
        (operator.gt, "cmpgt"),
        (operator.ge, "cmpge"),
        (operator.eq, "cmpeq")
    ])
    # 对比运算测试函数,接受函数 `func` 和字符串 `intrin` 作为参数
    def test_operators_comparison(self, func, intrin):
        # 如果是浮点数类型,则使用默认数据
        if self._is_fp():
            data_a = self._data()
        else:
            # 否则,使用 `_int_max() - self.nlanes` 为起点的数据
            data_a = self._data(self._int_max() - self.nlanes)
        # 使用 `_int_min()` 为起点,反向的数据
        data_b = self._data(self._int_min(), reverse=True)
        # 载入 `data_a` 和 `data_b` 数据
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)
        # 从当前对象中获取 `intrin` 字符串对应的方法或属性
        intrin = getattr(self, intrin)

        # 获取真值掩码
        mask_true = self._true_mask()
        
        # 定义将向量转换为布尔值的函数
        def to_bool(vector):
            return [lane == mask_true for lane in vector]

        # 对 `data_a` 和 `data_b` 进行函数 `func` 的比较
        data_cmp = [func(a, b) for a, b in zip(data_a, data_b)]
        # 使用 `intrin` 方法对 `vdata_a` 和 `vdata_b` 进行操作,然后将结果转换为布尔值
        cmp = to_bool(intrin(vdata_a, vdata_b))
        # 断言 `cmp` 的结果与 `data_cmp` 一致
        assert cmp == data_cmp

    # 逻辑运算测试函数
    def test_operators_logical(self):
        # 如果是浮点数类型,则使用默认数据
        if self._is_fp():
            data_a = self._data()
        else:
            # 否则,使用 `_int_max() - self.nlanes` 为起点的数据
            data_a = self._data(self._int_max() - self.nlanes)
        # 使用 `_int_min()` 为起点,反向的数据
        data_b = self._data(self._int_min(), reverse=True)
        # 载入 `data_a` 和 `data_b` 数据
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)

        # 如果是浮点数类型,则将 `vdata_a` 和 `vdata_b` 转换为无符号整数
        if self._is_fp():
            data_cast_a = self._to_unsigned(vdata_a)
            data_cast_b = self._to_unsigned(vdata_b)
            cast, cast_data = self._to_unsigned, self._to_unsigned
        else:
            # 否则,直接使用 `data_a` 和 `data_b`
            data_cast_a, data_cast_b = data_a, data_b
            cast, cast_data = lambda a: a, self.load

        # 对 `data_cast_a` 和 `data_cast_b` 进行按位异或操作,并转换为相应类型
        data_xor = cast_data([a ^ b for a, b in zip(data_cast_a, data_cast_b)])
        vxor = cast(self.xor(vdata_a, vdata_b))
        # 断言 `vxor` 的结果与 `data_xor` 一致
        assert vxor == data_xor

        # 对 `data_cast_a` 和 `data_cast_b` 进行按位或操作,并转换为相应类型
        data_or  = cast_data([a | b for a, b in zip(data_cast_a, data_cast_b)])
        vor  = cast(getattr(self, "or")(vdata_a, vdata_b))
        # 断言 `vor` 的结果与 `data_or` 一致
        assert vor == data_or

        # 对 `data_cast_a` 和 `data_cast_b` 进行按位与操作,并转换为相应类型
        data_and = cast_data([a & b for a, b in zip(data_cast_a, data_cast_b)])
        vand = cast(getattr(self, "and")(vdata_a, vdata_b))
        # 断言 `vand` 的结果与 `data_and` 一致
        assert vand == data_and

        # 对 `data_cast_a` 进行按位取反操作,并转换为相应类型
        data_not = cast_data([~a for a in data_cast_a])
        vnot = cast(getattr(self, "not")(vdata_a))
        # 断言 `vnot` 的结果与 `data_not` 一致
        assert vnot == data_not

        # 如果 `self.sfx` 不在 ("u8") 中,则返回
        if self.sfx not in ("u8"):
            return
        # 对 `data_cast_a` 和 `data_cast_b` 进行按位与非操作
        data_andc = [a & ~b for a, b in zip(data_cast_a, data_cast_b)]
        vandc = cast(getattr(self, "andc")(vdata_a, vdata_b))
        # 断言 `vandc` 的结果与 `data_andc` 一致
        assert vandc == data_andc

    # 交叉测试函数,使用参数化测试
    @pytest.mark.parametrize("intrin", ["any", "all"])
    @pytest.mark.parametrize("data", (
        [1, 2, 3, 4],
        [-1, -2, -3, -4],
        [0, 1, 2, 3, 4],
        [0x7f, 0x7fff, 0x7fffffff, 0x7fffffffffffffff],
        [0, -1, -2, -3, 4],
        [0],
        [1],
        [-1]
    ))
    def test_operators_crosstest(self, intrin, data):
        """
        Test intrinsics:
            npyv_any_##SFX
            npyv_all_##SFX
        """
        # 将 `data` 加载为长度为 `self.nlanes` 的数据
        data_a = self.load(data * self.nlanes)
        # 使用 `intrin` 字符串对应的方法或属性
        func = eval(intrin)
        intrin = getattr(self, intrin)
        # 获取期望结果
        desired = func(data_a)
        # 使用 `intrin` 方法对 `data_a` 进行操作,获取 SIMD 结果
        simd = intrin(data_a)
        # 断言 SIMD 结果不为空,并与期望结果一致
        assert not not simd == desired
    def test_conversion_boolean(self):
        # 根据当前后缀生成布尔转换函数
        bsfx = "b" + self.sfx[1:]
        to_boolean = getattr(self.npyv, "cvt_%s_%s" % (bsfx, self.sfx))
        from_boolean = getattr(self.npyv, "cvt_%s_%s" % (self.sfx, bsfx))

        # 生成假值和真值的布尔向量
        false_vb = to_boolean(self.setall(0))
        true_vb  = self.cmpeq(self.setall(0), self.setall(0))
        # 断言假值和真值不相等
        assert false_vb != true_vb

        # 从布尔向量还原为原始类型的值
        false_vsfx = from_boolean(false_vb)
        true_vsfx = from_boolean(true_vb)
        # 断言还原后的值不相等
        assert false_vsfx != true_vsfx

    def test_conversion_expand(self):
        """
        Test expand intrinsics:
            npyv_expand_u16_u8
            npyv_expand_u32_u16
        """
        # 如果后缀不是'u8'或'u16',则直接返回
        if self.sfx not in ("u8", "u16"):
            return
        # 根据当前后缀确定扩展后的类型
        totype = self.sfx[0]+str(int(self.sfx[1:])*2)
        expand = getattr(self.npyv, f"expand_{totype}_{self.sfx}")
        # 准备数据,以便接近边缘以检测任何偏差
        data  = self._data(self._int_max() - self.nlanes)
        vdata = self.load(data)
        # 执行扩展操作
        edata = expand(vdata)
        # 分别取数据的下半部分和上半部分
        data_lo = data[:self.nlanes//2]
        data_hi = data[self.nlanes//2:]
        # 断言扩展后的结果与分离的数据部分相等
        assert edata == (data_lo, data_hi)

    def test_arithmetic_subadd(self):
        # 如果是浮点数类型,则使用随机数据
        if self._is_fp():
            data_a = self._data()
        else:
            data_a = self._data(self._int_max() - self.nlanes)
        # 准备数据B,反向加载最小整数
        data_b = self._data(self._int_min(), reverse=True)
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)

        # 非饱和加法操作
        data_add = self.load([a + b for a, b in zip(data_a, data_b)]) # 加载用于类型转换
        add  = self.add(vdata_a, vdata_b)
        # 断言加法操作的结果相等
        assert add == data_add
        data_sub  = self.load([a - b for a, b in zip(data_a, data_b)])
        sub  = self.sub(vdata_a, vdata_b)
        # 断言减法操作的结果相等
        assert sub == data_sub

    def test_arithmetic_mul(self):
        # 如果后缀是'u64'或's64',则直接返回
        if self.sfx in ("u64", "s64"):
            return

        # 如果是浮点数类型,则使用随机数据
        if self._is_fp():
            data_a = self._data()
        else:
            data_a = self._data(self._int_max() - self.nlanes)
        # 准备数据B,反向加载最小整数
        data_b = self._data(self._int_min(), reverse=True)
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)

        # 执行乘法操作
        data_mul = self.load([a * b for a, b in zip(data_a, data_b)])
        mul = self.mul(vdata_a, vdata_b)
        # 断言乘法操作的结果相等
        assert mul == data_mul

    def test_arithmetic_div(self):
        # 如果不是浮点数类型,则直接返回
        if not self._is_fp():
            return

        # 准备数据A和B,分别加载为向量
        data_a, data_b = self._data(), self._data(reverse=True)
        vdata_a, vdata_b = self.load(data_a), self.load(data_b)

        # 执行除法操作
        data_div = self.load([a / b for a, b in zip(data_a, data_b)])
        div = self.div(vdata_a, vdata_b)
        # 断言除法操作的结果相等
        assert div == data_div
    def test_arithmetic_intdiv(self):
        """
        Test integer division intrinsics:
            npyv_divisor_##sfx
            npyv_divc_##sfx
        """
        # 如果是浮点数测试,则直接返回,不进行整数除法测试
        if self._is_fp():
            return

        # 获取整数的最小值
        int_min = self._int_min()

        def trunc_div(a, d):
            """
            Divide towards zero works with large integers > 2^53,
            and wrap around overflow similar to what C does.
            """
            # 特殊情况处理:当被除数为整数最小值且除数为-1时,返回被除数本身
            if d == -1 and a == int_min:
                return a
            # 判断被除数和除数的符号
            sign_a, sign_d = a < 0, d < 0
            # 根据符号确定向零舍入的整数除法
            if a == 0 or sign_a == sign_d:
                return a // d
            return (a + sign_d - sign_a) // d + 1

        # 构造测试数据,包括正数和负数,用于测试整数溢出
        data = [1, -int_min]  # to test overflow
        data += range(0, 2**8, 2**5)
        data += range(0, 2**8, 2**5-1)
        bsize = self._scalar_size()
        if bsize > 8:
            data += range(2**8, 2**16, 2**13)
            data += range(2**8, 2**16, 2**13-1)
        if bsize > 16:
            data += range(2**16, 2**32, 2**29)
            data += range(2**16, 2**32, 2**29-1)
        if bsize > 32:
            data += range(2**32, 2**64, 2**61)
            data += range(2**32, 2**64, 2**61-1)
        
        # 对测试数据进行负数化
        data += [-x for x in data]
        
        # 使用itertools的product函数,生成所有可能的被除数和除数组合,进行测试
        for dividend, divisor in itertools.product(data, data):
            # 将除数转换为所需格式
            divisor = self.setall(divisor)[0]  # cast
            if divisor == 0:
                continue
            # 将被除数加载到所需格式
            dividend = self.load(self._data(dividend))
            # 计算使用向零舍入的整数除法的期望结果
            data_divc = [trunc_div(a, divisor) for a in dividend]
            # 获取除数的参数
            divisor_parms = self.divisor(divisor)
            # 调用被测函数进行除法运算
            divc = self.divc(dividend, divisor_parms)
            # 断言期望结果与被测结果相等
            assert divc == data_divc

    def test_arithmetic_reduce_sum(self):
        """
        Test reduce sum intrinsics:
            npyv_sum_##sfx
        """
        # 如果数据类型不在指定的范围内,则直接返回,不进行求和操作测试
        if self.sfx not in ("u32", "u64", "f32", "f64"):
            return
        
        # 执行 reduce sum 测试
        data = self._data()
        vdata = self.load(data)

        # 计算 Python 原生列表的求和结果
        data_sum = sum(data)
        # 调用被测函数进行求和操作
        vsum = self.sum(vdata)
        # 断言被测求和结果与 Python 原生求和结果相等
        assert vsum == data_sum

    def test_arithmetic_reduce_sumup(self):
        """
        Test extend reduce sum intrinsics:
            npyv_sumup_##sfx
        """
        # 如果数据类型不在指定的范围内,则直接返回,不进行求和操作测试
        if self.sfx not in ("u8", "u16"):
            return
        
        # 执行 extend reduce sum 测试
        rdata = (0, self.nlanes, self._int_min(), self._int_max()-self.nlanes)
        for r in rdata:
            data = self._data(r)
            vdata = self.load(data)
            # 计算 Python 原生列表的求和结果
            data_sum = sum(data)
            # 调用被测函数进行扩展求和操作
            vsum = self.sumup(vdata)
            # 断言被测扩展求和结果与 Python 原生求和结果相等
            assert vsum == data_sum
    # 定义测试函数,用于测试条件性的加减运算,支持所有的数据类型
    def test_mask_conditional(self):
        """
        Conditional addition and subtraction for all supported data types.
        Test intrinsics:
            npyv_ifadd_##SFX, npyv_ifsub_##SFX
        """
        # 载入数据,使用默认顺序
        vdata_a = self.load(self._data())
        # 载入数据,使用反向顺序
        vdata_b = self.load(self._data(reverse=True))
        # 创建真值掩码,比较零向量是否等于自身
        true_mask  = self.cmpeq(self.zero(), self.zero())
        # 创建假值掩码,比较零向量是否不等于自身
        false_mask = self.cmpneq(self.zero(), self.zero())

        # 计算数据的差值
        data_sub = self.sub(vdata_b, vdata_a)
        # 使用真值掩码进行条件减法运算
        ifsub = self.ifsub(true_mask, vdata_b, vdata_a, vdata_b)
        # 断言条件减法的结果与直接计算的差值相等
        assert ifsub == data_sub
        # 使用假值掩码进行条件减法运算
        ifsub = self.ifsub(false_mask, vdata_a, vdata_b, vdata_b)
        # 断言条件减法的结果等于 vdata_b
        assert ifsub == vdata_b

        # 计算数据的和
        data_add = self.add(vdata_b, vdata_a)
        # 使用真值掩码进行条件加法运算
        ifadd = self.ifadd(true_mask, vdata_b, vdata_a, vdata_b)
        # 断言条件加法的结果与直接计算的和相等
        assert ifadd == data_add
        # 使用假值掩码进行条件加法运算
        ifadd = self.ifadd(false_mask, vdata_a, vdata_b, vdata_b)
        # 断言条件加法的结果等于 vdata_b
        assert ifadd == vdata_b

        # 如果不是浮点数类型,则直接返回,不继续执行以下代码
        if not self._is_fp():
            return
        
        # 计算数据的除法
        data_div = self.div(vdata_b, vdata_a)
        # 使用真值掩码进行条件除法运算
        ifdiv = self.ifdiv(true_mask, vdata_b, vdata_a, vdata_b)
        # 断言条件除法的结果与直接计算的除法结果相等
        assert ifdiv == data_div
        # 使用真值掩码进行条件零除法运算
        ifdivz = self.ifdivz(true_mask, vdata_b, vdata_a)
        # 断言条件零除法的结果与直接计算的除法结果相等
        assert ifdivz == data_div
        # 使用假值掩码进行条件除法运算
        ifdiv = self.ifdiv(false_mask, vdata_a, vdata_b, vdata_b)
        # 断言条件除法的结果等于 vdata_b
        assert ifdiv == vdata_b
        # 使用假值掩码进行条件零除法运算
        ifdivz = self.ifdivz(false_mask, vdata_a, vdata_b)
        # 断言条件零除法的结果等于零向量
        assert ifdivz == self.zero()
bool_sfx = ("b8", "b16", "b32", "b64")
int_sfx = ("u8", "s8", "u16", "s16", "u32", "s32", "u64", "s64")
fp_sfx  = ("f32", "f64")
all_sfx = int_sfx + fp_sfx

# 定义测试用例的注册表,映射后缀到对应的测试类
tests_registry = {
    bool_sfx: _SIMD_BOOL,
    int_sfx : _SIMD_INT,
    fp_sfx  : _SIMD_FP,
    ("f32",): _SIMD_FP32,
    ("f64",): _SIMD_FP64,
    all_sfx : _SIMD_ALL
}

# 遍历目标字典中的每个目标和其对应的 npyv 对象
for target_name, npyv in targets.items():
    # 获取当前目标的 SIMD 宽度信息
    simd_width = npyv.simd if npyv else ''
    # 将目标名称按 '__' 分割,用于多目标的情况
    pretty_name = target_name.split('__') # multi-target separator
    
    if len(pretty_name) > 1:
        # 如果有多个目标,将其格式化为形如 '(target1 target2)' 的字符串
        pretty_name = f"({' '.join(pretty_name)})"
    else:
        pretty_name = pretty_name[0]

    skip = ""
    skip_sfx = dict()

    if not npyv:
        # 如果 npyv 不存在,表示当前机器不支持该目标
        skip = f"target '{pretty_name}' isn't supported by current machine"
    elif not npyv.simd:
        # 如果目标支持的 SIMD 特性不存在,则表示不支持该目标
        skip = f"target '{pretty_name}' isn't supported by NPYV"
    else:
        # 检查是否支持单精度和双精度的 SIMD 计算
        if not npyv.simd_f32:
            skip_sfx["f32"] = f"target '{pretty_name}' doesn't support single-precision"
        if not npyv.simd_f64:
            skip_sfx["f64"] = f"target '{pretty_name}' doesn't support double-precision"

    # 遍历测试注册表中的每个后缀列表及其对应的测试类
    for sfxes, cls in tests_registry.items():
        for sfx in sfxes:
            # 获取当前后缀对应的跳过信息,如果没有则使用整体的跳过信息
            skip_m = skip_sfx.get(sfx, skip)
            inhr = (cls,)
            attr = dict(npyv=targets[target_name], sfx=sfx, target_name=target_name)
            # 根据命名规则创建测试类的名称
            tcls = type(f"Test{cls.__name__}_{simd_width}_{target_name}_{sfx}", inhr, attr)
            if skip_m:
                # 如果存在跳过信息,则为该测试类添加 pytest 的跳过标记
                pytest.mark.skip(reason=skip_m)(tcls)
            # 将创建的测试类添加到全局命名空间中
            globals()[tcls.__name__] = tcls