Das alte Thema: cgi.FieldStorage und Python3
Wer jetzt nicht sofort das Stöhnen anfängt, dem erkläre ich das mal: cgi.FieldStorage ist dazu da, Multipart-Datenströme (z.B. File-Uploads bei HTTP) zu entschlüsseln. In Python2.x waren strings noch byte-strings und alles hat wunderbar funktioniert. In Python3 kommt cgi.FieldStorage aber plötzlich nicht mehr mit byte-strings klar, da es intern immer noch native strings (die nun aber unicode strings sind) verwendet. Infolgedessen stirbt cgi.FieldStorage, sobald man es mit Bytes füttert. Aus der Datenleitung kommen nun aber leider Bytes, was cgi.FieldStorage nutzlos für Python3 Umgebungen macht. (Von der Annahme, das die .readline() Methode des Streams einen len-Parameter unterstützt, was Socket Streams aber nicht immer tun, will ich jetzt mal gar nicht sprechen)
Ich habe für Bottle ein Workaround gebastelt. Es passiert meine Tests und sollte funktionieren, ist aber so hässlich und hacky, das ich gern noch ein paar zweite Meinungen hätte. Hier die Idee:
In Python2.x packe ich wsgi.input in einen StreamIO oder eine tempfile mit 'w+b', je nach dem wie groß der Inhalt nach Angabe von Content-Length ist. Damit umgehe ich das .readline(1234) Problem. cgi.FieldStorage wirft dann (wie erwartet) rohe string-keys und string-daten aus.
In Python3 wird wsgi.input in ein ByteIO statt StringIO verpackt. Bevor es allerdings an cgi.FieldStorage übergeben wird, kommt noch ein io.TextIOWrapper(self.body, encoding='ISO-8859-1') drum rum. Damit bekommt cgi.FieldStorage Unicode, womit es einigermaßen klar kommt und wirft unicode keys und Daten zurück. Möchte man dann an die rohen Byte-Daten ran kommen, kann man sie wieder mit 'ISO-8859-1' kodieren, da der ISO Standard bijektiv ist.
Wie gesagt, es sollte klappen. Keine Ahnung, ob es das in freier Wildbahn auch tut. Meinungen/Ideen dazu?
cgi.FieldStorage und Python3
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Bottle: Micro Web Framework + Development Blog
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Das Problem ist seit Python3.0 bekannt. Auf WSGI1.1 oder 2.0 wartet man seit dem vergeblich. Auf angepasste Module ebenfalls. Python3 ist einfach noch nicht fertig.
Bottle: Micro Web Framework + Development Blog
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Kenne mich in den tiefen der Thematik nicht aus...
Wenn ich es richtig verstehe, willst du cgi.FieldStorage so belassen wie es ist und der Work-a-round drum rum bauen, oder? Wäre es da nicht klüger cgi.FieldStorage neu zu implementieren bzw. zu ändern?
Wenn ich es richtig verstehe, willst du cgi.FieldStorage so belassen wie es ist und der Work-a-round drum rum bauen, oder? Wäre es da nicht klüger cgi.FieldStorage neu zu implementieren bzw. zu ändern?
- Defnull
- User
- Beiträge: 778
- Registriert: Donnerstag 18. Juni 2009, 22:09
- Wohnort: Göttingen
- Kontaktdaten:
Nicht unbedingt, da cgi.FieldStorage 1000 Sonderfälle und Tricks kennt und fest verzahnt mit anderen Modulen ist. Bei jedem anderen Projekt würde ich dir zu stimmen, aber bei Bottle wäre dann das halbe Framework eine neu-Implementation von cgi.FieldStorage. Das möchte ich, wenn es geht, vermeiden.jens hat geschrieben:Kenne mich in den tiefen der Thematik nicht aus...
Wenn ich es richtig verstehe, willst du cgi.FieldStorage so belassen wie es ist und der Work-a-round drum rum bauen, oder? Wäre es da nicht klüger cgi.FieldStorage neu zu implementieren bzw. zu ändern?
Bottle: Micro Web Framework + Development Blog
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Ich meinte auch nicht, nur in Bottle eine neue Version von cgi.FieldStorage mit zu liefern, sondern wirklich die Version in Python zu verbessern. Bis in Python dann eine funktionierende Version vorliegt, kannst du ja den work-a-round nutzten...
Btw. wie machen es die anderen Frameworks?
Btw. wie machen es die anderen Frameworks?
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Was spricht denn gegen einen Workaround? So wie Defnull das beschrieben hat, kann man diesen ja später bei einer Lösung für FieldStorage in Py 3.x den Workaround einfach entfernen - also imho eine gute Idee für die aktuelle Lage.
@jens: Bei Pylons habe ich nichts explizites zu Python 3 gefunden, bei Django steht, dass Python 3 nicht wirklich unterstützt wird (was Du ja wohl weißt ) und bei TurboGears wird es explizit ausgeschlossen. Auch wenn das nicht alles abdeckt, so deutet es eben an, dass viele hier keinen Workaround betreiben und lieber ganz auf Python 3 Unterstützung verzichten.
Da ich mich so tief in der Materie auch nicht auskenne, weiß ich nicht, ob so eine Lösung wie Defnull sie beschrieben hat bei größeren Projekten zu Problemen führen kann. Vermutlich will eben kein größeres Framework sein eigenes Süppchen kochen...
@jens: Bei Pylons habe ich nichts explizites zu Python 3 gefunden, bei Django steht, dass Python 3 nicht wirklich unterstützt wird (was Du ja wohl weißt ) und bei TurboGears wird es explizit ausgeschlossen. Auch wenn das nicht alles abdeckt, so deutet es eben an, dass viele hier keinen Workaround betreiben und lieber ganz auf Python 3 Unterstützung verzichten.
Da ich mich so tief in der Materie auch nicht auskenne, weiß ich nicht, ob so eine Lösung wie Defnull sie beschrieben hat bei größeren Projekten zu Problemen führen kann. Vermutlich will eben kein größeres Framework sein eigenes Süppchen kochen...