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

Ouverte
#100,950 2 commentaires 1 réaction 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

stdlib type-bug
Langage dominant
Python
Étoiles
77.2k
Forks
36k
Métriques de merge des PR
Métriques de PR en attente

Description

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.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Reproduisez l’exemple avec foobar/foo-bar.py, puis examinez l’implémentation de resolve_name dans pkgutil.py ainsi que unittest.mock.patch là où il est utilisé. La modification est terminée lorsque les noms acceptés par importlib.import_module sont gérés de manière cohérente par le chemin de patch, avec une couverture pour un nom de fichier de module contenant un tiret.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
python
Domaine
testing-qa
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
48/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.