venv - virtual python imports

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
syntor
User
Beiträge: 88
Registriert: Donnerstag 2. Dezember 2010, 03:56

Hallo

Ich habe angefangen an einem Projekt zu arbeiten, das aus mehreren Git-repositories besteht.
Es war mir wichtig, an diesem Projekt arbeiten zu können, und den Code immer direkt im zugehörigen Repo anpassen zu können, ohne anschliessend den ganzen source irgendwohin zu kopieren, damit er in der richtigen Ordnerstruktur vorhanden ist, damit alle imports funktionieren.

Eine möglichkeit wäre gewesen, jedes Repository so aufzubauen:

Code: Alles auswählen

[...]
./lib/<importname>/code ist hier
[...]
Somit könnte ich einfach alle ./lib Ordner in sys.path einfügen. Jedoch gefällt es mir nicht, den unnützen "lib" order zu haben, auch nicht dass dann für jedes Repository ein Ordner mehr durchsucht werden muss.

Stattdessen habe ich mich über import-hooks schlau gemacht, und verwende nun einen
meta_path-hook um meine imports selbst aufzulösen.

Ich verwalte eine Liste mit aliases (also die virtuellen python module/packages) und ordne die einem Pfad zu.
Dadurch ist es möglich, Module/repositories logisch zu gruppieren, ohne dass sie in einer Ordnerstruktur abgelegt sind, die dies ermöglichen - auch kann ich so nested-repositories ohne Submodule simulieren - oder gar Subversion-like "subdir-checkouts" simulieren.

https://github.com/alshain/venv

Was den Code betrifft: quick and dirty in ein eigenes Paket verwandelt. Die Klasse kommt dann wohl noch weg...

Das Ding scheint jedenfalls zu funktionieren... Ich schätze mal es gibt noch fehlerhafte imports, wenn ein Alias nur teilweise im (sub)package-Namen vorhanden ist. (Alias = url, import urllib)

Was denkt ihr dazu, oder gibts sowas schon? Ich habe mir virtualenv kurz angeschaut, aber es scheint nicht das zu machen, was ich möchte. Ich gebe aber zu, dass ich es nur überflogen habe :)
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Git Submodule kennst du?
syntor
User
Beiträge: 88
Registriert: Donnerstag 2. Dezember 2010, 03:56

auch kann ich so nested-repositories ohne Submodule simulieren
Ja, aber das die sind nicht in der Lage all das zu lösen, zudem wollte ich das nicht.
syntor
User
Beiträge: 88
Registriert: Donnerstag 2. Dezember 2010, 03:56

Hallo

Ich bin mir jetzt nicht ganz sicher, weshalb ich nur eine Antwort bekommen habe.

Gibt es das einfach schon, oder habe ich das miserabel erklärt?
lunar

Du bekommst wohl deswegen keine Antwort, weil niemand sonst sowas benötigt. Ich zumindest kann mir kein Szenario vorstellen, in welchem diese Lösung wirklich nötig oder auch nur sinnvoll wäre, dementsprechend glaube ich, dass Du ein Problem löst, welches gar nicht existiert. Doch ich lasse mich gerne überzeugen, wenn Du ein solches Szenario aufzeigen kannst, indem man mit "git submodule" oder auch nur mit distutils und virtualenv nicht auskommen würde.
syntor
User
Beiträge: 88
Registriert: Donnerstag 2. Dezember 2010, 03:56

Also den Zusammenhang mit git-submodules sehe ich ehrlichgesagt nicht direkt. (Ja, am Anfang habe ich das mal erwäht, obwohl ich mich jetzt ehrlichgesagt gerade frage, weshalb :) )


Zuerst einmal, die Situation: Ich arbeite an einem Projekt mit anderen Entwicklern zusammen via Git-repositories. Im Moment sind es rund zehn davon (Framework + Plugins).

virtualenv ist nicht, wie es der Name suggeriert, virtuell. Es wird eine komplett neue Laufzeitumgebung erstellt, inklusive Interpreter und Anhängsel, alles wird kopiert.

venv soll keine Alternative zu virtualenv sein, es verfolgt andere Ziele.
Kurz gesagt erlaubt es, Paketnamen auf eine beliebige Ordnerstruktur abzubilden.


Wenn ich am entwickeln bin, möchte ich direkt den Code in meinem Repository ausgeführt bekommen. Das heisst, ich möchte nicht jedesmal meinen Code aus meinem Repository in das Python-Environment kopieren müssen. Anstatt eine Installationsroutine zu schreiben, (distutils) kannst du dir bei venv diesen Schritt schenken. Natürlich kannst du es auch kombinieren.

Man könnte natürlich sagen, warum nicht ein via virtualenv eine Entwicklungsumgebung schaffen, und die Git-Repositories direkt in das Python-Environment legen.
Normalerweise, hat man jedoch nicht nur Code in den Repositories. Man hat noch Dokumentation, Tests und je nachdem noch andere Dateien, die nicht wirklich in die Python-Umgebung gehören. Des weiteren müsste man dann einen Symlink anlegen, da der Code ja dann in einem Unterordner des Git-Repositories liegt.

Git kennt zwar sogenannte sparse-checkouts, das heisst, dass alle Ordner die nicht auf diesem Teilpfad liegen, nicht heruntergeladen werden. Jedoch wird dennoch dieser Teilpfad auch im lokalen Repository angelegt, anstatt dass dieser Teilpfad als "root" fungieren würde.

Ein Symlink würde diese Problematik lösen, da dann der Code nicht mehr in einem bestimmten Ordner liegen müsste. Jedoch hat dies den Nachteil, dass es sicher unter Windoes nicht funktioniert.

venv dagegen klinkt sich in den import-Prozess ein, und kann zur Laufzeit entscheiden, woher nun ein bestimmes Paket/Submodule geladen werdon soll. Es

Ein kleiner, eher nebensächlicher Vorteil ist noch, ist, dass sys.path nicht angepasst wird, ein unnötiges traversieren der Ordner wird umgangen, dies wird umso wichtiger je mehr Pfade darin sind.

Ich hoffe, ich konnte hier die Idee die hinter venv liegt und warum distutils und virtualenv dazu nicht geeignet sind aufzeigen.
lunar

Ehrlich gesagt, nein. Ich erkenne immer noch kein Szenario, in dem Dein "venv" obligatorisch wäre. Ich sehe nicht einmal irgendwelche konkreten Vorteile in dem beschriebenen Szenario mit mehreren, voneinander abhängenden Repos. Ich hätte einfach ein "virtualenv" erzeugt, die Abhängigkeiten mittels setuptools dorthin installiert [1] und anschließend dieses "virtualenv" zum Testen genutzt.

Du wirst mir nun antworten, dass Du weder setuptools noch virtualenv nutzt, worauf ich Dir anschließend meine Zweifel an Deinen Entwicklungsprozeduren darlegen werde, denn distutils/setuptools zum Deployment und virtualenv zur Bewältigung der Abhängigkeiten sind eigentlich obligatorisch für vernünftige Entwicklung mit Python. Möchtest Du das jetzt wirklich durchexerzieren? Schließlich musst Du Dein Projekt mir gegenüber nicht verteidigen, ich habe Dir ja nur erklärt, warum Du keine Antworten erhältst.

[1] Mit "python setup.py develop" verweist der Eintrag im Import-Pfad auf den Quelltextbaum, so dass man nicht erneut installieren muss, wenn man eine Abhängigkeit aktualisiert.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

syntor hat geschrieben:virtualenv ist nicht, wie es der Name suggeriert, virtuell. Es wird eine komplett neue Laufzeitumgebung erstellt, inklusive Interpreter und Anhängsel, alles wird kopiert.
virtualenv nutzt ausschliesslich symlinks, kopiert wird nur env/bin/activate(und andere Skripte?).
Normalerweise, hat man jedoch nicht nur Code in den Repositories. Man hat noch Dokumentation, Tests und je nachdem noch andere Dateien, die nicht wirklich in die Python-Umgebung gehören. Des weiteren müsste man dann einen Symlink anlegen, da der Code ja dann in einem Unterordner des Git-Repositories liegt.
Also so oft muss ich Tests von anderen Projekten nicht ausführen und die Dokumentation findet sich auf der jeweiligen Webseite. Unabhängig davon kann man aber dafür problemlos git submodule nutzen.

Letztendlich kann man aber auch einfach virtualenv nutzen und über pip die Abhängigkeiten aus den Git Repositories installieren, damit habe ich den entscheidenden Vorteil den Code nicht ändern zu müssen und alles was distribute nutzt kann man so installieren dass symlinks verwendet werden so dass Updates problemlos statt finden. Desweiteren funktioniert dieser Ansatz problemlos mit tox und führt garantiert zu keinen Fehlern zur Laufzeit. Womit wir zur Frage kommen was machst du eigentlich wenn du keine Zugriff auf die fremden Repositories hast?
syntor
User
Beiträge: 88
Registriert: Donnerstag 2. Dezember 2010, 03:56

Zuerst einmal danke für die ausführlichen Antworten!
lunar hat geschrieben:Ehrlich gesagt, nein. Ich erkenne immer noch kein Szenario, in dem Dein "venv" obligatorisch wäre. Ich sehe nicht einmal irgendwelche konkreten Vorteile in dem beschriebenen Szenario mit mehreren, voneinander abhängenden Repos. Ich hätte einfach ein "virtualenv" erzeugt, die Abhängigkeiten mittels setuptools dorthin installiert [1] und anschließend dieses "virtualenv" zum Testen genutzt.
Ich möchte auch nicht sagen, dass das Skript obligatorisch ist :) Man kann das was es macht, problemlos auch ohne das Skript erreichen, das habe ich in meinem Post ja auch geschrieben. Für mich ist es blos Komfort, den ich mit anderen Mitteln nicht zu erreichen vermag, deshalb gefällt mir diese Diskussion jetzt auch schon viel mehr, da ich nun sehe, was auch möglich ist. Es geht mir ja auch nicht darum, das Projekt zu verteidigen (Projekt ist jetzt fast übertrieben, es ist ja mehr ein Codeschnipsel), sondern nur zu erklären, was ich mir dabei gedacht habe und da ich das nun dargelegt habe, die Möglichkeit zu haben, andere Wege kennenzulernen, die mein Script gutmöglich überflüssig machen.

An diesem Punkt ist es vielleicht noch sinnvoll anzufügen, dass auf meiner Hauptmaschine Windows läuft, und ich leider nicht in den Genuss von Symlinks komme, ausser ich gehe über cygwin.
lunar hat geschrieben:Ich hätte einfach ein "virtualenv" erzeugt, die Abhängigkeiten mittels setuptools dorthin installiert [1] und anschließend dieses "virtualenv" zum Testen genutzt.
Bei dem was ich gemeint hatte, bezog ich mich auf das Testen während des Entwicklungsprozess. Da möchte ich nicht immer die Installationsroutine ausführen nur weil ich eine Zeile geändert habe. Aber ich glaube nicht wirklich, dass du das gemeint hast.
DasIch hat geschrieben:virtualenv nutzt ausschliesslich symlinks, kopiert wird nur env/bin/activate(und andere Skripte?).
This script only symlinks a small portion of the standard library into the environment, and so on Windows it is feasible to simply copy these files over.
Ok, wir hatten beide nicht ganz recht. Das steht im Vergleich zu dem, was es anders macht als virtual-python. Aber wenn du ein Paket in eine solche Python Umgebung installierst, wird es dann nicht dorthin kopiert, auch wenn du sie schon hast? Vielleicht liegt das ja auch daran, dass ich Windows habe. Möglich wäre ja, dass auf Linux die Pakete an einem zentralen Ort mit einem Versions-Suffix abgelegt werden, und dann per symlink darauf verwiesen wird.
Normalerweise, hat man jedoch nicht nur Code in den Repositories. Man hat noch Dokumentation, Tests und je nachdem noch andere Dateien, die nicht wirklich in die Python-Umgebung gehören. Des weiteren müsste man dann einen Symlink anlegen, da der Code ja dann in einem Unterordner des Git-Repositories liegt.
Also so oft muss ich Tests von anderen Projekten nicht ausführen und die Dokumentation findet sich auf der jeweiligen Webseite. Unabhängig davon kann man aber dafür problemlos git submodule nutzen.[/quote]
Ich weiss nicht genau, was du mit den "Tests von anderen Projekten". Ich wollte sagen, dass ich in der Python-Umgebung ja dann nur den Code aus dem Repository haben kann, da er sonst ja nicht gefunden werden kann, wenn der Code in einem Unterordner des Repositories liegt, und ich - wegen Windows - keine symlinks verwenden kann, und auch auf neuen Versionen das nicht gut gelöst wird, obwohl es ja seit Vista unterstützt wird.

Ja klar, du hast Recht wenn du sagst, dass ich stattdessen einfach verschiedene Repositories bzw Submodules verwenden könnte.
Letztendlich kann man aber auch einfach virtualenv nutzen und über pip die Abhängigkeiten aus den Git Repositories installieren, damit habe ich den entscheidenden Vorteil den Code nicht ändern zu müssen und alles was distribute nutzt kann man so installieren dass symlinks verwendet werden so dass Updates problemlos statt finden.
Ok, ich schätze das erledigt dann meine Frage von vorhin erledigt, zu einem Teil zumindest. Wie funktioniert es denn genau?
Womit wir zur Frage kommen was machst du eigentlich wenn du keine Zugriff auf die fremden Repositories hast?
Das verstehe ich jetzt nicht. Was hat venv mit Zugriff auf Git-Repositories zu tun? venv hat ja gar nichts mit Git am Hut, es war nur der Kontext, in welchem ich es verwende.
Du wirst mir nun antworten, dass Du weder setuptools noch virtualenv nutzt, worauf ich Dir anschließend meine Zweifel an Deinen Entwicklungsprozeduren darlegen werde, denn distutils/setuptools zum Deployment und virtualenv zur Bewältigung der Abhängigkeiten sind eigentlich obligatorisch für vernünftige Entwicklung mit Python.
Ja da hast du Recht. Ich bin in Sachen Python auch noch sehr neu ;)

Nur sind diese Dinge auf Windows einfach wirklich argmühsam, wie ich jetzt gerade festgestellt habe, als ich setuptools installieren wollte, und der dachte ich hätte kein Python installiert.



Wäre es Richtig zu sagen, dass venv eine Teilmenge von virtualenv ist, wobei es einfach die Aufgabe des Betriebssystems die Symlinks aufzulösen übernimmt?
lunar

Du musst nicht jedes Mal eine Installationsroutine ausführen, wenn sich eine Zeile geändert hat. Mit "python setup.py develop" wird einfach der Quelltextbaum in den Import-Pfad eingefügt, ein "import" verweist daher immer auf die aktuelle Datei. So kannst Du ein einzelnes "virtualenv" anlegen, welches quasi automatisch immer die aktuelle Version Deines Programms verwendet bzw. zum "Import" anbietet.

Zur Verwaltung der virtuellen Umgebungen bietet sich tox an. Damit kann man Unittests automatisch in verschiedenen virtuellen Umgebungen mit verschiedenen Python-Versionen oder verschiedenen Versionen der Abhängigkeiten laufen lassen, außerdem lässt sich tox auch wunderbar in Hudson integrieren.

Ich für meinen Teil nutze tox zur Ausführung der automatischen Tests, und nutze ein davon unabhängiges virtualenv mit "python setup.py develop", um immer die aktuelle Version meines Projekts zum Spielen im Interpreter zur Verfügung zu haben.
syntor
User
Beiträge: 88
Registriert: Donnerstag 2. Dezember 2010, 03:56

Ok.. ich habe am Wochenende jetzt meinen Desktop auf Gentoo umgestellt und dort funktioniert das alles ohne Gefrickel wie auf Windows :)

Danke für die Info, sieht wohl so aus als ob ich mein Snippet jetzt nicht mehr wirklich brauchen werde :)

Ausser ich hätte mal das doch sehr aussergewöhnliche Bedürfnis, den Importmechanisms anzupassen, dann weiss ich ja jetzt wenigestens wie es geht :)

Vielen Dank!
Antworten