分享

新一代 Python Linter 工具 Ruff

 黄爸爸好 2023-11-03 发布于上海

            


Setup

Setup

学习中...

关注他

最近几年Rust在前端工具链领域影响越来越大,甚至提出了《Rust 是 JavaScript 基建的未来》,凡是能用 Rust 重写的前端工具就用 Rust 重写,结果突出一个字 - 。这股风气也被悄然带入到了其他解释性语言领域,Ruby 使用 Rust 实现 YJIT 编译器;在 Python 语言领域,出现了 Ruff 项目,官方简介:

一个用Rust编写的非常快速的Python linter:比现有的 linter 快 10-100 倍⚡️

Ruff 利用 RustPython 的 AST 解析器,实现自己的 AST 遍历、visitor 抽象和 lint 规则逻辑。它目标是比其他工具快几个数量级,同时提供代码检查、autofix等一站式的解决方案。

Ruff 可以用来替换flake8(加上各种插件),isortpydocstyleyesqaeradicatepyupgrade和 autoflake,所有这些都比任何单独的工具执行速度快几十或数百倍。Ruff 超越了传统 linter 的职责,而是作为一种高级代码转换工具,能够升级类型注释、重写类定义、对import导入进行排序等等。

下面简单介绍下用法:

安装和使用

安装上非常简单,借助于maturin,Ruff 可以像其他第三方Python包一样通过pip安装:

pip install ruff

然后就可以使用 Ruff 了:

ruff path/to/code/to/check.py
ruff path/to/code/
ruff path/to/code/*.py

你还可以在watch模式下运行 Ruff,当文件改变时自动执行:

ruff path/to/code/ --watch

也可以和 pre-commit 一起工作:

- repo: https://github.com/charliermarsh/ruff-pre-commit  # Ruff version.
  rev: 'v0.0.198'
  hooks:
    - id: ruff      # Respect `exclude` and `extend-exclude` settings.
      args: ["--force-exclude"]

配置

Ruff 可以通过pyproject.toml和命令行进行配置。有关可配置选项的完整列表,请参阅 API文档。 默认配置如下:

[tool.ruff]
line-length = 88

# Enable Pyflakes `E` and `F` codes by default.
select = ["E", "F"]
ignore = []

# Exclude a variety of commonly ignored directories.
exclude = [
    ".bzr",
    ".direnv",
    ".eggs",
    ".git",
    ".hg",
    ".mypy_cache",
    ".nox",
    ".pants.d",
    ".ruff_cache",
    ".svn",
    ".tox",
    ".venv",
    "__pypackages__",
    "_build",
    "buck-out",
    "build",
    "dist",
    "node_modules",
    "venv",
]
per-file-ignores = {}

# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

# Assume Python 3.10.
target-version = "py310"

[tool.ruff.mccabe]
# Unlike Flake8, default to a complexity level of 10.
max-complexity = 10

当然也可以自定义配置。例如,下面将配置Ruff 为:

  1. 避免检查line-length问题(E501)

  2. 不移除未使用的import(F401)

  3. 忽略在文件__init__.py中的import-at-top-of-file错误(E402)

[tool.ruff]
# Enable Pyflakes and pycodestyle rules.
select = ["E", "F"]

# Never enforce `E501` (line length violations).
ignore = ["E501"]

# Never try to fix `F401` (unused imports).
unfixable = ["F401"]

# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`.
[tool.ruff.per-file-ignores]
"__init__.py" = ["E402"]
"path/to/file.py" = ["E402"]

Ruff 模仿了 Flake8 的错误代码系统,其中每个错误代码由一个1-3个字母的前缀组成,后面跟着3个数字(例如F401)。前缀表示错误代码的“源”(例如,F表示Pyflakes, E表示pycodestyle, ANN表示flake8-annotations)。启用的错误集由selectignore选项决定,它们既支持完整的错误代码(例如F401),也支持前缀(例如F)。 Ruff 也支持自己的配置文件ruff.toml(类似于 ESLint 的 .eslintrc),层级上少了 [tool.ruff],例如:

# Enable Pyflakes and pycodestyle rules.
select = ["E", "F"]

# Never enforce `E501` (line length violations).
ignore = ["E501"]

# Always autofix, but never try to fix `F401` (unused imports).
fix = true
unfixable = ["F401"]

# Ignore `E402` (import violations) in all `__init__.py` files, and in `path/to/file.py`.
[per-file-ignores]
"__init__.py" = ["E402"]
"path/to/file.py" = ["E402"]

也可以通过命令行提供一些常见的配置设置:

ruff path/to/code/ --select F401 --select F403

类似于 ESLint, Ruff 支持分层配置,Python文件以距离它“最近的”的pyproject.toml作为其配置。和 ESLint 不同的是 Ruff 不会跨配置文件合并设置;相反,使用“最近的”配置文件,并且忽略任何父配置文件。代替这种隐式级联,Ruff 支持一个扩展字段,它允许您从另一个pyproject.toml继承设置。像这样:

# Extend the `pyproject.toml` file in the parent directory.
extend = "../pyproject.toml"
# But use a different line length.
line-length = 100

上述规则同样适用于ruff.toml配置文件。 在代码中可以使用 # noqa: {code}注释忽略代码行/块的错误:

# Ignore F841.x = 1  # noqa: F841# Ignore E741 and F841.i = 1  # noqa: E741, F841# Ignore _all_ errors.x = 1  # noqa

当前支持的规则参见:https://github.com/charliermarsh/ruff#supported-rules

编辑器集成

VS Code

vscode提供了 Ruff VS Code extension,可以直接在插件管理中安装使用,它支持 autofiximport排序等功能。

动图封面

PyCharm(外部工具)

Ruff 可以在 PyCharm 中作为外部工具安装。打开首选项,然后导航到工具>外部工具。在那里,添加一个具有以下配置的新工具:

Ruff可以作为一个可运行的action

PyCharm(插件)

在 IntelliJ 插件市场也能找到非官方维护的 Ruff 插件,相比外部工具,操作上更方便一点。

其他Vim/Github Actions等配置方法可以查阅官方文档

其他

Ruff 可以和Python另一个明星项目 - 格式化工具black 一起使用,只需要 line-length有相同配置既可。

Ruff 第一个版本发布在2022年8月30日,可以说是一个非常新的项目,虽然作者迭代的非常积极(目前版本为 v0.0.198),但是规则实现上没有常用的 Pylint 规则多,并不能完全替代 Pylint。当前 Pylint 总共实现了409条规则,而Ruff实现了224条,其中有60条与 Pylint 规则集重叠。主观上,Pylint倾向于实现更多基于类型推断的规则(例如,验证函数调用中参数的数量)。关于 Pylint 规则替代实现官方也有跟踪,详见 #970。Ruff 目前还不支持第三方插件,仅仅在项目范围内有一个插件系统,详见 #283

相信不久的将来能看到功能更完善、支持更多的规则、更好用的 Ruff。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多