你计划如何处理迁移到Python 3?

我相信这是Python大多数开发人员认为Python 3即将推出的主题。 一些问题让我们朝着正确的方向前进:

  1. 你会有一个python 2和python 3版本要同时维护吗?或者一旦它完成,你会只是有一个python 3版本?

    • 你已经开始或计划很快开始? 或者你打算等到最后的版本才能全面展开?

这是Twisted的总体计划。 我原本是去博客这个,但是后来我想:为什么要在博客上写点东西呢?

  1. 等到有人在乎

    现在,没有人拥有Python 3.我们不会花费大量的努力,直到至less有一个实际的用户出现并说“我需要Python 3.0的支持”,除了这个事实之外,还有一个很好的理由3.0看起来有光泽。

  2. 等到我们的依赖已经迁移。

    一个像Twisted这样的大系统有很多的依赖关系。 对于初学者,我们的包括:

    • Zope界面
    • PyCrypto
    • PyOpenSSL
    • pywin32
    • PyGTK (尽pipe这种依赖关系现在非常轻,到了迁移的时候,我希望Twisted会有更多的GUI工具)
    • pyasn1
    • PyPAM
    • gmpy

    其中一些项目有自己的一系列依赖项,所以我们不得不等待这些项目。

  3. 等到有人关心足够的帮助

    慈善事业上,有5个人在扭曲工作 – 我说“慈善”,因为这算我,而且我还没有犯下几个月。 我们现在有超过1000个开放的门票 ,实际上修复其中的一些将是很好的 – 修正错误,增加function,并且通常使Twisted成为一个更好的产品 – 在花费时间将其移植到大量语言的新版本。

    这可能包括赞助商为我们付出的代价,但我希望有志愿者涌入,他们关心3.0的支持,并希望帮助社区向前迈进。

  4. 按照Guido的build议。

    这意味着我们不会改变我们的API ,我们将遵循Guido去年发布的过渡性开发准则 。 首先进行unit testing,然后在Twisted代码库上运行2to3转换工具 。

  5. 报告2to3工具的错误,并为其提供文件补丁

    当我们到达实际使用它的地步时,我预计将来运行2to3会有很多问题。 运行Twisted现在需要很长时间,而且(最近我检查了一下,很久以前)不能parsingTwisted存储库中的一些文件,所以不会导入结果输出。 我认为在小型项目中将会有相当多的成功案例,而且在实际上为我们工作之前,还需要大量的工具。

    但是,Python开发团队在回应我们的错误报告方面非常有帮助,对这些问题的早期反应令人鼓舞,所以我希望所有这些问题都能及时得到解决。

  6. 保持数年的兼容性。

    现在,Twisted支持Python 2.3到2.5。 目前,我们正在2.6的支持(我们显然必须在3.0之前完成!)。 我们的计划是根据长期支持的Ubuntu版本8.04(包括Python2.5)修改我们支持的Python版本,直到2013年才会支持。根据Guido的build议,我们需要放弃对2.5的支持以支持3.0,但我希望我们能find一个解决方法(我们非常有创意的版本兼容性黑客)。

    因此,我们计划在至less2013年之前支持Python 2.5。在两年内,Ubuntu将发布另一个长期支持的Ubuntu版本:如果它们仍然存在,并且保持按计划进行,那么将会是10.04。 就我个人而言,我猜测这会随着Python 2.x(也许是Python 2.8)发布为/usr/bin/python ,因为发行版中包含了大量的Python软件,需要很长时间才能更新。 那么, 从那时起五年,在2015年,我们可以开始考虑放弃2.x的支持。

    在此期间,我们将继续遵循Guido关于迁移的build议:在2.x代码库上运行2to3,并修改2.x代码库以保持两个版本的testing通过。

    这样做的结果是Python 3.x在我的35岁生日之前不会成为Twisted的语言 – 它将成为我的Python 2.x代码的一个目标运行时(以及一系列指南和限制)。 我预计在未来十年左右,Python 2.x将会编写程序。

所以,这是计划。 我希望最终在一年左右时间里保守得可笑, 3.x的过渡很容易,每个人都快速升级。 其他事情也可能发生:2.x和3.x分支可能会聚,有人可能最终编写一个3to2或另一个运行时(想到PyPy)可能允许运行2.x和3.x代码直接相同的过程,使我们的转换过程更容易。

然而,目前我们认为,多年以来,我们会让拥有庞大代码库的人们(或者正在编写新代码的人们想要使用尚未被迁移的其他库),他们仍然想要Twisted中的新function和错误修复。 很快,我希望我们也会有一些想要在python 3上使用Twisted的用户。我想尽可能为所有这些人提供一个积极的经验。

Django项目使用库six来维护一个在Python 2 Python 3( 博客文章 )上同时工作的代码库。

six是通过提供一个兼容性层来智能地将导入和functionredirect到它们各自的位置(以及统一其他不兼容的变化)。

明显的优势:

  • Python 2和Python 3不需要单独的分支
  • 没有转换工具,比如2to3。

2.6的主要思想是提供一个到3.0的迁移path。 所以你可以使用from __future__ import X缓慢地移植一个特性,直到你把所有的特性都固定下来,并且可以移动到3.0。 3.0的许多function也将stream入2.6,所以您可以逐渐缩小语言差距,而不是一味迁移一切。

在工作中,我们计划先从2.5升级到2.6。 然后,我们开始一次一个模块缓慢启用3.0function。 在某些时候,系统的整个子部分可能会准备好3.x.

唯一的问题是图书馆。 如果一个图书馆从不迁徙,我们就会被旧的图书馆所困住。 但我相当有信心,我们将在适当的时候为这一部分取得好的select。

作为图书馆作者说:

我正在等待最终版本发布。 我认为,就像大多数Python社区一样,2.x将继续成为几个星期或几个月的主导版本。 这是足够的时间来发布一个不错的,精美的3.x版本。

我将维护单独的2.x和3.x分支。 2.x将向后兼容2.4,所以我不能在2.6 / 3.0中使用很多花哨的语法或新特性。 相比之下,3.x分支将使用这些function中的每一个,从而为用户带来更好的体验。 testing套件将被修改,以便2to3将在其上工作,并且我将为两个分支维护相同的testing。

同时支持

我想尝试将BeautifulSoup库转换为3x用于我正在处理的项目,但是我可以看到维护两个不同的代码分支将会是一件痛苦的事情。

目前处理这个问题的模型包括:

  1. 对2x分支进行更改
  2. 运行2to3
  3. 祈祷它第一次做适当的转换
  4. 运行代码
  5. 运行unit testing来validation一切正常
  6. 将输出复制到3x分支

这种模式的工作,但恕我直言,它很烂。 对于每一个变化/释放你必须经过这些步骤::叹息::。 此外,它阻碍了开发人员扩展3x分支的新function,只能在py3k中支持,因为您仍然将所有代码定位到2x。

解决scheme…使用预处理器

由于我无法find一个体面的c风格的预处理器与python #define和#ifdef指令,我写了一个。

它叫做pypreprocessor,可以在PYPI中find

基本上,你所做的是:

  1. 导入pypreprocessor
  2. 检测脚本运行的是哪个版本的python
  3. 在版本的预处理器(例如'python2'或'python3')中设置一个'define'
  4. 撒上'#ifdef python2'和'#ifdef python3'指令代码是特定于版本的
  5. 运行代码

而已。 现在它可以工作在2倍和3倍。 如果您担心运行预处理器会带来额外的性能提升,那么还会有一种模式将所有元数据去除,并将后处理的源文件输出到文件中。

最重要的是,你只需要做2to3转换一次。

这是一个工作的例子:

 #!/usr/bin/env python # py2and3.py import sys from pypreprocessor import pypreprocessor #exclude if sys.version[:3].split('.')[0] == '2': pypreprocessor.defines.append('python2') if sys.version[:3].split('.')[0] == '3': pypreprocessor.defines.append('python3') pypreprocessor.parse() #endexclude #ifdef python2 print('You are using Python 2x') #ifdef python3 print('You are using python 3x') #else print('Python version not supported') #endif 

这些是terminal的结果:

  python py2and3.py
  >>>您正在使用Python 2x 
  python3 py2and3.py
  >>>你正在使用python 3x

如果你想输出到一个文件,并且没有额外的元数据制作干净的版本特定的源文件,那么在pypreprocessor.parse()语句之前的某处添加这两行:

 pypreprocessor.output = outputFileName.py pypreprocessor.removeMeta = True 

然后:

 python py2and3.py

将创build一个名为outputFileName.py的文件,该文件是python 2x的特定版本,没有额外的元数据。

 python3 py2and3.py

将创build一个名为outputFileName.py的文件,该文件是python 3x特有的,没有额外的元数据。

有关文档和更多示例,请参阅GoogleCode上的pypreprocessor 。

我真诚地希望这有助于。 我喜欢在python中编写代码,我希望看到3x领域的支持进展。 我讨厌看到语言没有进步。 尤其是,由于3x版本parsing了许多特色的WTF,并且使得语法对于从其他语言迁移的用户来说更加友好。

目前的文件是完整的,但并不广泛。 我会尽快让wiki获得更广泛的信息。

更新:

虽然我专门devise了pypreprocessor来解决这个问题,但是它不起作用,因为在任何代码执行之前,词法分析器都会对所有代码进行语法检查。

如果python具有真正的C预处理器指令支持,它将允许开发人员在同一个文件中同时编写python2x和python3k代码,但由于C预处理器的恶名(滥用macrosreplace来更改语言关键字),我不看到合法的C预处理器支持被添加到Python的任何时间。

Zope Toolkit在Python 3支持方面进展缓慢。 主要是因为这些库很多很复杂。

对于大多数图书馆我使用2to3。 一些图书馆没有它,因为它们很简单,或者大部分代码都是C扩展。 zc.buildout是一个相关的软件包,它将运行相同的代码,而不用2to3来支持Python 2和3。

我们将ZTK移植到Python 3,因为其他许多库和框架都依赖于它,例如Twisted和Pyramid框架。

我的一些更复杂的2.x代码将保持在2.5或2.6。 一旦我使用的某些第三方库经常更新为3,我将进入所有新开发的3.0。