2009-07-21 40 views
8

我在寫一個setup.py使用setuptools的Python包,並希望包括在LONG_DESCRIPTION領域的非ASCII字符:在setup.py中使用Unicode元數據的正確方法是什麼?

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

不幸的是,經過一個Unicode對象設置()或者突破的以下兩個命令與UnicodeEncodeError

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

如果我使用原始UTF-8字符串爲LONG_DESCRIPTION字段,那麼下面的命令中斷以UnicodeDecodeError:

 
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
#!/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="[email protected]", 
     url="http://en.wikipedia.org/wiki/Fudz", 
    ) 

我正在與上述代碼測試 - 存在從--long-說明中,僅對從rst2html沒有錯誤;上傳似乎工作正常(雖然我實際取消上傳)並註冊要求我輸入我沒有的用戶名。但是評論中的回溯很有幫助 - 這是register命令中導致問題的自動轉換爲unicode

請參閱the illusive setdefaultencoding以獲取更多信息 - 基本上你希望Python中的默認編碼能夠將編碼後的字符串轉換回unicode,但設置它很困難。在這種情況下,我認爲這是值得的:

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

甚至是正確的,你可以從locale得到它 - 有一個在/usr/lib/python2.6/site.py註釋掉的代碼,你可以找到,做這一點,但我會離開這個討論目前。

+0

我不知道我可以將完整的追溯信息粘貼到此處的評論中;回溯結束於/usr/lib/python2.6/distutils/command/register.py第264行(在post_to_server中),它嘗試執行此操作:value = unicode(value).encode(「utf-8」)。正如你所看到的,我使用Python 2.6;一個更高版本的distutils將不得不是真正的流血事件。 – 2009-07-27 18:12:37

+0

您會注意到,複製要求您在該字段中至少有一個非ASCII字符。 – 2009-07-27 18:14:06

+0

我可以重現'python設置。py註冊'錯誤與我在這裏的所有三個版本的Python:2.4,2.5和2.6。 – 2009-07-27 18:15:28

1

您需要將您的unicode長的描述u"bläh bläh bläh"更改爲正常的字符串"bläh bläh bläh"並添加編碼頭作爲文件的第二行:

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

顯然,你需要使用UTF-8的文件編碼也是如此。

+0

「如果我在long_description字段中使用原始UTF-8字符串,則以下命令將與UnicodeDecodeError:python setup.py寄存器」 – 2009-07-27 18:10:04

+0

_不是原始字符串(r「blähbläh」),只是一個完美的源代碼中的正常字符串。 它只爲我輸入代碼工作。確保你使用UTF-8編碼保存文件。 你說你是從一個文本文件加載真正的long_description。當您從文件中讀取文本時,可能無法正確解碼文本。確保使用正確的文本文件編碼解碼文本。 – wbg 2009-08-04 16:45:47

+0

我對Marius有類似的問題。我在CHANGES.txt中使用了變音符號,用於描述長描述。 codecs.open(...,encoding = ...),所有正確的東西。但最終,「setup.py --long-description」會執行「print」和「setup.py upload」做一個「unicode()」。 UTF8編碼字符串的unicode失敗,並且unicode字符串的打印失敗。 RAARGH。 Marius:你骯髒的黑客就像一個魅力。 – 2009-09-17 12:16:00

相關問題