首页 > 解决方案 > google colab UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfa in position 21: invalid start byte

问题描述

我正在使用 Google Colab 运行 git 命令(我在 colab 中安装了一个包含 git repo 的 google 驱动器)。所有命令都没有问题,突然有些命令停止工作。

这些命令在我的 Colab 中仍然有效:

!git branch
!git stash pop
!git log -1

但是这些命令在我的 Colab 中产生了一个以前没有发生的错误:

!git status
!git checkout master
!git pull origin master

的输出

!git stash pop 
!git status
No stash entries found.
---------------------------------------------------------------------------
UnicodeDecodeError                        Traceback (most recent call last)
<ipython-input-27-7155109ce28e> in <module>()
     12 get_ipython().system('git stash pop')
     13 # !git branch
---> 14 get_ipython().system('git status')
     15 # !git pull origin master
     16 # if os.path.isdir(WORKING_DIR):

5 frames
/usr/local/lib/python3.6/dist-packages/google/colab/_shell.py in system(self, *args, **kwargs)
    100       kwargs.update({'also_return_output': True})
    101 
--> 102     output = _system_commands._system_compat(self, *args, **kwargs)  # pylint:disable=protected-access
    103 
    104     if pip_warn:

/usr/local/lib/python3.6/dist-packages/google/colab/_system_commands.py in _system_compat(shell, cmd, also_return_output)
    438   # stack.
    439   result = _run_command(
--> 440       shell.var_expand(cmd, depth=2), clear_streamed_output=False)
    441   shell.user_ns['_exit_code'] = result.returncode
    442   if -result.returncode in _INTERRUPTED_SIGNALS:

/usr/local/lib/python3.6/dist-packages/google/colab/_system_commands.py in _run_command(cmd, clear_streamed_output)
    193       os.close(child_pty)
    194 
--> 195       return _monitor_process(parent_pty, epoll, p, cmd, update_stdin_widget)
    196   finally:
    197     epoll.close()

/usr/local/lib/python3.6/dist-packages/google/colab/_system_commands.py in _monitor_process(parent_pty, epoll, p, cmd, update_stdin_widget)
    220   while True:
    221     try:
--> 222       result = _poll_process(parent_pty, epoll, p, cmd, decoder, state)
    223       if result is not None:
    224         return result

/usr/local/lib/python3.6/dist-packages/google/colab/_system_commands.py in _poll_process(parent_pty, epoll, p, cmd, decoder, state)
    273       output_available = True
    274       raw_contents = os.read(parent_pty, _PTY_READ_MAX_BYTES_FOR_TEST)
--> 275       decoded_contents = decoder.decode(raw_contents)
    276 
    277       sys.stdout.write(decoded_contents)

/usr/lib/python3.6/codecs.py in decode(self, input, final)
    319         # decode input (taking the buffer into account)
    320         data = self.buffer + input
--> 321         (result, consumed) = self._buffer_decode(data, self.errors, final)
    322         # keep undecoded input until the next call
    323         self.buffer = data[consumed:]

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xfa in position 21: invalid start byte

如您所见,!git stash pop有效但无效!git status。请注意,直到最近,我的 Colab 中的所有 git 命令都运行良好。似乎 Colab 中发生了一些事情,使它拒绝了一些 git 命令。

是的,我已经尝试创建一个新的 Colab 并在那里重写有问题的 git 命令,但错误仍然存​​在。我还尝试删除每个字符并从头开始重写它们(以防有隐藏字符导致问题)。

在我的本地机器上,这些命令可以正常工作并且不会打印任何奇怪的字符:

$ git status
On branch tf2
nothing to commit, working tree clean

有什么想法吗?

标签: pythongitunicodegoogle-colaboratorypython-unicode

解决方案


首先,阅读https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no -excuses/以便这个答案的其余部分有意义。

现在,这里的问题是您已经告诉不同的子系统(在本例中为 Python 和 Git)使用不同的编码。具体来说,您已经告诉 Python 期待 UTF-8 编码的数据。您的 Git 可能根本没有使用任何特定的编码,只是通过复制原始字节。通常,您的git status输出将使用八进制转义编码(参见,例如,如何使 Git 在控制台窗口中正确显示 UTF-8 编码的路径名?Git 与文件名中的 ä 混淆)。其他命令不进行任何特殊编码(参见,例如,使 git diff 正确显示 UTF8 编码的字符)并且git status可以被告知如何表现。--porcelain=v2和_-zoptions 在 中特别有用git status,尽管您必须重写您自己的 Python 代码以期望字节序列。

您可能需要弄清楚底层文件系统中使用的实际编码是什么。如果您不想处理此类问题,请确保所有文件名都使用简单的 ASCII 字符:schön例如,没有文件名为 .


推荐阅读