Probleme mit cxfreeze und Python 3.1

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
BlackJack

@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.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

@BlackJack: Mit become.py natürlich.

Tut mir leid für den unqualifizierten Beitrag, ich konnte nicht widerstehen.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Dav1d
User
Beiträge: 1437
Registriert: Donnerstag 30. Juli 2009, 12:03
Kontaktdaten:

Mir tuts auch Leid, ich hab nicht mitgedacht
the more they change the more they stay the same
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

Hmm. Eher würde ich eine eigene print-Funktion verwenden:

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)
(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.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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...
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

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...
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.

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
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nee, ich hätte jetzt das selbe geschrieben wenn ich nicht vorher F5 gedrückt hätte. ;)

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
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
heiliga horsd

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! :wink:
Mein cxfreeze funktioniert wieder und ich bin ansonsten recht glücklich :)
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nun ja, diese ganze Encoding-Sch*** finde ich weitaus mehr als eine Lapalie, aber sei's drum.
Antworten