Oddbean new post about | logout
 Zur Ehrenrettung von Python sei gesagt, daß es im "print()" explodiert und nicht im "getnames()".

Das ist schon mal was.

https://assets.chaos.social/media_attachments/files/111/062/228/714/503/149/original/ec80d3f5f41cb942.png 
 Vermutlich ist es sinnvoll, POSIX weiter einzuschränken und zu verlangen, daß Dateinamen valide utf8 Strings sein müssen.

Aber das ist nicht, was im Standard steht und auch nicht, was alle Dateisysteme tun und es kann zu einigermaßen unerwartetem Verhalten führen.

Zudem ist es so, daß einige Programmiersprachen (Python zum Beispiel) von Strings verlangen, daß sie ein valides Encoding haben (und per Default utf8 verwenden), aber Dateinamen und Strings äquivalent setzen.

Das kann Ärger machen. 
 @87c98d39 Nicht ganz korrekt, Python verarbeitet strings als Unicode-Strings.

Und konvertiert mittlerweile defaultmässig in fast allen locales per utf8 die Ein- und Ausgabe.
(Gott sei Dank)

(Die früheren 3er Pythons waren "korrekter" und hatten "ascii" als default wenn nichts besseres gefunden werden konnte: was zu Probleme führte, Programme die Umlaute auf stdout ausgaben, crashten mit einem EncodingError wenn man ihre Ausgabe redirected hat.) 
 @d598c4a5 wie sollte der Code zum untar oben Deiner Meinung nach idealerweise aussehen? 
 Ah, Rust hat natürlich einen eigenen Typ für Syscalls, OsString.

Und OsString.to_string_lossy() für die Anzeige:
https://doc.rust-lang.org/std/ffi/struct.OsString.html#method.to_string_lossy

"Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER." 
 Python hat lustigerweise in sys eine Funktion getfilesystemencoding() ohne Parameter, als ob alle Filesysteme immer dasselbe Encoding hätten und das nicht Path-dependent sei.

https://docs.python.org/3/library/sys.html#sys.getfilesystemencoding

Und es gibt os.fsencode() und os.fsdecode().

https://docs.python.org/3/library/os.html#os.fsencode

Damit kann man den Kram dann anfassen.

https://assets.chaos.social/media_attachments/files/111/062/480/066/666/589/original/d23102fe865b1cd1.png 
 @87c98d39 Klar. Die Namen sind Bytes-Strings, da kann alles drin sein. print() möchte aber für deine Ausgabe das richtig machen, muss also erst mal interpretieren, was schief geht. 
 @f7edc411 Wie sollte tarnames.py Deiner Meinung nach idealerweise geschrieben sein? 
 @87c98d39 Mit welchem Tool hast du denn das Tarfile generiert? Python thematisiert Encoding Issues in Tarfile auch in ihrer Doku. Es gibt inzwischen ein TAR Format dass encodings von Dateinamen thematisiert aber von GNU Tar noch nicht das default format ist. "tar --help" zeigt bei mir format=GNU, es müsste Posix sein.

https://en.wikipedia.org/wiki/Tar_(computing)#cite_note-gnu.org2-18 
 @aa320704 Mit gnu tar.

Ich habe das o.a. C-Programm auf xfs laufen lassen und dann keks eingetart.

Aber das ist nicht das Problem. Alle Dateisystemfunktionen von Python arbeiten mit str, aber Posix würde bytes verlangen.

Ich habe dann os.fsencode() gefunden, und damit kommt man auch an Namen mit ungültigen Encodings ran. Intern macht Python ganz grauenhafte Dinge.