python / python/cpython

pkgutil.walk_packages(None) imports tests and then their SkipTest exceptions ends iteration

未關閉
#131,684 6 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

還沒有人認領這個 Issue。

pending stdlib type-bug
主要語言
Python
星號
77.2k
分支
36k
PR 合併指標
PR 指標待擷取

描述

Bug report

I have to be clear that in some ways this isn't technically a bug per se, it's documented in the documentation, I just think the default behavior should be different because it's not ergonomic -- and that behavior change should be documented. It's a bug in the sense of I tried to do the simplest thing possible and Python was like "NOPE" and I was like "well that's gotta be a bug in Python," and I believe I am technically wrong but a lot of people in similar positions would assume the same.

Basic problem: Stdlib contains non-importable modules, if they fail with ImportError then pkgutil.walk_packages will ignore them, and those are the only packages it will ignore by default. But stdlib contains a bunch of non-importable test-case modules that instead fail with unittest.SkipTest. This means that any use of the default args on walk_packages() errors out, you have to manually tell it that SkipTest is a fine error to ignore.

Bug description:

Steps to Reproduce

Fire up python 3.13, then run the following two lines:

>>> import pkgutil
>>> [p.name for p in pkgutil.walk_packages()]
Traceback (most recent call last):
  File "<python-input-7>", line 1, in <module>
    [p.name for p in pkgutil.walk_packages()]
                     ~~~~~~~~~~~~~~~~~~~~~^^
  File "/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/pkgutil.py", line 93, in walk_packages
    yield from walk_packages(path, info.name+'.', onerror)
  File "/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/pkgutil.py", line 78, in walk_packages
    __import__(info.name)
    ~~~~~~~~~~^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.13/3.13.2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/test/test_free_threading/__init__.py", line 8, in <module>
    raise unittest.SkipTest("GIL enabled")
unittest.case.SkipTest: GIL enabled

OR, fire up homebrew's (or poetry's) python 3.12, then run the same:

Python 3.12.9 (main, Feb  4 2025, 14:38:38) [Clang 16.0.0 (clang-1600.0.26.6)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkgutil
>>> [p.name for p in pkgutil.walk_packages()]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/homebrew/Cellar/python@3.12/3.12.9/Frameworks/Python.framework/Versions/3.12/lib/python3.12/pkgutil.py", line 93, in walk_packages
    yield from walk_packages(path, info.name+'.', onerror)
  File "/opt/homebrew/Cellar/python@3.12/3.12.9/Frameworks/Python.framework/Versions/3.12/lib/python3.12/pkgutil.py", line 78, in walk_packages
    __import__(info.name)
  File "/opt/homebrew/Cellar/python@3.12/3.12.9/Frameworks/Python.framework/Versions/3.12/lib/python3.12/test/test_gdb/__init__.py", line 22, in <module>
    raise unittest.SkipTest("test_gdb only works on source builds at the moment.")
unittest.case.SkipTest: test_gdb only works on source builds at the moment.

Cause

Seems to be pretty obvious, these are test modules that exist all the time (whether GIL is enabled or not, whether debugger is enabled or not) but they raise an exception when they get imported.

Suggestions

pkgutil should be able to catch and discard unittest.SkipTest.

The easiest way to do this is to make unittest.SkipTest a subclass of ImportError instead of Exception, but that "smells risky" (in particular it presumably isn't only thrown when people import modules). The smarter way to do this is to just document that we by default don't error on SkipTest either and adjust the code at https://github.com/python/cpython/blob/v3.13.2/Lib/pkgutil.py#L82 accordingly.

CPython versions tested on:

3.11.11, 3.12.9, 3.13.2

Operating systems tested on:

macOS

Linked PRs
  • gh-148926

貢獻指南

開啟貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

研究方向

從 Lib/pkgutil.py 第 82 行附近開始,針對 issue 中描述的 Python 測試套件使用 pkgutil.walk_packages() 重現失敗。檢查連結的 PR gh-148926 以及相關文件和測試;當約定的 SkipTest 行為已實作並記錄在文件中,且沒有破壞現有的錯誤處理時,即可視為完成。

由索引模型根據 Issue 內容生成。

評估

技術堆疊
python
領域
backend
Issue 類型
缺陷
難度
4/5
預估耗時
3-5 天
活躍度
停滯
描述清晰度
基本清楚
新手友好度
25/100

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。