boah, kann EINMAL was funktionieren ? Cheetah Unicode

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.
Antworten
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

ich als alter php user und gewillter auf python umsteiger verzweifle langsam an der sache. ich hab zig probleme, die ich in php ned hatte. ich glaube python will mich los werden :(

naja, SO einfach nicht....nicht solange hier freundliche menschen sind die einem newb helfen :)

also, mein xml file ist utf-8: http://www.motolink.ch/amazon.xml

irgendwie mag cheetah keine umlaute. ich kann das file einlesen und in der konsole ausgeben, wobei da statt umlaute halt fragezeichen kommen.

aber wenn ich eine variable mit umlaut in cheetah ausgeben will kommt dies:

Code: Alles auswählen

Traceback (most recent call last):
  File "c:\python25\lib\site-packages\cherrypy-3.1b1-py2.5.egg\cherrypy\_cprequest.py", line 564, in respond
    cherrypy.response.body = self.handler()
  File "c:\python25\lib\site-packages\cherrypy-3.1b1-py2.5.egg\cherrypy\_cpdispatch.py", line 24, in __call__
    return self.callable(*self.args, **self.kwargs)
  File "C:\Python25\test\cptest.py", line 89, in search
    return str(template)
  File "c:\python25\lib\site-packages\cheetah-2.0.1-py2.5.egg\Cheetah\Template.py", line 982, in __str__
    def __str__(self): return getattr(self, mainMethName)()
  File "C:\Python25\test\hauptvorlage.py", line 185, in respond
    return _dummyTrans and trans.response().getvalue() or ""
  File "c:\python25\lib\site-packages\cheetah-2.0.1-py2.5.egg\Cheetah\DummyTransaction.py", line 32, in getvalue
    return ''.join(outputChunks)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 676: ordinal not in range(128)


ich hab ma googled und es scheint cheetah hat mit unicode probleme ?
BlackJack

Es gibt generell in Python Probleme wenn man versucht (Byte-)Zeichenketten mit Werten ausserhalb von ASCII mit Unicode zu mischen. Und das ist auch gut so™. Das verhindert nämlich, dass man am Ende Daten mit inkonsistenter Kodierung hat, wenn man nicht aufpasst.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

debian75 hat geschrieben:also, mein xml file ist utf-8: http://www.motolink.ch/amazon.xml
Hallo debian75!

Als Erstes solltest du dir das durchlesen und verstanden haben: http://www.python-forum.de/topic-5095.html

Und dann musst du dir klar werden, welches Encoding deine generierten HTML-Seiten haben sollen.

Nehmen wir mal an, dass du alles unter Debian programmierst, deine ``locale`` auf "iso-8859-15" eingestellt sind und deine HTML-Seiten im Encoding "iso-8859-15" generiert werden sollen.

Dann brauchst du dir um das Encoding deiner Python-Module keine großen Sorgen zu machen. Diese sind dann normalerweise auch automatisch "iso-8859-15". Also kommt in die Python-Module dieser Header rein:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
In den Kopf der Cheetah-Templates kommt diese Anweisung rein:

Code: Alles auswählen

#encoding iso-8859-15
Und im HTML-Code solltest du auch noch auf das Encoding aufmerksam machen:

Code: Alles auswählen

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
  <meta http-equiv="content-type" content="text/html; charset=iso-8859-15" />
</head>
<body>
...
Jetzt ist alles vorbereitet. Jetzt musst du dich nur noch darum kümmern, dass vom Python-Programm aus "iso-8859-15"-Bytestrings und kein Unicode oder UTF-8 übergeben wird.

Falls du einen UTF-8-Bytestring vor dir hast und diesen an Cheetah übergeben möchtest, dann könnte das ungefähr so aussehen:

Code: Alles auswählen

utf8string = '\xc3\x96sterreich'
my_template.my_value = utf8string.decode("utf-8").encode("iso-8859-15")
Ob du direkt auch Unicode übergeben kannst und dir dadurch die Umwandlung von Unicode nach "iso-8859-15" durch ``.encode("iso-8859-15")`` sparen kannst, das weiß ich jetzt nicht auswendig. Das müsste man ausprobieren.

mfg
Gerold
:-)
Zuletzt geändert von gerold am Dienstag 4. Dezember 2007, 08:49, insgesamt 1-mal geändert.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Jan-Peer
User
Beiträge: 166
Registriert: Dienstag 2. Oktober 2007, 10:55

Die Fehlermeldung hatte ich in den letzten Tagen - allerdings nicht im Zusammenhang mit Cheetah - öfters: Sie tritt in zwei Fällen auf:

1) Du versuchst, einen Unicode-String mit Zeichen, die in ASCII nicht enthalten sind, nach ASCII zu konvertieren

2) Du versuchst, einen String, der bereits Unicode ist, nach Unicode zu decoden.

Ich persönlich würde auf letzteres tippen und meinen (deinen) Code mal daraufhin abklopfen.

Schönen Gruß

Jan-Peer
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Keine Unicode Probleme hat man, wenn die ganze Toolchain intern unicode verwendet, das WSGI Gateway Unicode Liefert und die Templates alle in utf-8 vorliegen und die App darüber informiert ist, dass die Templates utf-8 sind.

Wenn du von PHP herwechselst bist du bei Cheetah glaub ich falsch. Schau dir mal Mako an (das ist PHP ähnlich) oder Jinja (das ist Smarty ähnlich). Die nutzen auch beide Unicode intern.

//EDIT: @gerold: warum sollte man irgendwann nicht utf-8 nutzen wollen? Selbst auf Windows bekommst du deine Editoren auf utf-8 umgestellt.
TUFKAB – the user formerly known as blackbird
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Unter Debian sehe ich auch keine Probleme UTF-8 zu nutzen. Seit Etch ist das sowieso Standard.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Leonidas hat geschrieben:Unter Debian sehe ich auch keine Probleme UTF-8 zu nutzen. Seit Etch ist das sowieso Standard.
Hallo!

Dann drehen wir das Ganze mal um. ;-)

Nehmen wir mal an, dass du alles unter Debian programmierst, deine ``locale`` auf "utf-8" eingestellt sind und deine HTML-Seiten im Encoding "utf-8" generiert werden sollen.

Dann brauchst du dir um das Encoding deiner Python-Module keine großen Sorgen zu machen. Diese sind dann normalerweise auch automatisch "utf-8". Also kommt in die Python-Module dieser Header rein:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf-8 -*-
In den Kopf der Cheetah-Templates kommt diese Anweisung rein:

Code: Alles auswählen

#encoding utf-8
Und im HTML-Code solltest du auch noch auf das Encoding aufmerksam machen:

Code: Alles auswählen

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>
...
Jetzt ist alles vorbereitet. Jetzt musst du dich nur noch darum kümmern, dass vom Python-Programm aus "utf-8"-Bytestrings und kein Unicode oder iso-8859-15 übergeben wird.

Falls du einen iso-8859-15-Bytestring vor dir hast und diesen an Cheetah übergeben möchtest, dann könnte das ungefähr so aussehen:

Code: Alles auswählen

iso885915string = '\xd6sterreich'
my_template.my_value = iso885915string.decode("iso-8859-15").encode("utf-8")
lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

debian75 hat geschrieben:ich als alter php user und gewillter auf python umsteiger verzweifle langsam an der sache. ich hab zig probleme, die ich in php ned hatte.
Doch, bei PHP hast du die auch, da sieht man sie nur nicht. Oder kann PHP mittlerweile nativ unicode (stichel)? ;)
ich glaube python will mich los werden :(
Ich glaube, dieses Gefühl kommt daher, dass python sehr viel rigoroser ist, was "style" angeht. Bei PHP muss man erstmal E_STRICT aktivieren, bevor man sieht, was man anstellt, bei python kriegt man's sofort ungefragt "mitten in die Fresse".
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

AFAIK kann PHP *immer* noch nicht vernünftig mit Unicode umgehen, richtig.

Zum Thema "Python ist restriktiv" gibt es bei SitePoint.com irgendwo einen Artikel, iirc von Harry Fuecks, der Perl, PHP, Python und Ruby auf ihre Reaktionen in Fehlerfällen vergleicht. Sollte man mal gelesen haben.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Y0Gi hat geschrieben:Zum Thema "Python ist restriktiv" gibt es bei SitePoint.com irgendwo einen Artikel, iirc von Harry Fuecks, der Perl, PHP, Python und Ruby auf ihre Reaktionen in Fehlerfällen vergleicht. Sollte man mal gelesen haben.
Meinst du das? Ist IMHO Quatsch... Probleme durch ignorieren lösen, klasse Idee.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Zum Thema "Python ist restriktiv" gibt es bei SitePoint.com irgendwo einen Artikel, iirc von Harry Fuecks, der Perl, PHP, Python und Ruby auf ihre Reaktionen in Fehlerfällen vergleicht. Sollte man mal gelesen haben.
Erstmal Danke für die Seite. Hättest du vielleicht noch einen Tip für den Titel des Textes, vom Herrn Fuecks sieht irgendwie keiner der Artikel nach dem was du sagtest, aus.
AFAIK kann PHP *immer* noch nicht vernünftig mit Unicode umgehen, richtig.
Das kommt aber wirklich mit PHP6, versprochen, ehrlich ;) Oder, um es mal innerhalb von PHP in Relation zu setzen: NACH den (ach so unwichtigen) Namespaces.
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

moin,

also ich habe jetzt in jede datei utf-8 zuoberst deklariert. dann habe ich alle dateien als utf-8 abgespeichert.

leider bekomme ich trotzdem den error:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 675: ordinal not in range(128)


ich hab auch versucht den string in iso umzuwandeln:

pagedata = pagedata.decode("utf-8").encode("iso-8859-15")


dann kommt aber:

XMLSyntaxError: Input is not proper UTF-8, indicate encoding ! von element tree...

*verzweiflung*
BlackJack

*Wobei* bekommst Du den Fehler denn?
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

BlackJack hat geschrieben:*Wobei* bekommst Du den Fehler denn?
also, ich habe jetzt alles wieder nach iso-8859-1 gemacht. dann habe ich meinen code zeile für zeile ausgeführt:

page = urllib.urlopen("http://blabla.xml")
pagedata = page.read()

1. Test: return pagedata

OK: ich bekomme den text im browser angezeigt, inkl. umlauten.

2. Test:

pagedata mit emelemt tree durchsuchen und ein paar xml inhalte in listen
schreiben.

OK: funktioniert

3. Test:

ich will die liste an mein cheetah template übergeben:
template.mainlist = list

ERROR: wie gesagt, motzt wegen asci rum.

4. Test

ich übergebe die liste nicht dem template, sondern mach direkt nen print:
print list

OK: wird in der konsule ausgegeben, JEDOCH nicht mit umlauten sondern mit so zeugs:

u"Thomas"
M\xfcnchen


was heisst das nun ? dass die inhalte der liste unicode sind ?
warum zeigs es bei direktem return im browser richtig an ?
warum falsch bei print in der konsole ?

h.e.l.p
BlackJack

1. Da arbeitest Du nur mit Bytes und nicht mit Zeichen.

3. Bei ``template.mainlist = list`` gibt's die Fehlermeldung? Das wäre überraschend.

4. Wenn Du eine Liste ausgibst, wird vom Inhalt die `repr()`-Form ausgegeben, das heisst die Funktion wird auf jedes Element der Liste angewendet. Damit mit man als Programmierer genau sieht was da *wirklich* drin steckt, werden Zeichenketten bei `repr()` derart "escaped", dass nur ASCII-Zeichen verwendet werden. Das ist nicht "falsch" sondern eben das Verhalten von Listen wenn man sie nach einer Zeichenkettendarstellung fragt.

Und ja, in der Liste sind Unicode-Zeichenketten. Nicht weiter verwunderlich wenn die aus einem XML-Dokument stammen, weil XML mit Unicode arbeitet.

Bei einem "direkten return" wie bei 1. gibst Du dem Browser die ungeparste XML-Datei. Sofern die in ASCII oder UTF-8 kodiert ist, oder die Kodierung in der XML-Deklaration richtig angegeben wurde, parst der Browser die ankommenden Bytes natürlich korrekt.

Also die Frage ist immer noch wobei *genau* der Fehler auftritt. Wenn ich mal raten müsste, mischt Du irgendwo Unicode mit normalen Zeichenketten und die normale Zeichenkette enthält Bytes ausserhalb vom ASCII-Bereich.
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

BlackJack hat geschrieben: Also die Frage ist immer noch wobei *genau* der Fehler auftritt. Wenn ich mal raten müsste, mischt Du irgendwo Unicode mit normalen Zeichenketten und die normale Zeichenkette enthält Bytes ausserhalb vom ASCII-Bereich.
also *wo* frage ich mich ja auch :).....ich weiss im moment nur, dass es entweder bei der übergabe ans template passiert oder aber halt später im template selbst.

ich weiss nicht genau was du mit "mischen" von zeichenketten meinst.
BlackJack

Mit mischen meine ich, es werden wahrscheinlich irgendwo Zeichenkette mit Bytewerten ausserhalb vom ASCII-Wertebereich mit Unicode-Zeichenketten verbunden. Dann wird nämlich versucht die Zeichenkette in Unicode umzuwandeln. Das geht ohne explizite Angabe der Kodierung aber nur bei ASCII:

Code: Alles auswählen

In [555]: 'hallo' + u'xyz'
Out[555]: u'halloxyz'

In [556]: 'hällö' + u'xyz'
---------------------------------------------------------------------------
<type 'exceptions.UnicodeDecodeError'>    Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

<type 'exceptions.UnicodeDecodeError'>: 'ascii' codec can't decode byte 0xc3 in position 1: ordinal not in range(128)
Wenn das beim Template passiert, enthält das vielleicht Bytes ausserhalb vom ASCII-Wertebereich!? Kann Cheetah mit Unicode umgehen!? Wenn nicht musst Du selbst vorher alle Unicode-Zeichenketten entsprechen kodieren.
debian75
User
Beiträge: 90
Registriert: Dienstag 27. November 2007, 01:05

ok, hab mal folgenden test gemacht:

Code: Alles auswählen

template.test = "Hühü" --> geht, wird richtig angezeigt
template.test = u"Hallo" --> geht nicht.

folgendes geht aber: 

test = u"Hello"
test = test.encode("iso-8859-15")
template.title = test
das problem ist jetzt nur noch, dass ich eine liste und nicht einen einzelnen string übergeben will. kann man eine ganze liste umwandeln oder muss ich das machen bevor ich sie fülle ?

thnx u gruss
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

debian75 hat geschrieben:muss ich das machen bevor ich sie fülle ?
Hallo debian75!

Beim Füllen. Oder vor dem Übergeben jeden Listeneintrag in einer Schleife durchlaufen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Antworten