Python3 convert

Python3 に移行して随分たったが今頃気がつく。
コレ (cp932 to utf-8) ができない!
g_convert | PaePoi

GLib.convert() 関数の第一引数は gchar* なので cp932 の文字列を渡す必要がある。
Python3 では当然 bytes(b’…’) である。
そのまま指定するとバイト配列なくて文字列にしなさいというエラーになる。

#!/usr/bin/env python3

"""
    ConvertError: Must be string, not bytes
"""

import sys
from gi.repository import GLib

try:
    result, contents = GLib.file_get_contents(sys.argv[1])
    if result:
        try:
            text, bytes_read, bytes_written = GLib.convert(contents, len(contents), "UTF-8", "CP932")
            print(text)
        except Exception as e:
            print("ConvertError: {0}".format(e))
except Exception as e:
    print("FileError: {0}".format(e))

python3_g_convert

Python2 だと bytes と str って実は同じものだから問題ないのだけど。
Python3 では文字列に変換っっって何だそれ、cp932 だぞおい。

Python3 の文字列が UCS-4 になった弊害がこんなところに…
いや pygobject が今後対応してくれるかもしれないけど。

あれこれ試してみたけど現状 GLib や Gio では対処できないようだ。
しかたがないので Python 組み込みの decode() を使ってみる。

#!/usr/bin/env python3

import sys
from gi.repository import GLib

"""
    f = open(sys.argv[1], encoding="cp932")
    print(f.read())
    f.close()
"""

try:
    result, contents = GLib.file_get_contents(sys.argv[1])
    if result:
        try:
            str932 = contents.decode("cp932")
            print(str932)
        except Exception as e:
            print("ConvertError: {0}".format(e))
except Exception as e:
    print("FileError: {0}".format(e))

g_convert を使うより圧倒的に簡単なコードになってしまった。
というか組み込みの open() なら更に簡単だったり。

Vala からも参考にできるよう今までやってきたつもりだけど、もう無理。
しかし Vala の string が gchar* のままなのは本当に正解だよね。