nikkie-ftnextの日記

イベントレポートや読書メモを発信

coloramaでinit()はいけません。代わりにjust_fix_windows_console()しましょう

はじめに

七尾百合子さん、お誕生日 60日目 おめでとうございます! nikkieです。

Today(※最近) I Learned です。

目次

懺悔:colorama.init()してましたァ!

ターミナルに色付きの出力をするために使ったライブラリ colorama。

https://pypi.org/project/colorama/

colorama.init()には副作用がありました。
https://github.com/tartley/colorama/blob/0.4.6/README.rst#initialisation

It's not safe to call init multiple times;

just_fix_windows_console()を使いましょう

執筆時の最新バージョン 0.4.6 (2022年10月リリース)で追加されています。
https://github.com/tartley/colorama/blob/0.4.6/CHANGELOG.rst

Add alternative to 'init()', called 'just_fix_windows_console'.

init()にあった副作用をなくしたそうです。
完全上位互換と理解しました。
https://github.com/tartley/colorama/blob/0.4.6/README.rst#initialisation

It's safe to call this function multiple times.
It's safe to call this function on non-Windows platforms, but it won't do anything.

実装 https://github.com/tartley/colorama/blob/0.4.6/colorama/initialise.py#L72-L93

  • sys.platform != "win32"ならば早期リターン(Windows以外では(何回呼び出しても)何もしない)
  • グローバル変数を見て早期リターン(何回呼び出しても安全)

crawl4aiがcolorama.init()を複数回呼ぶ実装だった

colorama.just_fix_windows_console()に気づいたきっかけの事象です。

crawl4aiというライブラリをDockerコンテナで動かす中で、RecursionErrorが送出されました(coloramaは0.4.6)。
同様のissueも挙がっています

原因箇所はコンストラクタ内のcolorama.init()と考えています1
https://github.com/unclecode/crawl4ai/blob/vr0.6.0/crawl4ai/async_logger.py#L115

判断理由は https://github.com/tartley/colorama/issues/351#issuecomment-1256947914 より

The solution would be to call colorama.init only once, outside the constructor.

crawl4aiのソースを書き換えて、init()の代わりにjust_fix_windows_console()で手元では直っています。

colorama.init()によるRecursionErrorに対応するプルリクエストがあり、学びを踏まえてjust_fix_windows_console()の存在をコメントしました。
https://github.com/unclecode/crawl4ai/pull/977#issuecomment-2833370817
crawl4aiとしてはcoloramaからrichに移行して対応したようです。
https://github.com/unclecode/crawl4ai/pull/977#issuecomment-2875298388

終わりに

colorama 0.4.6からはjust_fix_windows_console()を使いましょう。
Web上にはinit()の例が豊富にあると思いますが、just_fix_windows_console()が上位互換(と理解)です。
アップデートに追従していきましょう。


  1. なお私には「printするこれはロガーか?」というツッコミがあります(別に書くかも)