ついにfixutf8のTest()が動いた!だけど…
osutilインポートエラーの修正
osutilのインポートエラーが出ているので、まずはどのモジュールをインポートしようとしているのか突き止めようと思います。
ignoreの時と同じようにC:\Python27\Lib\site-packages\mercurialの中を探してみたところ、C:\Python27\Lib\site-packages\mercurial\cextの下にosutil.pyが存在していました。
from mercurial import util, osutil, dispatch, extensions, i18n
mercurialではなくmercurial.cextからimportするように変更します。
from mercurial import util, dispatch, extensions, i18n from mercurial.cext import osutil
この状態で実行してみたところ、インポートエラーが発生しなくなりましたが、別の個所でエラーになります。
win32helper.pyでmapcpがNoneでエラーになる
エラーが発生しているのは、fixutf8.pyではなく同じフォルダ内にあるwin32helper.pyのようです。
fixutf8.pyのtest()関数で呼び出しているwin32helper.rawprint()関数の内部で起きています。
u = s.decode('utf-8') try: if oldcp != 65001: s = u.encode('cp%d' % oldcp) except UnicodeError: if usecpmap: cpname, newcp = mapcp(u)
mapcp(u)で発生していて、uはtry節の直前で定義されていて、ブレイクポイントで中身を確認しても文字列が入っており、Noneではないので、mapcpがNoneということになります。
mapcpで検索をしてみたところ、先頭でmapcp = Noneと定義されていました。
さらに別の関数の内部で
def uisetup(ui): global usecpmap, mapcp usecpmap = ui.config('fixutf8', 'usecpmap', usecpmap) if usecpmap: import cpmap mapcp = cpmap.reduce
global変数としてmapcpにcpmap.reduceというものが代入されていました。
cpmap.reduceは同フォルダの別ファイルcpmap.pyの最後に定義されている関数でした。
def reduce(s): l = list(cps) for c in s: l = [cp for cp in charmap[ord(c)] if cp in l] return (l[0], cpmap[l[0]])
どうやらmapcp変数は関数ポインタとして利用されているようです。
ここでwin32helper.pyに戻って処理を良く見ると、関数ポインタがセットされるuisetup()関数は直接スクリプトを起動したときにどこからも呼ばれないことが分かります。
そこでrawprint()関数の内部で、Noneだったら関数ポインタを設定するように変更します。
if usecpmap: global mapcp if mapcp is None: import cpmap mapcp = cpmap.reduce cpname, newcp = mapcp(u)
この状態で実行したところ無事エラーが出なくなりました。
ついにfixutf8.pyのTest()実行 しかし
実行結果はこのようになりました。
this is a test と表示されました。
さっそく日本語ファイルがコミットできるか試してみます。
日本語ファイルは文字化けしたままでした。
テストが通ったから大丈夫だと思ったのですが、甘かったようです。
何やら警告のようなものが文字化けた状態で出ています。
fixutf8.pyを有効にしたままコミットしようとしたところ、別のエラーが発生しています。
File "mercurial\vfs.pyo", line 403, in __call__
TypeError: __init__() got an unexpected keyword argument 'checkambig'
TypeError: __init__() got an unexpected keyword argument 'checkambig'
存在しないcheckambig引数を渡してるようです。
エラーが出てるのがmercurial側のソースのようです。
次はこのエラーを調べてみることにします。