Skip to content

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

@Locked-chess-official

Description

@Locked-chess-official

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-importlibtype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions