特に Windows で rshell を pip install rshell
で インストールしても rshell を実行しようにもエラーをだして動かない場面に直面することがあります。
エラーの例
C:\MyProject\aaa> rshell
Traceback (most recent call last):
File "<frozen runpy>", line 198, in _run_module_as_main
File "<frozen runpy>", line 88, in _run_code
File "C:\Users\Hoge\AppData\Local\Programs\Python\Python311\Scripts\rshell.exe\__main__.py", line 4, in <module>
File "C:\Users\Hoge\AppData\Local\Programs\Python\Python311\Lib\site-packages\rshell\command_line.py", line 1, in <module>
import rshell.main
File "C:\Users\Hoge\AppData\Local\Programs\Python\Python311\Lib\site-packages\rshell\main.py", line 80, in <module>
import readline
File "C:\Users\Hoge\AppData\Local\Programs\Python\Python311\Lib\site-packages\readline.py", line 34, in <module>
rl = Readline()
^^^^^^^^^^
File "C:\Users\Hoge\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyreadline\rlmain.py", line 422, in __init__
BaseReadline.__init__(self)
File "C:\Users\Hoge\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyreadline\rlmain.py", line 62, in __init__
mode.init_editing_mode(None)
File "C:\Users\Hoge\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyreadline\modes\emacs.py", line 633, in init_editing_mode
self._bind_key('space', self.self_insert)
File "C:\Users\Hoge\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyreadline\modes\basemode.py", line 162, in _bind_key
if not callable(func):
^^^^^^^^^^^^^^
File "C:\Users\Hoge\AppData\Local\Programs\Python\Python311\Lib\site-packages\pyreadline\py3k_compat.py", line 8, in callable
return isinstance(x, collections.Callable)
^^^^^^^^^^^^^^^^^^^^
AttributeError: module 'collections' has no attribute 'Callable'
原因
${PYTHONPATH}\Lib\site-packages\pyreadline\py3k_compat.py
このファイルに不具合があるからです。
対策方法
py3k_compat.py
を以下の通りソースコードを修正すれば回避できます。
--- py3k_compat.py.orig 2023-08-17 22:45:26.488592900 +0900
+++ py3k_compat.py 2023-08-17 21:32:57.439240300 +0900
@@ -5,7 +5,7 @@ if sys.version_info[0] >= 3:
import collections
PY3 = True
def callable(x):
- return isinstance(x, collections.Callable)
+ return isinstance(x, collections.abc.Callable)
def execfile(fname, glob, loc=None):
loc = loc if (loc is not None) else glob