B907 crashes when bugbear is run on Python 3.12
AlexWaygood opened this issue · comments
Alex Waygood commented
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.)