PEP 376 – Datenbank installierter Python-Distributionen
- Autor:
- Tarek Ziadé <tarek at ziade.org>
- Status:
- Final
- Typ:
- Standards Track
- Thema:
- Packaging
- Erstellt:
- 22. Feb 2009
- Python-Version:
- 2.7, 3.2
- Post-History:
- 22. Juni 2009
Zusammenfassung
Das Ziel dieses PEP ist es, eine Standardinfrastruktur für die Verwaltung von installierten Projektverteilungen auf einem System bereitzustellen, damit alle Werkzeuge, die Projekte installieren oder entfernen, interoperabel sind.
Um dieses Ziel zu erreichen, schlägt der PEP ein neues Format zur Beschreibung installierter Distributionen auf einem System vor. Er beschreibt auch eine Referenzimplementierung für die Standardbibliothek.
In der Vergangenheit wurde ein Versuch unternommen, eine Installationsdatenbank zu erstellen (siehe PEP 262).
In Verbindung mit PEP 345 ersetzt der aktuelle Vorschlag PEP 262.
Hinweis: Der Implementierungsplan verlief nicht wie erwartet und sollte daher für diesen PEP nur informativ betrachtet werden.
Begründung
Derzeit gibt es zwei Probleme bei der Installation von Distributionen in Python
- Es gibt zu viele Möglichkeiten, dies zu tun, und das erschwert die Interoperabilität.
- Es gibt keine API, um Informationen über installierte Distributionen zu erhalten.
Wie Distributionen installiert werden
Derzeit kann bei der Installation einer Distribution in Python jedes Element in einem anderen Verzeichnis installiert werden.
Zum Beispiel installiert Distutils den reinen Python-Code im Verzeichnis purelib, das für Unix-ähnliche Systeme und Mac OS X lib/python2.6/site-packages ist oder Lib\site-packages unter dem Installationsverzeichnis von Python für Windows.
Zusätzlich fügt der Unterbefehl install_egg_info des Distutils install-Befehls eine .egg-info-Datei für das Projekt im Verzeichnis purelib hinzu.
Zum Beispiel werden für die Distribution docutils, die ein Paket, ein zusätzliches Modul und ausführbare Skripte enthält, drei Elemente in site-packages installiert:
docutils: Das Paketdocutils.roman.py: Ein zusätzliches Modul, das vondocutilsverwendet wird.docutils-0.5-py2.6.egg-info: Eine Datei, die die Metadaten der Distribution enthält, wie in PEP 314 beschrieben. Diese Datei entspricht der DateiPKG-INFO, die vom Befehlsdisterstellt wird.
Einige ausführbare Skripte, wie rst2html.py, werden ebenfalls im Verzeichnis bin der Python-Installation hinzugefügt.
Ein weiteres Projekt namens setuptools [1] hat zwei weitere Formate zur Installation von Distributionen, genannt EggFormats [4]:
- ein eigenständiges
.egg-Verzeichnis, das alle Distributionsdateien und die Metadaten der Distribution in einer Datei namensPKG-INFOin einem Unterverzeichnis namensEGG-INFOenthält.setuptoolserstellt andere Dateien in diesem Verzeichnis, die als ergänzende Metadaten betrachtet werden können. - ein
.egg-info-Verzeichnis, das insite-packagesinstalliert wird und dieselben Dateien wieEGG-INFOim.egg-Format enthält.
Das erste Format wird automatisch verwendet, wenn Sie eine Distribution installieren, die die Funktion setuptools.setup in ihrer setup.py-Datei verwendet, anstelle der distutils.core.setup-Funktion.
setuptools fügt außerdem einen Verweis auf die Distribution in eine Datei namens easy-install.pth ein.
Zuletzt stellt das Projekt setuptools ein ausführbares Skript namens easy_install [2] bereit, das alle Distributionen, einschließlich Distutils-basierter, in eigenständige .egg-Verzeichnisse installiert.
Wenn Sie eigenständige .egg-info-Verzeichnisse für Ihre Distributionen haben möchten, z. B. das zweite setuptools-Format, müssen Sie dies bei der Arbeit mit einer Setuptools-basierten Distribution oder dem Skript easy_install erzwingen. Sie können dies durch die Option --single-version-externally-managed **oder** die Option --root erzwingen. Dies bewirkt, dass das Projekt setuptools das Projekt wie Distutils installiert.
Diese Option wird verwendet von
Deinstallationsinformationen
Distutils bietet keinen uninstall-Befehl. Wenn Sie eine Distribution deinstallieren möchten, müssen Sie ein Power-User sein und die verschiedenen installierten Elemente entfernen und dann die .pth-Datei überprüfen, um sie bei Bedarf zu bereinigen.
Und der Prozess unterscheidet sich je nach den Werkzeugen, die Sie zur Installation der Distribution verwendet haben, und ob das setup.py der Distribution Distutils oder Setuptools verwendet.
Unter bestimmten Umständen können Sie nicht sicher wissen, ob Sie alles entfernt haben oder ob Sie nicht eine andere Distribution beschädigt haben, indem Sie eine Datei entfernen, die von mehreren Distributionen gemeinsam genutzt wird.
Aber es gibt ein gemeinsames Verhalten: Wenn Sie eine Distribution installieren, werden Dateien auf Ihr System kopiert. Und es ist möglich, diese Dateien für die spätere Entfernung im Auge zu behalten.
Darüber hinaus hat das Pip-Projekt kürzlich eine uninstall-Funktion erhalten. Es zeichnet alle installierten Dateien auf, indem es die Option record des Befehls install verwendet.
Was dieser PEP vorschlägt
Um diese Probleme zu lösen, schlägt dieser PEP einige Änderungen vor:
- Ein neues
.dist-info-Format, das ein Verzeichnis verwendet und sich an einem Format desEggFormats-Standards vonsetuptoolsorientiert. - Neue APIs in
pkgutil, um Informationen über installierte Distributionen abfragen zu können. - Eine Deinstallationsfunktion und ein Deinstallationsskript in Distutils.
Ein .dist-info-Verzeichnis pro installierter Distribution
Dieser PEP schlägt ein Installationsformat vor, das von einer der Optionen im EggFormats-Standard inspiriert ist, nämlich derjenigen, die ein separates Verzeichnis im site-packages-Verzeichnis verwendet.
Dieses separate Verzeichnis wird wie folgt benannt:
name + '-' + version + '.dist-info'
Dieses .dist-info-Verzeichnis kann folgende Dateien enthalten:
METADATA: Enthält Metadaten, wie in PEP 345, PEP 314 und PEP 241 beschrieben.RECORD: Zeichnet die Liste der installierten Dateien auf.INSTALLER: Zeichnet den Namen des Werkzeugs auf, das zur Installation des Projekts verwendet wurde.REQUESTED: Die Anwesenheit dieser Datei zeigt an, dass die Installation des Projekts explizit angefordert wurde (d. h. nicht als Abhängigkeit installiert wurde).
Die Dateien METADATA, RECORD und INSTALLER sind obligatorisch, während REQUESTED fehlen kann.
Dieser Vorschlag wird Python selbst nicht beeinträchtigen, da die Metadaten-Dateien in der Standardbibliothek außer von Distutils noch nirgendwo verwendet werden.
Er wird die Projekte setuptools und pip beeinträchtigen, aber da sie bereits mit einem Verzeichnis arbeiten, das eine PKG-INFO-Datei enthält, wird die Änderung keine tiefgreifenden Folgen haben.
RECORD
Eine RECORD-Datei wird zur Installationszeit in das .dist-info-Verzeichnis eingefügt, wenn eine Quellcode-Distribution mit dem Befehl install installiert wird. Beachten Sie, dass bei der Installation einer Binärverteilung, die mit dem Befehl bdist oder einem bdist-basierten Befehl erstellt wurde, die RECORD-Datei ebenfalls installiert wird, da diese Befehle den Befehl install zur Erstellung von Binärverteilungen verwenden.
Die Datei RECORD enthält die Liste der installierten Dateien. Diese entsprechen den Dateien, die von der Option record des Befehls install aufgeführt werden, und werden standardmäßig generiert. Dies ermöglicht die Implementierung einer Deinstallationsfunktion, wie weiter unten in diesem PEP erläutert. Der Befehl install bietet auch eine Option, um das Schreiben der RECORD-Datei zu verhindern. Diese Option sollte bei der Erstellung von Systempaketen verwendet werden.
Auch Drittanbieter-Installationswerkzeuge sollten keine Dateien überschreiben oder löschen, die sich nicht in einer RECORD-Datei befinden, ohne vorher zu fragen oder zu warnen.
Diese RECORD-Datei ist von PEP 262 FILES inspiriert.
Die Datei RECORD ist eine CSV-Datei, die aus Datensätzen besteht, eine Zeile pro installierter Datei. Das Modul csv wird zum Lesen der Datei verwendet, mit diesen Optionen:
- Feldtrennzeichen :
, - Anführungszeichen :
". - Zeilenende :
os.linesep(also\r\noder\n)
Wenn eine Distribution installiert wird, können Dateien installiert werden unter
- der **Basisort**: Pfad, der durch die Option
--install-libdefiniert ist und standardmäßig das site-packages-Verzeichnis ist. - dem **Installationspräfix**: Pfad, der durch die Option
--prefixdefiniert ist und standardmäßigsys.prefixist. - ein beliebiger anderer Pfad im System.
Jeder Datensatz besteht aus drei Elementen:
- der **Pfad** der Datei
- ein mit „/“ getrennter Pfad, relativ zum **Basisort**, wenn sich die Datei unter dem **Basisort** befindet.
- ein mit „/“ getrennter Pfad, relativ zum **Basisort**, wenn sich die Datei unter dem **Installationspräfix** befindet UND wenn der **Basisort** ein Unterpfad des **Installationspräfixes** ist.
- ein absoluter Pfad, der den lokalen Plattformtrenner verwendet.
- ein Hash des Inhalts der Datei. Beachten Sie, dass für generierte
pyc- undpyo-Dateien kein Hash vorhanden ist, da sie automatisch auspy-Dateien erzeugt werden. Das Überprüfen des Hashes der entsprechendenpy-Datei reicht also aus, um zu entscheiden, ob die Datei und ihre zugehörigenpyc- oderpyo-Dateien geändert wurden.Der Hash ist entweder die leere Zeichenkette oder der Hash-Algorithmus, wie er in
hashlib.algorithms_guaranteedbenannt ist, gefolgt von einem Gleichheitszeichen=, gefolgt von der urlsafe-base64-nopad-Kodierung des Digests (base64.urlsafe_b64encode(digest)mit entferntem nachgestelltem=). - die Größe der Datei in Bytes.
Das Modul csv wird zum Erstellen dieser Datei verwendet, daher ist das Feldtrennzeichen „,“. Jedes „,“-Zeichen, das innerhalb eines Feldes gefunden wird, wird automatisch von csv maskiert.
Beim Lesen der Datei wird die Option U verwendet, sodass die Unterstützung für universelle Zeilenenden (siehe PEP 278) aktiviert wird, um Probleme beim Lesen einer Datei zu vermeiden, die auf einer Plattform erstellt wurde, die einen anderen Zeilenend terminator verwendet.
Hier ist ein Beispiel für eine RECORD-Datei (Auszug):
lib/python2.6/site-packages/docutils/__init__.py,md5=nWt-Dge1eug4iAgqLS_uWg,9544
lib/python2.6/site-packages/docutils/__init__.pyc,,
lib/python2.6/site-packages/docutils/core.py,md5=X90C_JLIcC78PL74iuhPnA,66188
lib/python2.6/site-packages/docutils/core.pyc,,
lib/python2.6/site-packages/roman.py,md5=7YhfNczihNjOY0FXlupwBg,234
lib/python2.6/site-packages/roman.pyc,,
/usr/local/bin/rst2html.py,md5=g22D3amDLJP-FhBzCi7EvA,234
/usr/local/bin/rst2html.pyc,,
python2.6/site-packages/docutils-0.5.dist-info/METADATA,md5=ovJyUNzXdArGfmVyb0onyA,195
lib/python2.6/site-packages/docutils-0.5.dist-info/RECORD,,
Beachten Sie, dass die RECORD-Datei keinen Hash von sich selbst enthalten kann und hier nur erwähnt wird.
Ein Projekt, das eine config.ini-Datei in /etc/myapp installiert, wird wie folgt hinzugefügt:
/etc/myapp/config.ini,md5=gLfd6IANquzGLhOkW4Mfgg,9544
Auf einer Windows-Plattform wird der Laufwerksbuchstabe für absolute Pfade hinzugefügt, sodass eine Datei, die nach c:MyApp kopiert wird, wie folgt lautet:
c:\etc\myapp\config.ini,md5=gLfd6IANquzGLhOkW4Mfgg,9544
INSTALLER
Der Befehl install verfügt über eine neue Option namens installer. Diese Option ist der Name des Werkzeugs, das zur Aufrufung der Installation verwendet wird. Es handelt sich um eine normalisierte Kleinbuchstaben-Zeichenkette, die [a-z0-9_\-\.] entspricht.
$ python setup.py install –installer=pkg-system
Wenn sie nicht angegeben wird, wird standardmäßig distutils verwendet.
Wenn eine Distribution installiert wird, wird die Datei INSTALLER im Verzeichnis .dist-info mit diesem Wert generiert, um zu verfolgen, **wer** die Distribution installiert hat. Die Datei ist eine einzeilige Textdatei.
REQUESTED
Einige Installationswerkzeuge erkennen automatisch nicht erfüllte Abhängigkeiten und installieren sie. In diesen Fällen ist es nützlich zu verfolgen, welche Distributionen rein als Abhängigkeit installiert wurden, damit der Benutzer bei der Deinstallation der abhängigen Distribution über die verwaiste Abhängigkeit informiert werden kann.
Wenn eine Distribution auf direkte Benutzeranfrage installiert wird (der übliche Fall), wird eine Datei REQUESTED zum .dist-info-Verzeichnis der installierten Distribution hinzugefügt. Die Datei REQUESTED kann leer sein oder eine Markierungs-Kommentarzeile enthalten, die mit dem Zeichen „#“ beginnt.
Wenn ein Installationswerkzeug eine Distribution automatisch als Abhängigkeit einer anderen Distribution installiert, sollte die Datei REQUESTED nicht erstellt werden.
Der Befehl install von distutils erstellt standardmäßig die Datei REQUESTED. Er akzeptiert die Optionen --requested und --no-requested, um explizit anzugeben, ob die Datei erstellt wird.
Wenn eine Distribution, die bereits als Abhängigkeit auf dem System installiert war, später namentlich installiert wird, erstellt der distutils install-Befehl die Datei REQUESTED im .dist-info-Verzeichnis der vorhandenen Installation.
Implementierungsdetails
Hinweis: Dieser Abschnitt ist nicht normativ. Letztendlich wurde dieser PEP von Drittanbieterbibliotheken und -werkzeugen implementiert und nicht von der Standardbibliothek.
Neue Funktionen und Klassen in pkgutil
Um den Inhalt des .dist-info-Verzeichnisses nutzen zu können, müssen wir in der Standardbibliothek eine Reihe von APIs hinzufügen. Der beste Ort, um diese APIs zu platzieren, ist pkgutil.
Funktionen
Die neuen Funktionen, die im Modul pkgutil hinzugefügt werden, sind:
distinfo_dirname(name, version)-> Verzeichnisnamenamewird in einen standardmäßigen Distributionsnamen umgewandelt, indem alle Folgen von nicht-alphanumerischen Zeichen durch ein einzelnes „-“ ersetzt werden.versionwird in eine standardmäßige Versionszeichenkette umgewandelt. Leerzeichen werden zu Punkten, und alle anderen nicht-alphanumerischen Zeichen (außer Punkten) werden zu Bindestrichen, wobei Folgen von mehreren Bindestrichen zu einem einzigen Bindestrich zusammengefasst werden.Beide Attribute werden dann in ihre dateinamen-escapte Form umgewandelt, d.h. alle „-“-Zeichen werden durch „_“ ersetzt, außer dem in „dist-info“ und dem, das den Namen vom Versionsnummer trennt.
get_distributions()-> Iterator vonDistribution-Instanzen.Bietet einen Iterator, der nach
.dist-info-Verzeichnissen insys.pathsucht undDistribution-Instanzen für jede davon zurückgibt.get_distribution(name)->Distributionoder None.obsoletes_distribution(name, version=None)-> Iterator vonDistribution-Instanzen.Iteriert über alle Distributionen, um herauszufinden, welche Distributionen
name*obsolet* machen. Wenn eineversionangegeben wird, wird sie zur Filterung der Ergebnisse verwendet.provides_distribution(name, version=None)-> Iterator vonDistribution-Instanzen.Iteriert über alle Distributionen, um herauszufinden, welche Distributionen
name*bereitstellen*. Wenn eineversionangegeben wird, wird sie zur Filterung der Ergebnisse verwendet. Scannt alle Elemente insys.pathund sucht nach allen Verzeichnissen, die mit.dist-infoenden. Gibt eineDistributionzurück, die dem.dist-info-Verzeichnis entspricht, das eine METADATA enthält, dienamefür diename-Metadaten übereinstimmt.Diese Funktion gibt nur das erste gefundene Ergebnis zurück, da nicht mehr als ein Wert erwartet wird. Wenn das Verzeichnis nicht gefunden wird, wird None zurückgegeben.
get_file_users(path)-> Iterator vonDistribution-Instanzen.Iteriert über alle Distributionen, um herauszufinden, welche Distributionen
pathverwenden.pathkann ein lokaler absoluter Pfad oder ein relativer, mit „/“ getrennter Pfad sein.Ein lokaler absoluter Pfad ist ein absoluter Pfad, bei dem Vorkommen von „/“ durch den Systemtrenner gemäß
os.sepersetzt wurden.
Distribution-Klasse
Eine neue Klasse namens Distribution wird mit dem Pfad des .dist-info-Verzeichnisses erstellt, das an den Konstruktor übergeben wird. Beim Instanziieren werden die in METADATA enthaltenen Metadaten gelesen.
Distribution(path) -> Instanz
Erstellt eineDistribution-Instanz für den angegebenenpath.
Distribution bietet die folgenden Attribute:
name: Der Name der Distribution.metadata: Eine Instanz vonDistributionMetadata, die mit der METADATA-Datei der Distribution geladen ist.requested: Ein Boolescher Wert, der angibt, ob die Metadaten-Datei REQUESTED vorhanden ist (mit anderen Worten, ob die Distribution auf Benutzeranfrage installiert wurde).
Und die folgenden Methoden:
get_installed_files(local=False)-> Iterator von (pfad, hash, größe)Iteriert über die
RECORD-Einträge und gibt für jede Zeile ein Tupel(path, hash, size)zurück. WennlocalTrueist, wird der Pfad in einen lokalen absoluten Pfad umgewandelt. Andernfalls wird der Rohwert ausRECORDzurückgegeben.Ein lokaler absoluter Pfad ist ein absoluter Pfad, bei dem Vorkommen von „/“ durch den Systemtrenner gemäß
os.sepersetzt wurden.uses(path)-> BooleschGibt
Truezurück, wennpathinRECORDaufgeführt ist.pathkann ein lokaler absoluter Pfad oder ein relativer, mit „/“ getrennter Pfad sein.get_distinfo_file(path, binary=False)-> DateiobjektGibt eine Datei zurück, die sich im.dist-info-Verzeichnis befindet.Gibt eine
file-Instanz für die durchpathangegebene Datei zurück.pathmuss ein mit „/“ getrennter Pfad relativ zum.dist-info-Verzeichnis oder ein absoluter Pfad sein.Wenn
pathein absoluter Pfad ist und nicht mit dem Pfad des.dist-info-Verzeichnisses beginnt, wird eineDistutilsErrorausgelöst.Wenn
binaryTrueist, wird die Datei im schreibgeschützten Binärmodus (rb) geöffnet, andernfalls im schreibgeschützten Modus (r).get_distinfo_files(local=False)-> Iterator von PfadenIteriert über die
RECORD-Einträge und gibt für jede Zeile Pfade zurück, wenn der Pfad auf eine Datei im.dist-info-Verzeichnis oder einem seiner Unterverzeichnisse zeigt.Wenn
localTrueist, wird jeder Pfad in einen lokalen absoluten Pfad umgewandelt. Andernfalls wird der Rohwert ausRECORDzurückgegeben.
Beachten Sie, dass die API in fünf Klassen organisiert ist, die mit Verzeichnissen und Zip-Dateien arbeiten (daher funktioniert sie auch mit Dateien, die in Zip-Dateien enthalten sind; siehe PEP 273 für weitere Details). Diese Klassen werden in der Dokumentation der Prototypimplementierung für interessierte Leser beschrieben [7].
Beispiele
Verwenden wir einige der neuen APIs mit unserem docutils-Beispiel:
>>> from pkgutil import get_distribution, get_file_users, distinfo_dirname
>>> dist = get_distribution('docutils')
>>> dist.name
'docutils'
>>> dist.metadata.version
'0.5'
>>> distinfo_dirname('docutils', '0.5')
'docutils-0.5.dist-info'
>>> distinfo_dirname('python-ldap', '2.5')
'python_ldap-2.5.dist-info'
>>> distinfo_dirname('python-ldap', '2.5 a---5')
'python_ldap-2.5.a_5.dist-info'
>>> for path, hash, size in dist.get_installed_files()::
... print '%s %s %d' % (path, hash, size)
...
python2.6/site-packages/docutils/__init__.py,b690274f621402dda63bf11ba5373bf2,9544
python2.6/site-packages/docutils/core.py,9c4b84aff68aa55f2e9bf70481b94333,66188
python2.6/site-packages/roman.py,a4b84aff68aa55f2e9bf70481b943D3,234
/usr/local/bin/rst2html.py,a4b84aff68aa55f2e9bf70481b943D3,234
python2.6/site-packages/docutils-0.5.dist-info/METADATA,6fe57de576d749536082d8e205b77748,195
python2.6/site-packages/docutils-0.5.dist-info/RECORD
>>> dist.uses('docutils/core.py')
True
>>> dist.uses('/usr/local/bin/rst2html.py')
True
>>> dist.get_distinfo_file('METADATA')
<open file at ...>
>>> dist.requested
True
Neue Funktionen in Distutils
Distutils bietet bereits eine sehr einfache Möglichkeit zur Installation einer Distribution, nämlich die Ausführung des Befehls install über das Skript setup.py der Distribution.
Distutils2 wird eine sehr einfache uninstall-Funktion bereitstellen, die in distutils2.util hinzugefügt wird und den Namen der zu deinstallierenden Distribution als Argument nimmt. uninstall verwendet die oben beschriebenen APIs und entfernt alle eindeutigen Dateien, solange sich ihr Hash nicht geändert hat. Anschließend entfernt sie leere Verzeichnisse, die zurückbleiben.
uninstall gibt eine Liste der deinstallierten Dateien zurück.
>>> from distutils2.util import uninstall
>>> uninstall('docutils')
['/opt/local/lib/python2.6/site-packages/docutils/core.py',
...
'/opt/local/lib/python2.6/site-packages/docutils/__init__.py']
Wenn die Distribution nicht gefunden wird, wird eine DistutilsUninstallError ausgelöst.
Filterung
Um sie zu einer Referenz-API für Drittanbieterprojekte zu machen, die steuern möchten, wie die uninstall-Funktion funktioniert, kann ein zweites aufrufbares Argument verwendet werden. Es wird für jede entfernte Datei aufgerufen. Wenn der Aufrufer True zurückgibt, wird die Datei entfernt. Wenn er False zurückgibt, bleibt sie unberührt.
Beispiele
>>> def _remove_and_log(path):
... logging.info('Removing %s' % path)
... return True
...
>>> uninstall('docutils', _remove_and_log)
>>> def _dry_run(path):
... logging.info('Removing %s (dry run)' % path)
... return False
...
>>> uninstall('docutils', _dry_run)
Natürlich kann ein Drittanbieterwerkzeug die Low-Level-APIs von pkgutil verwenden, um seine eigene Deinstallationsfunktion zu implementieren.
Installer-Markierung
Wie bereits in diesem PEP erläutert, fügt der Befehl install eine Datei INSTALLER im Verzeichnis .dist-info mit dem Namen des Installers hinzu.
Um zu vermeiden, dass Distributionen entfernt werden, die von einem anderen Paketierungssystem installiert wurden, nimmt die Funktion uninstall ein zusätzliches Argument installer entgegen, das standardmäßig auf distutils2 gesetzt ist.
Bei Aufruf überprüft uninstall, ob die Datei INSTALLER mit diesem Argument übereinstimmt. Andernfalls wird eine DistutilsUninstallError ausgelöst.
>>> uninstall('docutils')
Traceback (most recent call last):
...
DistutilsUninstallError: docutils was installed by 'cool-pkg-manager'
>>> uninstall('docutils', installer='cool-pkg-manager')
Dies ermöglicht es einer Drittanbieteranwendung, die Funktion uninstall zu verwenden und stark darauf hinzuweisen, dass kein anderes Programm eine zuvor installierte Distribution entfernen soll. Dies ist nützlich, wenn ein Drittanbieterprogramm, das auf Distutils-APIs basiert, während der Installation zusätzliche Schritte auf dem System durchführt und diese bei der Deinstallation rückgängig machen muss.
Hinzufügen eines Deinstallationsskripts
Ein uninstall-Skript wird in Distutils2 hinzugefügt und wie folgt verwendet:
$ python -m distutils2.uninstall projectname
Beachten Sie, dass das Skript nicht prüft, ob die Entfernung einer Distribution eine andere Distribution beschädigt. Es stellt jedoch sicher, dass alle entfernten Dateien von keiner anderen Distribution verwendet werden, indem es die Deinstallationsfunktion verwendet.
Beachten Sie auch, dass dieses Deinstallationsskript die REQUESTED-Metadaten ignoriert; diese werden nur für die Verwendung durch externe Werkzeuge zur Bereitstellung einer fortschrittlicheren Abhängigkeitsverwaltung bereitgestellt.
Abwärtskompatibilität und Roadmap
Diese Änderungen führen keine Kompatibilitätsprobleme ein, da sie implementiert werden in
- pkgutil in neuen Funktionen
- distutils2
Der Plan ist, die in diesem PEP beschriebene Funktionalität in pkgutil für Python 3.2 und in Distutils2 aufzunehmen.
Distutils2 wird auch einen Backport des neuen pgkutil enthalten und kann ab 2.4 verwendet werden.
Distributionen, die mit bestehenden, vor der Standardisierung bestehenden Formaten installiert wurden, verfügen nicht über die erforderlichen Metadaten für die neue API und werden daher ignoriert. Drittanbieterwerkzeuge können natürlich weiterhin ältere Formate zusätzlich zum neuen Format unterstützen, um den Übergang zu erleichtern.
Referenzen
Danksagungen
Jim Fulton, Ian Bicking, Phillip Eby, Rafael Villar Burke und viele Leute auf Pycon und Distutils-SIG.
Urheberrecht
Dieses Dokument wurde gemeinfrei erklärt.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0376.rst
Zuletzt geändert: 2024-12-15 20:57:13 GMT