目录
RUFF概述
特点
安装和使用
应用场景
配置
编辑器集成
PyCharm(外部工具)
Ruff的规则
Ruff速度快的几个原因
最后
注意:后续技术分享,第一时间更新,以及更多更及时的技术资讯和学习技术资料,将在公众号CTO Plus发布,请关注公众号:CTO Plus
Ruff是一个基于Python的代码检查工具,它可以帮助我们在编写Python代码时发现潜在的问题并提供修复建议。本文我将在Python3.11版本下,介绍Ruff的特点、使用方法以及在项目中的应用场景。
最近几年Rust在前端工具链领域影响越来越大,甚至提出了《Rust 是 JavaScript 基建的未来》,凡是能用 Rust 重写的前端工具就用 Rust 重写,结果突出一个字 - 快。这股风气也被悄然带入到了其他解释性语言领域,Ruby 使用 Rust 实现 YJIT 编译器;在 Python 语言领域,出现了 Ruff 项目,官方简介:
一个用Rust编写的非常快速的Python linter:比现有的 linter 快 10-100 倍⚡️
在公众号CTO Plus的这篇文章对Rust做了一个基本介绍《Rust:一门安全、并发和高性能的系统编程语言,能为我们带来哪些利好》,具体可以参考这篇文章,后面我将对Ruff的源码进行深度剖析,这里先简单看下他的源码结构。
从源码中可以看出,项目工程用的是Rust的Cargo构建工具,这个工具将在文章《Rust进阶1. 安装Rust编程环境,并编写你的第一个Rust程序,以及两款rustc、cargo工具使用方法和常用指令总结》中做介绍。
在他的核心代码目录crates下,可以看到全是基于Cargo构建的标准Rust项目
以及非常多的.rs文件,.rs文件是Rust编写的源码问题,同比.py是Python的源码文件。
本篇属于【代码规范与扫描】系列内容的第三篇,前面几篇可以根据自己情况执行查阅:
- 《企业级Python代码静态扫描-代码规范、逻辑、语法、安全检查,以及代码自动编排介绍》
- 《通读Python PEP8代码规范》
- 《Python代码扫描:新一代 Python Linter工具Ruff》
- 《Python代码扫描:提升Python代码质量的神器-pylint详解与使用指南》
- 《Python代码扫描:轻量级Python静态代码分析工具pyflakes》
- 《Python代码扫描:Python代码规范与错误检查的利器-flake8详解与实践》
- 《Python代码扫描:静态类型检查的最佳选择mypy》
- 《Python代码扫描:自动化移除Python代码中的冗余-autoflake使用技巧与实例》
- 《Python代码扫描:Python代码格式化的利器-yapf详解与最佳实践》
- 《Python代码扫描:一键格式化Python代码的黑魔法-black使用教程》
- 《Python代码扫描:导入语句自动排序工具-isort使用指南与示例》
- 《Python代码扫描:自动化修复Python代码风格的工具-autopep8详解与实例》
- 《Python代码扫描:项目中的代码规范与错误检查-pyproject-flake8配置与使用方法》
- 《Python代码扫描:企业级代码代码安全漏洞扫描Bandit》
RUFF概述
Ruff第一个版本发布在2022年8月30日,可以说是一个非常新的项目,虽然作者迭代的非常积极(目前版本为 v0.0.198),但是规则实现上没有常用的 Pylint 规则多,并不能完全替代 Pylint。当前 Pylint 总共实现了409条规则,而Ruff实现了224条,其中有60条与 Pylint 规则集重叠。主观上,Pylint倾向于实现更多基于类型推断的规则(例如,验证函数调用中参数的数量)。关于 Pylint 规则替代实现官方也有跟踪,详见 #970。Ruff 目前还不支持第三方插件,仅仅在项目范围内有一个插件系统,详见 https://github.com/astral-sh/ruff/issues/283。
Ruff 利用 Rust Python 的 AST 解析器,实现自己的 AST 遍历、visitor 抽象和 lint 规则逻辑。它目标是比其他工具快几个数量级,同时提供代码检查、autofix等一站式的解决方案。
Ruff 可以用来替换flake8(加上各种插件)、isort、pydocstyle、yesqa、eradicate、pyupgrade和 autoflake,所有这些都比任何单独的工具执行速度快几十或数百倍。Ruff 超越了传统 linter 的职责,而是作为一种高级代码转换工具,能够升级类型注释、重写类定义、对import导入进行排序等等。
特点
Ruff具有以下几个特点:
1. 首先是速度快、功能强大。
2. 定制规则:Ruff提供了一系列的默认规则,同时也支持自定义规则。我们可以根据项目的需求定义自己的规则,以满足特定的代码质量要求。
3. 代码风格检查:Ruff可以检查代码的风格是否符合PEP 8规范,如缩进、命名规范、代码布局等。
4. 代码质量检查:Ruff可以检查代码中的一些常见问题,如未使用的变量、未使用的导入、重复的代码等,以提高代码的量和可维护性。
5. 静态分析:Ruff通过静态分析Python代码来检查潜在的问题,不需要运行代码即可发现潜在的错误和不规范的代码。
6. 报告生成:Ruff可以生成详细的报告,包括每个问题的描述、位置和建议的修复方法。这些报告可以帮助我们快速定位和解决代码中的问题。
下面简单介绍下用法:
安装和使用
安装上非常简单,借助于maturin,Ruff 可以像其他第三方Python包一样通过pip安装,只需按照以下步骤进行操作:
1. 安装Ruff:可以通过pip命令安装Ruff,如下所示:
pip install ruff
安装完成后,在D:\env311\Scripts目录下即可看到一个ruff.exe的可执行文件
2. 执行检查:在命令行中执行以下命令,即可对指定的Python代码进行检查:
扫描指定目录:ruff /path/to/code
这将对指定路径下的所有Python文件进行检查,并生成相应的报告。
针对指定文件扫描
ruff path/to/code/to/check.py
使用通配符进行扫描
ruff path/to/code/*.py
还可以在watch模式下运行 Ruff,当文件改变时自动执行:
ruff path/to/code/ --watch
按照不同的目录和文件执行检查
ruff check . # Lint all files in the current directory (and any subdirectories)
ruff check path/to/code/ # Lint all files in `/path/to/code` (and any subdirectories)
ruff check path/to/code/*.py # Lint all `.py` files in `/path/to/code`
ruff check path/to/code/to/file.py # Lint `file.py`
也可以和 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"]
3. 解读报告:Ruff将生成一个报告文件,其中包含了检查结果和问题的详细信息。我们可以根据报告中的建议来修复代码中的问题。
应用场景
Ruff可以在许多项目中应用,特别是在大型项目和团队协作中。以下是Ruff的一些应用场景:
1. 代码规范:对于遵循PEP 8规范的项目,Ruff可以帮助我们检查代码的风格是否符合规范,并提供相应的修复建议。
2. 代码质量:Ruff可以帮助我们检查代码中的一些常见问题,如未使用的变量、未使用的导入和重复的代码等,以提高代码的质量和可维护性。
3. 团队协作:在团队协作中,Ruff可以帮助我们统一代码风格和质量标准,以提高代码的一致性和可读性。
4. 持续集成:在持续集成环境中,Ruff可以作为一个检查步骤,帮助我们在代码提交前发现问题,以避免将错误的代码合并到主分支。
配置
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 为:
避免检查line-length问题(E501)
不移除未使用的import(F401)
忽略在文件__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)。启用的错误集由select和ignore选项决定,它们既支持完整的错误代码(例如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
编辑器集成
PyCharm(外部工具)
Ruff 可以在 PyCharm 中作为外部工具安装。打开首选项,然后导航到工具>外部工具。在那里,添加一个具有以下配置的新工具:
Ruff可以作为一个可运行的action。
Ruff的规则
Ruff支持500多个lint规则,其中许多规则的灵感来自流行的工具,如Flake8、isort、pyupgrade等。无论规则的起源如何,Ruff都将Rust中的每一条规则作为第一方功能重新实现。具体官方参考规则库:https://beta.ruff.rs/docs/rules/
默认情况下,Ruff启用Flake8的E和F规则。Ruff支持F类的所有规则,以及E类的一个子集,省略了那些因使用自动格式化程序(如Black)而过时的风格规则。
关于Flake8和Black将在公众号CTO Plus后面的文章中做详细介绍,敬请关注。
如果你刚开始使用Ruff,那么默认规则集是一个很好的起点:它可以在零配置的情况下捕获各种常见错误(如未使用的导入)。
除了默认设置之外,Ruff还重新实现了一些最流行的Flake8插件和相关的代码质量工具,包括:
- autoflake
- eradicate
- flake8-2020
- flake8-annotations
- flake8-async
- flake8-bandit (#1646)
- flake8-blind-except
- flake8-boolean-trap
- flake8-bugbear
- flake8-builtins
- flake8-commas
- flake8-comprehensions
- flake8-copyright
- flake8-datetimez
- flake8-debugger
- flake8-django
- flake8-docstrings
- flake8-eradicate
- flake8-errmsg
- flake8-executable
- flake8-future-annotations
- flake8-gettext
- flake8-implicit-str-concat
- flake8-import-conventions
- flake8-logging-format
- flake8-no-pep420
- flake8-pie
- flake8-print
- flake8-pyi
- flake8-pytest-style
- flake8-quotes
- flake8-raise
- flake8-return
- flake8-self
- flake8-simplify
- flake8-slots
- flake8-super
- flake8-tidy-imports
- flake8-todos
- flake8-type-checking
- flake8-use-pathlib
- flynt (#2102)
- isort
- mccabe
- pandas-vet
- pep8-naming
- pydocstyle
- pygrep-hooks
- pylint-airflow
- pyupgrade
- tryceratops
- yesqa
Ruff速度快的几个原因
Ruff它之所以能够运行得非常快速,可以归因于以下几个方面:
1. 采用 AST(抽象语法树)分析:Ruff 使用 Python 的内置库 ast 来解析源代码并生成抽象语法树。相比于直接解析源代码,AST 分析可以更高效地遍历和分析代码结构,从而提高性能。
2. 基于规则的静态分析:Ruff 通过定义一系列的规则来检查代码,这些规则可以检测出代码中的潜在问题和风格违规。相比于动态分析或符号执行等复杂的分析技术,基于规则的静态分析方法更加简单和高效。
3. 并行处理:Ruff 可以并行处理多个文件,从而提高分析的速度。它可以同时启动多个分析任务,每个任务独立运行,互不干扰。这样可以充分利用多核处理器的计算能力,加快分析的速度。
4. 优化算法:Ruff 使用了一些优化算法来提高分析的效率。例如,可以通过缓存已经分析过的模块,避免重复解析和分析;还可以通过剪枝等技术,减少不必要的分析路径,提高分析的效率。
最后
Ruff 还可以和Python另一个格式化工具black 一起使用,只需要 line-length有相同配置既可。关于black工具的详细介绍将在后面的文章《Python代码扫描:一键格式化Python代码的黑魔法-black使用教程》中做详细介绍,敬请关注公众号CTO Plus后面的文章。
Ruff是一个强大的Python代码检查工具,可以帮助我们发现潜在的问题并提供修复建议。它通过静态分析Python代码来检查代码风格和质量,并生成详细的报告。在代码规范、代码质量、团队协作和持续集成等场景中,Ruff都可以发挥重要的作用,帮助我们提高代码的质量和可维护性。
参考资料
GitHub - astral-sh/ruff: An extremely fast Python linter, written in Rust.
https://github.com/charliermarsh/ruff#supported-rules
Meta issue: plugin system · Issue #283 · astral-sh/ruff · GitHub
https://beta.ruff.rs/docs/tutorial/
https://beta.ruff.rs/docs/rules/
https://beta.ruff.rs/docs/configuration/
https://beta.ruff.rs/docs/settings/
Python代码规范:企业级代码静态扫描-代码规范、逻辑、语法、安全检查,以及代码规范自动编排(1)_pycharm 检查代码规范_SteveRocket的博客-CSDN博客
https://blog.csdn.net/zhouruifu2015/article/details/129877179
Python专栏
https://blog.csdn.net/zhouruifu2015/category_5742543
更多资料 · 微信公众号搜索【CTO Plus】关注后,获取更多,我们一起学习交流。
关于公众号的描述访问如下链接
更多精彩,关注我公号,一起学习、成长
关于Articulate“做一个知识和技术的搬运工。做一个终身学习的爱好者。做一个有深度和广度的技术圈。”一直以来都想把专业领域的技https://mp.weixin.qq.com/s?__biz=MzIyMzQ5MTY4OQ==&mid=2247484278&idx=1&sn=2b774f789b4c7a2ccf10e465a1b9def6&chksm=e81c2070df6ba966026fd7851efa824b5e2704e3fd34e76228ca4ce64d93f7964cd4abe60f2b#rd
标准库系列-推荐阅读:
-
Python基础之开发必备-标准库(内置模块)汇总详细介绍(持续更新……)
-
Python标准库45. math模块实践
-
Python标准库87. typing模块实践
-
Python标准库88. 数据库 (sqlite3) 实践
-
Python标准库89. signal模块实践以及与Linux的信号
-
看这一篇就够了Python的35个关键字的含义、作用、特性以及使用方式详解
推荐阅读:
-
Python基础之最新的73个内置函数(1)
-
Python基础之最新的73个内置函数(2)
-
Python基础之最新的73个内置函数(3)
-
Python基础之最新的73个内置函数(4)
-
Python基础之最新的73个内置函数(5)
-
Python基础之最新的73个内置函数(6)
-
Python基础之最新的73个内置函数(7)