webentwicklung-frage-antwort-db.com.de

Überprüfen einer Python Modulversion zur Laufzeit

Viele Python Module von Drittanbietern haben ein Attribut, das die Versionsinformationen für das Modul enthält (normalerweise so etwas wie module.VERSION oder module.__version__), manche jedoch nicht.

Besondere Beispiele für solche Module sind libxslt und libxml2.

Ich muss überprüfen, ob zur Laufzeit die richtige Version dieser Module verwendet wird. Gibt es eine Möglichkeit, dies zu tun?

Eine mögliche Lösung wäre, den Quellcode zur Laufzeit einzulesen, zu haschen und ihn dann mit dem Hash der bekannten Version zu vergleichen, aber das ist böse.

Gibt es bessere Lösungen?

108
Gruff

Ich würde mich vom Hashing fernhalten. Die verwendete Version von libxslt enthält möglicherweise einen Patch, der sich nicht auf Ihre Verwendung auswirkt.

Als Alternative möchte ich vorschlagen, dass Sie nicht zur Laufzeit prüfen (Sie wissen nicht, ob dies eine schwierige Anforderung ist oder nicht). Für die python Zeug, das ich schreibe und das externe Abhängigkeiten hat (Bibliotheken von Drittanbietern), schreibe ich ein Skript, das Benutzer ausführen können, um ihre python zu überprüfen, ob Die entsprechenden Versionen der Module sind installiert.

Bei Modulen ohne definiertes 'version'-Attribut können Sie die enthaltenen Schnittstellen (Klassen und Methoden) überprüfen, um festzustellen, ob sie mit der erwarteten Schnittstelle übereinstimmen. Nehmen Sie dann in dem Code an, an dem Sie gerade arbeiten, an, dass die Module von Drittanbietern die Schnittstelle haben, die Sie erwarten.

6
Mark Roddy

Verwenden Sie pkg_resources . Alles, was von PyPI installiert wurde, sollte mindestens eine Versionsnummer haben.

>>> import pkg_resources
>>> pkg_resources.get_distribution("blogofile").version
'0.7.1'
230
EnigmaCurry

Einige Ideen:

  1. Suchen Sie nach Funktionen, die in den von Ihnen benötigten Versionen vorhanden sind oder nicht.
  2. Wenn es keine Funktionsunterschiede gibt, überprüfen Sie die Funktionsargumente und -signaturen.
  3. Wenn Sie anhand von Funktionssignaturen nichts herausfinden können, richten Sie einige Stub-Aufrufe zum Zeitpunkt des Imports ein und überprüfen Sie ihr Verhalten.
6

Sie können verwenden

pip freeze

um die installierten Pakete im Anforderungsformat zu sehen.

2
nos

Sie können importlib_metadata Bibliothek dafür.

Wenn Sie python <3.8, installiere es zuerst mit:

pip install importlib_metadata

Seit python 3.8 es ist in der Standardbibliothek von Python enthalten.

Um die Version eines Pakets zu überprüfen (in diesem Beispiel lxml), führen Sie Folgendes aus:

>>> from importlib_metadata import version
>>> version('lxml')
'4.3.1'

Beachten Sie, dass dies nur für Pakete funktioniert, die von PyPI installiert wurden. Außerdem müssen Sie einen Paketnamen als Argument an die version -Methode übergeben, anstatt einen Modulnamen, den dieses Paket bereitstellt (obwohl diese normalerweise identisch sind).

1
Jakub Kukul

Ich fand es ziemlich unzuverlässig, die verschiedenen verfügbaren Tools zu verwenden (einschließlich des besten pkg_resources, Das von diese andere Antwort erwähnt wird), da die meisten von ihnen nicht alle Fälle abdecken. Beispielsweise

  • eingebaute Module
  • module nicht installiert, sondern nur zum python Pfad hinzugefügt (von Ihrem IDE zum Beispiel)
  • zwei Versionen desselben Moduls verfügbar (eine im python Pfad ersetzt die installierte)

Da wir einen zuverlässigen Weg brauchten, um die Version von jedem Paket, Modul oder Submodul zu erhalten, schrieb ich getversion . Es ist ganz einfach zu bedienen:

from getversion import get_module_version
import foo
version, details = get_module_version(foo)

Einzelheiten finden Sie in der Dokumentation .

0
smarie