配置yapf和isort的Vim与Pytest插件
2019-01-01 12:01:42 +08 字数:1977 标签: Vim Python Test用Vim写Python,曾是一件流行的事,而今已经变得小众。 实际上,Vim仍然是Python开发的最佳利器之一,在很多方面,甚至优于PyCharm这样的IDE。
本文会基于Vim,介绍Python的风格统一与格式化方法。 并且,还会集成它们到pytest中去。
yapf简介 ¶
Golang的出现,改变了很多事。 它从Python中学走了编程风格、代码规范的固化,毕竟这关乎优雅。 Python的固化,跟多还停留在规范层面,如PEP8。 Golang从一开始就更进一步,用gofmt把这种固化做成了源文件格式化。
这固然带来了很多争议,但也带来了很多便利。 这些便利可以总结为一句话——结束了关于风格与规范的圣战。
yapf就是在gofmt的思路下,反馈给Python社区的礼物。 可以在YAPF Online Demo中,试用yapf并查看效果。
isort简介 ¶
yapf只专注于格式化,而不会去修改内容和顺序。
这在大部分区域都没问题,但在import
区域,却显得不足。
在Pylint下,Python的import
,也需要像Java那样有确定的顺序和分组,而yapf无能为力。
这就是isort的领域。
isort会把import
分成标准库、第三方库、本地库三种,分别按字母排序。
格式化的结果,能自动满足Pylint的需要。
实际上,它本身就是Pylint的一个依赖。
更难得的是,isort自己提供了一个Wiki——isort Plugins · timothycrosley/isort Wiki——介绍了如何给几种流行的编辑环境配置插件。
安装与配置插件 ¶
pip install yapf isort
安装很简单,命令行使用也很方便,可以自行查看--help
。
这里谈谈两种配置到Vim的两种方法。
vim-autoformat与vim-isort ¶
以下为基于Vundle.vim的插件配置。
Plugin 'Chiel92/vim-autoformat'
let g:formatter_yapf_style = 'pep8'
Plugin 'fisadev/vim-isort'
noremap <F2> :Autoformat<CR>:Isort<CR>
vim-autoformat是一个通用的Vim格式化插件,它通过yapf对Python提供支持。 vim-isort则是一个简单的,专为isort而生的插件。
最后,这里配置了
ale ¶
以上的两个插件,无疑是能用的,孤也用了很长时间。 但比起ale来,在通用性上,还是略显不足。
Plugin 'w0rp/ale'
let g:ale_fixers = {
\ 'python': ['yapf', 'isort'],
\ }
noremap <F2> :ALEFix<CR>
以上配置为真实ale配置的一个简化版。 它比上一个插件方案看上去清晰多了,并且很容易兼容更多fixer、更多语言。
(ale本身是一个很大的话题,这里不多介绍。)
配置 ¶
yapf配置与优先级:
- Specified on the command line
- In the
[style]
section of a.style.yapf
file in either the current directory or one of its parent directories.- In the
[yapf]
section of asetup.cfg
file in either the current directory or one of its parent directories.- In the
~/.config/yapf/style
file in your home directory.
isort配置:
- 局部配置有三种(优先级不明)
.isort.cfg
,使用[settings]
区域setup.cfg
或tox.ini
,使用[isort]
区域pyproject.toml
,使用[tool.isort]
区域
- 全局配置
~/.isort.cfg
,使用[settings]
区域
yapf和isort,虽然都有还不错的默认配置,但也不能完全不调整。
尤其是,它们会格式化同一区域,会有一些冲突情况,比如最后一个import的comma(,
)。
虽然它俩都有各自的配置文件与优先顺序,但本地配置中都支持setup.cfg
。
所以,推荐在项目的setup.cfg
中进行配置,固化在项目中。
[isort]
line_length = 79
multi_line_output = 3
include_trailing_comma = true
[yapf]
based_on_style = facebook
coalesce_brackets = true
dedent_closing_brackets = true
以上为孤的个人配置,至少解决了已知的comma冲突问题。
集成到pytest ¶
既然谈到固化,就要有检查。 如果两个人开发同一个文件,一个人有做文件格式化,另一个没有,那么前者就经常会自动修改后者的代码,带来不必要的冲突; 如果两个人的格式化配置不一样,那么故事就更精彩了。
用相同的配置建立同一的标准,并且在每一次commit都去检查它,这才是完整的方案。 而pytest能实现这个方案。
在setup.py
的tests_require
中,或者requirements.txt
中,添加pytest-isort和~~pytest-yapf~~(推荐使用pytest-yapf3),并且安装它们。
然后,配置setup.cfg
。
[tool:pytest]
addopts = --verbose
--isort
--yapf
...
isort_ignore = setup.py
[isort]
...
[yapf]
...
这里,主要是添加--isort
和--yapf
到已有的pytest配置中。
pytest-isort还支持isort_ignore
,忽略不需要检查的文件;
pytest-yapf还不支持这个功能。
配置完成后,一切尽在pytest
。
pytest-yapf3 ¶
现在推荐pytest-yapf3,这是孤写的插件。
由于pytest-yapf完成度不高,也不再维护,因此孤fork出来重写了一份。
3
的意思,除了区分外,也是只支持Python 3的意思。
除原先的基本功能外,增加了以下改进:
- Basic support to validate yapf.
- Fix the diff line count error and improve the performance.
- Display
YAPF-check
as the error session name. - Display
YAPF
inpytest --verbose
. - Add yapf as a marker to enable
pytest -m yapf
. - Support
yapf-ignore
to ignore specified files. - Skip running if a file is not changed.
- 100% test coverage.
结语 ¶
咦?那为什么……