代码之家  ›  专栏  ›  技术社区  ›  Marius Gedminas

在setup.py中使用Unicode元数据的正确方法是什么?

  •  9
  • Marius Gedminas  · 技术社区  · 17 年前

    我正在使用setuptools为一个python包编写一个setup.py,并希望在long_描述字段中包含一个非ASCII字符:

    #!/usr/bin/env python
    from setuptools import setup
    setup(...
          long_description=u"...", # in real code this value is read from a text file
          ...)
    

    不幸的是,将unicode对象传递给setup()会中断以下两个命令之一,并出现unicodeencode错误

    python setup.py --long-description | rst2html
    python setup.py upload
    

    如果我对long_description字段使用原始的utf-8字符串,那么以下命令将以unicodedecode错误中断:

    python setup.py register
    

    我通常通过运行“python setup.py sdist register upload”来发布软件,这意味着对sys.argv进行检查并传递正确的对象类型的丑陋的黑客攻击是正确的。

    最后,我放弃并实施了另一个丑陋的黑客:

    class UltraMagicString(object):
        # Catch-22:
        # - if I return Unicode, python setup.py --long-description as well
        #   as python setup.py upload fail with a UnicodeEncodeError
        # - if I return UTF-8 string, python setup.py sdist register
        #   fails with an UnicodeDecodeError
    
        def __init__(self, value):
            self.value = value
    
        def __str__(self):
            return self.value
    
        def __unicode__(self):
            return self.value.decode('UTF-8')
    
        def __add__(self, other):
            return UltraMagicString(self.value + str(other))
    
        def split(self, *args, **kw):
            return self.value.split(*args, **kw)
    
    ...
    
    setup(...
          long_description=UltraMagicString("..."),
          ...)
    

    没有更好的方法吗?

    3 回复  |  直到 17 年前
        1
  •  5
  •   Reinout van Rees    17 年前

    这显然是在python 2.6中修复的distutils错误: http://mail.python.org/pipermail/distutils-sig/2009-September/013275.html

    Tarek建议将post-to-u服务器进行修补。修补程序应预处理 “data”参数并将其转换为Unicode,然后调用原始方法。见 http://mail.python.org/pipermail/distutils-sig/2009-September/013277.html

        2
  •  3
  •   Eric O. Lebigot    16 年前
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    from setuptools import setup
    setup(name="fudz",
          description="fudzily",
          version="0.1",
          long_description=u"bläh bläh".encode("UTF-8"), # in real code this value is read from a text file
          py_modules=["fudz"],
          author="David Fraser",
          author_email="davidf@sjsoft.com",
          url="http://en.wikipedia.org/wiki/Fudz",
          )
    

    我正在用上面的代码进行测试——没有错误来自——长描述,只来自rst2html;上传看起来工作正常(尽管我取消了实际上传),注册器要求我输入我没有的用户名。但是你评论中的回溯是有帮助的——它是自动转换为 unicode 在 register 导致问题的命令。

    见 the illusive setdefaultencoding 有关这方面的更多信息——基本上,您希望Python中的默认编码能够将编码的字符串转换回Unicode,但是设置它是很困难的。在这种情况下,我认为值得付出努力:

    import sys
    reload(sys).setdefaultencoding("UTF-8")
    

    或者说是正确的,你可以从 locale -有代码被注释掉了 /usr/lib/python2.6/site.py 你会发现这样做,但我现在就离开讨论。

        3
  •  1
  •   wbg    17 年前

    您需要更改Unicode长描述 u"bläh bläh bläh" 到普通字符串 "bläh bläh bläh" 并添加一个编码头作为文件的第二行:

    #!/usr/bin/env python
    # encoding: utf-8
    ...
    ...
    

    显然,您还需要使用UTF-8编码保存文件。