C# or VB.NET でファイルからPythonコードを読み込む時の文字コードの指定の仕方

タイトル長い・・・
この間、「IronPython を定義ファイル代わりに - k_maruの思うところ」を書いたのだが、その Python コードで日本語(非Ascii文字)を扱うと文字化けしてしまった。

テストコードは以下のような感じ。

<Test()> _
Public Sub 日本語も大丈夫()
  Dim user As New User()
  engine.Globals.Item("user") = user
  engine.ExecuteFile("JapaneseSampleInfo.py")

  Assert.AreEqual("ほげ", user.Name)
End Sub

日本語が書いてある JapaneseSampleInfo.py は以下。

user.Id = 1999
user.Name = 'ほげ'

結果がこれ。

あからさまに文字コードが一致しないので、とりあえず IronPythonソースコードを読んでみた。それによるとどうやらファイル中に文字コードを記述できるらしい。ちなみにデフォルトは Ascii で読み込んでいた。以下の規則にしたがってファイル中に文字コードを指定できる。

  1. ファイルの1行目または2行目に指定されている。
  2. 行の長さは 10 文字以上。
  3. 行の先頭は '#' (コメント)ではじまっている。
  4. 'coding' という文字列が含まれる。
  5. 'coding' の直後に ':' もしくは '=' が記述されている。
  6. ':' もしくは '=' の直後に 0 文字以上の空白とその後ろに連続する文字列がある。
  7. 上記の文字列が IronPython 上で判断できる文字コードの文字列である。

ということで、 JapaneseSampleInfo.py の先頭に以下の文字列を追加してみた。

#coding=shift_jis

で、テストを走らせて見ると、

通った。

python encoding」でググルと以下のような、文字列が引っかかった。

# -*- encoding: utf-8 -*-

見た目にはこっちの方がきれいなので、この方がいいかも知れない。

ちなみに PythonEngine クラスには、SystemState 型の Sys というプロパティがあって、そこには DefaultEncoding という System.Text.Encoding 型のプロパティがあった。素直に考えるとこの値で文字コードを指定できそうなものだが、値を指定してもまったく無意味だった。というより、 IronPython のコード中でファイルの文字コードを検出するときにこの値はまったく使われていないので無意味なのは当然といえば当然か。