Problem mit PyInstaller

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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Versuch mal die Konsole. IDLE muss stdout und stdin manipulieren für die Umlenkung in das eigene Fenster.
Benutzeravatar
__blackjack__
User
Beiträge: 14030
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.
Benutzeravatar
__blackjack__
User
Beiträge: 14030
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.
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich frage mich, warum überhaupt stdout ändern. Das sollte doch die aktuell eingestellte Codepage der Console automatisch ermitteln.

Code: Alles auswählen

C:\> chcp 1252
Wenn man statt dessen in Python den Hack macht, dann stimmt die Ausgabe nicht mehr weil "äöü" als "õ÷³" ausgegeben wird.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Benutzeravatar
__blackjack__
User
Beiträge: 14030
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. :-)
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

@__blackjack__: die Probleme tauchen dann nur in IDLE nicht auf? Das die bei Windows 20 Jahre nach der Jahrtausendwende keinen Euro darstellen koennen... nun gut.
Benutzeravatar
__blackjack__
User
Beiträge: 14030
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.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
Benutzeravatar
__blackjack__
User
Beiträge: 14030
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. ;-)
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

@__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:

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>
Benutzeravatar
__blackjack__
User
Beiträge: 14030
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.
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

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