Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

`WarningsRecorder.pop()` returns the last match instead of the first when warning categories are unrelated

未关闭
#15,097 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@Aditya-XR 已经在做这个了。

开始于 2026年9月24日。

  • #15098 来自 @Aditya-XR —— 未关闭
  • #15105 来自 @chen-maker999 —— 已关闭,未合并
  • #15119 来自 @Tejas5405 —— 未关闭

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
python
领域
testing-qa

调研方向

Start at the WarningsRecorder.pop implementation and read TestSubclassWarningPop plus test_recording, especially the existing category-selection loop. Add a regression case using unrelated warning categories and verify that pop returns the first matching warning; run the relevant warning-recorder tests.

由索引模型根据 Issue 内容生成。

描述

WarningsRecorder.pop() (and pytest.warns(...).pop() / recwarn.pop()) returns the last matching warning instead of the first one when the recorded warnings have categories that are unrelated to each other.

import warnings

def test_pop(recwarn):
    warnings.warn("first", UserWarning)
    warnings.warn("second", RuntimeWarning)
    warnings.warn("third", DeprecationWarning)
    assert str(recwarn.pop().message) == "first"
E       AssertionError: assert 'third' == 'first'

The docstring says pop returns "the first recorded warning which is an instance of cls, but not an instance of a child class of any other match". None of the three categories is a subclass of another, so the first one should come back. That was also the behaviour before 8.0.

The cause is the "best inexact match" loop added in #11160 (the fix for #10701):

if issubclass(w.category, cls) and (
    best_idx is None
    or not issubclass(w.category, self._list[best_idx].category)
):
    best_idx = i

not issubclass(new, best) is true both when new is more general than best and when the two are unrelated siblings. So every sibling replaces the current best, and the loop ends up on the last one.

The existing tests in TestSubclassWarningPop only use a single parent/child chain, so they don't catch this. test_recording pops a UserWarning and a DeprecationWarning, but both have the message "hello", so it passes whichever one comes back.

Reproduced on main (pytest 9.2.0.dev345+g872117358), Python 3.13.5, Windows 11. The loop was introduced by #11160, so the bug is present since 8.0.0; in 7.4.x pop() returned the first match. I have a fix with regression tests ready and will open a PR.

主要语言
Python
星标
14.6k
派生
3.4k
平均合并
2 天 7 小时
30 天内合并 PR
29

环境准备

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

pytest-dev/pytest 的其他 Issue

查看 pytest-dev/pytest 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。