当前位置: 首页 > 后端技术 > Python

Python官方团队在打包项目踩过的坑

时间:2023-03-25 23:49:34 Python

华夏猫鱼:打包系列的第三篇翻译,是全网关于这个话题最详细(也是最高级)的系列。原作者是Python官方打包团队成员,virtualenv和tox项目的维护者,setuptools和pip项目的贡献者。英语|Python打包-成长的烦恼【1】原创|BERNATGABOR翻译|猫下豌豆花免责声明:本文经原作者授权翻译,转载请保留原始出处,请勿用于商业或非法用途。在前两篇文章中,我介绍了Python的包的类型以及它们是如何构建的,尤其是PEP-517/518。虽然这些更改主要是为了使打包更加稳健,但我们在实施和发布时遇到了一些问题。这篇文章将介绍一部分,希望提供经验教训,并提出一些有趣的问题以在未来解决。查看PEP-517和PEP-518中的变化,可以说构建后端(即setuptools、flit)只是通过Python模块提供功能接口。大部分繁重的工作都在构建前端,它需要生成隔离的Python,然后以新的方式调用构建后端。如今,当我们谈论构建前端时,我们的选择主要是pip或poetry(对于开发人员来说是tox)。这些项目由社区维护,由少数活跃的开发人员在业余时间维护。他们并没有因此获得报酬,而且需要仔细考虑这些工具的多种使用方式。考虑到这一点,从PEP首次被接受到实施花了将近两年的时间也就不足为奇了。规划、测试和实施已经在后台进行了一年多。但是尽管做了所有的准备,第一个版本还是不可避免地破坏了一些包,而且在大多数情况下,人们做了一些让维护者感到惊讶的事情。让我们尝试了解其中的一些示例以及它们是如何解决的。照片由MinkMingle/Unsplash拍摄-准备就绪!PEP-518此PEP介绍了TOML文件格式。[2]一种专门为方便读/写配置而创建的格式。尽管打包配置是在构建系统部分下描述的,但其他工具可以自由地将它们的配置放在tool:name部分下,因为它们在PyPi命名空间中有名称。各种工具立即开始利用这一点(例如Towncrier[3]、black[4]等)。当pip18.0(2018年7月22日发布)[5]添加对PEP-518包的支持时,使用pyproject.toml是最早出现的问题,因为PEP-518要求所有带有pyproject.toml的包必须指定build-backend部分。但是,包只在其他项目的配置文件中预先使用它,并且由于它们没有预先指定它,当pip遇到这些文件时,它会引发一个错误,指出pyproject.toml文件无效。PEP-517pipwheel缓存问题pip在PEP-517世界中的安装方式是首先生成一个wheel然后将其提取。要进入PEP-517世界,必须指定build-backend密钥,否则每个语句都需要回退到使用setup.py命令。当pip构建轮子时,它默认通过缓存系统进行构建。这是一种提速机制,这样当多个虚拟环境需要同一个轮子的时候,我们不用重新构建它,而是重用它。PEP-517wheel的构建操作也利用了这种机制。但是,当您禁用缓存时,这会变得很麻烦。因为没有可用于构建轮子的目标文件夹。所以构建过程会失败,问题见附录。[6]这个问题虽然很早就出现了,但这是由于大多数CI系统在启用此选项的情况下运行。仅仅一天后,pip19.0.1就解决了这个问题。pyproject.toml不包含在setuptools中事实证明,构建后端实际上不仅仅是公开其API,如PEP-517中所述。后端还需要确保将pyproject.toml附加到构建的源包中,否则用户机器上的构建后端将无法使用它。setuptools1650[7]将为setuptools[8]修复此问题,在早期版本中只需在MANIFEST.in中指定pyproject.toml。照片由JorgeZapata/Unsplash拍摄——什么?!从setup.py导入构建的包永远不会发生另一个意想不到的问题是从setup.py中导入包时。按照惯例,包的版本既作为包的元数据(setup.py中的setuptools,setup函数的版本参数)公开,也作为包根目录中的__version__变量公开。可以在两个地方指定变量的内容,但要使它们保持同步很麻烦。一种解决方法:许多包将它放在根目录下的version.py中,然后从setup.py和包根目录导入它,例如frommypy.versionimport__version__asversion。这是可行的,因为当有人调用Python脚本时,当前工作目录会自动添加到sys.path(因此您可以导入它下面公开的内容)。但是,这种添加当前工作目录的行为从来都不是强制性的,并且在通过pythonsetup.pysdist调用构建时会产生更多的副作用。由于此行为是一种副作用(无法保证),因此从setup.py导入的所有项目都应在构建开始时明确地将脚本文件夹添加到sys路径。是否应该在打包期间(尚未构建/分发时)导入已编译的包是有争议的(尽管Python打包组倾向于这样做)。但是,当setuptools实际上通过setuptools.build_meta公开其接口时,它选择不将当前工作目录添加到系统PATH。PEP从来不需要后端来进行此添加,因为大多数构建后端(本质上是声明性的)根本不需要它。因此,此类功能被认为是前端的责任。setuptools认为,如果用户需要这个功能,应该在setup.py中明确说明,并提前在sys.path中手动添加相应的路径。为了简化pip代码库,pip决定加入PEP-517,让大家把pyproject.toml添加到setuptools后端。现在由于这个问题,甚至没有选择加入PEP-517的软件包也会崩溃。为了解决这个问题,setuptools添加了一个新的构建后端(setuptools.build_meta:__legacy__),当没有指定构建后端时,前端可以将其用作默认值;当项目添加构建后端密钥时,它们的setup.py也必须更改为将源根添加到sys.path或避免从源根导入。另一个有趣的问题出现在自举后端,它拥有更紧密的用户群,但暴露了一个有趣的问题。如果我们不想使用轮子,只能通过源码分发来设置;我们应该如何解决“如何提供构建后端的构建后端”的问题呢?例如,setuptools将自身与setuptools打包在一起。也就是说,当setuptools通过PEP-517指定它时,构建前端将进入无限循环。要安装pugs库,它首先会尝试创建一个隔离环境。这个环境需要setuptools,所以搭建前端需要造轮子来满足。wheelbuild本身将触发隔离环境的创建,而这又取决于setuptools。如何打破这个循环?要求所有构建后端必须作为轮子公开?允许后端自行构建?这些自建后端是否应该背负依赖?各种观点、正反双方争论已久,有兴趣的请进入pythonDiscourseboard[9]发表你的看法。照片由SneakyElbow/Unsplash拍摄-我们是帮派总结打包很难。在我的业余时间完善一个打包系统,允许用户在打包过程中编写和运行任意代码而不会造成任何破坏几乎是不可能的。现在使用PEP-518,构建时依赖性是明确的,并且构建环境很容易创建。通过PEP-517,我们可以使用更具声明性的打包命名空间,这可以降低用户错误的可能性,并在无法避免错误时提供更好的消息。诚然,某些软件包在进行这些更改时可能会损坏,并且我们可能会使曾经有效的无效。然而,我们(PyPa的维护者)这样做并不是出于恶意,所以当出现问题时,请务必填写错误报告,详细说明问题所在、您如何使用它以及您的用例。我们正努力真诚地改进打包生态系统,为此我们创建了集成测试[10]存储库,以确保在未来至少有一些边缘情况在它们登陆您的机器之前被捕获。如果您对打包有任何建议或要求,欢迎在“讨论Python论坛[11]”的打包部分进行讨论,或提出相关工具的问题。照片由MilanPopovic/Unsplash拍摄-目前就这些,感谢阅读!我要感谢PaulGanssle[12]审阅打包系列和TechAtBloomberg[13]让我在工作期间做出开源贡献。###相关链接[1]Python打包——成长的烦恼:https://www.bernat.tech/growi...[2]TOML文件格式。:https://github.com/toml-lang/...[3]Towncrier:https://pypi.org/project/town...[4]黑色:https://pypi.org/project/black/[5]pip18.0(2018年7月22日发布):https://pip.pypa.io/en/stable...[6]问题见附件。:https://github.com/pypa/pip/i...[7]setuptools1650:https://github.com/pypa/setup...[8]设置工具:https://github.com/pypa/setup...[9]python讨论板:https://discuss.python.org/t/...[10]集成测试:https://github.com/pypa/integ...[11]Python论坛讨论:https://discuss.python.org/c/...[12]PaulGanssle:https://twitter.com/pganssle[13]TechAtBloomberg:https://twitter.com/techatblo...公众号【Python猫】,本号连载一系列优质文章,包括喵星哲学猫系列、Python进阶系列、好书推荐系列、技术写作、优质英文推荐及翻译等,欢迎关注哦。