Before: Save g:ale_python_flake8_executable Save g:ale_python_flake8_options Save g:ale_python_flake8_use_global Save g:ale_python_flake8_change_directory unlet! g:ale_python_flake8_executable unlet! g:ale_python_flake8_args unlet! g:ale_python_flake8_options unlet! g:ale_python_flake8_use_global unlet! g:ale_python_flake8_change_directory let b:bin_dir = has('win32') ? 'Scripts' : 'bin' runtime ale_linters/python/flake8.vim call ale#test#SetDirectory('/testplugin/test/command_callback') After: Restore unlet! g:ale_python_flake8_args unlet! b:bin_dir unlet! b:executable call ale#test#RestoreDirectory() call ale#linter#Reset() call ale#semver#ResetVersionCache() Execute(The flake8 callbacks should return the correct default values): AssertEqual \ 'flake8', \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual \ ale#Escape('flake8') . ' --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.0']) " Try with older versions. call ale#semver#ResetVersionCache() AssertEqual \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('flake8') . ' --format=default -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9']) Execute(The option for disabling changing directories should work): let g:ale_python_flake8_change_directory = 0 AssertEqual \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.0']) Execute(The flake8 command callback should let you set options): let g:ale_python_flake8_options = '--some-option' AssertEqual \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('flake8') \ . ' --some-option --format=default' \ . ' --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.4']) call ale#semver#ResetVersionCache() AssertEqual \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('flake8') \ . ' --some-option --format=default -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9']) Execute(You should be able to set a custom executable and it should be escaped): let g:ale_python_flake8_executable = 'executable with spaces' AssertEqual \ 'executable with spaces', \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual \ ale#Escape('executable with spaces') . ' --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('executable with spaces') \ . ' --format=default' \ . ' --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.0']) Execute(The flake8 callbacks should detect virtualenv directories): silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') let b:executable = ale#path#Simplify( \ g:dir . '/python_paths/with_virtualenv/env/' . b:bin_dir . '/flake8' \) AssertEqual \ b:executable, \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual \ ale#Escape(b:executable) . ' --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape(b:executable) \ . ' --format=default --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.0']) Execute(The FindProjectRoot should detect the project root directory for namespace package via Manifest.in): silent execute 'file ' . fnameescape(g:dir . '/python_paths/namespace_package_manifest/namespace/foo/bar.py') AssertEqual \ ale#path#Simplify(g:dir . '/python_paths/namespace_package_manifest'), \ ale#python#FindProjectRoot(bufnr('')) Execute(The FindProjectRoot should detect the project root directory for namespace package via setup.cf): silent execute 'file ' . fnameescape(g:dir . '/python_paths/namespace_package_setup/namespace/foo/bar.py') AssertEqual \ ale#path#Simplify(g:dir . '/python_paths/namespace_package_setup'), \ ale#python#FindProjectRoot(bufnr('')) Execute(The FindProjectRoot should detect the project root directory for namespace package via pytest.ini): silent execute 'file ' . fnameescape(g:dir . '/python_paths/namespace_package_pytest/namespace/foo/bar.py') AssertEqual \ ale#path#Simplify(g:dir . '/python_paths/namespace_package_pytest'), \ ale#python#FindProjectRoot(bufnr('')) Execute(The FindProjectRoot should detect the project root directory for namespace package via tox.ini): silent execute 'file ' . fnameescape(g:dir . '/python_paths/namespace_package_tox/namespace/foo/bar.py') AssertEqual \ ale#path#Simplify(g:dir . '/python_paths/namespace_package_tox'), \ ale#python#FindProjectRoot(bufnr('')) Execute(The FindProjectRoot should detect the project root directory for non-namespace package): silent execute 'file ' . fnameescape(g:dir . '/python_paths/no_virtualenv/subdir/foo/bar.py') AssertEqual \ ale#path#Simplify(g:dir . '/python_paths/no_virtualenv/subdir'), \ ale#python#FindProjectRoot(bufnr('')) " Some users currently run flake8 this way, so we should support it. Execute(Using `python -m flake8` should be supported for running flake8): silent execute 'file ' . fnameescape(g:dir . '/python_paths/with_virtualenv/subdir/foo/bar.py') let g:ale_python_flake8_executable = 'python' let g:ale_python_flake8_options = '-m flake8 --some-option' AssertEqual \ 'python', \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual \ ale#Escape('python') . ' -m flake8 --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('python') . ' -m flake8 --some-option --format=default -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9']) call ale#semver#ResetVersionCache() " Leading spaces shouldn't matter let g:ale_python_flake8_options = ' -m flake8 --some-option' AssertEqual \ 'python', \ ale_linters#python#flake8#GetExecutable(bufnr('')) AssertEqual \ ale#Escape('python') . ' -m flake8 --version', \ ale_linters#python#flake8#VersionCheck(bufnr('')) AssertEqual \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('python') . ' -m flake8 --some-option --format=default -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['2.9.9']) Execute(Setting executable to 'pipenv' appends 'run flake8'): let g:ale_python_flake8_executable = 'path/to/pipenv' AssertEqual \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('path/to/pipenv') . ' run flake8 --format=default --stdin-display-name %s -', \ ale_linters#python#flake8#GetCommand(bufnr(''), ['3.0.0'])