Problem mit PyInstaller
- __blackjack__
- User
- Beiträge: 14028
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Das gilt für beide Probleme, also sowohl `detach()` als auch `click.echo()`.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
- __blackjack__
- User
- Beiträge: 14028
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Noch mal zu dem ``codecs.getwriter("cp1252")(sys.stdout.detach())``: Das vermischt IMHO ”altes” und ”neues” Python. `detach()` impliziert ein Python bei `sys.stdout` etwas aus dem `io`-Modul ist. Dann braucht man aber das `codecs`-Modul nicht mehr. Statt den `io.TextIOWrapper` durch einen `codecs.StreamWriter` zu ersetzen, würde ich den eher durch einen neuen `io.TextIOWrapper` ersetzen, also: ``io.TextIOWrapper(sys.stdout.detach(), 'cp1252')``. Dabei vielleicht auch noch anderen Zustand wie das `line_buffering` vom alten `io.TextIOWrapper` übernehmen, damit sich wirklich nur die Kodierung ändert.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Ich frage mich, warum überhaupt stdout ändern. Das sollte doch die aktuell eingestellte Codepage der Console automatisch ermitteln.
Wenn man statt dessen in Python den Hack macht, dann stimmt die Ausgabe nicht mehr weil "äöü" als "õ÷³" ausgegeben wird.
Code: Alles auswählen
C:\> chcp 1252
Das koennte ein Seiteneffekt von pyinstaller sein. Denn offensichtlich wird das Encoding auf ein uraltes cp850 gestellt. Inwiefern man da dann auch noch am Terminal selbst rumschrauben muss, steht auf einem anderen Blatt. Ich verstehe den Sinn, eine Anwendung die auf der Konsole ausgibt, mit pyinstaller zu basteln, eh nicht so ganz. Da wuerde ich dann immer auf eine GUI zurueckgreifen.
- __blackjack__
- User
- Beiträge: 14028
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@__deets__: cp850 ist die Standardkodierung die im Konsolenfenster erwartet wird. Python erkennt das dann auch so, egal ob mit oder ohne PyInstaller.
@Sirius3: Ich bin ja noch nicht so wirklich bei Python 3 angekommen, aber wenn ich meine Programme/Skripte portiere, dann würde ich wahrscheinlich auch `stdout` ändern damit die sich weiter so verhalten wie bisher. Denn bisher kodiere ich einfach alles als UTF-8, weil damit a) alles kodiert werden kann, und b) das auf fast allen Systemen so funktioniert. Für die doofen Ausnahmesysteme gibt's dann eine Option wo der Benutzer etwas anderes als UTF-8 wählen kann wenn er möchte.
@Sirius3: Ich bin ja noch nicht so wirklich bei Python 3 angekommen, aber wenn ich meine Programme/Skripte portiere, dann würde ich wahrscheinlich auch `stdout` ändern damit die sich weiter so verhalten wie bisher. Denn bisher kodiere ich einfach alles als UTF-8, weil damit a) alles kodiert werden kann, und b) das auf fast allen Systemen so funktioniert. Für die doofen Ausnahmesysteme gibt's dann eine Option wo der Benutzer etwas anderes als UTF-8 wählen kann wenn er möchte.

„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
- __blackjack__
- User
- Beiträge: 14028
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@__deets__: Die Konsole die man bei der PowerShell bekommt hat das Problem nicht mehr, da wird je nach Version UTF-16 oder UTF-8 mit oder ohne BOM verwendet. Und man kann die Kodierung in der cmd.exe-Konsole ja umschalten wenn man möchte. Die wollen da halt rückwärtskompatibel bleiben was die Standardeinstellung bei der Kodierung angeht — unter DOS war/ist das halt cp850 für Westeuropa. 

„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Um so mehr ein Grund, die Konsole fuer die Anwendung nicht zu benutzen. Oder kann man das Encoding irgendwie umstellen per ANSI-escape-sequenz oder sowas? Denn global konfigurieren bringt ja nix, per pyinstaller verteilte Pakete koennen das ja nicht vorraussetzen.
- __blackjack__
- User
- Beiträge: 14028
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Man könnte als Systemanforderung dokumentieren, das eine ordentliche Konsole, also zum Beispiel eine PowerShell verwendet werden muss, oder das und wie man die cmd.exe-Konsole umkonfiguriert, oder man packt eine Batch-Datei zum starten dazu.
Oder man konfiguriert die Konsole aus dem Programm heraus um, wenn das über die Windows-API geht. Oder man tauscht den `TextIOWrapper` aus, mit einem der die gleiche Kodierung verwendet, aber bei Fehlern nicht 'strict' reagiert.
Oder man verwendet kein `print()` sondern gibt das in einem Tk-Fenster aus.
Oder man verwendet kein Windows. Mein persönlicher Favorit.
Oder man konfiguriert die Konsole aus dem Programm heraus um, wenn das über die Windows-API geht. Oder man tauscht den `TextIOWrapper` aus, mit einem der die gleiche Kodierung verwendet, aber bei Fehlern nicht 'strict' reagiert.
Oder man verwendet kein `print()` sondern gibt das in einem Tk-Fenster aus.
Oder man verwendet kein Windows. Mein persönlicher Favorit.

„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
@__blackjack__: aber Python ist ja so intelligent, das Encoding das in der Konsole aktiv ist, zu übernehmen. Da muß man nichts an stdout herumhacken.
Ich habe jetzt auch gemerkt, es lag an der Schriftart, dass das cmd-Fenster sich so komisch verhalten hat:
Ich habe jetzt auch gemerkt, es lag an der Schriftart, dass das cmd-Fenster sich so komisch verhalten hat:
Code: Alles auswählen
C:\Users\sirus3> chcp 1252
Aktive Codepage: 1252.
C:\Users\sirus3> python
Python 2.7.13
Type "help", "copyright", "credits" or "license" for more information.
>>> print u"\xfc"
ü
>>> print u"\u20ac"
€
>>> ^Z
C:\Users\sirus3> chcp 850
Aktive Codepage: 850.
C:\Users\sirus3> python
Python 2.7.13
Type "help", "copyright", "credits" or "license" for more information.
>>> print u"\xfc"
ü
>>> print u"\u20ac"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python\lib\encodings\cp850.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character u'\u20ac' in position 0: character maps to <undefined>
- __blackjack__
- User
- Beiträge: 14028
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Sirius3: Ich weiss das Python die Kodierung erkennt, aber was nützt mir das? CP1252 funktioniert ja auch nur solange bis der der Scraper was aus einer Webseite holt und versucht auszugeben was in CP1252 nicht kodiert werden kann. Für Programme die man einem Endbenutzter zumuten kann, darf das IMHO nicht mit einer Ausnahme aussteigen. Und spätestens wenn der Benutzer die Ausgabe in einer Datei umleitet, fände ich das megablöd wenn ich da von lokalen Einstellungen abhängig bin ob das nun funktioniert, oder bei irgendwelchen Zeichen kracht. Also muss ich mich auch in Python 3 immer explizit um Kodierungen kümmern.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Ich wollte nur sagen, dass __deets__s Lösung weder nötig noch eine Lösung ist. Solange alles UTF-kodiert ist, hat man kein Problem, für Altsysteme braucht man irgendeine Lösung. Und da es scheinbar keine einfache Lösung gibt, muß man wohl in den einen oder anderen sauren Apfel beißen. Statt einer Exception hätte ich wohl lieber errors='replace' gesetzt, und das mit einer Warning kombiniert.