跳转到主要内容

又一进口修复工具

项目描述

重新格式化Python导入,以便它们可以通过flake8-import-order。这大致是

  • 每行一个导入

  • 按字母顺序排序,具有对点、大小写敏感性和点名称排序的样式选项

  • 按内置/外部库/当前应用程序(也可以样式控制)分组

  • 删除未使用的导入,使用pyflakes将“未使用导入”警告与实际代码行匹配

  • 删除重复导入(注意这尚未包括对不同导入的重复符号名称)

  • 没有星号导入(例如from <foo> import *);这些被重写为显式名称,通过从每个目标模块导入所有名称,然后删除所有未使用的名称来实现

  • 支持TYPE_CHECKING导入块。

当前程序在 flake8-import-order 的基础上进行封装,以便重用该工具提供的导入分类和排序风格。如果没有提供选项,脚本将直接查找带有 [flake8] 部分的 setup.cfg 文件,并使用 flake8-import-order 参数 "application-import-names""application-package-names""import-order-style" 对导入进行排序,使排序方式与该代码检查器期望的一致。所有单行导入风格,例如 google、cryptography、pycharm,都应该正常工作。

可以对导入进行特殊分类,可以是表示导入不应该被删除的注释“# noqa”,也可以是可选的注释“# noqa nosort”,这将导入放入特殊的“不排序”类别,并将所有“nosort”导入按其原始顺序排列,放在所有已排序导入之后。这可以用于特殊情况,其中几个导入必须以某种顺序相对排列(目前 SQLAlchemy 有两条这样的行)。

应用程序也不会影响位于条件语句或defs内部或以任何方式缩进的导入,除非是 TYPE_CHECKING 导入。这也是 flake8-import-order 的行为;只有位于源文件列零的导入被计算,尽管位于其他定义下方的行上的导入也被计算,这些导入会被移到源文件的顶部部分。

zzzeek,你为什么写这样的程序,有十几个 pep8 导入修复器

我已经看过了很多。我需要一个能够

  • 直接与 flake8-import-order 一起使用,这样我们就能保证导入匹配

  • 具有 shell 能力,不仅仅是 vim 或 sublime text 的插件(Python Fix Imports,免费)

  • 删除未使用的导入,而不仅仅是重新格式化(importanize)

  • 重新格式化导入,而不仅仅是删除未使用的导入(autoflake)

  • 不会遗漏删除未使用的导入,即使它位于多行导入中(autoflake)

  • 将所有导入拆分为单独的行,而不仅仅是当行大于 80 个字符时(importanize)

  • 仍然很简单(因为我们已经超越了最初的“极其简单”基线,因为所有问题最终都不是那么简单),因为(由于 pyflakes 和 flake8-import-order 已经做了大部分工作)这是一个极其简单的任务,这里(仍然)不需要一个庞大的应用程序。

但是关于……isort 呢??

自从我几年前开发了 zimports 并现在将其应用于所有项目以来,isort 已经出现,并且已成为事实上的导入排序器,因为它实际上非常好用,功能强大。它在我的 vscode IDE 中默认开启,并由 pycqa 维护,显然是这个领域的获胜工具。

所以我想 使用 isort,我已经尝试过。我能够将其与我们现在排序导入的方式达到 99% 的相似度,唯一的例外是奇怪的相对导入问题,它仍然不能与 flake8-import-order 相比较(看起来词法排序没有正确工作)。也许我们可以让这部分工作起来,但这不是主要问题。

更大的不足是IIUC它,就像之前提到的“importanize”一样,只是重新格式化了现有的导入。它不会删除未使用的导入,也没有能力将import *扩展为单独的导入,因为它没有查看代码的其他部分。zimports实际上是建立在flake8之上的,这样我们就可以删除未使用的导入,并且它还使用flake8输出以及模块导入路径来扩展“*”导入。我在编写SQLAlchemy的测试脚本时经常使用这个功能,我只是从from sqlalchemy import *开始,然后让zimports清理所有内容。

也许可以保留zimports用于这部分,然后使用isort进行实际的排序。但这样我仍然只是在用zimports,尽管isort在找到需要排序的导入方面确实做得更好(它在方法体内部、在Cython文件内部进行排序,哇),但目前对我来说改变一切并不值得,因为无论如何我仍然需要维护zimports。

TL;DR;是的,去使用isort,我根本不想为其他人支持zimports! :) zimports做了一些我特别喜欢的事情,特别是删除未使用的导入,这对于我的用例来说是完全必要的。

使用方法

脚本可以在没有任何配置的情况下运行,选项如下

$ zimports --help
usage: zimports [-h] [-m APPLICATION_IMPORT_NAMES]
                [-p APPLICATION_PACKAGE_NAMES] [--style STYLE] [--multi-imports]
                [-k] [-kt] [--heuristic-unused HEURISTIC_UNUSED] [--statsonly]
                [-e] [--diff] [--stdout]
                filename [filename ...]

positional arguments:
  filename              Python filename(s) or directories

optional arguments:
  -h, --help            show this help message and exit
  -m APPLICATION_IMPORT_NAMES, --application-import-names APPLICATION_IMPORT_NAMES
                        comma separated list of names that should be
                        considered local to the application. reads from
                        [flake8] application-import-names by default.
  -p APPLICATION_PACKAGE_NAMES, --application-package-names APPLICATION_PACKAGE_NAMES
                        comma separated list of names that should be
                        considered local to the organization. reads from
                        [flake8] application-package-names by default.
  --style STYLE         import order styling, reads from [flake8] import-
                        order-style by default, or defaults to 'google'
  --multi-imports       If set, multiple imports can exist on one line
  -k, --keep-unused     keep unused imports even though detected as unused.
                        Implies keep-unused-type-checking
  -kt, --keep-unused-type-checking
                        keep unused imports even though detected as unused in
                        type checking blocks. zimports does not detect type usage
                        in comments or when used as string
  --heuristic-unused HEURISTIC_UNUSED
                        Remove unused imports only if number of imports is
                        less than <HEURISTIC_UNUSED> percent of the total
                        lines of code. Ignored in type checking blocks
  --statsonly           don't write or display anything except the file stats
  -e, --expand-stars    Expand star imports into the names in the actual
                        module, which can then have unused names removed.
                        Requires modules can be imported
  --diff                don't modify files, just dump out diffs
  --stdout              dump file output to stdout

目前,配置在中消费flake8参数,然后在中添加额外的zimports参数(自0.5.0版本起)——这两个文件的统一将在未来的版本中实现,可能是在flake8增加了toml支持时。

# setup.cfg

[flake8]
enable-extensions = G
ignore =
    A003,
    E203,E305,E711,E712,E721,E722,E741,
    F841,
    N801,N802,N806,
    W503,W504
import-order-style = google
application-import-names = sqlalchemy,test

# pyproject.toml, integrated with black

[tool.black]
line-length = 79
target-version = ['py37']


[tool.zimports]
black-line-length = 79
keep-unused-type-checking = true

# other options:
# multi-imports = true
# keep-unused = true

然后,在大多数干净的源树上的典型运行如下

$ zimports lib/
[Unchanged]     lib/sqlalchemy/inspection.py (in 0.0058 sec)
[Unchanged]     lib/sqlalchemy/log.py (in 0.0221 sec)

...

[Unchanged]     lib/sqlalchemy/orm/attributes.py (in 0.2152 sec)
[Unchanged]     lib/sqlalchemy/orm/base.py (in 0.0363 sec)
[Writing]       lib/sqlalchemy/orm/relationships.py ([2% of lines are imports] [source +0L/-2L] [3 imports removed in 0.3287 sec])
[Unchanged]     lib/sqlalchemy/orm/strategies.py (in 0.2237 sec)

程序有两种通用使用模式。一种是对已有整洁导入的应用程序的日常使用。在这样应用程序的源文件上运行zimports应该不会产生任何变化,除非是最近编辑过的源文件,可能需要对导入进行一些排序。这种使用模式类似于Black,你可以运行“zimports .”并找到需要调整的文件,而其他文件则保持不变。

另一种使用模式是对导入未组织的应用程序进行前端清理。在这种使用模式下,目标是使源文件被清理,以便可以直接运行zimports而无需对文件进行任何修改,包括所有必要的导入要么被本地使用,要么被标记为不删除。

在这个阶段可能会出现的问题包括,某些导入未使用且应该被删除,而其他看似未使用的导入实际上仍然被程序的另一部分使用。另一个问题是,在复杂情况下改变导入的顺序可能会因为创建无法解决的导入循环而使应用程序无法运行。最后,一些程序使用了import *,导入了一长串未知部分中的一些名称。提供了--keep-unused--heuristic-unused--expand-stars选项来帮助处理这些问题,直到代码可以完全重排,这样运行zimports就不再产生变化。

在某些应用程序中,可能存在明显未使用的导入,这些导入是从外部导入的,这个问题可能比较突出。为了允许那些在本地未使用的导入保留在源文件中,__all__ 部分的符号将不会被移除,同样,跟有 `` # noqa`` 注释的导入也不会被移除。这两种技术可以应用于那些在其他模块中使用但未在源文件中引用的导入。对于那些很少见的情况,即某些导入确实需要非常具体的导入顺序才能工作,这些导入可以跟一个 `` # noqa nosort`` 注释,这样这些行就会被添加到所有导入的末尾的特殊分组中,在那里它们不会被移除,并且它们之间的顺序将会被保留。

当前程序要求您至少传递一个文件名或目录名作为参数。它也没有 Black 具有的文件缓存功能,这允许它只查看自上次运行以来已更改的文件。计划是检查它是否在一个 git 仓库中,如果没有给出文件名,它将运行要提交的文件。

作为 git 钩子使用

zimports 可以与 pre-commit git 钩子框架一起使用。要添加插件,将以下内容添加到您的 .pre-commit-config.yaml 文件中。注意,rev: 属性指的是要使用的 zimports 的 git 标签或修订号,例如 "master""0.1.3"

repos:
-   repo: https://github.com/sqlalchemyorg/zimports/
    rev: v0.4.5
    hooks:
    -   id: zimports

项目详情


下载文件

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

源分发

zimports-0.6.1.tar.gz (56.2 kB 查看哈希值)

上传时间

构建分发

zimports-0.6.1-py3-none-any.whl (20.5 kB 查看哈希值)

上传时间 Python 3

由以下支持

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