Before: call ale#assert#SetUpLinterTest('python', 'flake8') let b:bin_dir = has('win32') ? 'Scripts' : 'bin' WithChainResults ['3.0.0'] After: unlet! b:executable unlet! b:bin_dir call ale#assert#TearDownLinterTest() Execute(The flake8 callbacks should return the correct default values): AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] " The version check should be cached. WithChainResults [] AssertLinter 'flake8', [ \ '', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] " Try with older versions. call ale#semver#ResetVersionCache() WithChainResults ['2.9.9'] AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('flake8') . ' --format=default -', \] Execute(The option for disabling changing directories should work): let g:ale_python_flake8_change_directory = 0 AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', \ ale#Escape('flake8') . ' --format=default --stdin-display-name %s -', \] Execute(The flake8 command callback should let you set options): let g:ale_python_flake8_options = '--some-option' WithChainResults ['3.0.4'] AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('flake8') . ' --some-option' \ . ' --format=default --stdin-display-name %s -', \] call ale#semver#ResetVersionCache() WithChainResults ['2.9.9'] AssertLinter 'flake8', [ \ ale#Escape('flake8') . ' --version', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('flake8') . ' --some-option --format=default -', \] Execute(You should be able to set a custom executable and it should be escaped): let g:ale_python_flake8_executable = 'executable with spaces' AssertLinter 'executable with spaces', [ \ ale#Escape('executable with spaces') . ' --version', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('executable with spaces') \ . ' --format=default' \ . ' --stdin-display-name %s -', \] 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' \) AssertLinter b:executable, [ \ ale#Escape(b:executable) . ' --version', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape(b:executable) \ . ' --format=default' \ . ' --stdin-display-name %s -', \] 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' WithChainResults ['2.9.9'] AssertLinter 'python', [ \ ale#Escape('python') . ' -m flake8 --version', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('python') \ . ' -m flake8 --some-option --format=default -' \] call ale#semver#ResetVersionCache() " Leading spaces shouldn't matter let g:ale_python_flake8_options = ' -m flake8 --some-option' WithChainResults ['2.9.9'] AssertLinter 'python', [ \ ale#Escape('python') . ' -m flake8 --version', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('python') \ . ' -m flake8 --some-option --format=default -' \] Execute(Setting executable to 'pipenv' should append 'run flake8'): let g:ale_python_flake8_executable = 'path/to/pipenv' " FIXME: pipenv should check the vresion with flake8. WithChainResults [] AssertLinter 'path/to/pipenv', \ ale#path#BufferCdString(bufnr('')) \ . ale#Escape('path/to/pipenv') . ' run flake8 --format=default -'