Probleme mit cxfreeze und Python 3.1
@Dav1d: "einfach" `str` "überschreiben"? Wie das? Was soll das bringen? Und dann müsste man überall das neue `str` verwenden, man kommt aber wohl kaum an allen Code heran, der das Original verwendet.
Mir tuts auch Leid, ich hab nicht mitgedacht
the more they change the more they stay the same
Hmm. Eher würde ich eine eigene print-Funktion verwenden:
(das geht bestimmt hübscher?)
Dieses 'print' beachtet ein eventuell per locale.setlocale geändertes Encoding von sys.stdout, wirft keine UnicodeError-Ausnahmen sondern ersetzt nicht darstellbare Zeichen mit einem Platzhalter ('\ufffe' oder '?'), kann übergebene Byte-Strings direkt in einen Stream schreiben, falls dieser im Binärmodus geöffnet wurde, und sollte sich ansonsten wie das Standard-'print' verhalten.
*edit* hatte noch einen Fehler drin, jetzt behoben.
Code: Alles auswählen
import locale
import sys
def myprint(*args, **kwargs):
stream = kwargs.get('file', sys.stdout)
sep = kwargs.get('sep', ' ')
end = kwargs.get('end', '\n')
enc_in = enc_out = getattr(stream, 'encoding', locale.getpreferredencoding())
if stream == sys.stdout:
enc_out = locale.getlocale()[1] or enc_out
if 'b' in stream.mode:
sep, end = (char.encode(enc_out, 'replace') for char in (sep, end))
stream.write(sep.join(arg if isinstance(arg, bytes) else (arg if isinstance(arg, str) else repr(arg)).encode(enc_out, 'replace') for arg in args))
else:
stream.write(sep.join((arg if isinstance(arg, str) else repr(arg)).encode(enc_out, 'replace').decode(enc_in, 'replace') for arg in args))
stream.write(end)
Dieses 'print' beachtet ein eventuell per locale.setlocale geändertes Encoding von sys.stdout, wirft keine UnicodeError-Ausnahmen sondern ersetzt nicht darstellbare Zeichen mit einem Platzhalter ('\ufffe' oder '?'), kann übergebene Byte-Strings direkt in einen Stream schreiben, falls dieser im Binärmodus geöffnet wurde, und sollte sich ansonsten wie das Standard-'print' verhalten.
*edit* hatte noch einen Fehler drin, jetzt behoben.
codecs.EncodedFile() mit `replace` als Wert für `error` dürfte die Anforderungen doch eigentlich erfüllen, oder? Man müsste sich nur noch eine kleine Wrapperfunktion schreiben, die immer in das gewünschte Encoding übersetzt. Dies kann man z.B. auch als Datenstrom an `print()` übergeben, so dass man die Funktion nicht komplett neu implementieren muss...
Ja, daran dachte ich auch, aber es funktionierte nicht so, wie ich erwartet hatte. Kann aber gut sein, dass ich auf dem Schlauch stehe. Hier z.B.snafu hat geschrieben:codecs.EncodedFile() mit `replace` als Wert für `error` dürfte die Anforderungen doch eigentlich erfüllen, oder? Man müsste sich nur noch eine kleine Wrapperfunktion schreiben, die immer in das gewünschte Encoding übersetzt. Dies kann man z.B. auch als Datenstrom an `print()` übergeben, so dass man die Funktion nicht komplett neu implementieren muss...
Code: Alles auswählen
>>> import sys, codecs
>>> stdout = codecs.EncodedFile(sys.stdout, 'cp850', errors='replace')
>>> print('test', file=stdout)
TypeError: must be bytes or buffer, not str
>>> print(b'test', file=stdout)
TypeError: must be bytes or buffer, not str
Nee, ich hätte jetzt das selbe geschrieben wenn ich nicht vorher F5 gedrückt hätte.
Es gibt 3 Möglichkeiten:
1. Ich bin zu dumm, die Funktion zu verstehen
2. Die Python-Entwickler wollen einen verarschen
3. Die Funktion ist leider kaputt
Code: Alles auswählen
>>> import sys, locale, codecs
>>> f = codecs.EncodedFile(sys.stdout, locale.getpreferredencoding())
>>> f.write('bla')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.1/codecs.py", line 806, in write
data, bytesdecoded = self.decode(data, self.errors)
File "/usr/lib/python3.1/encodings/utf_8.py", line 16, in decode
return codecs.utf_8_decode(input, errors, True)
TypeError: must be bytes or buffer, not str
>>> f.write(b'bla')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.1/codecs.py", line 807, in write
return self.writer.write(data)
File "/usr/lib/python3.1/codecs.py", line 356, in write
self.stream.write(data)
TypeError: must be str, not bytes
1. Ich bin zu dumm, die Funktion zu verstehen
2. Die Python-Entwickler wollen einen verarschen
3. Die Funktion ist leider kaputt
Wie gesagt, die Nutzer meines Programms ohne eine Python-Installation werden mit diesem Schönheitsfehler leben müssen. Ihr müsst euch also hier nicht weiter den Kopf über solche Lapalien zerbrechen!
Mein cxfreeze funktioniert wieder und ich bin ansonsten recht glücklich
Mein cxfreeze funktioniert wieder und ich bin ansonsten recht glücklich