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
模块,遇到编码问题。configobj
是 python
内的一个解析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
另外,在 msys2
的 console
使用 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")