python / python/cpython

_find_incompatible_extension_module() lacks argument validation and raises TypeError or AttributeError when module_name is not string

Ouverte
#146,632 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

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

Description

Crash report

What happened?

Now the code for traceback._find_incompatible_extension_module is here:

def _find_incompatible_extension_module(module_name):
    import importlib.machinery
    import importlib.resources.readers

    if not module_name or not importlib.machinery.EXTENSION_SUFFIXES:
        return

    # We assume the last extension is untagged (eg. .so, .pyd)!
    # tests.test_traceback.MiscTest.test_find_incompatible_extension_modules
    # tests that assumption.
    untagged_suffix = importlib.machinery.EXTENSION_SUFFIXES[-1]
    # On Windows the debug tag is part of the module file stem, instead of the
    # extension (eg. foo_d.pyd), so let's remove it and just look for .pyd.
    if os.name == 'nt':
        untagged_suffix = untagged_suffix.removeprefix('_d')

    parent, _, child = module_name.rpartition('.')
    if parent:
        traversable = importlib.resources.files(parent)
    else:
        traversable = importlib.resources.readers.MultiplexedPath(
            *map(pathlib.Path, filter(os.path.isdir, sys.path))
        )

    for entry in traversable.iterdir():
        if entry.name.startswith(child + '.') and entry.name.endswith(untagged_suffix):
            return entry.name

However, it is a function for handle a raised exception ModuleNotFoundError. When it raised other exception, it will crash the whole python. For example:

>>> raise AttributeError(name=NotImplemented, obj=NotImplemented)
Traceback (most recent call last):
  File "<python-input-0>", line 1, in <module>
    raise AttributeError(name=NotImplemented, obj=NotImplemented)
AttributeError
>>> raise NameError(name=NotImplemented)
Traceback (most recent call last):
  File "<python-input-1>", line 1, in <module>
    raise NameError(name=NotImplemented)
NameError
>>> raise ImportError(name=NotImplemented, name_from=NotImplemented)
Traceback (most recent call last):
  File "<python-input-2>", line 1, in <module>
    raise ImportError(name=NotImplemented, name_from=NotImplemented)
ImportError
>>> raise ModuleNotFoundError(name=NotImplemented)
Traceback (most recent call last):
  File "<python-input-3>", line 1, in <module>
ModuleNotFoundError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\code.py", line 324, in push
    more = self.runsource(source, filename, symbol=_symbol)
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\_pyrepl\console.py", line 239, in runsource
    result = self.runcode(code)
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\_pyrepl\console.py", line 186, in runcode
    self.showtraceback()
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\code.py", line 128, in showtraceback
    self._showtraceback(typ, value, tb.tb_next, "")
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\code.py", line 144, in _showtraceback
    self._excepthook(typ, value, tb)
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\_pyrepl\console.py", line 174, in _excepthook
    lines = traceback.format_exception(
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\traceback.py", line 168, in format_exception
    te = TracebackException(type(value), value, tb, limit=limit, compact=True)
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\traceback.py", line 1136, in __init__
    elif abi_tag := _find_incompatible_extension_module(module_name):
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\traceback.py", line 1914, in _find_incompatible_extension_module
    if not module_name or not importlib.machinery.EXTENSION_SUFFIXES:
TypeError: NotImplemented should not be used in a boolean context

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\_pyrepl\main.py", line 58, in interactive_console
    run_multiline_interactive_console(console)
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\_pyrepl\simple_interact.py", line 174, in run_multiline_interactive_console
    console.showtraceback()
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\code.py", line 128, in showtraceback
    self._showtraceback(typ, value, tb.tb_next, "")
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\code.py", line 144, in _showtraceback
    self._excepthook(typ, value, tb)
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\_pyrepl\console.py", line 174, in _excepthook
    lines = traceback.format_exception(
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\traceback.py", line 168, in format_exception
    te = TracebackException(type(value), value, tb, limit=limit, compact=True)
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\traceback.py", line 1208, in __init__
    context = TracebackException(
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\traceback.py", line 1136, in __init__
    elif abi_tag := _find_incompatible_extension_module(module_name):
  File "C:\Users\hh180\my_python\traceback_suggest_improve\Lib\traceback.py", line 1914, in _find_incompatible_extension_module
    if not module_name or not importlib.machinery.EXTENSION_SUFFIXES:
TypeError: NotImplemented should not be used in a boolean context

For traceback function, it needs to check isinstance(module_name, str) and use try...except to include it.

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Output from running 'python -VV' on the command line:

No response

Linked PRs
  • gh-146633

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

Lisez Lib/traceback.py à _find_incompatible_extension_module ainsi que le chemin de TracebackException qui l'appelle. Commencez par tests.test_traceback.MiscTest.test_find_incompatible_extension_modules, puis ajoutez une couverture pour les noms de modules qui ne sont pas des chaînes et vérifiez que le formatage de la traceback ne lève plus d'exception secondaire ; le PR gh-146633 lié indique que ce travail est déjà en cours.

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

Évaluation

Stack technique
python
Domaine
devtools
Type d'issue
Bug
Difficulté
3/5
Temps estimé
1-2 jours
Activité
À l'abandon
Clarté
Clairement spécifiée
Accessibilité débutants
25/100

Recevez les nouvelles issues par e-mail

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