检查您的轮子是否包含正确的内容
项目描述
将正确文件放入您的轮子中很复杂,有时我们会出错,发布包含__pycache__目录或tests/的轮子。我们必须在将轮子上传到PyPI之前手动检查每个轮子的内容吗?为什么不让我们这个程序来检查呢?只需在您的轮子上运行check-wheel-contents,如果检测到一些常见的错误和错误,它将失败并通知您。以下是错误及其常见原因和相应的修复方法。
安装
check-wheel-contents 需要Python 3.7或更高版本。只需使用Python 3的pip来安装check-wheel-contents及其依赖项。
python3 -m pip install check-wheel-contents
用法
check-wheel-contents [<options>] <wheel or directory> ...
check-wheel-contents 可以接受零个或多个参数,每个参数指向要分析的wheel文件或包含要分析wheel文件的目录。如果给定的wheel文件在任何检查中失败,程序将打印出每个检查的消息以及(如果适用)导致检查失败的文件路径列表,并退出程序,状态码非零。如果wheel文件通过所有检查,程序将打印 {wheel文件路径}: OK。
选项
- -c FILE, --config FILE
从指定的文件读取配置;下面有更多信息
- --no-config
禁用从配置文件读取
- -h, --help
显示用法信息并退出
- -V, --version
显示程序版本并退出
剩余的选项可以在命令行或配置文件中指定;有关更多信息,请参阅“配置选项”。
配置
配置文件
如果命令行上指定了配置文件,使用--config选项,check-wheel-contents将从该文件读取配置。具有.toml扩展名的文件被解析为TOML文件,配置从tool.check-wheel-contents表读取。所有其他文件被解析为INI文件,其配置从[check-wheel-contents]部分读取(除非文件名为setup.cfg,在这种情况下使用[tool:check-wheel-contents]部分代替)。
如果命令行上没有指定配置文件,程序将开始搜索名为pyproject.toml、tox.ini、setup.cfg、check-wheel-contents.cfg或.check-wheel-contents.cfg的文件,从当前目录开始,向上搜索。文件将使用与--config选项相同的规则进行读取,并使用列表中包含适当部分的第一个文件。搜索停止一旦找到包含任何命名文件的目录,即使这些文件中没有一个包含相关部分。
配置选项
以下选项可以在命令行或配置文件中设置。命令行上的设置会覆盖配置文件中的设置。配置文件中的未知键将被忽略。
- --select <checks> / select = <checks>
仅选择/启用给定的检查。<checks>是由逗号分隔的检查ID和/或检查ID前缀列表(用于选择以给定前缀开始的检查)。
在TOML文件中,<checks>也可以作为字符串列表给出。
默认情况下,选择所有检查(尽管在某些选项给出或未给出时,某些检查可能是无效的)。
- --ignore <checks> / ignore = <checks>
忽略/跳过指定的检查。 <checks> 是一个由逗号分隔的检查ID列表和/或检查ID前缀列表(用于忽略所有以给定前缀开头的检查)。
在TOML文件中,<checks>也可以作为字符串列表给出。
默认情况下,不忽略任何检查。
- --toplevel <names> / toplevel = <names>
告诉 check-wheel-contents 检查 wheel 的顶级库条目是否等于由逗号分隔的列表 <names> 中的名称集;例如,--toplevel foo.py,bar/ 检查 foo.py、bar 以及没有其他内容位于 wheel 的顶级。目录名称后面的反斜杠是可选的。
在 TOML 文件中,<names> 可以作为字符串列表提供。
此选项禁用检查 W009 并启用检查 W201 和 W202。它也被检查 W005 用于防止在故意用作顶级名称的常见名称上失败。
- --package <path> / package = <paths>
告诉 check-wheel-contents 检查 wheel 的库部分是否包含以 <path> 为根的文件树。
命令行中给出的路径相对于当前工作目录解析。配置文件中给出的路径相对于包含配置文件的目录解析。
在命令行中,可以通过多次提供 --package 来指定多个路径。在配置文件中,可以通过将 package 设置为逗号分隔的路径列表来指定多个路径。在 TOML 文件中,<paths> 可以作为字符串列表提供。
此选项禁用检查 W009 并启用检查 W101 和 W102。
- --src-dir <path> / src_dir = <paths>
与 --package 相同,但只检查 <path>(它必须是一个目录)的内容,而不是 <path> 本身,与 wheel 的内容进行比较。
- --package-omit <patterns> / package_omit = <patterns>
忽略 --package 或 --src-dir 参数中与逗号分隔的列表 <patterns> 中的任何 glob 模式匹配的文件和目录。被忽略的文件将不会在检查 W101 的 wheel 中查找,如果其中任何文件出现在 wheel 中,它将导致检查 W102 失败。
在 TOML 文件中,<patterns> 可以作为字符串列表提供。
默认忽略的模式集是 .*, CVS, RCS, *.pyc, *.pyo, *.egg-info。
检查
注意:除非另有说明,否则这里列出的常见原因及其修复是针对使用 setuptools 开发的项目特定的。使用 flit 和 poetry 等其他工具的用户必须查阅这些项目的文档以解决失败的检查。
注意:在用 setuptools 重建 wheel 时,首先删除 build/ 目录是一个好主意。(这可以通过单个命令 python setup.py clean --all bdist_wheel 完成。)不这样做可能会导致各种检查继续失败或开始出现新的失败。
W001 — 轮包含 .pyc/.pyo 文件
如果轮中包含任何具有 .pyc 或 .pyo 扩展名的文件,则此检查将失败。这样的文件是编译后的 Python 字节码文件,它们不属于轮,因为(a)它们是平台特定的,因此对许多用户来说没有用,并且(b)pip 会自动为轮中的 .py 文件生成 .pyc 文件。
常见原因
您的 include_package_data 设置为 True,您的 MANIFEST.in 包含 graft packagename 或 recursive-include packagename *,并且类似的 global-exclude *.py[co] 行要么在 MANIFEST.in 中缺失,要么位于错误的位置。
解决方案:确保 global-exclude *.py[co] 出现在您的 MANIFEST.in 文件中 在 所有 include、recursive-include、global-include 和 graft 命令之后。
您在 setup.cfg 中设置了 [install]optimize = 1(或者,等价地,在 setup.py 中设置了 options={"install": {"optimize": "1"}})。
解决方案:删除此设置。它仅在使用 setup.py install 时有用,但该命令已被弃用。
W002 — 轮包含重复文件
如果轮中任何两个文件的内容相同,则此检查将失败。常见的文件内容,例如空文件或仅包含“# -*- coding: utf-8 -*-”行的文件,将排除在此检查之外。
常见原因
(与构建工具无关) 您在实际上想重命名文件或目录时复制了文件或目录。
解决方案:删除文件或目录的原始副本。
您构建了一个轮,重命名了一个文件或目录,然后在删除 build/ 目录之前再次构建了轮。
解决方案:删除 build/ 目录并重新构建轮。
W003 — 轮包含非模块在库顶层
如果轮的纯库或 platlib 部分的根目录中存在任何非 Python 模块或 .pth 文件,则此检查将失败。非模块应在轮的其他位置
许可证和类似通知应使用轮的 *.dist-info 目录中的 wheel 的 license_files 选项存储。
包数据/资源文件应位于包目录内,以便可以使用 pkg_resources 或 importlib-resources 定位。
项目 README 应已用作项目的 long_description,在这种情况下,README 的文本已包含在轮的 *.dist-info/METADATA 文件中。因此,不需要在轮的库部分存储 README。
W004 — 模块未位于可导入的路径上
如果轮的纯库或 platlib 部分中的任何 Python 模块由于一个或多个路径组件不是有效的 Python 标识符而无法导入,则此检查将失败。
常见原因
(与构建工具无关) 您为包目录或模块命名时包含了不允许在 Python 标识符中使用的连字符或其他字符。
解决方案:重命名受影响的目录或模块以删除受影响的字符,最可能的方法是将它更改为下划线。
(构建工具无关) 您给包目录或模块取了一个Python关键字的名称。
解决方案:重命名有问题的目录或模块。
(构建工具无关) 您的包包含由 alembic 或 Django 生成的数据库迁移文件,这些文件(可能)以数字开头,因此没有有效的Python标识符作为名称。
解决方案:忽略此检查。(目前尚未实现仅针对特定文件忽略检查。)
W005 — 轮包含库中常见的顶级名称
如果任何文件或目录命名为 .eggs、.nox、.tox、.venv、app、build、cli、data、dist、doc、docs、example、examples、lib、scripts、src、test、tests 或 venv,并且位于轮的 purelib 或 platlib 部分的根目录,则此检查失败。这些名称通常用于不属于轮的目录(除了 src,其内容属于轮但本身不属于轮)。项目应仅使用类似项目名称的顶级名称;使用通用名称会导致不同项目的文件在安装时相互覆盖。
如果设置了 --toplevel 选项,则该选项中列出的名称不会导致此检查失败。
常见原因
对于 src:您未能正确设置 src/ 布局。 src 不应包含 __init__.py 文件,where='src' 需要传递给 setup.py 中的 setuptools.find_packages(),并且 package_dir={"": "src"} 需要传递给 setup.py 中的 setup()。
对于除 src 之外的目录:目录包含一个 __init__.py 文件,并且目录未在 setup.py 中 setuptools.find_packages() 的 exclude 参数中列出。
解决方案:在传递给 find_packages() 的 exclude 参数的列表中包含 'DIRNAME' 和 'DIRNAME.*'。
对于除 src 之外的目录:目录在 find_packages() 的 exclude 参数中列出,但未包含 'DIRNAME.*',并且目录的子目录包含一个 __init__.py 文件。
解决方案:在传递给 find_packages() 的 exclude 参数的列表中包含 'DIRNAME.*'。
您实际上希望将测试或示例包含在您的轮中。
解决方案:将测试或任何内容移动到主包目录内部(例如,将 tests/ 移动到 somepackage/tests/),这样它们在安装时就不会与其他项目的文件冲突。
您实际上正在制作一个名称在列表中的包。
解决方案:在 --toplevel 选项中包含您的包名称,这样 check-wheel-contents 就知道它应该在那里。
W006 — __init__.py 在库顶级目录下
如果 wheel 的 purelib 或 platlib 部分根目录下存在名为 __init__.py 的文件,则此检查失败。 __init__.py 文件只应放在包目录内部,而不是在安装的根目录。
常见原因
您未能正确设置 src/ 布局。 src 不应包含 __init__.py 文件,where='src' 需要在 setup.py 中的 setuptools.find_packages() 传递,并且 package_dir={"": "src"} 需要在 setup.py 中的 setup() 传递。
您在项目根目录下创建了一个 __init__.py 文件,并在 setup.py 中设置了 packages='.'。
解决方案:正确配置项目包。对于单文件模块,将它们的名字列表(不带 .py 扩展名)传递给 setup() 的 py_modules 参数。对于包模块(目录),将它们的名称及其子包的虚名称列表(可能通过调用 setuptools.find_packages() 获取)传递给 packages。
W007 — Wheel 库为空
如果 wheel 的 purelib 或 platlib 部分没有文件,则此检查失败。
常见原因
您的项目由单个 .py 模块组成,但您在 setup.py 中使用 packages 关键字声明了它。
解决方案:必须使用 py_modules 关键字在 setup() 中声明单文件模块。传递不带 .py 扩展名的单文件模块名称列表。
您正在使用 setuptools.find_packages() 列出用于 setup() 的包,但您的包不包含 __init__.py 文件。
解决方案:在您的包中创建一个 __init__.py 文件。如果您无法这样做,因为您正在构建一个命名空间包,请使用 setuptools.find_namespace_packages() 而不是 find_packages()。确保适当地设置参数,以便函数仅找到您的主要包;更多信息请参阅文档。
您故意创建一个只包含脚本、头文件或其他数据文件的 wheel。
解决方案:忽略此检查。
W008 — Wheel 为空
如果 wheel 除了 *.dist-info 元数据目录外没有其他文件,则此检查失败。它比 W007 更严格,旨在针对创建仅包含脚本、头文件和其他数据文件的 wheel 的用户,他们需要忽略 W007。
常见原因
与 W007 相同的原因
您故意创建了一个空轮,其主要功能是安装一系列依赖项。
解决方案:忽略此检查。
W009 — Wheel 包含多个顶级库条目
如果 wheel 的 purelib 和 platlib 部分之间包含多个顶级条目(不包括 .pth 文件以及以下划线开头的文件和目录),则此检查失败。这通常表明在包装项目时出现了错误,因为很少有项目想要分发带有多个顶级模块或包的代码。
如果命令行或配置文件中提供了 --toplevel、--package 或 --src-dir 选项,则禁用此检查。
常见原因
您构建了一个轮子,重命名了顶层文件或目录,然后在没有先删除 build/ 目录的情况下再次构建轮子。
解决方案:删除 build/ 目录并重新构建轮。
您在 setup.py 中使用 setuptools.find_packages(),您的项目包含多个包含 __init__.py 文件的目录,并且除了主包之外,这些目录中的一个或多个没有列入 find_packages() 的 exclude 参数。
解决方案:将除了主包之外项目中所有包含 __init__.py 的目录的列表传递给 find_packages() 的 exclude 参数。为了正确排除,每个目录 DIRNAME 应对应于列表中的两个元素,'DIRNAME' 和 'DIRNAME.*',以确保目录及其所有子目录被排除。
您故意创建了一个包含多个顶层 Python 模块或包的轮子。
解决方案:使用 --toplevel 选项让 check-wheel-contents 知道预期哪些顶层条目。
W010 — 顶层库目录不包含 Python 模块
如果轮子的纯库或平台库部分根目录下的目录树不包含 Python 模块,则此检查失败。排除 *-stubs 目录。
W101 — 轮子库在包树中缺少文件
此检查仅在设置 --package 或 --src-dir 选项时启用。如果 --package 或 --src-dir 的参数中的路径在轮子的纯库或平台库部分中未出现,则检查失败。从检查中排除空目录和与通过 --package-omit 或其默认值指定的任何模式匹配的本地文件和目录。
注意,此检查仅检查文件路径,即文件和目录的名称。不检查文件内容。
例如,给定以下本地树
/usr/src/project/ ├── foo/ │ ├── .gitignore │ ├── __init__.py │ └── foo.py └── src/ ├── bar/ │ ├── __init__.py │ ├── bar.py │ ├── empty/ │ └── quux/ │ └── data.dat └── bar.egg-info/ └── PKG-INFO
如果提供了选项 --package /usr/src/project/foo 和 --src-dir /usr/src/project/src,并且将 --package-omit 留在其默认值,那么 check-wheel-contents 将在轮子中查找以下路径,如果其中任何一个未出现在纯库或平台库部分中,则检查失败
foo/__init__.py foo/foo.py bar/__init__.py bar/bar.py bar/quux/data.dat
请注意,foo/.gitignore 和 src/bar.egg-info 被排除在此检查之外(并且如果它们出现在轮子中,将导致检查 W102 失败)。空目录完全忽略。
常见原因
对于 Python 文件:您未能将项目的所有包和子包传递给 setup() 的 packages 参数。如果您使用 setuptools.find_packages(),所有包和子包都需要包含 __init__.py 文件。
对于非 Python 文件:您未能适当地声明项目包数据。有关如何执行此操作的说明,请参阅 setuptools 文档。
W102 — 轮子库包含包树中不存在的文件
此检查仅在设置 --package 或 --src-dir 选项时启用。如果 wheel 的 purelib 或 platlib 部分包含任何不在用 --package 或 --src-dir 指定的文件树中存在的路径的文件,则此检查失败。
注意,此检查仅检查文件路径,即文件和目录的名称。不检查文件内容。
例如,给定 W101 下的示例中的本地树和选项,如果 wheel 的 purelib 或 platlib 部分包含除以下文件之外的任何文件,则此检查将失败:
foo/__init__.py foo/foo.py bar/__init__.py bar/bar.py bar/quux/data.dat
注意,与用 --package-omit 或其默认值指定的任何模式匹配的文件和目录在本地树中将被忽略,因此 wheel 中具有这些名称的任何条目都会导致此检查失败。空目录完全忽略。
常见原因:查看 W009 的常见原因
W201 — Wheel 库缺少指定的顶级条目
此检查仅在设置 --toplevel 选项时启用。如果 --toplevel 选项中给出的一个或多个名称不出现在 wheel 的 purelib 或 platlib 部分的根部,则此检查失败。
常见原因:查看 W007 的常见原因
W202 — Wheel 库有未声明的顶级条目
此检查仅在设置 --toplevel 选项时启用。如果 wheel 的 purelib 或 platlib 部分的根部有文件或目录未列入 --toplevel 选项中,则此检查失败。*.pth 文件在此检查中将被忽略。
常见原因:查看 W009 的常见原因
项目详情
下载文件
下载您平台上的文件。如果您不确定选择哪个,请了解更多关于 安装包 的信息。
源分发
构建分发
check-wheel-contents-0.6.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 64419c4e150e1de6f2d0bce7d4c7668eebfac127f0274014dd1a56ba07525364 |
|
MD5 | b7d7a45797e4da9cd49d4f7334ef350b |
|
BLAKE2b-256 | 530630db4d32c297d90ca10b95bf3b5640898d894d9ed77cb53aad493e279e34 |
check_wheel_contents-0.6.0-py3-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 5c0e510d3e8e5f0f9207a7e7b0c2a8ae7bbc7044117712be667821da |
|
MD5 | 3d3b9c306952b9d777d3773cf316a2cd |
|
BLAKE2b-256 | 0a0d5228a8651247449d11a24ed72ff18413283fd34b8fdee0db60cc4ba950 |