为什么生成器在通过 pytest 调用时不会引发 StopIteration 异常?

问题描述 投票:0回答:1

考虑发电机:

def sample():
    print("Setup")
    yield
    print("Teardown")


gen = sample()
next(gen)
next(gen)

当我调用第一个 next(gen) 时,生成器会执行到 print("Setup") 为止,下次调用它时,它会执行到 print("Teardown") 之后。而且,由于没有第二个yield语句,它会引发StopIteration异常。但是当我进行以下修改时:

import pytest
@pytest.fixture
def sample():
    print("Setup")
    yield
    print("Teardown")


def test_case(sample):
    print("Executing test case")

现在,当我运行 pytest 命令时,所有代码都正确执行,首先是设置部分,然后是 test_case,然后是拆卸部分。我确信 pytest 在执行过程中会调用生成器两次,因为所有打印语句都在执行。但是这里为什么没有引发 StopIteration 异常呢?我的假设是 pytest 正在内部处理它。证实我的假设,如果我错了,请纠正我。谢谢你。

python pytest generator
1个回答
0
投票

查看fixtures.py中@pytest.fixture的源代码。

@pytest.fixture
是一个装饰器,因此它创建了一个看起来与
sample()
完全相同的新函数,但它周围有一个包装器。第一次调用
sample()
时,包装器期望函数正常返回。第二次调用
sample()
时,它期望函数返回
StopIteration
,并显式丢弃它。

一般来说,您不应期望具有装饰器的函数与不带装饰器的同一函数具有相同的行为方式。

© www.soinside.com 2019 - 2024. All rights reserved.