2020/05/10

python-socketioでAttributeError: 'module' object has no attribute 'main_thread'が出る場合の対処法

背景


Python2.7でpython-socketioを使用したとき時、下記のエラーが発生した。
$ python ./test_socketio_client.py 
Traceback (most recent call last):
  File "./test_socketio_client.py", line 123, in 
    sio_client = SocketIOClient('127.0.0.1', 10000, 'test', 'secret')
  File "./test_socketio_client.py", line 76, in __init__
    self.sio_        = socketio.Client()
  File "/home/emptyset/.local/lib/python2.7/site-packages/socketio/client.py", line 88, in __init__
    threading.current_thread() == threading.main_thread():
AttributeError: 'module' object has no attribute 'main_thread'

記事の目的


python-socketioのAttributeErrorを解決する

原因と対策


エラー原因

threadingモジュールのバージョン問題である。threadingの説明によると、main_thread関数は、バージョン 3.4以降で追加されたメソッドであるため、Python2系では使用できない。

対策

該当モジュールのmain_thread関数を修正する。
  1. python-socketioの該当モジュール(例/home/emptyset/.local/lib/python2.7/site-packages/socketio/client.py)を修正する
  2. 修正前
            global original_signal_handler
            if original_signal_handler is None and \
                    threading.current_thread() == threading.main_thread():
                original_signal_handler = signal.signal(signal.SIGINT,
                                                        signal_handler)
    修正後
            global original_signal_handler
            if original_signal_handler is None and\
                    threading.current_thread().isDaemon() is False:
                original_signal_handler = signal.signal(signal.SIGINT,
                                                        signal_handler)
    Clientのインスタンス生成がmainスレッドでのみ可能になってるが、この部分を削除した。代わりに、スレッドがデーモンかの判定を追加した。(mainスレッド以外がデーモンであると仮定)
  3. python-engineioの該当モジュール(例/home/emptyset/.local/lib/python2.7/site-packages/engineio/client.py)を修正する
  4. 修正前
            global original_signal_handler
            if original_signal_handler is None and \
                    threading.current_thread() == threading.main_thread():
                original_signal_handler = signal.signal(signal.SIGINT,
                                                        signal_handler)
    修正後
            global original_signal_handler
            if original_signal_handler is None and \
                    threading.current_thread().isDaemon() is False:
                original_signal_handler = signal.signal(signal.SIGINT,
                                                        signal_handler)
    Clientのインスタンス生成がmainスレッドでのみ可能になってるが、この部分を削除した。代わりに、スレッドがデーモンかの判定を追加した。(mainスレッド以外がデーモンであると仮定)
  5. 動作確認を行う
  6. $ python ./test_socketio_client.py 
    Try to connect to server(localhost:10000, namespace="/test", query="secret")
    Namespace may be invalid.(namespace="/test")
    Connected to server (localhost:10000, namespace="/test", query="secret")
    Send message {'test_data': 'send_from_client'} (namespace="/test")
    Emit message {'test_data': 'emit_from_client'} (namespace="/test")
    Received message {u'test_ack': u'send_from_server'}
    Received message {u'test_ack': u'emit_from_server'}
    ...

まとめ


  • python-socketioでAttributeError: 'module' object has no attribute 'main_thread'が出る場合の対処法について調査、記載した

参考文献



変更履歴


  1. 2020/05/10: 新規作成

0 件のコメント:

コメントを投稿

MQTTの導入

背景 IoTデバイスの接続環境構築のため、MQTT(mosquitto)の導入を行った。 記事の目的 MQTT(mosquitto)をUbuntuに導入する mosquitto ここではmosquittoについて記載する。 MQTT MQTT(Message Qu...