在 PyPI 上发布一个非向后兼容的库?
Releasing a non-backwards compatible library on PyPI?
我在 PyPI 上有一个名为 foobar
的库,它目前的版本是 1.2.0
(使用语义版本控制)。
下一版本不保留 API 与版本 1.x
的兼容性,因此我将其发布为 2.0.0
。
将这个新版本发布到 PyPI 的最佳做法是什么,以便使用 1.x
版本的客户不会意外升级到 2.0.0
并破坏他们的代码? (我假设有些人没有在他们的代码中强制执行像 >=1.0.0, <2.0.0
这样的版本依赖)。
在 PyPI 上创建一个名为 foobar2
的全新包并将新版本推送到那里会更好吗?其他项目如何处理这个问题?
我断言:API 变化通常分为两类。
新的API B代替了A,但是A完全可以用新的API B来实现。因此,同时维护旧的API和新 API。
这可以像移动新的 API 一样简单,以整理或合理化您的模块,也可以更复杂,例如将 args 转换为 kwargs 或其他。
新 API 替换旧 API 但由于技术原因无法实施。
这些是 IMO 类别的选项。你采取哪一个将在很大程度上取决于你所做的改变以及你 a) 关心多少或 b) 与你的用户保持联系并可以与你的用户交谈(即,如果只是一些,你可以逃脱一些未经宣布的破坏您团队中的人随后可以帮助解决他们的问题)。
1。在你的新版本中同时提供旧版本和新版本。
使用新的 API 实现旧的 API 但使用 warnings 模块将其标记为已弃用。你给人们通知转换,你可以在将来的某个时候删除旧的 API。
这是 API 第一类更改的最佳做法。它使每个人都保持在同一个流中,并允许您在将来的某个时间整理。
2。警告,然后引入新的API.
如果您处于情况 2 或情况 1 但无法证明使用新的资源来实施旧的,那么您可以轻松发布版本 1.2.1,该版本使用警告模块来警告用户您即将添加一个会破坏他们的代码的新版本,并且他们应该迅速将该版本固定在他们的 requirements.txt
中。
说你什么时候发布 2.0 版,然后你就警告过他们了。
但是,只有在为您的用户从 1.2.0 迁移到 2.0 的工作量不大的情况下,这才是真正公平的。
3。添加一个全新的包。
如果存在显着差异,并且您的用户将他们的代码更新到他们本质上需要重写代码的程度将是一种正确的痛苦,那么您不应该害怕使用全新的包裹。我们都会犯错误,考虑到 Python 2 和 Python 3 之间的差异,Python 社区中没有人不知道这一点 :-)。 unittest2
以前也是这样的例子。
人们会期待什么。
就个人而言,如果我在我关心的系统上进行了自动升级,并且如果我没有将版本固定为仅升级维护版本,那么如果有人发布了我的系统自动发布的重大升级,我会认为这是我的错服用但随后停止工作。
在我看来,这给了你道德制高点,但对于那些没有检查并被烧毁的懒惰用户(或更糟的是客户)来说,这并没有多少安慰。
其他人做什么
- paramiko 保持 API 向后兼容 1.x 到 2.0
- beautifulsoup 在 PyPI 上更改名称(从 BeautifulSoup 到 bs4)
- django 倾向于弃用功能并在以后的功能发布中删除它们,一般来说,如果没有,我永远不会将我关心的 django 安装从 1.X 升级到 1.(X+1)首先测试它。 (我认为这是最佳实践,就像 django 人做的很多事情一样。)
所以总结是:有一个混合,这真的取决于你。然而,避免用户自己造成问题的唯一完全安全的方法是完全保持向后兼容性或创建一个新包,如 BeautifulSoup 所做的那样。
我在 PyPI 上有一个名为 foobar
的库,它目前的版本是 1.2.0
(使用语义版本控制)。
下一版本不保留 API 与版本 1.x
的兼容性,因此我将其发布为 2.0.0
。
将这个新版本发布到 PyPI 的最佳做法是什么,以便使用 1.x
版本的客户不会意外升级到 2.0.0
并破坏他们的代码? (我假设有些人没有在他们的代码中强制执行像 >=1.0.0, <2.0.0
这样的版本依赖)。
在 PyPI 上创建一个名为 foobar2
的全新包并将新版本推送到那里会更好吗?其他项目如何处理这个问题?
我断言:API 变化通常分为两类。
新的API B代替了A,但是A完全可以用新的API B来实现。因此,同时维护旧的API和新 API。
这可以像移动新的 API 一样简单,以整理或合理化您的模块,也可以更复杂,例如将 args 转换为 kwargs 或其他。
新 API 替换旧 API 但由于技术原因无法实施。
这些是 IMO 类别的选项。你采取哪一个将在很大程度上取决于你所做的改变以及你 a) 关心多少或 b) 与你的用户保持联系并可以与你的用户交谈(即,如果只是一些,你可以逃脱一些未经宣布的破坏您团队中的人随后可以帮助解决他们的问题)。
1。在你的新版本中同时提供旧版本和新版本。
使用新的 API 实现旧的 API 但使用 warnings 模块将其标记为已弃用。你给人们通知转换,你可以在将来的某个时候删除旧的 API。
这是 API 第一类更改的最佳做法。它使每个人都保持在同一个流中,并允许您在将来的某个时间整理。
2。警告,然后引入新的API.
如果您处于情况 2 或情况 1 但无法证明使用新的资源来实施旧的,那么您可以轻松发布版本 1.2.1,该版本使用警告模块来警告用户您即将添加一个会破坏他们的代码的新版本,并且他们应该迅速将该版本固定在他们的 requirements.txt
中。
说你什么时候发布 2.0 版,然后你就警告过他们了。
但是,只有在为您的用户从 1.2.0 迁移到 2.0 的工作量不大的情况下,这才是真正公平的。
3。添加一个全新的包。
如果存在显着差异,并且您的用户将他们的代码更新到他们本质上需要重写代码的程度将是一种正确的痛苦,那么您不应该害怕使用全新的包裹。我们都会犯错误,考虑到 Python 2 和 Python 3 之间的差异,Python 社区中没有人不知道这一点 :-)。 unittest2
以前也是这样的例子。
人们会期待什么。
就个人而言,如果我在我关心的系统上进行了自动升级,并且如果我没有将版本固定为仅升级维护版本,那么如果有人发布了我的系统自动发布的重大升级,我会认为这是我的错服用但随后停止工作。
在我看来,这给了你道德制高点,但对于那些没有检查并被烧毁的懒惰用户(或更糟的是客户)来说,这并没有多少安慰。
其他人做什么
- paramiko 保持 API 向后兼容 1.x 到 2.0
- beautifulsoup 在 PyPI 上更改名称(从 BeautifulSoup 到 bs4)
- django 倾向于弃用功能并在以后的功能发布中删除它们,一般来说,如果没有,我永远不会将我关心的 django 安装从 1.X 升级到 1.(X+1)首先测试它。 (我认为这是最佳实践,就像 django 人做的很多事情一样。)
所以总结是:有一个混合,这真的取决于你。然而,避免用户自己造成问题的唯一完全安全的方法是完全保持向后兼容性或创建一个新包,如 BeautifulSoup 所做的那样。