5

StringIOを使用してConfigObjにフィードしようとしています。単体テストでこれを実行して、構成オブジェクトでテストする内容に応じて、構成「ファイル」をその場でモックできるようにします。

構成モジュールで処理していることがたくさんあります(残りのアプリの情報を集約して「フォーマット」するいくつかのconfファイルを読んでいます)。しかし、テストでは、私は地獄からのユニコードエラーに直面しています。私は、この質問の目的のために抽出して過度に単純化した、最小限の機能コードに問題を突き止めたと思います。

私は次のことをしています:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import configobj
import io

def main():
    """Main stuff"""

    input_config = """
    [Header]
    author = PloucPlouc
    description = Test config

    [Study]
    name_of_study = Testing
    version = 9999
    """

    # Just not to trust my default encoding
    input_config = unicode(input_config, "utf-8")

    test_config_fileio = io.StringIO(input_config)    
    print configobj.ConfigObj(infile=test_config_fileio, encoding="UTF8")

if __name__ == "__main__":
    main()

次のトレースバックが生成されます。

Traceback (most recent call last):
File "test_configobj.py", line 101, in <module>
    main()
File "test_configobj.py", line 98, in main
    print configobj.ConfigObj(infile=test_config_fileio, encoding='UTF8')
File "/work/irlin168_1/USER/Apps/python272/lib/python2.7/site-packages/configobj-4.7.2-py2.7.egg/configobj.py", line 1242, in __init__
    self._load(infile, configspec)
File "/work/irlin168_1/USER/Apps/python272/lib/python2.7/site-packages/configobj-4.7.2-py2.7.egg/configobj.py", line 1302, in _load
    infile = self._handle_bom(infile)
File "/work/irlin168_1/USER/Apps/python272/lib/python2.7/site-packages/configobj-4.7.2-py2.7.egg/configobj.py", line 1442, in _handle_bom
    if not line.startswith(BOM):
UnicodeDecodeError: 'ascii' codec can't decode byte 0xef in position 0: ordinal not in range(128)

LinuxでPython-2.7.2(32ビット)を使用しています。コンソールとエディター(Kile)のロケールはfr_FR.utf8に設定されています。

私はこれができると思いました。

io.StringIOのドキュメントから、次のようになりました。

StringIOオブジェクトは、Unicodeまたは8ビットの文字列を受け入れることができますが、2つを混合することには注意が必要です。

そして、ConfigObjのドキュメントから、私はこれを行うことができます:

>>> config = ConfigObj('config.ini', encoding='UTF8')
>>> config['name']
    u'Michael Foord'

そしてこれ

infile:なし

infileを指定する必要はありません。これを省略すると、空のConfigObjが作成されます。infileは次のようになります:

   [...]
   A StringIO instance or file object, or any object with a read method. The filename attribute of your ConfigObj will be None [5].

'エンコーディング':なし

デフォルトでは、ConfigObjはUnicodeに渡すファイル/文字列をデコードしません[8]。構成ファイルをUnicode(キーとメンバー)として使用する場合は、ファイルをデコードするためのエンコードを提供する必要があります。このエンコードは、書き込み時に構成ファイルをエンコードするためにも使用されます。

私の質問は、なぜそれがこれを生み出すのかということです。(単純な)Unicode処理から他に何が理解できませんでしたか?...

この答えを見て、私は変更しました:

input_config = unicode(input_config, "utf8")

to(コーデックモジュールbreforehandのインポート):

input_config = unicode(input_config, "utf8").strip(codecs.BOM_UTF8.decode("utf8", "strict"))

含まれている可能性のあるバイト順マークを取り除くために、しかしそれは役に立ちませんでした。

どうもありがとう

注意:io.StringIOの代わりにStringIO.StringIOを使用した場合、同じトレースバックがあります。

4

1 に答える 1

4

この行:

input_config = unicode(input_config, "utf8")

入力をUnicodeに変換していますが、次の行は次のとおりです。

print configobj.ConfigObj(infile=test_config_fileio, encoding="UTF8")

入力がUTF-8でエンコードされたバイト文字列であることを宣言しています。このエラーは、バイト文字列が予期されたときにUnicode文字列が渡されたことを示しているため、上記の最初の行をコメントアウトすると問題が解決するはずです。configobj現時点では持っていないので、テストできません。

于 2012-08-06T20:08:15.497 に答える