mycli 启动 UnicodeDecodeError 及运行时 WinError 995 问题

mycli 是一个 python 写的功能强大的 mysql 命令行补全工具,交互体验类似 ipython 或者 jupyter。项目在这里.

直接使用 pip 来安装即可,pip install mycli.
编码错误
安装完毕运行报错。

UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xa8 in position 52: invalid start byte

报错的调用栈如上。报错的部分是 configobj 模块,遇到编码问题。configobjpython 内的一个解析ini 格式的配置文件的模块。

按照提示,先找到配置文件的位置。定位到圈出来的部分,在文件 D:\ProgramData\Anaconda3\Lib\site-packages\mycli\main.py 的 136 行的这处报错,对应的内容如下。

        # Load config.
        config_files = (self.system_config_files +
                        [myclirc] + [self.pwd_config_file])
        c = self.config = read_config_files(config_files)

看到这里是有初始化一个配置文件列表,往下一步,找到具体的编码报错的配置文件。

在文件 D:\ProgramData\Anaconda3\Lib\site-packages\mycli\config.py 的 105 行(read_config_files 这个函数里),在这里增加 2 个打印。

    print("**************", _files)
    while _files:
        _file = _files.pop(0)
        print("*********************", os.path.realpath(_file))

再次运行,得到报错的配置文件是 C:\Users\Administrator\~\.myclirc

数据库名称

使用 nodepad++ 打开这个文件,看到默认使用的编码是 ASIN, 手动将编码更改为 utf-8.
选择编码
很快看到 63,64 行的两个不可见字符,去掉这两个不可见字符,保存即可。
问题字符
当然也可以根据调用栈的最下端,在文件 D:\ProgramData\Anaconda3\Lib\site-packages\configobj.py 的 1517 行加些打印,定位到配置文件中的行。其实代码里已经有注释说明可能抛出异常。

        if encoding:
            for i, line in enumerate(infile):
                if isinstance(line, six.binary_type):
                    # NOTE: The isinstance test here handles mixed lists of unicode/string
                    # NOTE: But the decode will break on any non-string values
                    # NOTE: Or could raise a ``UnicodeDecodeError``
                    infile[i] = line.decode(encoding)
        return infile

另外,在 msys2console 使用 mycli ,包括在 msys2 里运行 ipython 同样会出现的问题:控制台不能正常的输入输出,需要借助 winpty.

winpty mycli -u root ...

正常运行使用过程中,发现另外一个问题,经常提示 WinError 995.

Unhandled exception in event loop:
File “d:\programdata\anaconda3\lib\asyncio\proactor_events.py”, line 768, in _loop_self_reading
f.result() # may raise
File “d:\programdata\anaconda3\lib\asyncio\windows_events.py”, line 808, in _poll
value = callback(transferred, key, ov)
File “d:\programdata\anaconda3\lib\asyncio\windows_events.py”, line 457, in finish_recv
raise ConnectionResetError(*exc.args)
Exception [WinError 995] 由于线程退出或应用程序请求,已中止 I/O 操作。
Press ENTER to continue…

这里 给出了解决方法,就是在 D:\ProgramData\Anaconda3\Lib\asyncio\proactor_events.py 这个文件的 _loop_self_reading 函数里增加两行代码,对应行数在 765 行。

            if self._stopping:
                raise exceptions.CancelledError("Event loop is stopping")

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zhouguoqionghai/article/details/115997766