os.listdir und filesystemencoding

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.
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mittwoch 5. April 2006, 07:02

So, ich bin jetzt ein wenig schlauer...

Es liegt definitiv an meinem Linux-System :(

Ich hab zwar mal das folgende Probiert, aber eine Lösung ist das nicht:

Code: Alles auswählen

import sys, locale

tryCodecs = ["utf-8", "latin-1"]

tryCodecs.append(sys.getdefaultencoding().lower())
tryCodecs.append(sys.getfilesystemencoding().lower())
tryCodecs.append(locale.getpreferredencoding().lower())

tryCodecs = tuple(set(tryCodecs))


def makeUnicodeList(items):
    def tryConvert(item):
        for codec in tryCodecs:
            try:
                return unicode(item, codec)
            except UnicodeError:
                pass
        raise UnicodeError("Can't convert item")

    result = []
    for item in items:
        if isinstance(item, unicode):
            result.append(item)
            continue

        try:
            item = tryConvert(item)
        except UnicodeError:
            continue
        else:
            result.append(item)

    return result

dirList = os.listdir(u".")
dirList = makeUnicodeList(dirList)
Das ganze hilft leider nicht viel. Ich hab zwar im Ergebnis unicode, aber es funktionieren dann keine Befehle wir os.stat() und os.path.* mehr. Da diese die Verz./Dateien nicht mehr finden können :(

Also hab ich nochmal ein neuen Test gemacht. Diesmal hab ich per Samba von Windows aus neue Dateien mit Umlauten gemacht. Siehe da, nun klappt es direkt! Also os.listdir() spuckt direkt unicode aus und os.stat() und os.path.* arbeiten richtig.


Das komische ist, das ich auf der Konsole folgendes für äöüß sehe: äöüà - Was für mich aussieht wie UTF-8. String Escaped ist das:
\xc3\xa4\xc3\xb6\xc3\xbc\xc3\x9f
Das für beide Fälle. Also einmal bei den Dateien die ich direkt auf dem Ubuntu-Rechner erzeugt hab und einmal die Dateien die ich per Samba
erstellt hab.
Ein Unterschied sieht man allerdings im mc! Die durch Samba erstellten Dateien sehe ich nur mit äöüà die unter Linux erstellten Dateien sehe ich richtig mit äöüß

Also liegt das ganze Problem wohl an meiner Linux installation :(

Nur sollte Python in dem Falle nicht irgendwie trotzdem funktionieren?

Kompliziert wird es, weil ich ja die Dateinamen als Webseite anzeigen lasse, mit Links. Diese Links sollten auch funktionieren ;)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 6. April 2006, 07:55

Also es liegt wohl wirklich an meiner Linux installation... Also hab ich das gemacht:

Code: Alles auswählen

sudo dpkg-reconfigure locales
und nur "de_DE.UTF-8" aktiviert... Siehe da die Umlaute sehe ich nun in meinem lokalen Test-Skript richtig und os.listdir() spukt alles korrekt in unicode aus!

Allerdings ist das nur die halbe Miete :cry: Denn meine WebApp hat weiterhin das selbe Problem :evil:

Ich hab mal folgendes gemacht:

Code: Alles auswählen

def get_file_encoding(f):
    if hasattr(f, "encoding"):
        return f.encoding
    else:
        return "not set"

print "sys.stdin.encoding:", get_file_encoding(sys.stdin)
print "sys.stdout.encoding:", get_file_encoding(sys.stdout)
print "sys.stderr.encoding:", get_file_encoding(sys.stderr)
print "sys.getdefaultencoding():", sys.getdefaultencoding()
print "sys.getfilesystemencoding():", sys.getfilesystemencoding()
print "locale.getpreferredencoding():", locale.getpreferredencoding()
Das spukt mir mit meine lokalen-TestSkript folgendes aus:
sys.stdin.encoding: UTF-8
sys.stdout.encoding: UTF-8
sys.stderr.encoding: None
sys.getdefaultencoding(): ascii
sys.getfilesystemencoding(): UTF-8
locale.getpreferredencoding(): UTF-8
Das selbe mach ich mit PyDown und siehe da, es spuckt immer noch andere Werte aus:
sys.stdin.encoding: None
sys.stdout.encoding: None
sys.stderr.encoding: None
sys.getdefaultencoding(): utf-8
sys.getfilesystemencoding(): ANSI_X3.4-1968
locale.getpreferredencoding(): ANSI_X3.4-1968
Wie kommt das zustande? :shock:

Ich denke deswegen funktioniert PyDown auch immer noch nicht mit Umlauten, weil Python versucht die Dateinamen mit ANSI_X3.4-1968 zu entschlüsseln :(

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Donnerstag 6. April 2006, 08:40

Dank Martin v. Löwis von der Maillingliste hab ich dafür nun auch ein Lösung:
Offenbar läuft Apache mit LANG=C. Es gibt zwei Möglichkeiten:

1. Du änderst die locale, in der Apache läuft, z.B. indem Du
in /etc/init.d/apache2 den Text

ENV="env -i LANG=C PATH=/usr/local/bin:/usr/bin:/bin"

durch

ENV="env -i LANG=de_DE.UTF-8 PATH=/usr/local/bin:/usr/bin:/bin"

ersetzt (besser würde man ENV in /etc/default/apache2 setzen)
Nach der Änderung geht's nun endlich!

EDIT:
Noch ein Anmerkung. URLs behandle ich nun so:

Code: Alles auswählen

url = urllib.quote(url.encode("utf-8"))
und zurück mit

Code: Alles auswählen

url = unicode(urllib.unquote(url), "utf-8")
Das klappt bei mir bisher unter Windows und Linux...

Außerdem muß ich bei ZIP-Dateien noch ein arcname = arcname.encode("cp437") machen, denn Namen in ZIP-Dateien werden immer mit dem codepage 437 gespeichert, siehe Kommentare im Python-Bug 878120
Leider steht das mal wieder nicht in der Doku, deswegen hab ich mal einen neuen BugReport geschrieben: http://sourceforge.net/tracker/index.ph ... tid=105470

Der Thread auf der Maillingliste ist hier zu finden:
"[Python-de] filesystemencoding jens" :lol:

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten