2016-11-21 2 views
6

Ich arbeite mit Djangos Internationalisierungsfunktionen, um Übersetzungszeichenfolgen für eine Webanwendung zu generieren.UnicodeError Fehler beim Aufruf von Django i18n makemessages Befehl

Ein Problem entsteht, wo ich versuche, und rufen makemessages, und die vorhandene Sprache .po Datei enthält ein Sonderzeichen (wie $, £, etc).

Wo einer dieser existiert, versucht makemessages die vorhandene .po Datei zu laden und zu entschlüsseln. Wenn es dies tut, ich erhalte eine Fehlermeldung:

Traceback (most recent call last): 
File "manage.py", line 18, in <module> 
    execute_from_command_line(sys.argv) 
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 354, in execute_from_command_line 
    utility.execute() 
File "/usr/local/lib/python2.7/dist-packages/django/core/management/__init__.py", line 346, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 394, in run_from_argv 
    self.execute(*args, **cmd_options) 
File "/usr/local/lib/python2.7/dist-packages/django/core/management/base.py", line 445, in execute 
    output = self.handle(*args, **options) 
File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/makemessages.py", line 325, in handle 
    self.write_po_file(potfile, locale) 
File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/makemessages.py", line 458, in write_po_file 
    msgs, errors, status = gettext_popen_wrapper(args) 
File "/usr/local/lib/python2.7/dist-packages/django/core/management/commands/makemessages.py", line 51, in gettext_popen_wrapper 
    stdout = stdout.decode(stdout_encoding) 
File "/usr/lib/python2.7/encodings/utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xa2' in position 2105: ordinal not in range(128) 

Ich habe versucht, zurück durch die Zurückverfolgungs hier zu graben, aber ich bin ratlos, was passiert.

Es scheint, als ob Django die bestehenden .po Datei als UTF8 zu entschlüsseln versucht, aber dann, wenn es neu kodiert, es mit einem ASCII Codec.

Alle Einsichten, was falsch ist, würden massiv geschätzt werden.


Edit:

  • OS: Ubuntu 15.10 und OS X 10.11.6
  • Python: 2.7.10 und 2.7.11
  • Django: 1.8.14
  • Six: 1.10.0

Ich habe versucht, neu zu installieren Django/Sechs wie vorgeschlagen, aber der Fehler ist immer noch da.

Ubuntus localedef --list-archive:

en_AG 
en_AG.utf8 
en_AU.utf8 
en_BW.utf8 
en_CA.utf8 
en_DK.utf8 
en_GB.utf8 
en_HK.utf8 
en_IE.utf8 
en_IN 
en_IN.utf8 
en_NG 
en_NG.utf8 
en_NZ.utf8 
en_PH.utf8 
en_SG.utf8 
en_US.utf8 
en_ZA.utf8 
en_ZM 
en_ZM.utf8 
en_ZW.utf8 

Content-type der problematischen Übersetzungsdatei:

"Content-Type: text/plain; charset=UTF-8\n" 
+0

http://stackoverflow.com/questions/22106777/unicode-issue-with-makemessages-all-django-1-6-2-python-3-3 – trinchet

+0

Versuchen Sie dies: 'LC_CTYPE = en_US.UTF-8 python manage.py makemessages'; funktioniert es? –

+1

@ nobe4: Macht es einen Unterschied, wenn Sie es mit 'LC_CTYPE = en_US.UTF-8 python manage.py makemessages' ausführen? Und, BTW, was ist Ihr Betriebssystem und Version? –

Antwort

3

Hinweis: Dies ist eine andere Ausnahme Lage von this similar question in den Kommentaren erwähnt.

Es scheint mir der einzige Weg, dies kann passieren, wenn es eine Änderung an Ihrer Django-Installation gab oder es gibt einen Fehler in der Python 2.7-Version.

Ihr Stack ist:

> msgs, errors, status = gettext_popen_wrapper(args) 
> stdout = stdout.decode(stdout_encoding) 

gettext_popen_wrapper (? Auf django 1.8, das ist, was ich glaube, Sie verwenden, können Sie bestätigen) und popen_wrapper die stdout erzeugt (nach Kommentare/Docstrings zu entfernen und reindenting für Klarheit findet popen_wrapper und gettext_popen_wrapper auf github für den unverfälschten Code):

def popen_wrapper(args, os_err_exc_type=CommandError, universal_newlines=True): 
    try: 
     p = Popen(args, shell=False, stdout=PIPE, stderr=PIPE, 
       close_fds=os.name != 'nt', universal_newlines=universal_newlines) 
    except OSError as e: 
     strerror = force_text(e.strerror, DEFAULT_LOCALE_ENCODING, 
           strings_only=True) 
     six.reraise(os_err_exc_type, os_err_exc_type('Error executing %s: %s' % 
        (args[0], strerror)), sys.exc_info()[2]) 
    # NB: subprocess.Popen.communicate() should return two bytes 
    # (i.e. str in python 2) objects 
    output, errors = p.communicate() 
    return (
     output, 
     force_text(errors, DEFAULT_LOCALE_ENCODING, strings_only=True), 
     p.returncode 
    ) 

def gettext_popen_wrapper(args, 
          os_err_exc_type=CommandError, 
          stdout_encoding="utf-8"): 
    manual_io_wrapper = six.PY3 and stdout_encoding != DEFAULT_LOCALE_ENCODING 

    stdout, stderr, status_code = popen_wrapper(
     args, os_err_exc_type=os_err_exc_type, 
     universal_newlines=not manual_io_wrapper) 

    if manual_io_wrapper: 
     stdout = io.TextIOWrapper(io.BytesIO(stdout), encoding=stdout_encoding).read() 
    if six.PY2: 
     # EXCEPTION HIT ON THE FOLLOWING LINE 
     stdout = stdout.decode(stdout_encoding) 
    return stdout, stderr, status_code 

So stdout shoul d sei ein einfaches str Objekt (d.h.ein paar Bytes, die dekodiert werden müssen, wenn wir stdout.decode() anrufen. Wenn dies der Fall war, warum ist dann die Ausnahme in de Codierung? Wir müssten nur codieren, wenn das Objekt bereits ein Unicode-Objekt war, d.h. wenn es vom Typ unicode war. Und sicher genug, wenn wir die Zeile

stdout = stdout.decode('utf-8') 

vor

stdout = stdout.decode(stdout_encoding) 

Dann jetzt die decode Methode erste Versuche, encode die Unicode-stdout, die default encoding of ascii verwenden, die die Ausnahme verursacht Sie gesehen haben. Ich habe auch den gleichen Fehler durch manual_io_wrapper-True Einstellung, die die stdout = io.TextWrapper(...) Leitung verursachte auch passieren (was auch eine Unicode produziert), aber das ist nicht True sein sollte, weil Sie auf Python sind 2 nicht 3.

ich denke also entweder:

  • Sie eine schlechte von django oder six installieren haben, oder es ist editiert. Versuchen Sie, sie erneut zu installieren.
  • Sie haben einen Fehler in subprocess.Popen.communicate() und aus irgendeinem Grund traf es Zurückgeben eines unicode kein str (ich glaube, in Python 3, die möglich ist, wenn universal_newlines are turned on. Sie Meilenzahl auf eine neuere Version durch eine Neuinstallation Python oder ein Upgrade bekommen kann.

Meine obwohl Hauptsache ist, dass ich nicht glaube, es ist ein Thema Umwelt, es wäre interessant für alle Nachuntersuchungen zu wissen:.

  • welche Plattform Sie sind auf
  • was python 2.7 du benutzt
  • was Django Sie verwenden.
+0

Danke für die Antwort, ich werde meine Frage aktualisieren. – nobe4

1

In der folgenden Zeile irgendwie ist stdout nicht Byte str aber seine unicode und Sie bekommen Ausnahme während der impliziten Codierung dieser unicode.

stdout = stdout.decode('utf-8') 

, dass aufgrund der Tatsache ist, dass decode() auf Byte durchgeführt werden sollte str und wenn wir versuchen, decode auf unicode, in Python aufrufen 2.7, wird es einen impliziten Aufruf mit diesem unicode zu encode dauern, bis der decode, und diese Anruf an encode wird Standard charset verwenden, die in Python ascii ist.

unicode.encode() --> byte # results in str 
byte.decode() --> unicode # results in unicode 
unicode.decode() --> unicode.encode().decode() # implicit encode call 

Also, starten Untersuchung mit dem, was stdout unicode sein verursacht.

Danke.

Verwandte Themen