Skip to content

Commit

Permalink
python: flake8: fix length processing in f-strings
Browse files Browse the repository at this point in the history
"F821 undefined name 'bar'" with `f'foo bar'` refers to the beginning of
the f-string, and therefore the entry's `length` property should not be
set.

This changes the flake8 postprocessing to use the generic length
postprocessor, which results in no `length` attribute for this entry
(since it checks if the text is there).

A proper fix would be to search for the next `{bar}`, and adjust the
lnum/col also.
  • Loading branch information
blueyed committed Feb 16, 2018
1 parent ab5262f commit dbb679f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 16 deletions.
21 changes: 12 additions & 9 deletions autoload/neomake/makers/ft/python.vim
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,14 @@ function! neomake#makers#ft#python#Flake8EntryProcess(entry) abort
let type = ''
endif

let l:token = matchstr(a:entry.text, "'.*'")
if strlen(l:token)
" remove quotes
let l:token = substitute(l:token, "'", '', 'g')
if a:entry.type ==# 'F' && (a:entry.nr == 401 || a:entry.nr == 811)
" The unused column is incorrect for import errors and redefinition
" errors.
let token_pattern = '\v''\zs[^'']+\ze'
if a:entry.type ==# 'F' && (a:entry.nr == 401 || a:entry.nr == 811)
" Special handling for F401 (``module`` imported but unused) and
" F811 (redefinition of unused ``name`` from line ``N``).
" The unused column is incorrect for import errors and redefinition
" errors.
let token = matchstr(a:entry.text, token_pattern)
if !empty(token)
let l:view = winsaveview()
call cursor(a:entry.lnum, a:entry.col)
" The number of lines to give up searching afterwards
Expand Down Expand Up @@ -172,9 +173,11 @@ function! neomake#makers#ft#python#Flake8EntryProcess(entry) abort
endif

call winrestview(l:view)
endif

let a:entry.length = strlen(l:token) " subtract the quotes
let a:entry.length = strlen(l:token)
endif
else
call neomake#postprocess#generic_length_with_pattern(a:entry, token_pattern)
endif

let a:entry.text = a:entry.type . a:entry.nr . ' ' . a:entry.text
Expand Down
14 changes: 11 additions & 3 deletions autoload/neomake/postprocess.vim
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
" Generic postprocessor to add `length` to `a:entry`.
" The pattern can be overridden on `self`, and should adhere to this:
" The pattern can be overridden on `self` and should adhere to this:
" - the matched word should be returned as the whole match (you can use \zs
" and \ze).
" - enclosing patterns should be returned as \1 and \2, where \1 is used as
" offset when the first entry did not match.
" See tests/postprocess.vader for tests/examples.
" See neomake#postprocess#generic_length_with_pattern for a non-dict variant.
function! neomake#postprocess#generic_length(entry) abort dict
if a:entry.bufnr == bufnr('%') && a:entry.lnum > 0 && a:entry.col
if a:entry.lnum > 0 && a:entry.col
let pattern = get(self, 'pattern', '\v(["''`])\zs[^\1]{-}\ze(\1)')
let start = 0
let best = 0
Expand All @@ -18,7 +19,8 @@ function! neomake#postprocess#generic_length(entry) abort dict
let l = len(m[0])
if l > best
" Ensure that the text is there.
if getline(a:entry.lnum)[a:entry.col-1 : a:entry.col-2+l] == m[0]
let line = getbufline(a:entry.bufnr, a:entry.lnum)[0]
if line[a:entry.col-1 : a:entry.col-2+l] == m[0]
let best = l
endif
endif
Expand All @@ -38,6 +40,12 @@ function! neomake#postprocess#generic_length(entry) abort dict
endif
endfunction

" Wrapper to call neomake#process#generic_length (a dict function).
function! neomake#postprocess#generic_length_with_pattern(entry, pattern) abort
let this = {'pattern': a:pattern}
return call('neomake#postprocess#generic_length', [a:entry], this)
endfunction

" Deprecated: renamed to neomake#postprocess#generic_length.
function! neomake#postprocess#GenericLengthPostprocess(entry) abort dict
return neomake#postprocess#generic_length(a:entry)
Expand Down
9 changes: 5 additions & 4 deletions tests/ft_python.vader
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,20 @@ Execute (python: flake8: errorformat/postprocess: F811):
bwipe!

Execute (neomake#makers#ft#python#Flake8EntryProcess):
let entry = {'type': 'F', 'nr': 841, 'text': "local variable 'foo' is assigned to but never used"}
let bufnr = bufnr('%')
let entry = {'type': 'F', 'nr': 841, 'text': "local variable 'foo' is assigned to but never used", 'lnum': 1, 'col': 1, 'bufnr': bufnr}
call neomake#makers#ft#python#Flake8EntryProcess(entry)
AssertEqual entry.type, 'W'

let entry = {'type': 'F', 'nr': 999, 'text': "something"}
let entry = {'type': 'F', 'nr': 999, 'text': "something", 'lnum': 1, 'col': 1, 'bufnr': bufnr}
call neomake#makers#ft#python#Flake8EntryProcess(entry)
AssertEqual entry.type, 'E'

let entry = {'type': 'F', 'nr': 404, 'text': "not found"}
let entry = {'type': 'F', 'nr': 404, 'text': "not found", 'lnum': 1, 'col': 1, 'bufnr': bufnr}
call neomake#makers#ft#python#Flake8EntryProcess(entry)
AssertEqual entry.type, 'W'

let entry = {'type': 'F', 'nr': 407, 'text': "no future"}
let entry = {'type': 'F', 'nr': 407, 'text': "no future", 'lnum': 1, 'col': 1, 'bufnr': bufnr}
call neomake#makers#ft#python#Flake8EntryProcess(entry)
AssertEqual entry.type, 'E'

Expand Down

0 comments on commit dbb679f

Please sign in to comment.