2009-07-21 7 views
8

estaba escribiendo un setup.py para un paquete Python usando setuptools y quería incluir un carácter no ASCII en el campo long_description:¿Cuál es la forma correcta de usar los metadatos Unicode en setup.py?

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

Desafortunadamente, pasando un objeto Unicode de configuración() rompe una de las tras dos comandos con un UnicodeEncodeError

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

Si utilizo una cadena de texto en UTF-8 para el campo long_description, a continuación, las siguientes mando rompe con una UnicodeDecodeError:

 
python setup.py register 

Por lo general, lanzo software ejecutando 'python setup.py sdist register upload', lo que significa que los hacks feos que miran en sys.argv y pasan el tipo de objeto correcto están fuera.

Al final me di por vencido y puesto en marcha un feo corte diferente:

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("..."), 
     ...) 

no hay una manera mejor?

Respuesta

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", 
    ) 

Estoy probando con el código anterior - no hay ningún error de --long-descripción, sólo a partir rst2html; La carga parece funcionar bien (aunque cancelo la carga en realidad) y registrarse me pide mi nombre de usuario que no tengo. Pero el rastreo en su comentario es útil: es la conversión automática a unicode en el comando register que causa el problema.

Consulte the illusive setdefaultencoding para obtener más información sobre esto: básicamente, desea que la codificación predeterminada en Python sea capaz de convertir su cadena codificada a unicode, pero es complicado configurarla. En este caso creo que vale la pena el esfuerzo:

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

O incluso ser correcta se puede obtener de la locale - no hay código comentado en /usr/lib/python2.6/site.py que se puede encontrar que hace esto, pero voy a dejar que la discusión por ahora.

+0

No estoy seguro de poder pegar la traza completa en un comentario aquí; el rastreo termina en /usr/lib/python2.6/distutils/command/register.py línea 264 (en post_to_server) donde intenta hacer esto: value = unicode (value) .encode ("utf-8"). Como pueden ver, estoy usando Python 2.6; una versión posterior de distutils tendría que ser algo realmente sangriento. –

+0

Observará que la reproducción requiere que tenga al menos un carácter que no sea ASCII en el campo. –

+0

Puedo reproducir la configuración de 'python'.Error de py register 'con las tres versiones de Python que tengo aquí: 2.4, 2.5 y 2.6. –

1

necesita cambiar su Unicode descripción larga u"bläh bläh bläh" a una cadena normal de "bläh bläh bläh" y añadir una cabecera de codificación que la segunda línea del archivo:

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

Obviamente, es necesario guardar el archivo con codificación UTF-8 codificación, también.

+0

"Si utilizo una cadena UTF-8 sin procesar para el campo long_description, el siguiente comando se rompe con UnicodeDecodeError: python setup.py registra" –

+0

_Not_ una cadena sin procesar (r "bläh bläh"), simplemente un perfecto cadena normal en la fuente. Me funcionó escribir el código. Asegúrese de guardar el archivo con codificación UTF-8. Dijiste que estabas cargando la long_description real desde un archivo de texto. Es posible que no decodifique correctamente el texto cuando lo lea desde el archivo. Asegúrese de decodificar el texto con la codificación correcta para el archivo de texto. – wbg

+0

Tengo problemas similares a Marius. Tengo diéresis en un CHANGES.txt que utilizo para mi descripción larga. codecs.open (..., encoding = ...), todas las cosas correctas. Pero al final, "setup.py --long-description" hace una "impresión" y "setup.py upload" hace un "unicode()". Y el unicode de una cadena con codificación utf8 falla y la impresión de una cadena Unicode falla. RAARGH. Marius: tu truco sucio funciona como un encanto. –

Cuestiones relacionadas