Modul zum Nachinstallieren fehlender Pythonpakete

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.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

@BlackJack, hmm ... ja das ist wirklich gefährlich.
Siehst Du eine Möglichkeit, daß die Module selbst nicht ausgeführt werden, sondern nur der evtl. Fehlerbericht?
BlackJack

@Nobuddy: Keine 100% zuverlässige und vor allem keine die *Du* implementieren könntest.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

@BlackJack, sowas habe ich mir schon gedacht ..., auf jeden Fall war`s für mich eine gute Übung. :wink:
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Wer aber mal Lust hat modul_control.py zu testen, ist herzlichst dazu eingeladen.
Hier findest Du modul_control.py: https://gist.github.com/3034277

Erstelle einen Ordner, füge ein oder mehrere testmodule.py hinzu und erzeuge darin einen Fehler, z.B. ein Modul das nicht installiert oder importiert ist. Stelle modul_control.py in den gleichen Ordner und starte dies dann.

Über Eure Resonanz würde ich mich freuen!

Grüße Nobuddy

Nachtrag: Bin gerade dabei, noch ein paar Ungereimtheiten zu beheben, poste morgen einen neuen Link!
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dafür dass ein Modul dessen Aufgabe es ist Module nachzuinstallieren gleich beim import von ``psutil`` crasht, find ich ja fast schon ironisch.

Wenn ich es starte kommt eine Menge absolut nutzloser leerzeilen. Ich habe leider keinen 4K Bildschirm, fände es besser wenn dein Modul etwas ökonomischer mit meinem Bildschirmplatz umgehen würde.

Und irgendwie wird nicht klar wie man es überhaupt nutzt. Ich hab man das Repo geklont und es gestartet. Keine Dokumentation und der Code ist so seltsam, dass ich gar keine sonderliche Lust habe den durchzugehen um zu erraten wie das zu Nutzen gedacht ist. Irgendwie geht es einen Ordner durch? Ich hätte eher gedacht dass es automatisch in ein laufendes Programm eingreift wenn ein Modul geladen wird welches nicht installiert ist, aber offenbar nicht.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo Leonidas,
Danke für Dein Info, ich werde die Fehler beheben. :wink:

psutil ist bei mir ein Extrapaket, das dürfte bei Dir dann nicht installiert sein (Fehler).

Ich habe auch keinen 4K Bildschirm, könnte es sein daß dies von einer Deiner Dateien im Ordner kommt, die überprüft werden?

An der Dokumentation werde ich arbeiten und mein Code lässt sich bestimmt noch verbessern. Kleine Infos zum Code wären da hilfreich, da man selbst oft 'den Wald vor lauter Bäumen nicht sieht'! :wink:

Daß es einen Ordner durchgeht ist richtig, dies habe ich auch so in meinem letzten Post beschrieben.
Leonidas hat geschrieben:Ich hätte eher gedacht dass es automatisch in ein laufendes Programm eingreift wenn ein Modul geladen wird welches nicht installiert ist, aber offenbar nicht.
Das wäre ein Option die man auch verfolgen könnte, da bräuchte ich dann doch etwas Unterstützung.

Sobald ich die Fehler behoben und die Dokumentation eingepflegt habe, werde ich eine neue Ausgabe von modul_control.py posten.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Naja, ich hab einfach nichts angegeben, einfach mit ``python2 modulname`` gestartet (nachdem ich ``python2-psutil`` nachinstalliert habe), du könntest ein Kommandozeileninterface implementieren, welches anzeigt was da genau jetzt wie erwartet wird.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Welches Betriebssystem nutzt Du, Windows oder Linux?

Wenn ich bei Linux in der Konsole (Terminal)

Code: Alles auswählen

cd /ort/zum/ordner/von/python modul_control.py
python modul_control.py
aufrufe, habe ich das Kommandozeileninterface.

Oder was meinst Du mit Kommandozeileninterface?
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Linux. Ich schau aber nochmal wenn ich heimkomme.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Habe nochmal kräftig am Code geschraubt ... :lol: und etliche Fehler beseitigt.
Den Code habe dokumentiert, im Moment noch nicht so umfangreich, das kommt aber noch sobald der eine oder Andere von Euch mir vielleicht eine Rückmeldung gibt.
Bei mir läuft es soweit fehlerfrei durch, hoffe daß das bei Euch auch so ist, wenn Ihr es testen solltet.

Hier das neue modul_control.py: https://gist.github.com/3041461

Eine kurze Ablaufbeschreibung, damit Ihr den Funktionsablauf kennt.
Als erstes wird überprüft, ob das Paket psutil installiert ist, wenn nicht wird eine Liste zur Installation angeboten. Hier das richtige Paket auswählen und eingeben. Anschließend wird nach dem Installationsbefehl gefragt, den man auswählt.
Zu Auswahl stehen 'apt-get; aptitude und pip'. Bei der Installation von psutil läßt sich pip noch nicht einsetzen, außer pip ist bei Euch schon installiert.

Das Modul überprüft alle Dateien in einem Ordner, die mit .py enden. Unterordner werden nicht berücksichtigt.
Es wird nach Fehlern in Dateien geschaut. Dies werden dann unterschiedlich behandelt.
Zuerst wird auf ImportError, dann auf NameError und anschließend auf BaseException geprüft.
Bei einem ImportError und NameError, wird wenn möglich das fehlende Modul zur Installation angeboten.
Weiter werden bei NameError und BaseException, die Fehlermeldungen getrennt ausgegeben.
Das mit den Exceptions ist bei Bedarf weiter ausbaubar.

Auch das was Leonadis schon angesprochen hat, 'in ein laufendes Programm eingreift wenn ein Modul geladen wird welches nicht installiert ist', ist mit kleineren Umbauarbeiten möglich.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen,
habe modul_control.py weiter optimiert, hier https://gist.github.com/3048599 könnt Ihr es Euch anschauen.

Habe noch ein Problem, das ich bis jetzt nicht lösen konnte.

Code: Alles auswählen

def modul_check():
    counter = 0
    for prog in FILE_LIST:
        if '.py' in prog and not '.pyc' in prog and not PROG in prog:
            datei = prog
            modul = prog.split('.py')[0]

            try:
                if counter == 0:
                    no_mod()
                    imp.load_source(modul, datei)
                    counter = 1
                else:
                    imp.load_source(modul, datei)
'imp.load_source(modul, datei)' öffnet ja die Datei bzw. bei einem Fehler in der Datei, wird ein Error ausgegeben.
Nach dem öffnen der Datei, möchte ich diese auch wieder schließen.
Nun habe ich schon versucht mit psutil die Datei ausfindig zu machen, um diese dann mit terminate() zu beenden.
Leider gibt psutil nichts über die gestartete Datei aus.

Könnte da Eure Hilfe benötigen! :?

Welche Tipps bzw. Lösung könnt Ihr mir geben, um dieses Problem zu lösen?

Grüße Nobuddy
BlackJack

@Nobuddy: Welches Problem? ``imp.load_source(modul, datei)`` öffnet keine Datei die es nicht auch wieder schliesst. Und was Du da jetzt mit `psutil` suchen willst, ist mir auch nicht klar. Es gibt da nämlich auch keinen Prozess zum Beenden. Dateien kann man schon gar nicht beenden.

Der gezeigte Quelltext sieht auch schon wieder gruselig aus. `FILE_LIST` ist eine Konstante? Oder „übergibst” Du hier mal wieder Daten über einen globalen Namen‽

Die Tests mit ``in`` und den Datei*endungen* sehen auch nicht robust aus. Wenn Du auf Datei*endungen* testen möchtest, solltest Du genau *das* tun — testen ob das am *Ende* steht, und nicht *irgendwo* in der Zeichenkette. Und wenn Du eine Dateiendung mit einer bekannten Länge am Ende entfernen möchtest, dann geht das auch direkter als mit `split()`.

Zum `counter` sage ich jetzt mal nichts…
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

@BlackJack, das war mir nicht klar, daß `imp.load_source(modul, datei)`, die Datei öffnet und wieder schließt.
Dann brauche ich auch kein 'psutil' und kann den Code was damit zusammenhängt inklusive 'counter' (teilweise) entfernen, was das Ganze dann etwas einfacher gestaltet! :)

FILE_LIST ist bei mir:

Code: Alles auswählen

# Alle Dateien des Ordners in FILE_LIST speichern.
FILE_LIST = set()
PATH = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
LIST = os.listdir(PATH)

for files in LIST:
    if os.path.isfile(files):
        FILE_LIST.add(files)
Danke für Deinen inpurt zu den Tests mit den Dateiendungen. :wink:

Code: Alles auswählen

for prog in FILE_LIST:
        if '.py' in prog and not '.pyc' in prog and not PROG in prog:
Geht auch einfacher mit

Code: Alles auswählen

if prog[int(len(prog) - 3):] == '.py' and prog != PROG:
Hattest Du so etwas im Sinn, oder doch was ganz anderes?

Und zu guter Letzt, hat sich dann das mit 'split()' auch erledigt, durch

Code: Alles auswählen

modul = prog[:int(len(prog) - 3)]
Wenn ich das oben beschriebene behoben habe, versuche ich den Code zu 'entgruseln'. :wink:

Danke für Deine Rückmeldung! :D
BlackJack

@Nobuddy: Ich hatte etwas anderes im Sinn. Lern mal bitte die Methoden auf Zeichenketten auswendig, also Namen und was sie tun. ;-)

Und dann beschreib mal was bei `len()` als Ergebnistyp heraus kommt, und was der Ergebnistyp ist, wenn man davon eine 3 abzieht.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

BlackJack hat geschrieben:Und dann beschreib mal was bei `len()` als Ergebnistyp heraus kommt, und was der Ergebnistyp ist, wenn man davon eine 3 abzieht.
Dazu ist natürlich die Zeit immer ein wenig knapp, wenn man gerade Flugzeugmodelle und Landebahnen in seinem Garten nachbaut ^^
Das Leben ist wie ein Tennisball.
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Ok, das 'int' war unnötig. :?

@EyDu, Nein ... schon auf der Raumstation Alphatauri ... :wink:
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo zusammen,
bin von Raumstation Alpatauri wieder zurück :lol:

modul_control.py habe ich 'entgruselt' und das Ganze umgebaut, hoffe ich kann Euch damit ein wenig überraschen!

Hier die aktuelle Version: https://gist.github.com/3075514

Würde mich freuen, wenn Ihr dies nochmals in Augenschein nehmen würdet! :wink:

Grüße Nobuddy
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Da die Nachfrage so groß ist :lol: , habe ich weitere Verbesserungen vorgenommen.
Jetzt ist es auch möglich, manuell die/den zu überprüfende(n) Datei bzw. Ordner anzugeben und überprüfen zu lassen.

Frisch aus dem Ofen: https://gist.github.com/3077815 :wink:
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Oh, jetzt sinds schon 420 Zeilen seltsamer Code. Zuerst mal, ich habe keine Lust das alles durchzugehen, daher nur paar Sachen die mir so aufgefallen sind: Warum importierst du alles auf einmal, wenn du beim ImportError nur auf die nicht-existenz von pip prüfst? Und warum `check = True`, man kann auch in Exception-Handler-Blöcken funktionen ausführen.

posix heißt nicht Linux. Kann auch BSD sein oder womöglich Mac OS X. Die Fehlermeldung ist grob falsch.

Warum ``file_list`` und ``filelist``, das ist ja sinnlose Namensgebung. Lies mal PEP8 und besser das aus. Und warum wird da eine Modulglobale Variable modifiziert, warum keine Rückgabewerte?

Warum einen Kommandozeilen-String zusammensetzen und danach ihn mit shlex zerlegen? Das ist so wie zu definieren ``a = 2 + 3 - 3`` nur um einer Variable den Wert 2 zuzuwiesen :roll: Vergiss für den Fall dass es shlex gibt, brauchst du eh nicht.

Und bei einer so hohen Zyklomatischen Komplexität hab ich gar keine Lust zu schauen ob das überhaupt funktioniert. Wenn eine Funktion zu viele Einrückungsebenen hat, dann heißt das, dass sie zu viel macht. Aufsplitten.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Nobuddy
User
Beiträge: 997
Registriert: Montag 30. Januar 2012, 16:38

Hallo Leonidas,
Danke für Deine Infos, ich werde versuchen Deine Vorschläge umzusetzen. :wink:

Ich habe alles in das Modul gepackt, was man sonst in mehrere Module aufteilen würde, daher auch die 420 Zeilen.
Der Grund dafür ist, daß ich dann nur ein Modul statt mehreren Modulen in den zu überprüfenden Ordner stelle, das finde ich als Vorteil.
Antworten