PEP 262 – Eine Datenbank installierter Python-Pakete
- Autor:
- A.M. Kuchling <amk at amk.ca>
- Status:
- Abgelehnt
- Typ:
- Standards Track
- Thema:
- Packaging
- Erstellt:
- 08. Jul. 2001
- Post-History:
- 27. Mär. 2002
Hinweis
Dieser PEP wurde durch PEP 345 und PEP 376 abgelöst, die angenommen wurden. Daher wird dieser PEP (implizit) abgelehnt.
Einleitung
Dieser PEP beschreibt ein Format für eine Datenbank der auf einem System installierten Python-Software.
(In diesem Dokument bezieht sich der Begriff "Distribution" auf eine Code-Sammlung, die zusammen entwickelt und verteilt wird. Eine "Distribution" ist dasselbe wie ein Red Hat- oder Debian-Paket, aber der Begriff "Paket" hat bereits eine Bedeutung in der Python-Terminologie und bedeutet "ein Verzeichnis mit einer Datei __init__.py darin.")
Anforderungen
Wir benötigen eine Möglichkeit, herauszufinden, welche Distributionen und welche Versionen dieser Distributionen auf einem System installiert sind. Wir wollen Funktionen anbieten, die mit CPAN, APT oder RPM vergleichbar sind. Erforderliche Anwendungsfälle, die unterstützt werden sollten, sind:
- Ist Distribution X auf einem System vorhanden?
- Welche Version von Distribution X ist installiert?
- Wo ist die neue Version von Distribution X zu finden? (Dies kann entweder als "eine Homepage, auf die der Benutzer gehen kann, um einen Download-Link zu finden" oder als "ein Ort, an dem ein Programm die neueste Version finden kann?" definiert werden. Beide sollten wahrscheinlich unterstützt werden.)
- Welche Dateien hat Distribution X auf meinem System abgelegt?
- Von welcher Distribution stammt die Datei x/y/z.py?
- Hat jemand x/y/z.py lokal modifiziert?
- Welche anderen Distributionen benötigt diese Software?
- Welche Python-Module bietet diese Distribution?
Datenbankstandort
Die Datenbank befindet sich in einer Reihe von Dateien unter <prefix>/lib/python<version>/install-db/. Dieser Standort wird im Rest dieses PEP als INSTALLDB bezeichnet.
Die Struktur der Datenbank ist bewusst einfach gehalten; jede Datei in diesem Verzeichnis oder seinen Unterverzeichnissen (falls vorhanden) beschreibt eine einzelne Distribution. Binäre Verpackungen von Python-Software wie RPMs können dann die Python-Datenbank aktualisieren, indem sie einfach die entsprechende Datei in das INSTALLDB-Verzeichnis installieren.
Die Begründung für das Scannen von Unterverzeichnissen ist, dass wir zu einem Verzeichnis-basierten Indizierungsschema übergehen können, wenn das Datenbankverzeichnis zu viele Einträge enthält. Dies würde uns beispielsweise ermöglichen, transparent von INSTALLDB/Numeric zu INSTALLDB/N/Nu/Numeric oder einem ähnlichen Hashing-Schema zu wechseln.
Datenbankinhalt
Jede Datei in INSTALLDB oder seinen Unterverzeichnissen beschreibt eine einzelne Distribution und hat den folgenden Inhalt:
Eine erste Zeile, die die Abschnitte in dieser Datei auflistet, getrennt durch Leerzeichen. Aktuell ist dies immer 'PKG-INFO DATEIEN ERFORDERT BIETET'. Dies dient der Zukunftssicherheit; wenn wir einen neuen Abschnitt hinzufügen, z. B. um Dokumentationsdateien aufzulisten, würden wir einen DOKUMENTE-Abschnitt hinzufügen und ihn in den Inhalten auflisten. Abschnitte sind immer durch leere Zeilen getrennt.
Eine Distribution, die Distutils für die Installation verwendet, sollte die Datenbank automatisch aktualisieren. Distributionen, die ihre eigene Installation durchführen, müssen die API der Datenbank verwenden, um ihren eigenen Eintrag manuell hinzuzufügen oder zu aktualisieren. Systempaketmanager wie RPM oder pkgadd können einfach die neue Datei in das INSTALLDB-Verzeichnis erstellen.
Jeder Abschnitt der Datei wird für einen anderen Zweck verwendet.
PKG-INFO-Bereich
Eine erste Reihe von RFC 822-Headern, die die Distributionsinformationen für eine Datei enthalten, wie in PEP 241, "Metadaten für Python-Softwarepakete", beschrieben.
DATEIEN-Bereich
Ein Eintrag für jede von der Distribution installierte Datei. Generierte Dateien wie .pyc und .pyo sind ebenfalls auf dieser Liste aufgeführt, ebenso wie die ursprünglichen .py-Dateien, die von einer Distribution installiert wurden; ihre Prüfsummen werden jedoch nicht gespeichert oder überprüft.
Der Eintrag jeder Datei ist eine einzelne Tabulator-getrennte Zeile, die die folgenden Felder enthält:
- Der vollständige Pfad der Datei, wie sie auf dem System installiert ist.
- Die Größe der Datei.
- Die Berechtigungen der Datei. Unter Windows ist dieses Feld immer 'unknown'.
- Der Besitzer und die Gruppe der Datei, getrennt durch einen Tabulator. Unter Windows sind beide Felder 'unknown'.
- Eine SHA1-Prüfsumme der Datei, hexadezimal kodiert. Für generierte Dateien wie *.pyc-Dateien muss dieses Feld den String "-" enthalten, was anzeigt, dass die Prüfsumme der Datei nicht überprüft werden soll.
ERFORDERT-Bereich
Dieser Abschnitt ist eine Liste von Strings, die die Dienste auflistet, die für die ordnungsgemäße Ausführung dieser Modul-Distribution erforderlich sind. Diese Liste enthält den Distributionsnamen ("python-stdlib") und Modulnamen ("rfc822", "htmllib", "email", "email.Charset"). Sie wird durch ein zusätzliches Argument 'requires' an die Funktion distutils.core.setup() spezifiziert. Zum Beispiel:
setup(..., requires=['xml.utils.iso8601',
Es wird zukünftig möglicherweise automatisierte Werkzeuge geben, die den gesamten Code durchsuchen und eine Liste von Anforderungen erstellen, aber es ist unwahrscheinlich, dass diese Werkzeuge alle möglichen Fälle abdecken können; eine manuelle Spezifikation von Anforderungen wird immer notwendig sein.
BIETET-Bereich
Dieser Abschnitt ist eine Liste von Strings, die die Dienste auflistet, die von einer installierten Distribution bereitgestellt werden. Diese Liste enthält den Distributionsnamen ("python-stdlib") und Modulnamen ("rfc822", "htmllib", "email", "email.Charset").
XXX Sollen Dateien aufgeführt werden? Z. B. $PREFIX/lib/color-table.txt, um Datendateien, benötigte Skripte usw. aufzunehmen.
Es wird zukünftig möglicherweise eine Option geben, die es Modulentwicklern ermöglicht, ihre eigenen Strings zu diesem Abschnitt hinzuzufügen. Man könnte zum Beispiel "XML-Parser" zu diesem Abschnitt hinzufügen, und andere Modul-Distributionen könnten dann "XML-Parser" als eine ihrer Abhängigkeiten auflisten, um anzuzeigen, dass mehrere verschiedene XML-Parser verwendet werden können. Vorerst ist diese Möglichkeit nicht unterstützt, da sie zu viele Fragen aufwirft: Benötigen wir ein zentrales Verzeichnis für gültige Strings oder sollen Leute einfach alles schreiben, was sie möchten? usw. usw...
API-Beschreibung
Es gibt eine grundlegende Klasse, InstallationDatabase. Der Code dafür befindet sich in distutils/install_db.py. (XXX Vorschläge für alternative Speicherorte in der Standardbibliothek oder einen alternativen Modulnamen?)
Die InstallationDatabase gibt Instanzen von Distribution zurück, die alle Informationen über eine installierte Distribution enthalten.
XXX Mehrere Felder in Distribution sind Duplikate von Feldern in distutils.dist.Distribution. Wahrscheinlich sollten sie in die hier vorgeschlagene Distribution-Klasse ausgelagert werden, aber kann dies abwärtskompatibel geschehen?
InstallationDatabase hat die folgende Schnittstelle:
class InstallationDatabase:
def __init__ (self, path=None):
"""InstallationDatabase(path:string)
Read the installation database rooted at the specified path.
If path is None, INSTALLDB is used as the default.
"""
def get_distribution (self, distribution_name):
"""get_distribution(distribution_name:string) : Distribution
Get the object corresponding to a single distribution.
"""
def list_distributions (self):
"""list_distributions() : [Distribution]
Return a list of all distributions installed on the system,
enumerated in no particular order.
"""
def find_distribution (self, path):
"""find_file(path:string) : Distribution
Search and return the distribution containing the file 'path'.
Returns None if the file doesn't belong to any distribution
that the InstallationDatabase knows about.
XXX should this work for directories?
"""
class Distribution:
"""Instance attributes:
name : string
Distribution name
files : {string : (size:int, perms:int, owner:string, group:string,
digest:string)}
Dictionary mapping the path of a file installed by this distribution
to information about the file.
The following fields all come from PEP 241.
version : distutils.version.Version
Version of this distribution
platform : [string]
summary : string
description : string
keywords : string
home_page : string
author : string
author_email : string
license : string
"""
def add_file (self, path):
"""add_file(path:string):None
Record the size, ownership, &c., information for an installed file.
XXX as written, this would stat() the file. Should the size/perms/
checksum all be provided as parameters to this method instead?
"""
def has_file (self, path):
"""has_file(path:string) : Boolean
Returns true if the specified path belongs to a file in this
distribution.
"""
def check_file (self, path):
"""check_file(path:string) : Boolean
Checks whether the file's size, checksum, and ownership match,
returning true if they do.
"""
Ergebnisse
Eine Beschreibung der Datenbank-API, die diesem PEP hinzugefügt werden soll.
Patches für Distutils, die 1) eine InstallationDatabase-Klasse implementieren, 2) die Datenbank aktualisieren, wenn eine neue Distribution installiert wird. 3) ein einfaches Paketmanagement-Tool hinzufügen, Features, die diesem PEP hinzugefügt werden sollen. (Oder sollte dies ein separater PEP sein?) Siehe [2] für den aktuellen Patch.
Offene Fragen
PJE schlägt vor, dass die Installationsdatenbank "potenziell in jedem Verzeichnis in sys.path vorhanden sein kann, wobei die Inhalte in der Reihenfolge von sys.path zusammengeführt werden. Dies würde die Installationen im Home-Verzeichnis oder an anderen alternativen Orten ermöglichen und den Prozess eines distutils install-Befehls, der die Datei schreibt, erleichtern." Schönes Feature: Es bedeutet, dass Paketmanagement-Tools Python-Pakete berücksichtigen können, die ein Benutzer privat installiert hat.
AMK fragt: Was macht setup.py, wenn ihm gesagt wird, Pakete in ein Verzeichnis zu installieren, das nicht in sys.path ist? Schreibt es ein install-db-Verzeichnis in das Verzeichnis, in das es schreiben soll, oder tut es nichts?
Soll die Paketdatenbankdatei selbst in der Dateiliste enthalten sein? (PJE würde Ja sagen, aber natürlich kann sie nicht ihre eigene Prüfsumme enthalten. AMK fällt kein Anwendungsfall ein, bei dem die Einbeziehung der DB-Datei wichtig ist.)
PJE wundert sich, ob die Paket-DB-Datei **zuerst** geschrieben werden soll, bevor andere Dateien installiert werden, damit fehlgeschlagene Teilinstallationen sowohl rückgängig gemacht als auch als fehlerhaft erkannt werden können. Dieser PEP muss möglicherweise einen Algorithmus zur Erkennung dieser Situation spezifizieren.
Sollen wir garantieren, dass das Format der Installationsdatenbanken über Python-Versionen hinweg kompatibel bleibt, oder unterliegt es beliebigen Änderungen? Wahrscheinlich müssen wir Kompatibilität garantieren.
Abgelehnte Vorschläge
Anstatt einer Textdatei pro Distribution könnte eine große Textdatei oder eine anydbm-Datei verwendet werden. Dies wurde aus mehreren Gründen abgelehnt. Erstens ist die Leistung wahrscheinlich keine extrem dringende Sorge, da die Datenbank nur beim Installieren oder Entfernen von Software verwendet wird, eine relativ seltene Aufgabe. Skalierbarkeit ist wahrscheinlich auch kein Problem, da viele Leute Hunderte von Python-Paketen installiert haben mögen, aber Tausende oder Zehntausende scheinen unwahrscheinlich. Schließlich sind einzelne Textdateien mit Installern wie RPM oder DPKG kompatibel, da ein binärer Packager die neue Datenbankdatei einfach in das Datenbankverzeichnis legen kann. Wenn eine große Textdatei oder eine Binärdatei verwendet würde, müsste die Python-Datenbank dann durch Ausführen eines Postinstallations-Skripts aktualisiert werden.
Unter Windows werden die Berechtigungen und der Besitzer/die Gruppe einer Datei nicht gespeichert. Windows unterstützt zwar Besitz und Zugriffsrechte, aber das Lesen und Setzen erfordert die win32all-Erweiterungen, und diese sind nicht im grundlegenden Python-Installer für Windows enthalten.
Referenzen
[1] Michael Mullers Patch (gepostet an die Distutils-SIG um den 28. Dezember 1999) generiert eine Liste installierter Dateien.
Danksagungen
Ideen für diesen PEP stammen ursprünglich von Beiträgen von Greg Ward, Fred L. Drake Jr., Thomas Heller, Mats Wichmann, Phillip J. Eby und anderen.
Viele Änderungen und Überarbeitungen dieses Dokuments wurden von den Lesern der Distutils SIG vorgeschlagen.
Urheberrecht
Dieses Dokument wurde gemeinfrei erklärt.
Quelle: https://github.com/python/peps/blob/main/peps/pep-0262.rst
Zuletzt geändert: 2025-02-01 08:55:40 GMT