flake8-sql
flake8-sql copied to clipboard
Support f-strings
It looks like flake8-sql fails to parse queries built with f-strings (the same string with .format() works)
Below is a compact example tested with: python -m flake8 flake8_sql_check.py
columns = 'col1,col2'
view = 'View1'
# Works, catches Q440
query = 'select {columns} From [{view}]'.format(columns=columns, view=view)
# Throws "TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'"
# query = f'select {columns} From [{view}]'
Full traceback:
C:\Users\king.kyle\Developer\project>poetry run python -m flake8 flake8_sql_check.py
Traceback (most recent call last):
File "c:\users\king.kyle\miniconda3\lib\runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\users\king.kyle\miniconda3\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8\__main__.py", line 4, in <module>
cli.main()
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8\main\cli.py", line 22, in main
app.run(argv)
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8\main\application.py", line 363, in run
self._run(argv)
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8\main\application.py", line 351, in _run
self.run_checks()
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8\main\application.py", line 264, in run_checks
self.file_checker_manager.run()
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8\checker.py", line 323, in run
self.run_serial()
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8\checker.py", line 307, in run_serial
checker.run_checks()
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8\checker.py", line 589, in run_checks
self.run_ast_checks()
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8\checker.py", line 494, in run_ast_checks
for (line_number, offset, text, _) in runner:
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8_sql\linter.py", line 49, in run initial_offset = _get_initial_offset(node, self.lines)
File "C:\Users\king.kyle\Developer\project\.venv\lib\site-packages\flake8_sql\linter.py", line 178, in _get_initial_offset
first_physical_line = physical_lines[query_end_lineno - len(logical_lines)]
TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'
I can possibly look into a PR later, but wanted to report the error since I've run into it a few times.
I just want to live dangerously:

Hahaha, I just went down a massive rabbit hole trying to figure this out, only to come out on the other side and realise there already was an issue on it :)
I went back to revisit this issue, but I oddly can no longer replicate it 🤔
@thomasaarholt, can you share a snippet that fails for you? What Python version were you using?
@KyleKing I am able to reproduce this error using Python 3.9.9, flake8 4.0.1 and flake8-sql 0.4.1 when running python -m flake8 flake8_sql_format_check.py on this file:
table_name = "mytable"
sql = f"SELECT id FROM {table_name} WHERE foo = 'bar'"
This gives the following traceback:
Traceback (most recent call last):
File "/Users/brox/.pyenv/versions/3.9.9/lib/python3.9/runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/Users/brox/.pyenv/versions/3.9.9/lib/python3.9/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8/__main__.py", line 4, in <module>
cli.main()
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8/main/cli.py", line 22, in main
app.run(argv)
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8/main/application.py", line 375, in run
self._run(argv)
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8/main/application.py", line 364, in _run
self.run_checks()
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8/main/application.py", line 271, in run_checks
self.file_checker_manager.run()
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8/checker.py", line 311, in run
self.run_serial()
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8/checker.py", line 295, in run_serial
checker.run_checks()
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8/checker.py", line 597, in run_checks
self.run_ast_checks()
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8/checker.py", line 500, in run_ast_checks
for (line_number, offset, text, _) in runner:
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8_sql/linter.py", line 49, in run
initial_offset = _get_initial_offset(node, self.lines)
File "/Users/brox/.pyenv/versions/sandbox/lib/python3.9/site-packages/flake8_sql/linter.py", line 178, in _get_initial_offset
first_physical_line = physical_lines[query_end_lineno - len(logical_lines)]
TypeError: unsupported operand type(s) for -: 'NoneType' and 'int'