この記事には古い内容が含まれています。以下で挙げている issue は、 mojimoji 最新版である v0.0.13 で解決されています(2024/01/13 追記)。
現在 mojimoji v0.0.12 以下を使用している方は、v0.0.13 にアップグレードするか、拙作 Habachen に移行されることをおすすめします。
はじめに
- mojimoji とは
- Habachen とは
mojimoji と Habachen は、いずれもネイティブ拡張を用いた CPython 上で動作する日本語の全角/半角変換ライブラリです。 Habachen は私が開発しています。
Habachen では、全角/半角に加えひらがな/カタカナの相互変換も可能になっている他、旧来の mojimoji に見られたいくつかの問題点が解消されています。
また、Python 3.13 以降の wheel(ビルド済みパッケージ)を提供しており、Python 3.14 から正式にサポートされるようになった free threading (No-GIL) モードにも対応しています(2025/10/25 追記)。
以前書いた Habachen の紹介記事ではそのパフォーマンスに焦点を当てていますが、元々は mojimoji の不満点を解消した CPython 用の日本語文字列変換ライブラリを自前で作り上げることが目的でした1。
Issues
mojimoji v0.0.12 では以下の issue が報告されています。
2024年1月現在、更新に伴い close 済みです(2024/01/13 追記)。
バックスラッシュが変換されない
タイトルの通りです。
- Habachen の場合
期待通り、半角バックスラッシュ (U+005C) と全角バックスラッシュ (U+FF3C) が相互に変換されます2。
>>> import habachen
>>> habachen.han_to_zen('\\')
'\'
>>> habachen.zen_to_han('\')
'\\'
めっちゃ環境依存なバグ
上のリンクで貼られていたコードでは再現できなかったのですが、以下のコードを Google Colab 上で実行してみたところ、おそらく報告されているものと同じ不具合により、セッションがクラッシュしました。
!pip install mojimoji
import mojimoji
def bug_test(text):
text = mojimoji.zen_to_han(text)
text = mojimoji.han_to_zen(text)
return text
bug_test("゙ンライフレキ")
どうやら文字列全体が半角の濁点から始まる場合に han_to_zen() 関数内で未定義動作を踏んでしまっているようです。今回の試行でのクラッシュは、未初期化変数の参照3とメモリブロックの範囲外アクセスが連鎖して malloc ヘッダが破壊されたことにより発生したものと見られます。
- Habachen の場合
以下のコードは、 Google Colab 上で正常に動作します。
!pip install habachen
import habachen
def bug_test(text):
text = habachen.zen_to_han(text)
text = habachen.han_to_zen(text)
return text
bug_test("゙ンライフレキ")
Cannot install on Python 3.12
本文で書かれている通り、 Cython によって生成される C++ コード内で古い API が使われているために Python 3.12 でインストールできないという問題です。 mojimoji では Python 3.3 以降非推奨である文字列表現形式 (Py_UNICODE*) がバッファとして利用されており、これと紐づけられている関数群が Python 3.12 で軒並み廃止されたことが影響しています。
なお、この issue に対しては現在プルリクエストが出されています。
- Habachen の場合
Python 3.12 でもインストールできます。
リンク追加要請の issue もありましたが、ここでは割愛します。
最後に
mojimoji はシンプルで扱いやすいライブラリですが、現在バージョン 0.0.12 ではいくつか基本的な部分での問題が確認されています4。Habachen では、ここで取り上げた問題は解消されており、パフォーマンスも改善されている他、バージョン 0.6.0 からは Python 3.14 で正式に導入された free threading (No-GIL) モードにも対応しているので、高速な全角/半角・ひらがな/カタカナ変換ライブラリを求めている方は、ぜひ Habachen の使用を検討していただければと思います。
本記事では CPython のネイティブ拡張を扱いましたが(C/C++ 難しい…)、最後にオススメの Pure Python 文字列変換ライブラリのリンクを貼っておきます。 Pure Python 実装ライブラリの利点としては、 C コンパイラが利用できない環境でもインストールできること、 Python 本体のバージョンアップによる内部 API 変更の影響を受けにくいことが挙げられます。
- jaconv
- Utsuho
-
全角/半角変換自体はそれほど複雑な処理ではないのですが、それなりに速いものを CPython 拡張モジュールとしてバグなく実装するのは結構面倒くさかったりします。 ↩
-
環境によっては、半角バックスラッシュが半角の円マークとして表示されるかもしれませんが、コードポイント上は同じものを指しています。 ↩
-
この時点で未定義動作となります。未定義動作なので、環境や条件によっては別の不具合が生じたり、問題が表出しなかったりしても不思議ではありません。 ↩
-
作者の方は他のことで忙しいのか、issue #21 が立てられてから1年以上更新されて
いないようですいなかったのですが、先日アップグレードされたようです(2024/01/13 追記)。 ↩