python / python/cpython

mock.patch cannot import an invalid-name module in >=3.11 due to importlib.import_module vs pkgutil.resolve_name differences when module has a dash in its filename

オープン
#100,950 コメント 2 件 リアクション 1 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

stdlib type-bug
主要言語
Python
スター
77.2k
フォーク
36k
PR マージ指標
PR 指標を取得中

説明

Bug report

importlib.import_module() and pkgutil.resolve_name() are inconsistent with regards to which formats they accept. For example, if I have a module that contains a dash (-) in its filename (for example in a Django management command), importlib.import_module() is able to import the module just fine, while pkgutil.resolve_name() will raise an exception about an invalid format.

Minimal reproducer (all files are empty):

$ find . -name \*.py
./foobar/__init__.py
./foobar/foo-bar.py
$ python3 -c 'import importlib; importlib.import_module("foobar.foo-bar")'
$ python3 -c 'import pkgutil; pkgutil.resolve_name("foobar.foo-bar")'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3.10/pkgutil.py", line 687, in resolve_name
    raise ValueError(f'invalid format: {name!r}')
ValueError: invalid format: 'foobar.foo-bar'

I would expect those to be consistent in the format they accept, i.e. accept and reject the same inputs.
My current actual problem is that unittest.mock.patch uses pkgutil.resolve_name() in Python 3.11 (but not in Python 3.10), what means that one cannot easily patch a function inside a Django management command module that contains a dash.

Your environment

Tested on Debian testing amd64 (x86_64) as of today, with both python 3.11.1 and 3.9.10.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

foobar/foo-bar.py の例を再現し、その後 pkgutil.py の resolve_name 実装と、それが使用されている箇所の unittest.mock.patch を調査します。importlib.import_module が受け付ける名前が patch path で一貫して処理され、ハイフンを含むモジュールファイル名のカバレッジが追加されれば、変更は完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
testing-qa
issue の種類
バグ
難易度
3/5
見積もり時間
1〜2日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
48/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。