python runtime_error ai_generated true

test_create_user 的 teardown 出错 文件 "...",行 ...,在 db_session 中 session.close() RuntimeError: generator didn't stop after throw()

ERROR at teardown of test_create_user File "...", line ..., in db_session session.close() RuntimeError: generator didn't stop after throw()

ID: python/pytest-teardown-error-generator

其他格式: JSON · Markdown 中文 · English
80%修复率
86%置信度
0证据数
2024-09-17首次发现

版本兼容性

版本状态引入弃用备注
3.x active — — —

根因分析

基于 yield 的 fixture 在测试注入异常后再次 yield 或抛出异常。通常由在 `finally` 内 yield 的 `try/finally`,或捕获异常后再次 yield 的生成器 fixture 引起。

English

A yield-based fixture raised or yielded again after the test injected an exception. Typically caused by a `try/finally` that yields inside `finally`, or a generator fixture that catches exceptions and yields again.

generic

解决方案

  1. 95% 成功率
    import pytest
    
    @pytest.fixture
    def db_session():
        session = SessionLocal()
        try:
            yield session
        finally:
            session.close()  # no yield here
  2. 90% 成功率
    import contextlib
    
    @contextlib.contextmanager
    def db_session():
        s = SessionLocal()
        try:
            yield s
        finally:
            s.close()
    
    # then in fixture
    @pytest.fixture
    def db():
        with db_session() as s:
            yield s

无效尝试

常见但无效的做法:

  1. 85% 失败

    pytest requires the generator to stop after the exception is thrown; a second yield triggers the same error.

  2. 70% 失败

    Loses teardown entirely; DB session/resources are never closed, causing connection leaks.