2009-07-21 16 views
8

stavo scrivendo un setup.py per un pacchetto Python utilizzando setuptools e volevano includere un carattere non ASCII nel campo long_description:Qual è il modo giusto per utilizzare i metadati Unicode in 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 
     ...) 

Purtroppo, passando un oggetto unicode di setup() rompe una delle dopo due comandi con un UnicodeEncodeError

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

Se uso una stringa UTF-8 prima per il campo long_description, quindi le seguenti pause di comando con un UnicodeDecodeError:

 
python setup.py register 

Generalmente rilascia software eseguendo "python setup.py sdist register upload", il che significa che i brutti hack che guardano a sys.argv e passano il giusto tipo di oggetto sono fuori proprio.

Alla fine ho rinunciato e implementato un diverso brutto 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("..."), 
     ...) 

non c'è un modo migliore?

risposta

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

sto testando con il codice di cui sopra - non c'è nessun errore da --long-descrizione, solo rst2html; il caricamento sembra funzionare bene (anche se annullo effettivamente il caricamento) e il registro mi chiede il mio nome utente che non ho. Ma il traceback nel tuo commento è utile: è la conversione automatica a unicode nel comando register che causa il problema.

Vedere the illusive setdefaultencoding per ulteriori informazioni su questo, in pratica si desidera che la codifica predefinita in Python sia in grado di convertire la stringa codificata in Unicode, ma è difficile impostarlo. In questo caso penso che sia valsa la pena:

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

O anche essere corretta si può ottenere dal locale - c'è codice commentato in /usr/lib/python2.6/site.py che si può trovare che fa questo ma lascio che la discussione per adesso.

+0

Non sono sicuro di poter incollare il traceback completo in un commento qui; il traceback termina in /usr/lib/python2.6/distutils/command/register.py riga 264 (nel post_to_server) dove tenta di farlo: value = unicode (value) .encode ("utf-8"). Come puoi vedere, sto usando Python 2.6; una versione successiva di distutils dovrebbe essere davvero roba del genere. –

+0

Si noterà che la riproduzione richiede effettivamente di avere almeno un carattere non ASCII nel campo. –

+0

Posso riprodurre l'installazione di Python.errore py register 'con tutte e tre le versioni di Python che ho qui: 2.4, 2.5 e 2.6. –

1

avete bisogno di cambiare il vostro unicode descrizione lunga u"bläh bläh bläh" in una stringa normale "bläh bläh bläh" e aggiungere un'intestazione di codifica come la seconda riga del file:

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

Ovviamente, è necessario salvare il file con codifica UTF-8 anche la codifica.

+0

"Se utilizzo una stringa UTF-8 non elaborata per il campo long_description, il seguente comando si interrompe con un UnicodeDecodeError: python setup.py registra" –

+0

_Non_ una stringa non elaborata (r "bläh bläh"), solo un perfetto stringa normale nella fonte. Ha funzionato solo digitando il codice. Assicurati di salvare il file con la codifica UTF-8. Hai detto che stavi caricando la vera long_description da un file di testo. È possibile che non si decodifichi correttamente il testo quando lo si legge dal file. Assicurati di decodificare il testo con la codifica corretta per il file di testo. – wbg

+0

Ho problemi simili a Marius. Ho delle dieresi in un file CHANGES.txt che uso per la mia lunga descrizione. codecs.open (..., encoding = ...), tutte le cose giuste. Ma alla fine, "setup.py --long-description" fa un "print" e "setup.py upload" fa un "unicode()". E unicode di una stringa con codifica utf8 fallisce e la stampa di una stringa unicode fallisce. RAARGH. Marius: il tuo trucco sporco funziona come un incantesimo. –

Problemi correlati