Python 2 / Python 3 Kompatibilitaet: ``contextlib.nested``

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
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ich stecke gerade in einem Projekt in dem ich zum einen mit Python 2.6 und zum anderen mit Python 3.x kompatibel sein muss, gleichzeitig aber gern `nested` nutzen wuerde.
Wegen Python2.6 faellt der eingebaute Support von `with` fuer `nested` aus.

Meine aktuelle Idee waere eine eigene Version `nested` auszuliefern, aber das wuerde ich gerne vermeiden.

Habt ihr eine bessere Idee?
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

cofi hat geschrieben:Meine aktuelle Idee waere eine eigene Version `nested` auszuliefern, aber das wuerde ich gerne vermeiden.
Ich wüsste aber nicht, wie es sonst gehen sollte. AFAIK kann man nicht einfach so die Fähigkeiten beliebiger Statements in Python verändern, ohne direkt was am Quellcode zu machen.
lunar

@snafu: Was haben Statements denn mit der Frage zu tun?! Es geht um die Funktion "nested()", eine Anweisung mit diesem Namen gibt es gar nicht. Das Problem ist in diesem Fall, dass es die Funktion "nested()" in Python 3 nicht mehr gibt, da die "with" Anweisung nun von Haus aus mehrere Generatoren unterstützt. "with" in Python 2 wiederum kann das nicht, so dass man hier auf "nested()" angewiesen ist. Was offensichtlich zu Konflikten führt, wenn der Quelltext sowohl unter Python 2 als auch unter Python 3 laufen muss.

@cofi: Vielleicht kann 2to3 "nested()" umwandeln. Ansonsten führt kein sinnvoller Weg an einer eigenen Implementierung der "nested()"-Funktion vorbei. Bei kleinen Funktionen kannst Du alternativ zwei Module schreiben, eines für Python 2, indem Du "nested()" in der Funktion nutzt, eines für Python 3, in dem Du das normale "with"-Statement nutzt. Dann kannst Du per "sys.version_info[0]" auswählen, welches Modul importiert werden soll. So musst Du halt jede betroffene Funktion einmal für Python 2 und einmal für Python 3 schreiben.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@lunar: Ich denke, mir ist durchaus klar, worum es geht. Deshalb sagte ich, dass man ein Statement (hier: `with`) nicht einfach so "Python-3-fähig" machen kann. Und `nested()`, was dann wohl die einzige Alternative wäre, will er ja eigentlich nicht benutzen (bzw nicht für die Nutzung unter Python 3 modifizieren). Das führte mich dann zu dem Schluss, dass dies vermutlich nicht funktionieren wird, ohne direkt etwas am CPython-Quellcode zu verändern. Weil: Wenn unter Python 3 kein `nested()` zur Hilfe genommen werden soll, dann kann Programmcode, der unter beiden Versionszweigen laufen soll, in meinen Augen nur ein angepasstes `with`-Statement für Python 2 verwenden - das wäre dann also der Umkehrschluss. Daher kam ich darauf und bin davon ausgegangen, dass die Herleitung soweit klar wäre. War sie aber wohl nicht...
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wie gesagt, das naheliegendste für mich wäre sowas in der Art:

Code: Alles auswählen

try:
    from contextlib import nested
except ImportError:
    if not on_py3k:
        raise
    nested = lambda *mgrs: mgrs
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

@snafu nested() muss einen contextmanager zurückgeben, deine Implementation tut es nicht.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Stimmt. Ich hatte die Idee unter Python 3 gar nicht getestet. :(
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Danke fuer die Antworten, ich hatte es schon befuerchtet.
Ich habe mich dafuer entschieden ``nested`` aus Python2.6 selbst mit auszuliefern und sowohl in Python2.6 als auch in Python 2.7+ zu verwenden.

2to3 ist fuer mich da die schlechtere Option, weil ich zum einen gerne _eine_ Codebase habe und zum anderen den Extra-Schritt aus der Entwicklung raushalten möchte, unabhaengig davon, ob es in dem Fall funktioniert.

@snafu: Ein gepatchter Interpreter ist dann doch zu viel des Guten :) Wenn das wirklich eine Option waere, koennte man ja auch gleich Python 2.7 verwenden.
Die "naheliegende" Lösung in korrekt ist dann doch wieder eine eigene Implementierung von ``nested``, was ich ja vermeiden wollte.
Antworten