编译蟒蛇3.6+蟒蛇2.7+

lib3to6的Python项目详细描述


lib3to6

将Python3.6+代码编译为Python2.7+兼容代码。这个想法相当 类似于bablehttps://babeljs.io/。使用最新的翻译和 在不牺牲向后兼容性的情况下使用(大多数)新的语言功能。

项目/回购:

mit license支持的python版本pycalver v201902.0030pypi versionpypi downloads

代码质量/ci:

构建状态用mypy检查类型代码覆盖率代码风格:sjfmt

<表><广告>名称角色自直到< /广告><正文>Manuel Barkhau(mbarkhau@gmail.com)作者/维护者2018-09年 -

项目状态(截至2019-02-21):实验性

我用这个图书馆主要是为了 pycalver项目无任何问题。我 在Python3.8接近发布之前,不会添加任何新的修正程序或检查程序。 请尝试发送您的反馈。

最终目标是涵盖所有记录在案的案件 http://python future.org和其中一个:

  1. 将文件转换为可用于任何版本的代码
  2. 提出错误,理想情况下指向 python-future.org或其他描述 编写向后兼容代码的替代方法。

https://docs.python.org/3.x/whatsnew/也包含了很多关于 可以检查的API更改,但检查和修复程序 只有当它们足够普遍的时候才会写,否则 工作太多了(不过也欢迎使用补丁)。

开发入门

$ git clone https://gitlab.com/mbarkhau/lib3to6.git
$ cd lib3to6/
lib3to6 $ make install
...
lib3to6 $ make test
...
lib3to6 $ make help

动机

这个项目的主要动机是能够使用mypy 不牺牲与旧版本python的兼容性。

# my_module/__init__.pydefhello(who:str)->None:importsysprint(f"Hello {who} from {sys.version.split()[0]}!")print(__file__)hello("世界")
$ pip install lib3to6
$ python -m lib3to6 my_module/__init__.py
# -*- coding: utf-8 -*-from__future__importabsolute_importfrom__future__importdivisionfrom__future__importprint_functionfrom__future__importunicode_literalsdefhello(who):importsysprint('Hello {0} from {1}!'.format(who,sys.version.split()[0]))print(__file__)hello('世界')

应用修复程序将python3代码的语义匹配为 即使在python2.7解释器上运行,也要尽可能接近。

已应用的一些修复程序:

- PEP263 magic comment to declare the coding of the python
  source file. This allows the string literal `"世界"` to
  be decoded correctly.
- `__future__` imports have been added. This includes the well
  known print statement -> function change. The unicode_literals
- Type annotations have been removed
- f string -> "".format  conversion

cli命令lib3to6非常适合演示, 但对于你的项目,最好在 setup.py文件。

# setup.pyimportsysimportsetuptoolspackages=setuptools.find_packages(".")package_dir={"":"."}ifany(arg.startswith("bdist")forarginsys.argv):importlib3to6package_dir=lib3to6.fix(package_dir)setuptools.setup(name="my-module",version="201808.1",packages=packages,package_dir=package_dir,)
~/my-module $ python setup.py bdist_wheel --python-tag=py2.py3
running bdist_wheel
...
~/my-module$ ls -1 dist/
my_module-201808.1-py2.py3-none-any.whl

~/my-module$ python3 -m pip install dist/my_module-201808.1-py2.py3-none-any.whl
Processing ./dist/my_module-201808.1-py2.py3-none-any.whl
Installing collected packages: my-module
Successfully installed my-module-201808.1

~/my-module$ python2 -m pip install dist/my_module-201808.1-py2.py3-none-any.whl
Processing ./dist/my_module-201808.1-py2.py3-none-any.whl
Installing collected packages: my-module
Successfully installed my-module-201808.1

为了确保我们从安装中导入我的_模块,作为 与本地目录相反,我们必须切换 目录。

~/$ python3 -c "import my_module"
/home/user/my-module/my_module/__init__.py
Hello 世界 from 3.6.5!

~/my-module$ cd ..
~/$ python3 -c "import my_module"
/home/user/envs/py36/lib/python3.6/site-packages/my_module/__init__.py
Hello 世界 from 3.6.5!

~$ python2 -c "import my_module"
/home/user/envs/py27/lib/python2.7/site-packages/my_module/__init__.py
Hello 世界 from 2.7.15!

功能支持

并非所有新的语言特性在旧的 版本。如果可以检测到这些,则会出现错误 使用这些功能时报告。

一个(显然不是详尽无遗的)特征列表 支持:

  • 异步/等待
  • 屈服于
  • @/matmul运算符

支持的功能

  • PEP 498:格式化字符串文本。
  • 注释的省略
  • 展开一般化
  • 仅限关键字参数
  • PEP 515:数字文本中的下划线
  • 将/zip/filter映射到ITertools等效项
  • 转换基于类的typing.namedtuple用法到赋值

一些新库具有后台端口,警告将指向:

  • 键入
  • 路径库
  • 秘密
  • IP地址
  • csv->;backports.csv
  • lzma->;backports.lzma
  • 枚举->;flufl.enum

工作原理

这个项目在python抽象语法的层次上工作 树(AST)。AST被转换为仅用于 在旧版本的python中也有效的构造。为了 它将使用 str.format方法。

>>>importsys>>>sys.version_info'3.6.5'>>>importlib3to6>>>py3_source='f"Hello {1 + 1}!"'>>>cfg={"fixers":["f_string_to_str_format"]}>>>py2_source=lib3to6.transpile_module(cfg,py3_source)>>>print(py3_source)f"Hello {1 + 1}!">>>print(py2_source)# -*- coding: utf-8 -*-"Hello {0}!".format(1+1)>>>print(lib3to6.parsedump_ast(py3_source))Module(body=[Expr(value=JoinedStr(values=[Str(s='Hello '),FormattedValue(value=BinOp(left=Num(n=1),op=Add(),right=Num(n=1),),conversion=-1,format_spec=None,),Str(s='!'),]))])>>>print(lib3to6.parsedump_ast(py2_source))Module(body=[Expr(value=Call(func=Attribute(value=Str(s='Hello {0}!'),attr='format',ctx=Load(),),args=[BinOp(left=Num(n=1),op=Add(),right=Num(n=1),)],keywords=[]))])

当然,这并不能涵盖兼容性的所有方面。 不能用这种方式自动转换API中的更改。

一个明显的例子是,没有办法传输代码 它使用异步等待。在这种情况下,lib3to6 只会引发一个checkerror。这只适用于你的来源 尽管如此,如果import使用一个库,该库使用async等待,在运行测试之前,一切看起来都很好 在Python 2.7上。

一个更微妙的例子是内置的语义变化 打开功能。

$ git clone https://gitlab.com/mbarkhau/lib3to6.git
$ cd lib3to6/
lib3to6 $ make install
...
lib3to6 $ make test
...
lib3to6 $ make help
0

通常有其他方法来编写等价的代码 适用于所有版本的python。为了这些普通的 lib3to6的不兼容将引发错误并建议 另一种方法,例如在本例中使用io.open。

$ git clone https://gitlab.com/mbarkhau/lib3to6.git
$ cd lib3to6/
lib3to6 $ make install
...
lib3to6 $ make test
...
lib3to6 $ make help

这里lib3to6您将给出一个"checkerror",但是 仍然由您负责编写代码,以便 在python3中句法翻译在语义上是等价的 和蟒蛇2。

lib3to6使用pythonast模块解析代码。这个 意味着您需要一个现代的python解释器来从 现代python到传统python解释器。你不能透明 解释程序无法解析的功能。预期用途是 对于使用最新python的库的开发人员 版本,但希望他们的库能够处理旧版本。

FAQ

  • 问:标语"兼容性很重要"不是很讽刺吗? 考虑到python 3.6+需要构建一个轮子?

  • A:讽刺的一点也不失。问题是,如何解析源 来自比python更新的python版本的代码 解释器本身支持。您可以在上安装lib3to6 旧版本的python,但是 该版本支持的功能。例如,你不会 能够在Python3.5上使用f""字符串,但大多数注释 工作正常。

  • 问:为什么要让蟒蛇2.7活着?就让它死吧!

  • 答:的确,lib3to6可以帮助解决这个问题。把你自己放在 一个在旧代码库工作的人的鞋子。不是 实事求是地抓住所有其他发展努力, 代码库被迁移和测试,而其他一切都在等待。

    相反,增量方法通常是唯一的选择。 使用lib3to6,代码库的各个模块可以 迁移到python3,剩下的代码基 未触及的该项目仍然可以在Python2.7中运行 环境,而开发人员越来越倾向于使用 巨蟒3。

    此外,lib3to6不仅仅是为了与 Python2.7,它还允许您使用新特性,如f" 字符串和变量注释,同时仍保持 与旧版本的python 3兼容。

  • 问:为什么不lib3to2

  • A:老实说,我对lib3to2不能说太多。似乎不是 被维护并查看源代码 更容易写一些新的东西,在ast级别上工作。 lib3to6的作用域比3to2更一般,您可以 使用它,即使您只关心从Python3.6转换 至3.5。

https://gitlab.com/mbarkhau/lib3to6的更改日志

V201902.0030

  • fix python 2内置项并不总是被正确覆盖。
  • 修复pypy兼容性测试
  • 更好的mypy覆盖率

V201812.0021-β

  • 递归地应用一些修复程序。

V201812.0020-α

  • 转到gitlab.com
  • 使用bootstrapit
  • 根据与pycalver的使用修复错误

V201809.0019-α

  • 检查错误包括日志行号

  • transfile错误现在包括文件名

  • 为重命名的模块添加了修复程序,例如 …代码块::diff

    $ git clone https://gitlab.com/mbarkhau/lib3to6.git
    $ cd lib3to6/
    lib3to6 $ make install
    ...
    lib3to6 $ make test
    ...
    lib3to6 $ make help
    2

V201808.0014-α

  • 更好地处理包目录
  • 更改为Calver版本控制<;https://calver.org/>;\uu
  • 删除控制台脚本以支持简单的python-m lib3to6
  • 重命名自three2six->;lib3to6

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java画布矩形位置   Java类文件未在Android Studio上编译或运行   Java“null”值从未分配给我的Runnable   java Jsp使用URL“保存或打开”访问pdf窗口在单击时显示错误   组件之间的Java swing通信   属性值的java正则表达式   java无法从myFile加载MainClass清单属性。震击器错误   Java内存碎片和大型阵列的分配   java是NullPointerException的一个问题   java如何使用鳄梨酱进行sftp的二次开发   新手程序员需要建议:“字符串索引超出范围”Java   基于页面的java Birt组头   使用集合时出错。使用ArrayList和类排序()。(爪哇)   在foursquare中使用多个单词进行带查询的java场馆搜索   有了新的Java14记录功能,是否可以为同一记录创建多个构造函数?   java创建自己的文件扩展名   java组织。阿帕奇。xml。安全性在Spring Boot下不工作   java谷歌地图标记标题安卓   java为什么选项卡小部件在安卓中位于内容之上?