2to3 - 如何从输入文件中保留换行符?
2to3 - how to keep newline characters from input file?
我正在尝试在 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
转换时是否可以保留旧的换行符?
在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
就足够了。
由于似乎没有标准的方法来改变命令行使用中的这种行为,我准备了非常简单的 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
此问题之前似乎已被报告为 Python 11594,但仍未解决。在调查中,我发现了推荐的解决方法,当 lib2to3 是来自 Python 的 运行 时,设置 lib2to3._to_system_newlines
没有任何效果 3. 对我有用的是覆盖 _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,因此我建议 运行ning lib2to3 来自 Python 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
转换时是否可以保留旧的换行符?
在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
就足够了。
由于似乎没有标准的方法来改变命令行使用中的这种行为,我准备了非常简单的 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
此问题之前似乎已被报告为 Python 11594,但仍未解决。在调查中,我发现了推荐的解决方法,当 lib2to3 是来自 Python 的 运行 时,设置 lib2to3._to_system_newlines
没有任何效果 3. 对我有用的是覆盖 _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,因此我建议 运行ning lib2to3 来自 Python 3.