Skip to content

B907 crashes when bugbear is run on Python 3.12 #393

@AlexWaygood

Description

@AlexWaygood

Minimal repro: using Python 3.12 (with flake8-bugbear installed), run flake8 on a file containing just this:

f'"{var:}"'
Resulting stack trace:
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Users\alexw\coding\slow-cpython-venv\Scripts\flake8.exe\__main__.py", line 7, in <module>
  File "C:\Users\alexw\coding\slow-cpython-venv\Lib\site-packages\flake8\main\cli.py", line 23, in main
    app.run(argv)
  File "C:\Users\alexw\coding\slow-cpython-venv\Lib\site-packages\flake8\main\application.py", line 198, in run
    self._run(argv)
  File "C:\Users\alexw\coding\slow-cpython-venv\Lib\site-packages\flake8\main\application.py", line 187, in _run
    self.run_checks()
  File "C:\Users\alexw\coding\slow-cpython-venv\Lib\site-packages\flake8\main\application.py", line 103, in run_checks
    self.file_checker_manager.run()
  File "C:\Users\alexw\coding\slow-cpython-venv\Lib\site-packages\flake8\checker.py", line 236, in run
    self.run_serial()
  File "C:\Users\alexw\coding\slow-cpython-venv\Lib\site-packages\flake8\checker.py", line 219, in run_serial
    ).run_checks()
      ^^^^^^^^^^^^
  File "C:\Users\alexw\coding\slow-cpython-venv\Lib\site-packages\flake8_noqa\noqa_filter.py", line 189, in run_checks
    result = super().run_checks(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\alexw\coding\slow-cpython-venv\Lib\site-packages\flake8\checker.py", line 524, in run_checks
    self.run_ast_checks()
  File "C:\Users\alexw\coding\slow-cpython-venv\Lib\site-packages\flake8\checker.py", line 426, in run_ast_checks
    for (line_number, offset, text, _) in runner:
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 70, in run
    visitor.visit(self.tree)
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 348, in visit
    super().visit(node)
  File "C:\Users\alexw\coding\cpython\Lib\ast.py", line 407, in visit
    return visitor(node)
           ^^^^^^^^^^^^^
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 432, in visit_Module
    self.generic_visit(node)
  File "C:\Users\alexw\coding\cpython\Lib\ast.py", line 415, in generic_visit
    self.visit(item)
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 348, in visit
    super().visit(node)
  File "C:\Users\alexw\coding\cpython\Lib\ast.py", line 407, in visit
    return visitor(node)
           ^^^^^^^^^^^^^
  File "C:\Users\alexw\coding\cpython\Lib\ast.py", line 417, in generic_visit
    self.visit(value)
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 348, in visit
    super().visit(node)
  File "C:\Users\alexw\coding\cpython\Lib\ast.py", line 407, in visit
    return visitor(node)
           ^^^^^^^^^^^^^
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 521, in visit_JoinedStr
    self.generic_visit(node)
  File "C:\Users\alexw\coding\cpython\Lib\ast.py", line 415, in generic_visit
    self.visit(item)
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 348, in visit
    super().visit(node)
  File "C:\Users\alexw\coding\cpython\Lib\ast.py", line 407, in visit
    return visitor(node)
           ^^^^^^^^^^^^^
  File "C:\Users\alexw\coding\cpython\Lib\ast.py", line 417, in generic_visit
    self.visit(value)
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 348, in visit
    super().visit(node)
  File "C:\Users\alexw\coding\cpython\Lib\ast.py", line 407, in visit
    return visitor(node)
           ^^^^^^^^^^^^^
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 520, in visit_JoinedStr
    self.check_for_b907(node)
  File "C:\Users\alexw\coding\flake8-bugbear\bugbear.py", line 1273, in check_for_b907
    and value.value[-1] in quote_marks
        ~~~~~~~~~~~^^^^
IndexError: string index out of range

This is because this snippet parses differently on Python 3.12 (presumably due to PEP 701).

On Python 3.11:
>>> import ast
>>> print(ast.dump(ast.parse("""f'"{var:}"'"""), indent=2))
Module(
  body=[
    Expr(
      value=JoinedStr(
        values=[
          Constant(value='"'),
          FormattedValue(
            value=Name(id='var', ctx=Load()),
            conversion=-1,
            format_spec=JoinedStr(values=[])),
          Constant(value='"')]))],
  type_ignores=[])
On Python 3.12:
>>> import ast
>>> print(ast.dump(ast.parse("""f'"{var:}"'"""), indent=2))
Module(
  body=[
    Expr(
      value=JoinedStr(
        values=[
          Constant(value='"'),
          FormattedValue(
            value=Name(id='var', ctx=Load()),
            conversion=-1,
            format_spec=JoinedStr(
              values=[
                Constant(value='')])),
          Constant(value='"')]))],
  type_ignores=[])

As a result of this, BugbearTestCase.test_b907 and BugbearTestCase.test_b907_format_specifier_permutations both crash on Python 3.12.

(N.B. I had to comment out the test that uses hypothesmith (and the import of hypothesmith) to get the tests to run on Python 3.12 -- seems like hypothesmith can't be installed on Python 3.12 yet.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions