跳转到主要内容

将Python项目的 %-格式化字符串转换为f-字符串的命令行工具。

项目描述

flynt - 字符串格式转换器

Actions Status License: MIT PyPI Downloads Code style: black

flynt 是一个命令行工具,可自动将项目的Python代码从旧的 "%-格式化" 和 .format(...) 字符串转换为Python 3.6+的 "f-字符串"。

F-字符串

它们不仅比其他格式化方法更易于阅读、更简洁、更不容易出错,而且速度也更快!

安装

pip install flynt。它需要Python版本3.7+。

使用方法

Flynt 将修改其运行的文件。在运行flynt之前将您的项目添加到版本控制系统。

运行: flynt {source_file_or_directory}

  • 对于单个文件,它将执行 'f-stringify':替换此文件中所有适用的字符串格式(文件将被修改)。
  • 对于文件夹,它将递归搜索文件夹并 f-stringify 它找到的所有 .py 文件。它跳过一些硬编码的文件夹名称: blacklist = {'.tox', 'venv', 'site-packages', '.eggs'}

它将运行的代码转换为Python 3.6+,因为 "f-字符串" 是从3.6版本开始引入的。

命令行选项

flynt -h 的输出

usage: flynt [-h] [-v | -q] [--no-multiline | -ll LINE_LENGTH]
             [-d | --stdout] [-s] [--no-tp] [--no-tf] [-tc] [-tj]
             [-f] [-a] [-e EXCLUDE [EXCLUDE ...]] [--version]
             [src ...]

flynt v.0.78

positional arguments:
  src                   source file(s) or directory (or a single `-`
                        to read stdin and output to stdout)

optional arguments:
  -h, --help            show this help message and exit
  -v, --verbose         run with verbose output
  -q, --quiet           run without outputting statistics to stdout
  --no-multiline        convert only single line expressions
  -ll LINE_LENGTH, --line-length LINE_LENGTH
                        for expressions spanning multiple lines,
                        convert only if the resulting single line
                        will fit into the line length limit. Default
                        value is 88 characters.
  -d, --dry-run         Do not change the files in-place and print
                        the diff instead. Note that this must be
                        used in conjunction with '--fail-on-change'
                        when used for linting purposes.
  --stdout              Do not change the files in-place and print
                        the result instead. This argument implies
                        --quiet, i.e. no statistics are printed to
                        stdout, only the resulting code. It is
                        incompatible with --dry-run and --verbose.
  -s, --string          Interpret the input as a Python code snippet
                        and print the converted version. The snippet
                        must use single quotes or escaped double
                        quotes.
  --no-tp, --no-transform-percent
                        Don't transform % formatting to f-strings
                        (default: do so)
  --no-tf, --no-transform-format
                        Don't transform .format formatting to
                        f-strings (default: do so)
  -tc, --transform-concats
                        Replace string concatenations (defined as +
                        operations involving string literals) with
                        f-strings. Available only if flynt is
                        installed with 3.8+ interpreter.
  -tj, --transform-joins
                        Replace static joins (where the joiner is a
                        string literal and the joinee is a static-
                        length list) with f-strings. Available only
                        if flynt is installed with 3.8+ interpreter.
  -f, --fail-on-change  Fail when changing files (for linting
                        purposes)
  -a, --aggressive      Include conversions with potentially changed
                        behavior.
  -e EXCLUDE [EXCLUDE ...], --exclude EXCLUDE [EXCLUDE ...]
                        ignore files with given strings in it's
                        absolute path.
  --version             Print the current version number and exit.

成功运行样本输出

38f9d3a65222:~ ikkamens$ git clone https://github.com/pallets/flask.git
Cloning into 'flask'...
...
Resolving deltas: 100% (12203/12203), done.

38f9d3a65222:open_source ikkamens$ flynt flask
Running flynt v.0.40

Flynt run has finished. Stats:

Execution time:                            0.789s
Files modified:                            21
Character count reduction:                 299 (0.06%)

Per expression type:
Old style (`%`) expressions attempted:     40/42 (95.2%)
`.format(...)` calls attempted:            26/33 (78.8%)
F-string expressions created:              48
Out of all attempted transforms, 7 resulted in errors.
To find out specific error messages, use --verbose flag.

_-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_._-_.
Please run your tests before committing. Did flynt get a perfect conversion? give it a star at:
~ https://github.com/ikamensh/flynt ~
Thank you for using flynt. Upgrade more projects and recommend it to your colleagues!

38f9d3a65222:~ ikkamens$

pre-commit钩子

要确保所有格式化字符串始终转换为f-字符串,您可以将flynt添加到您的 pre-commit 钩子。

将新部分添加到 .pre-commit-config.yaml

-   repo: https://github.com/ikamensh/flynt/
    rev: ''
    hooks:
    -   id: flynt

这将运行flynt在提交之前对所有修改的文件进行操作。

您可以通过添加 # noqa [: anything else] flynt [anything else] 来跳过某些行的转换。

配置文件

从 v0.71 版本开始,flynt 可以通过每个项目的 pyproject.toml 文件进行配置。使用与 CLI 相同的参数,并将它们添加到 [tool.flynt] 部分。CLI 参数优先于配置文件。您还可以使用位于 Unix 的 ~/.config/flynt.toml 或 Windows 的 ~/.flynt.toml 的 toml 文件全局配置。

关于

在此了解 f-strings

在工作项目中进行了一段时间的反复重构后,即使只覆盖了 50% 的 f-string 候选者,我也意识到某些地方可以自动化。而且与 ast 模块一起工作也很有趣。

转换的危险

格式化字符串不保证与转换前的完全相同。

'%s' % var 转换为 f'{var}'。在 var 是一个只有一个元素的元组时,这可能会与原始行为不同 - 在这种情况下,%s 显示元素,而 f-string 显示元组。示例

foo = (1,)
print('%s' % foo) # prints '1'
print(f'{foo}')   # prints '(1,)'

此外,一些参数会导致字符串格式化抛出异常。f-strings 与之前格式化不一致的一个例子是 %d 与 {:d} - 新格式不再接受浮点数。尽管大多数情况都通过将格式化说明符转换为 f-string 格式来解决,但精确的异常行为也可能不同。请确保您有足够的测试覆盖率。

其他鸣谢/依赖/链接

  • astor 用于将转换后的 AST 转换回代码。
  • 感谢 pyddf 的人在 2019 年春季黑客马拉松期间的支持、建议和参与,特别是 Holger Hass、Farid Muradov、Charlie Clark。
  • black 部分复制了查找 pyproject.toml 并解析它的逻辑

项目详情


发布历史 发布通知 | RSS 源

下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解更多关于安装包的信息

源分发

flynt-1.0.1.tar.gz (23.2 kB 查看哈希值)

上传时间

构建分发

flynt-1.0.1-py3-none-any.whl (33.3 kB 查看哈希值)

上传时间 Python 3

支持者

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误日志 StatusPage StatusPage 状态页面