Aufraeumen nach der Pruefkette: doppelter Code an eine Stelle
Die Runde vom 07.09.2026 hat neben den zwei echten Fehlern eine Reihe Wiederholungen und stumme Stellen gemeldet. Abgearbeitet in Etappen, jede fuer sich pruefbar - nach jeder liefen beide Pruefketten gruen. * Menueleiste: der Wechsel von einem Titel zum anderen brauchte ZWEI Klicks. Der grab_set der offenen Liste schluckt den ersten, die <Button-1>-Bindung des Titels feuert gar nicht. Das native tk.Menu, das diese Leiste ersetzt hat, wechselte schon beim blossen Ueberfahren - zwei Klicks waren also eine Verschlechterung gegenueber dem, was vorher da war. Die Klappliste wird ausserdem jetzt wie jede andere Position ueber theme.auf_bildschirm() begrenzt; am unteren Fensterrand lief sie vorher hinaus. Neu: pruef_menueleiste.py misst beides ueber echte Klickereignisse. * %LOCALAPPDATA%/ravokk wurde an drei Stellen einzeln ausgerechnet. Jetzt fragen alle gemeinsam.standard_ordner(). Laufen die je auseinander, fuehren die beiden Programme zwei Nummernbuecher - und das faellt erst auf, wenn eine Rechnungsnummer zum zweiten Mal vergeben ist (§ 14 Abs. 4 Nr. 4 UStG). * pruefe() stand 35-mal im Quelltext, in sechs Fassungen -> pruefhelfer.py. Die zwei Ausreisser sind mitgezogen: pruef_bilder.py schrieb ein eigenes Format, pruef_storno_verrechnet.py zaehlte in einer Zahl und konnte am Ende nicht sagen, WAS fehlschlug. * dlg_darstellung() und die drei Handgriffe des Umschaltens standen in beiden app.py fast wortgleich -> ThemeMixin in theme.py. Beide trugen inzwischen denselben langen Kommentar zu demselben Fehler; das war der Beweis, dass es eine Sache ist. Programmspezifisch bleiben der Hinweistext im Dialog (R31) und die Frage, ob die Einstellungen ausdruecklich gespeichert werden muessen. * pruef_gemeinsam_automatisch.py sagte im Text "genau ein Buch" und prueft ">= 1" mit einem any() - eine Pruefung, die nicht rot werden kann. Jetzt == 1, und der Dateiname wird mitgeprueft. Dazu neu: die neun Dateien, die im Kopf zusagen, sie laegen in beiden Programmen gleich, werden byteweise verglichen. Bei hinweis.py stimmte die Zusage seit dem 06.09. nicht mehr - gleicher Inhalt, CRLF gegen LF. * .gitattributes, damit die Zeilenenden nicht von der Maschine abhaengen. Ohne das meldet genau diese Pruefung nach einem frischen Checkout einen Unterschied, den es im Repository gar nicht gibt. * Sechs stumme "except OSError" sagen jetzt, warum sie schweigen duerfen, und einer meldet statt zu schweigen: schlaegt die Uebernahme einer alten config.json fehl, faengt das Programm ohne Firmendaten, Katalog und Zaehler neu an - und der Erfolgsfall schrieb eine Zeile, der Fehlerfall nicht. Die 24 stummen tk.TclError bleiben: dort wird ein Widget angefasst, das gerade zerstoert wurde, und eine Meldung waere Rauschen. * Tote Parameter und Variablen aus dem Umbau des Vortags: symbol_setzen(dunkel=), kachel(grund=, radius=), mit_trennlinie, sechs x/y-Berechnungen, die von theme.mittig() sofort ueberschrieben wurden, vier lokale "import ctypes". 39 Pruefstaende, 0 rot. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V4t48uxDok5rJXhC9bX1Ax
This commit is contained in:
parent
5babfc3e2e
commit
2b09d15cd0
36 changed files with 563 additions and 364 deletions
14
config.py
14
config.py
|
|
@ -58,6 +58,7 @@ def _daten_ordner():
|
|||
"""
|
||||
if not getattr(sys, "frozen", False):
|
||||
return EXE_DIR # aus der Quelle heraus bleibt alles, wo es ist
|
||||
import gemeinsam
|
||||
heim = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~")
|
||||
# NEBEN dem Programm, nicht darin: das Programm liegt in
|
||||
# ravokk/Rechnungstool, die Daten eine Ebene darueber in ravokk. Genau so
|
||||
|
|
@ -65,7 +66,8 @@ def _daten_ordner():
|
|||
# es den ordner rechnungstool und steuertool". Nur dadurch kann ein
|
||||
# Deinstallieren den Programmordner restlos leeren, ohne die Belege
|
||||
# anzufassen (§ 147 AO).
|
||||
kandidat = os.path.join(heim, "ravokk")
|
||||
# Gerechnet wird der Pfad nur an EINER Stelle - siehe dort.
|
||||
kandidat = gemeinsam.standard_ordner()
|
||||
if not _beschreibbar(kandidat):
|
||||
kandidat = os.path.join(EXE_DIR, "Daten")
|
||||
if not _beschreibbar(kandidat):
|
||||
|
|
@ -84,8 +86,14 @@ def _daten_ordner():
|
|||
os.replace(alt, neu_)
|
||||
print(f"[config] {name} aus {alt} übernommen")
|
||||
break
|
||||
except OSError:
|
||||
pass
|
||||
except OSError as e:
|
||||
# Nicht abbrechen - der naechste Ort wird noch probiert,
|
||||
# und zur Not faengt das Programm eben neu an. Aber sagen,
|
||||
# dass es schiefging: der Erfolgsfall schreibt eine Zeile,
|
||||
# und wer sie sucht und nicht findet, wuesste sonst nicht,
|
||||
# ob nichts da war oder ob die Uebernahme misslang. Es geht
|
||||
# um Firmendaten, Leistungskatalog und Rechnungszaehler.
|
||||
print(f"[config] {name} aus {alt} NICHT übernommen: {e}")
|
||||
return kandidat
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue