From 91e8422d6d67f1b1139b57b8707945ea2531443e Mon Sep 17 00:00:00 2001 From: infokiller Date: Thu, 16 Jun 2022 16:41:57 +0300 Subject: [PATCH] Add pyflyby fixer (using its tidy-imports script) (#4219) * add pyflyby fixer updates * pyflyby: add docs updates * add tests to pyflyby fixer --- autoload/ale/fix/registry.vim | 5 ++ autoload/ale/fixers/pyflyby.vim | 41 +++++++++++++++++ doc/ale-python.txt | 46 +++++++++++++++++++ doc/ale-supported-languages-and-tools.txt | 1 + doc/ale.txt | 1 + supported-tools.md | 1 + test/fixers/test_pyflyby_fixer_callback.vader | 38 +++++++++++++++ .../env/Scripts/tidy-imports.exe | 0 .../with_virtualenv/env/bin/tidy-imports | 0 9 files changed, 133 insertions(+) create mode 100644 autoload/ale/fixers/pyflyby.vim create mode 100644 test/fixers/test_pyflyby_fixer_callback.vader create mode 100755 test/test-files/python/with_virtualenv/env/Scripts/tidy-imports.exe create mode 100755 test/test-files/python/with_virtualenv/env/bin/tidy-imports diff --git a/autoload/ale/fix/registry.vim b/autoload/ale/fix/registry.vim index 2e772419..57fff655 100644 --- a/autoload/ale/fix/registry.vim +++ b/autoload/ale/fix/registry.vim @@ -136,6 +136,11 @@ let s:default_registry = { \ 'description': 'Apply prettier-eslint to a file.', \ 'aliases': ['prettier-eslint'], \ }, +\ 'pyflyby': { +\ 'function': 'ale#fixers#pyflyby#Fix', +\ 'suggested_filetypes': ['python'], +\ 'description': 'Tidy Python imports with pyflyby.', +\ }, \ 'importjs': { \ 'function': 'ale#fixers#importjs#Fix', \ 'suggested_filetypes': ['javascript'], diff --git a/autoload/ale/fixers/pyflyby.vim b/autoload/ale/fixers/pyflyby.vim new file mode 100644 index 00000000..81c0f05e --- /dev/null +++ b/autoload/ale/fixers/pyflyby.vim @@ -0,0 +1,41 @@ +" Author: infokiller +" Description: Tidy imports using pyflyby's tidy-import script +" https://github.com/deshaw/pyflyby + +call ale#Set('python_pyflyby_executable', 'tidy-imports') +call ale#Set('python_pyflyby_use_global', get(g:, 'ale_use_global_executables', 0)) +call ale#Set('python_pyflyby_options', '') +call ale#Set('python_pyflyby_auto_pipenv', 0) +call ale#Set('python_pyflyby_auto_poetry', 0) + +function! ale#fixers#pyflyby#GetExecutable(buffer) abort + if (ale#Var(a:buffer, 'python_auto_pipenv') || ale#Var(a:buffer, 'python_pyflyby_auto_pipenv')) + \ && ale#python#PipenvPresent(a:buffer) + return 'pipenv' + endif + + if (ale#Var(a:buffer, 'python_auto_poetry') || ale#Var(a:buffer, 'python_pyflyby_auto_poetry')) + \ && ale#python#PoetryPresent(a:buffer) + return 'poetry' + endif + + return ale#python#FindExecutable(a:buffer, 'python_pyflyby', ['tidy-imports']) +endfunction + +function! ale#fixers#pyflyby#Fix(buffer) abort + " let l:executable = ale#fixers#pyflyby#GetExecutable(a:buffer) + let l:executable = ale#fixers#pyflyby#GetExecutable(a:buffer) + let l:cmd = [ale#Escape(l:executable)] + + if l:executable =~? 'pipenv\|poetry$' + call extend(l:cmd, ['run', 'tidy-imports']) + endif + + let l:options = ale#Var(a:buffer, 'python_pyflyby_options') + + if !empty(l:options) + call add(l:cmd, l:options) + endif + + return {'command': join(l:cmd, ' ')} +endfunction diff --git a/doc/ale-python.txt b/doc/ale-python.txt index d001454e..41488a65 100644 --- a/doc/ale-python.txt +++ b/doc/ale-python.txt @@ -708,6 +708,52 @@ g:ale_python_pyflakes_auto_poetry *g:ale_python_pyflakes_auto_poetry* if true. This is overridden by a manually-set executable. +=============================================================================== +pyflyby *ale-python-pyflyby* + +g:ale_python_pyflyby_executable *g:ale_python_pyflyby_executable* + *b:ale_python_pyflyby_executable* + Type: |String| + Default: `'tidy-imports'` + + See |ale-integrations-local-executables| + + +g:ale_python_pyflyby_options *g:ale_python_pyflyby_options* + *b:ale_python_pyflyby_options* + Type: |String| + Default: `''` + + This variable can be changed to add command-line arguments to the pyflyby + tidy-imports invocation. + + +g:ale_python_pyflyby_use_global *g:ale_python_pyflyby_use_global* + *b:ale_python_pyflyby_use_global* + Type: |Number| + Default: `get(g:, 'ale_use_global_executables', 0)` + + See |ale-integrations-local-executables| + + +g:ale_python_pyflyby_auto_pipenv *g:ale_python_pyflyby_auto_pipenv* + *b:ale_python_pyflyby_auto_pipenv* + Type: |Number| + Default: `0` + + Detect whether the file is inside a pipenv, and set the executable to `pipenv` + if true. This is overridden by a manually-set executable. + + +g:ale_python_pyflyby_auto_poetry *g:ale_python_pyflyby_auto_poetry* + *b:ale_python_pyflyby_auto_poetry* + Type: |Number| + Default: `0` + + Detect whether the file is inside a poetry, and set the executable to `poetry` + if true. This is overridden by a manually-set executable. + + =============================================================================== pylama *ale-python-pylama* diff --git a/doc/ale-supported-languages-and-tools.txt b/doc/ale-supported-languages-and-tools.txt index 218832bc..10ee6ae5 100644 --- a/doc/ale-supported-languages-and-tools.txt +++ b/doc/ale-supported-languages-and-tools.txt @@ -466,6 +466,7 @@ Notes: * `pycodestyle` * `pydocstyle` * `pyflakes` + * `pyflyby` * `pylama`!! * `pylint`!! * `pylsp` diff --git a/doc/ale.txt b/doc/ale.txt index 1f5b3218..0d5d7564 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -3117,6 +3117,7 @@ documented in additional help files. pycodestyle...........................|ale-python-pycodestyle| pydocstyle............................|ale-python-pydocstyle| pyflakes..............................|ale-python-pyflakes| + pyflyby...............................|ale-python-pyflyby| pylama................................|ale-python-pylama| pylint................................|ale-python-pylint| pylsp.................................|ale-python-pylsp| diff --git a/supported-tools.md b/supported-tools.md index 24e8de42..4033205e 100644 --- a/supported-tools.md +++ b/supported-tools.md @@ -475,6 +475,7 @@ formatting. * [pycodestyle](https://github.com/PyCQA/pycodestyle) :warning: * [pydocstyle](https://www.pydocstyle.org/) :warning: * [pyflakes](https://github.com/PyCQA/pyflakes) + * [pyflyby](https://github.com/deshaw/pyflyby) :warning: * [pylama](https://github.com/klen/pylama) :floppy_disk: * [pylint](https://www.pylint.org/) :floppy_disk: * [pylsp](https://github.com/python-lsp/python-lsp-server) :warning: diff --git a/test/fixers/test_pyflyby_fixer_callback.vader b/test/fixers/test_pyflyby_fixer_callback.vader new file mode 100644 index 00000000..d017572e --- /dev/null +++ b/test/fixers/test_pyflyby_fixer_callback.vader @@ -0,0 +1,38 @@ +Before: + call ale#assert#SetUpFixerTest('python', 'pyflyby') + + let b:bin_dir = has('win32') ? 'Scripts' : 'bin' + +After: + call ale#assert#TearDownFixerTest() + + unlet! b:bin_dir + +Execute(The pyflyby callback should return the correct default values): + call ale#test#SetFilename('../test-files/python/with_virtualenv/subdir/foo/bar.py') + + AssertFixer + \ { + \ 'command': ale#Escape(ale#path#Simplify(g:dir . '/../test-files/python/with_virtualenv/env/' . b:bin_dir . '/tidy-imports')), + \ } + +Execute(Pipenv is detected when python_pyflyby_auto_pipenv is set): + let g:ale_python_pyflyby_auto_pipenv = 1 + + call ale#test#SetFilename('../test-files/python/pipenv/whatever.py') + + AssertFixer + \ { + \ 'command': ale#Escape('pipenv') . ' run tidy-imports' + \ } + +Execute(Poetry is detected when python_pyflyby_auto_poetry is set): + let g:ale_python_pyflyby_auto_poetry = 1 + + call ale#test#SetFilename('../test-files/python/poetry/whatever.py') + + GivenCommandOutput ['VERSION 5.7.0'] + AssertFixer + \ { + \ 'command': ale#Escape('poetry') . ' run tidy-imports' + \ } diff --git a/test/test-files/python/with_virtualenv/env/Scripts/tidy-imports.exe b/test/test-files/python/with_virtualenv/env/Scripts/tidy-imports.exe new file mode 100755 index 00000000..e69de29b diff --git a/test/test-files/python/with_virtualenv/env/bin/tidy-imports b/test/test-files/python/with_virtualenv/env/bin/tidy-imports new file mode 100755 index 00000000..e69de29b