PyCQA / flake8-bugbear

A plugin for Flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

B907 crashes when bugbear is run on Python 3.12

AlexWaygood opened this issue · comments

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.)