【问题标题】:The "version" entry in the metadata of setup.cfg is being ignoredsetup.cfg 元数据中的“版本”条目被忽略
【发布时间】:2021-12-19 23:10:42
【问题描述】:

我想编写一个新的 Python 包,我想通过 PyPI 提供它。 过去我总是使用setup.py。但这次我决定拥抱新的 使用setup.cfg 的最佳实践 反而。所以我开始阅读一些文档,主要是 https://setuptools.pypa.io/en/latest/userguide/declarative_config.html.

我还决定使用pyscaffold 来生成文件。 pyscaffold 为我生成了一个 setup.cfg 文件,我添加了(仅用于测试 目的)version = 5.1.1metadata 部分下,如 上面的文档。

为方便起见,我使用 anaconda 并创建了一个新的空环境:

$ python --version
Python 3.9.7
$  pip list
...
PyScaffold                    4.1.1
setuptools                    58.4.0
setuptools-scm                6.3.2
wheel                         0.37.0

但是当我执行pip install -e . 时,版本被忽略并且pip 分配了一个 不同的:

$ pip install -e .
Obtaining file:///tmp/test_package
  Installing build dependencies ... done
  Checking if build backend supports build_editable ... done
  Getting requirements to build wheel ... done
  Preparing metadata (pyproject.toml) ... done
Installing collected packages: test-package
  Attempting uninstall: test-package
    Found existing installation: test-package 0.0.post1.dev10+g3ed39c8.d20211106
    Uninstalling test-package-0.0.post1.dev10+g3ed39c8.d20211106:
      Successfully uninstalled test-package-0.0.post1.dev10+g3ed39c8.d20211106
  Running setup.py develop for test-package
Successfully installed test-package-0.0.post1.dev1+g228b46c

https://stackoverflow.com/a/27077610/1480131 提到 setuptools 版本 30.3.0 支持将元数据放入setup.cfg,我用的是58.4.0,这么多 更新的版本。

我还测试了不同的格式,比如version = file:VERSION.txt,但是 也没有帮助,pip 只是忽略了version 条目。

我错过了什么?我做错了什么?

我准备了一个带有文件的小型 git repo,以便能够重现 错误:https://github.com/shaoran/test_package 有没有人不一样 结果?

【问题讨论】:

    标签: python pip setuptools


    【解决方案1】:

    这是因为pyscaffold 生成了一个使用setuptools-scm 进行版本检测的项目。当使用setuptools-scm 时,版本不是从version 元数据中读取的,而是从存储库标签中解析的。 0.0.post1.dev10+g3ed39c8.d20211106的版本可以这样解读:

    • 0.0.post1 - 虚拟版本,因为您在 repo 中还没有任何标签;
    • dev10 - 你有十个不包含在任何版本标签中的提交(基本上是你自上次标记以来所做的提交数量);
    • g3ed39c8 - 您安装的提交的短哈希是 3ed39c8(前缀 g 表示它是一个 Git 存储库);
    • d20211106 - d 表示您从脏状态安装(Git 版本的一些文件被修改),其余的只是时间戳。

    如果您想使用来自setup.cfg 的版本元数据,只需将setuptools-scm 激活放入setup.py

    if __name__ == "__main__":
        try:
            setup()
        except:
            ...
    

    然后您也可以清理 pyproject.toml,尽管这不是明确要求的:

    [build-system]
    requires = ["setuptools>=46.1.0", "wheel"]
    build-backend = "setuptools.build_meta"
    

    如果您想继续使用setuptools-scm(IMO 是一个很好的工具,可以防止您意外发布具有相同版本但内容不同的 dist),那么只需添加一个新标签即可开始版本控制:

    $ git tag -a 5.1.1 -m 'start versioning'
    

    如果您有一个干净的 repo 状态(没有修改过的文件),pip install -e . 将立即安装 5.1.1 版本。否则,你会得到一个带有后缀的 5.1.1。

    使用setuptools-scm 的巧妙之处在于,setup.cfg 中的版本元数据被忽略了,因此您不必自己碰它,可以安全地删除version = 5.1.1 行。

    【讨论】:

    • 哦,我明白了,这很有道理。我稍后会测试。
    • 我还有一个问题:当没有可用的.git 目录时,setuptools-scm 如何推断版本?例如在 sdist 或自制 tarball 上?
    • 如果无法检测到存储库,setuptools-scm 会假定一个解压缩的源 dist,并将检查带有元数据的 PKG-INFO 文件是否位于根目录中。如果该文件不存在,则会引发错误并且安装将失败。所以 sdists 很好,但是没有 .git 索引的自制 tarball 本身不是。但是,自定义 tarball 可安装很容易 - 只需运行 python setup.py egg_info 并将 project.egg-info/PKG-INFO 复制到根目录即可。
    • 感谢您的信息。
    猜你喜欢
    • 2021-03-07
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多