简体   繁体   English

使用StringIO for ConfigObj和Unicode

[英]Using StringIO for ConfigObj and Unicode

I am trying to use StringIO to feed ConfigObj. 我正在尝试使用StringIO来提供ConfigObj。 I would like to do this in my unit tests, so that I can mock config "files", on the fly, depending on what I want to test in the configuration objects. 我想在单元测试中执行此操作,以便我可以动态地模拟配置“文件”,具体取决于我要在配​​置对象中测试的内容。

I have a whole bunch of things that I am taking care of in the configuration module (I am reading several conf file, aggregating and "formatting" information for the rest of the apps). 我在配置模块中有很多事情要处理(我正在阅读其他应用程序的几个conf文件,聚合和“格式化”信息)。 However, in the tests, I am facing a unicode error from hell . 但是,在测试中,我面临着来自地狱的unicode错误。 I think I have pinned down my problem to the minimal functionning code, that I have extracted and over-simplified for the purpose of this question. 我想我已经把我的问题归结为最小的功能代码,我已经提取并过度简化了这个问题的目的。

I am doing the following: 我正在做以下事情:

#!/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()

It produces the following traceback: 它产生以下回溯:

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)

I am using Python-2.7.2 (32 bits) on linux. 我在linux上使用Python-2.7.2(32位)。 My locale for the console and for the editor (Kile) are set to fr_FR.utf8. 我对控制台和编辑器(Kile)的语言环境设置为fr_FR.utf8。

I thought I could do this. 我以为我能做到这一点。

From the io.StringIO documentation , I got this: io.StringIO文档中 ,我得到了这个:

The StringIO object can accept either Unicode or 8-bit strings, but mixing the two may take some care. StringIO对象可以接受Unicode或8位字符串,但混合两者可能需要一些小心。

And from ConfigObj documentation , I can do this: ConfigObj文档中 ,我可以这样做:

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

and this : 这个

infile: None infile:无

You don't need to specify an infile. 您不需要指定infile。 If you omit it, an empty ConfigObj will be created. 如果省略它,将创建一个空的ConfigObj。 infile can be : infile可以是:

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

'encoding': None 'encoding':无

By default ConfigObj does not decode the file/strings you pass it into Unicode [8]. 默认情况下,ConfigObj不会将您传递给Unicode [8]的文件/字符串进行解码。 If you want your config file as Unicode (keys and members) you need to provide an encoding to decode the file with. 如果您希望配置文件为Unicode(密钥和成员),则需要提供一个编码来解码文件。 This encoding will also be used to encode the config file when writing. 编写时,此编码也将用于编码配置文件。

My question is why does it produce this? 我的问题是为什么会产生这个? What else did I not understand from (simple) Unicode handling?... 还有哪些(简单的)Unicode处理无法理解?...

By looking at this answer , I changed: 通过查看这个答案 ,我改变了:

input_config = unicode(input_config, "utf8")

to (importing codecs module breforehand): to(导入编解码器模块breforehand):

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

in order to get rid of possible included byte order mark, but it did not help. 为了摆脱可能包含的字节顺序标记,但它没有帮助。

Thanks a lot 非常感谢

NB: I have the same traceback if I use StringIO.StringIO instead of io.StringIO. 注意:如果我使用StringIO.StringIO而不是io.StringIO,我有相同的回溯。

This line: 这一行:

input_config = unicode(input_config, "utf8")

is converting your input to Unicode, but this line: 将您的输入转换为Unicode,但是这一行:

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

is declaring the input to be a UTF-8-encoded byte string. 声明输入是UTF-8编码的字节串。 The error indicates a Unicode string was passed when a byte string was expected, so commenting out the first line above should resolve the issue. 该错误表示在预期字节字符串时传递了Unicode字符串,因此注释掉上面的第一行应该可以解决问题。 I don't have configobj at the moment so can't test it. 我目前没有configobj所以无法测试它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM