What's the right way to use Unicode metadata in setup.py?

python, setuptools, unicode

Solution

It is apparently a distutils bug that has been fixed in python 2.6: http://mail.python.org/pipermail/distutils-sig/2009-September/013275.html

Tarek suggests to patch post_to_server. The patch should pre-process all values in the "data" argument and turn them into unicode and then call the original method. See http://mail.python.org/pipermail/distutils-sig/2009-September/013277.html

Problem

I was writing a setup.py for a Python package using setuptools and wanted to include a non-ASCII character in the long_description field: ``` #!/usr/bin/env python from setuptools import setup setup(... long_description=u"...", # in real code this value is read from a text file ...) ``` Unfortunately, passing a unicode object to setup() breaks either of the following two commands with a UnicodeEncodeError ``` python setup.py --long-description | rst2html python setup.py upload ``` If I use a raw UTF-8 string for the long_description field, then the following command breaks with a UnicodeDecodeError: ``` python setup.py register ``` I generally release software by running 'python setup.py sdist register upload', which means ugly hacks that look into sys.argv and pass the right object type are right out. In the end I gave up and implemented a different ugly hack: ``` 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("..."), ...) ``` Isn't there a better way?

Original source