python - 带有编解码器 header 的 ASCII 安全文件的编码问题,具体取决于行数

标签 python windows python-3.x encoding python-3.5

这是 Windows 上 Python 3.5.2 的神奇错误,这让我很沮丧。以下文件在此系统上失败:

C:\Python35\python.exe encoding-problem-cp1252.py
 File "encoding-problem-cp1252.py", line 2
SyntaxError: encoding problem: cp1252

几乎不包含任何内容 - 除了 coding header 之外还有一堆空行,但是删除任何行,即使是空行,它也会再次工作。我认为这是一个本地问题,所以我设置了 job on AppVeyor表现出相同的行为。

Python 是怎么回事?

有一个binary accurate version以下文件:

#!/usr/bin/env python
# -*- coding: cp1252 -*-


"""
There is nothing in this file, except that it is more
than 50 lines long. Running it with Python 3.5.2 on
Windows gives the following error:

    >python encoding-problem-cp1252.py
      File "encoding-problem-cp1252.py", line 2
    SyntaxError: encoding problem: cp1252

    >python
    Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
    Type "help", "copyright", "credits" or "license" for more information.

If you remove any lines from this file, it will
execute successfully.
"""



def restore(dump):
  """













  """
  return



def main():
  print('ok')



if __name__ == '__main__':
  main()

最佳答案

这看起来像是由 issue #20731 引起的回归.看起来位置计算假设总是有 CRLF 行结尾,而您的文件只有 LF 字符,导致不正确的偏移量 being calculated here :

fd = fileno(tok->fp);
/* Due to buffering the file offset for fd can be different from the file
 * position of tok->fp.  If tok->fp was opened in text mode on Windows,
 * its file position counts CRLF as one char and can't be directly mapped
 * to the file offset for fd.  Instead we step back one byte and read to
 * the end of line.*/
pos = ftell(tok->fp);
if (pos == -1 ||
    lseek(fd, (off_t)(pos > 0 ? pos - 1 : pos), SEEK_SET) == (off_t)-1) {
    PyErr_SetFromErrnoWithFilename(PyExc_OSError, NULL);
    goto cleanup;
}

当您将文件转换为使用 Windows (CRLF) 行结尾时,问题就消失了,但我可以理解,对于跨平台脚本来说,这不是一个实用的解决方案。

我已经提交了 issue #27797 ;这应该在 Python 本身中修复。

关于python - 带有编解码器 header 的 ASCII 安全文件的编码问题,具体取决于行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39032416/

相关文章:

python - "zypper install python-mysqldb mysql-server"找不到包

linux - 如果 python 脚本因错误而停止,请重新启动树莓派

python - 捕获所有 * 前面没有 < 的组

Python 将字典写入带标题的 csv

python - Scrapy错误: Spider must return Request, BaseItem或无,得到 'dict'

Python:如果可能的话,使私有(private)类方法始终静态?

python - numpy 的 c 源代码中的 at 符号 (@) 是如何使用的?

c++ - 是否有将 REFIID 转换为有用名称的操作系统功能?

c - 在 C 中读取环境变量时出错

c++ - 在可执行文件的资源中,如何找到默认图标?