cli.py: Hilfe-Patch steht ein zweites Mal außerhalb des try und hebt den dokumentierten Rückfall auf #148

Closed
opened 2026-09-26 11:46:16 +00:00 by torben · 2 comments
Owner

Befund (behoben in 7.1.0-beta.29, Commit 6c0ebcc)

tools/chemenu/cli.py patchte typer._click.core.Command.format_help innerhalb eines try/except (ImportError, AttributeError). Laut Kommentar darüber soll eine künftige typer-Version ohne typer._click nicht jeden wikitool-Aufruf beim Import abstürzen lassen, sondern auf ungerahmte Click-Hilfe zurückfallen (HAS_RICH ist ohnehin False).

Direkt nach dem except stand aber in Zeile 265 noch einmal, auf Modulebene und ohne Bedingung:

_typer_click_core.Command.format_help = _contract_format_help

Schlug der Import im try fehl, waren beide Namen undefiniert, und diese Zeile warf beim Import von cli.py einen NameError. Damit stürzte genau der Fall ab, den der Rückfall abfangen sollte, und zwar bei jedem Aufruf. Mit typer 0.27.2 fiel das nicht auf; dort war die Zeile nur redundant. Eingeführt mit 26e1018 (#121). Die Zeile ist entfernt, der Patch steht nur noch im try.

Entscheidung: wie der Test den Importfehler simuliert

Geprüft und verworfen:

  • sys.modules['typer._click.core'] = None: Das bricht typer selbst. typer/_click/core.py importiert decorators lazy in get_help_option, deshalb scheitert -h auch mit korrigiertem cli.py.
  • importlib.reload(chemenu.cli): reload läuft im selben __dict__. Die Namen vom ersten Import überleben, die fehlerhafte Zeile läuft durch, und der Test wäre auch mit dem Bug grün.

Umgesetzt: Subprozess mit gezieltem Import-Hook (builtins.__import__ wirft ImportError nur für typer._click.core, wenn chemenu.cli/__main__ importiert), danach runpy.run_module("chemenu.cli", run_name="__main__") mit search -h.

Akzeptanzkriterien

  • Die Zeile außerhalb des try ist entfernt.
  • Neuer Test test_missing_typer_click_falls_back_to_plain_click_help_instead_of_crashing in tools/chemenu/tests/test_cli.py: Exit 0, stdout beginnt mit Usage:, keine SYNOPSIS/EXIT STATUS, kein Traceback.
  • Derselbe Test ist gegen den alten Stand rot: Mit wieder eingefügter Zeile scheitert er mit genau dem NameError. Verifiziert, bevor der Fix zurückgesetzt wurde.
  • pytest (1550 grün), docs verify, instructions verify grün. Changelog über version bump --patch --impact low (7.1.0-beta.29).

Verifiziert

Lokal: volle Suite 1550 grün. CI auf 6c0ebcc: Runs 420 und 421 grün. Ein Nachzug in dd885db (7.1.0-beta.31, nur Kommentare und Changelog, betrifft #150) lief ebenfalls grün durch CI (Runs 422, 423).

Anmerkung zum Ablauf

Der Commit 6c0ebcc entstand per rohem git commit auf einem Feature-Branch und wurde per Fast-Forward nach main übernommen, bevor wikitool publish nur noch pushte. Das verstößt gegen AGENTS.md Invariante 5. Inhaltlich ist nichts verloren, aber der Commit trägt nicht die „Files changed“-Liste, die publish schreibt, und der Stack-Machinery-Hinweis von publish blieb aus, weil es nichts mehr zu stagen gab. Der Nachzug dd885db lief regulär über publish.

## Befund (behoben in `7.1.0-beta.29`, Commit 6c0ebcc) `tools/chemenu/cli.py` patchte `typer._click.core.Command.format_help` innerhalb eines `try/except (ImportError, AttributeError)`. Laut Kommentar darüber soll eine künftige typer-Version ohne `typer._click` nicht jeden `wikitool`-Aufruf beim Import abstürzen lassen, sondern auf ungerahmte Click-Hilfe zurückfallen (`HAS_RICH` ist ohnehin `False`). Direkt nach dem `except` stand aber in Zeile 265 noch einmal, auf Modulebene und ohne Bedingung: ```python _typer_click_core.Command.format_help = _contract_format_help ``` Schlug der Import im `try` fehl, waren beide Namen undefiniert, und diese Zeile warf beim Import von `cli.py` einen `NameError`. Damit stürzte genau der Fall ab, den der Rückfall abfangen sollte, und zwar bei jedem Aufruf. Mit typer 0.27.2 fiel das nicht auf; dort war die Zeile nur redundant. Eingeführt mit 26e1018 (#121). Die Zeile ist entfernt, der Patch steht nur noch im `try`. ## Entscheidung: wie der Test den Importfehler simuliert Geprüft und verworfen: - **`sys.modules['typer._click.core'] = None`**: Das bricht typer selbst. `typer/_click/core.py` importiert `decorators` lazy in `get_help_option`, deshalb scheitert `-h` auch mit korrigiertem `cli.py`. - **`importlib.reload(chemenu.cli)`**: `reload` läuft im *selben* `__dict__`. Die Namen vom ersten Import überleben, die fehlerhafte Zeile läuft durch, und der Test wäre auch mit dem Bug grün. Umgesetzt: **Subprozess mit gezieltem Import-Hook** (`builtins.__import__` wirft `ImportError` nur für `typer._click.core`, wenn `chemenu.cli`/`__main__` importiert), danach `runpy.run_module("chemenu.cli", run_name="__main__")` mit `search -h`. ## Akzeptanzkriterien - [x] Die Zeile außerhalb des `try` ist entfernt. - [x] Neuer Test `test_missing_typer_click_falls_back_to_plain_click_help_instead_of_crashing` in `tools/chemenu/tests/test_cli.py`: Exit 0, stdout beginnt mit `Usage:`, keine `SYNOPSIS`/`EXIT STATUS`, kein `Traceback`. - [x] Derselbe Test ist gegen den alten Stand rot: Mit wieder eingefügter Zeile scheitert er mit genau dem `NameError`. Verifiziert, bevor der Fix zurückgesetzt wurde. - [x] `pytest` (1550 grün), `docs verify`, `instructions verify` grün. Changelog über `version bump --patch --impact low` (`7.1.0-beta.29`). ## Verifiziert Lokal: volle Suite 1550 grün. CI auf 6c0ebcc: Runs 420 und 421 grün. Ein Nachzug in dd885db (`7.1.0-beta.31`, nur Kommentare und Changelog, betrifft #150) lief ebenfalls grün durch CI (Runs 422, 423). ## Anmerkung zum Ablauf Der Commit 6c0ebcc entstand per rohem `git commit` auf einem Feature-Branch und wurde per Fast-Forward nach `main` übernommen, bevor `wikitool publish` nur noch pushte. Das verstößt gegen AGENTS.md Invariante 5. Inhaltlich ist nichts verloren, aber der Commit trägt nicht die „Files changed“-Liste, die `publish` schreibt, und der Stack-Machinery-Hinweis von `publish` blieb aus, weil es nichts mehr zu stagen gab. Der Nachzug dd885db lief regulär über `publish`.
torben added the prio/plannedsize/Sarea/processkind/defect labels 2026-09-26 11:46:16 +00:00
Author
Owner

Changelog: Zeilennummer korrigiert (265 statt 280). Bug per Import-Hook reproduziert. Die Simulationsmethode für den Test ist jetzt entschieden: Subprozess mit gezieltem builtins.__import__-Hook. sys.modules=None bricht typer selbst und scheidet deshalb aus; importlib.reload wäre auch mit dem Bug grün. Kriterium „Test ist gegen den heutigen Baum rot“ ergänzt. Status: umsetzungsreif.

**Changelog:** Zeilennummer korrigiert (265 statt 280). Bug per Import-Hook reproduziert. Die Simulationsmethode für den Test ist jetzt entschieden: Subprozess mit gezieltem `builtins.__import__`-Hook. `sys.modules=None` bricht typer selbst und scheidet deshalb aus; `importlib.reload` wäre auch mit dem Bug grün. Kriterium „Test ist gegen den heutigen Baum rot“ ergänzt. Status: umsetzungsreif.
Author
Owner

Changelog: Body auf Endstand gebracht: alle Kriterien abgehakt, Rot/Grün-Verifikation und CI-Runs 420/421 genannt, Verstoß gegen Invariante 5 bei 6c0ebcc offen vermerkt. Geschlossen.

**Changelog:** Body auf Endstand gebracht: alle Kriterien abgehakt, Rot/Grün-Verifikation und CI-Runs 420/421 genannt, Verstoß gegen Invariante 5 bei 6c0ebcc offen vermerkt. Geschlossen.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: torben/chemenu#148