Alternative zu python-apt

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.
Antworten
pExplorer
User
Beiträge: 9
Registriert: Dienstag 21. Mai 2019, 19:54

Hallo,

das Vorhandensein von nötigen linux-packages prüfe ich in einem kleinen Programm mittels python-apt.
Dieses Modul wird aber nicht mehr gepflegt:
https://pypi.org/project/python-apt/

Code: Alles auswählen

import apt
	
self.worker.packages_to_check.append("lame")
self.worker.packages_to_check.append(self.lineEditConfigDP.text())
        
def run_packages_to_check(self):        
	self.progress.emit("<b>Installationspruefung:</b>")
        cache = apt.Cache()
        cache.open()
        for item in self.packages_to_check:
            try:
                cache[item].is_installed
                self.progress.emit(item)
            except KeyError:
                error_message = (
                    "Es fehlt das Paket:<br> " + item
                    + "<br>Zur Nutzung des vollen Funktionsumfanges "
                    + "muss es installiert werden!")
                self.progress.emit(error_message)
Gibt es dafür ein Äquivalent oder eine Alternative?
Benutzeravatar
__blackjack__
User
Beiträge: 14085
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pExplorer: Anmerkungen zum gezeigten Quelltext:

Das `Cache`-Objekt ist ein Kontextmanager, das sollte man mit ``with`` verwenden.

Der Code prüft eigentlich nur ob das Paket im Cache vorhanden ist, meldet aber keine Probleme mit Paketen die zwar im Cache sind, aber gar nicht vollständig installiert sind, entweder weil die Installation mitten drin abgebrochen wurde, oder das Paket entfernt wurde und noch Konfigurationsdateien vorhanden sind. Mit dem `is_installed`-Wert muss man halt auch irgend etwas *machen*.

Zeichenketten mit ``+`` zusammenstückeln ist eher BASIC denn Python. Um Werte in Zeichenketten zu formatieren gibt es f-Zeichenketten, und der Compiler verbindet Zeichenketten die nur durch Whitespace-Zeichen voneinander getrennt sind.

Ungetestet:

Code: Alles auswählen

    def run_packages_to_check(self):
        self.progress.emit("<b>Installationspruefung:</b>")
        with apt.Cache() as cache:
            cache.open()
            for package_name in self.packages_to_check:
                package = cache.get(package_name)
                self.progress.emit(
                    package_name
                    if package and package.is_installed
                    else (
                        f"Es fehlt das Paket:<br>"
                        f"{package_name}<br>"
                        f"Zur Nutzung des vollen Funktionsumfanges muss es"
                        f" installiert werden!"
                    )
                )
Wenn es nur um den Test auf „installiert“ geht, würde ich mir einfach eine Funktion basteln die ``dpkg-query`` aufruft:

Code: Alles auswählen

import subprocess


def is_installed(package_name):
    result = subprocess.run(
        ["dpkg-query", "--show", "--showformat", "${Status}\n", package_name],
        capture_output=True,
        check=False,
    )
    return b"install ok installed" in result.stdout.splitlines()

...

    def run_packages_to_check(self):
        self.progress.emit("<b>Installationspruefung:</b>")
        for package_name in self.packages_to_check:
            self.progress.emit(
                package_name
                if is_installed(package_name)
                else (
                    f"Es fehlt das Paket:<br>"
                    f"{package_name}<br>"
                    f"Zur Nutzung des vollen Funktionsumfanges muss es"
                    f" installiert werden!"
                )
            )
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
pExplorer
User
Beiträge: 9
Registriert: Dienstag 21. Mai 2019, 19:54

__blackjack__ hat geschrieben: Dienstag 22. Juli 2025, 14:33 @pExplorer: Anmerkungen zum gezeigten Quelltext:

Das `Cache`-Objekt ist ein Kontextmanager, das sollte man mit ``with`` verwenden.

Der Code prüft eigentlich nur ob das Paket im Cache vorhanden ist, meldet aber keine Probleme mit Paketen die zwar im Cache sind, aber gar nicht vollständig installiert sind, entweder weil die Installation mitten drin abgebrochen wurde, oder das Paket entfernt wurde und noch Konfigurationsdateien vorhanden sind. Mit dem `is_installed`-Wert muss man halt auch irgend etwas *machen*.

Zeichenketten mit ``+`` zusammenstückeln ist eher BASIC denn Python. Um Werte in Zeichenketten zu formatieren gibt es f-Zeichenketten, und der Compiler verbindet Zeichenketten die nur durch Whitespace-Zeichen voneinander getrennt sind.

Ungetestet:
...
Danke für die Hinweise!

Prinzipiell hab ich das so geändert und es tut was ich möchte:

Code: Alles auswählen

import subprocess


def is_installed(package_name):
    result = subprocess.run(
        ["dpkg-query", "--show", "--showformat", "${Status}\n", package_name],
        capture_output=True,
        check=False
    )
    return b"install ok installed" in result.stdout.splitlines()


def run_packages_to_check():
    print("Installationspruefung:")
    packages_to_check = []
    packages_to_check.append("a")
    packages_to_check.append("b")

    for package_name in packages_to_check:
        if is_installed(package_name):
            print("Paket vorhanden:")
            print(package_name)
        else:
            print("Es fehlt das Paket:")
            print(package_name)

run_packages_to_check()
( Das Komma nach `check=False' war, glaub' ich, zuviel.)
Benutzeravatar
__blackjack__
User
Beiträge: 14085
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@pExplorer: Für mich ist das Komma nicht zu viel. Klar kann man das weg lassen, aber dann hat man bei Änderungen, wie hinzufügen eines Arguments, zwei Zeilen die sich ändern und im diff auftauchen. Und die eine nur wegen des Kommas, wo sich sonst inhaltlich gar nichts geändert hat.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten