0%

Programme, die Argumente annehmen · Übung

Ergebnisse von Fehlern trennen

Das Programm akzeptiert jetzt die vollständige Schnittstelle. Eine Gewohnheit aus Kapitel 7 gehört aber noch zum alten festen Befehl: Erwartete Fehler werden auf stdout ausgegeben. Bei einer wiederverwendbaren CLI müssen Ergebnisse und Diagnosen unterscheidbar bleiben.

Das Ziel ändern, nicht die Ausnahmegrenze

Importiere sys und leite dann nur die erwartete Katalogmeldung an stderr:

except (FileNotFoundError, UnicodeDecodeError, csv.Error, ValueError) as exc:
    print(f"Could not convert catalog: {exc}", file=sys.stderr)
    return 1

Behalte den Ausnahmetext. Die Grenzen aus Kapitel 7 liefern begrenzte, deterministische Meldungen, die die fehlerhafte Kopfzeile, Zeile, das Feld oder die Dateioperation benennen. Sie durch Conversion failed zu ersetzen würde den nützlichen Teil verwerfen.

Erweitere das Tupel nicht. Ein TypeError durch einen Programmierfehler muss weiterhin mit seinem Traceback nach außen gelangen. stderr bedeutet nicht „alles abfangen“, sondern dass erwartete Diagnosen ein eigenes Ziel haben.

Jede zuständige Stelle behält ihren Status

Der endgültige Vertrag hat jetzt drei Zuständigkeiten:

  • main gibt 0 zurück, nachdem es die angeforderte Datei geschrieben und dies gemeldet hat;

  • main gibt 1 nach einem erwarteten Fehler an der Katalogschnittstelle zurück;

  • argparse löst bei Hilfe SystemExit(0) und bei Grammatikfehlern SystemExit(2) aus, bevor main die Konvertierung erreicht.

Der geschützte Einstieg bleibt:

if __name__ == "__main__":
    raise SystemExit(main())

Diese Zeile macht beim Ausführen der Datei aus dem von main zurückgegebenen Status den Prozessstatus. Beim Import tut sie nichts. Lies auf Modulebene keine Argumente ein, gib nichts aus und schreibe keine Datei: Tests und späterer Projektcode müssen die Funktionen importieren können, ohne versehentlich den Befehl auszuführen.

Am schnellsten siehst du, ob die beiden Datenströme stimmen, indem du sie in der Shell trennst. Führe einen fehlschlagenden Befehl aus und leite stdout mit > in eine Datei um. Der Fehler sollte weiterhin auf dem Bildschirm erscheinen, und die Datei sollte leer sein. Wenn der Fehler stattdessen in der Datei landet, geht er an stdout.

Was bewirkt raise SystemExit(main())?

Aufgabe

Vervollständige die Schnittstelle der CLI für Datenströme und Statuswerte.

  • Importiere sys.

  • Gib die begrenzte Meldung Could not convert catalog: <cause> nur bei FileNotFoundError, UnicodeDecodeError, csv.Error und ValueError auf sys.stderr aus.

  • Gib bei diesen Fehlern 1 zurück und nichts auf stdout aus.

  • Behalte die exakte Erfolgszeile auf stdout bei, mit leerem stderr und Status 0.

  • Bewahre das Verhalten von argparse: Hilfe mit Status 0, Grammatikfehler mit Status 2.

  • Lass unerwartete Programmierfehler unverändert nach außen gelangen.

  • Halte den Import frei von Seiteneffekten und behalte genau den geschützten Einstiegspunkt raise SystemExit(main()) bei.