2to3 - 如何从输入文件中保留换行符?

问题描述 投票:4回答:3

我试图在Windows机器上运行2to3,其中* .py文件具有Unix风格的行尾字符。运行2to3会修改输出文件中的换行符。

MCVE:

之前的print2.py内容

print "Hello, world!"\n

执行命令:

2to3 print2.py -w -n

打印后的print2.py内容

print("Hello, world!")\r\n

预期内容:

print("Hello, world!")\n

执行2to3转换时是否可以保留旧的换行符?

python python-3.x python-2.x python-2to3
3个回答
1
投票

由于似乎没有标准方法可以在命令行使用中更改此行为,因此我编写了非常简单的Python脚本,该脚本运行代码并修补不需要的行为。

这是python modernize的一个例子,但任何基于2to3的工具都可以。

# to access function to patch
import lib2to3.refactor
# actual main
import libmodernize.main
# convert str to list of args, not mandatory
import shlex
# patch problematic function, as suggested by @mfripp
lib2to3.refactor._to_system_newlines = lambda input: input 

args = shlex.split("-w -n src")  # prepare args
libmodernize.main.main(args)  # pass args to main, equivalent of running cmdline tool

0
投票

在Windows上,系统行分隔符是\r\n,我们可以在os.py中看到:

if 'posix' in _names:
    ...
    linesep = '\n'
    ...
elif 'nt' in _names:
    ...
    linesep = '\r\n'
    ...

此行分隔符用于lib2to3.refactor

def _to_system_newlines(input):
    if os.linesep != "\n":
        return input.replace(u"\n", os.linesep)
    else:
        return input

因此,为了使用2to3脚本保留行分隔符,应该足以在上面的函数中用return input.replace(u"\n", os.linesep)替换行return input


0
投票

这个问题似乎以前曾被报道为Python 11594,仍然没有得到解决。在调查中,我找到了推荐的解决方法,设置lib2to3._to_system_newlines在从Python 3运行lib2to3时没有任何效果。对我来说有用的是覆盖_open_with_encoding因此:

lib2to3.refactor._open_with_encoding = functools.partial(open, newline='')

我在jaraco.develop中提供了这个功能。可以像调用lib2to3一样调用模块,但应用了补丁:

python -m jaraco.develop.lib2to3 .

或者将它合并到libmodernize这样的另一个库中:

import runpy
from jaraco.develop import lib2to3
lib2to3.patch_for_newlines()
runpy.run_module('modernize')

这些技术可能无法在Python 2上运行,因此我建议从Python 3运行lib2to3。

© www.soinside.com 2019 - 2024. All rights reserved.