ENB: Big progress re annotations

25 views
Skip to first unread message

Edward K. Ream

unread,
Apr 6, 2026, 2:53:18 PMApr 6
to leo-editor
Today's work completes PR #4576 for now! This Engineering Notebook post describes what I did and why it works. This ENB is pre-writing for a much-needed update to info item #1585: Notes re Leo's code base.

One annotation to rule them all

Early today, mypy passed all of Leo using the QTextMixin class to annotate all of Leo's gui wrappers. It was far from clear that this scheme would work--the mixin class is the base class for the wrappers. It's not any particular class itself.

But mypy was good with this annotation. Hurray! I'm no expert re mypy, but I suspect that mypy treats the QTextMixin class as a stand-in for the other classes. It can do that (I suppose) because mypy is merely checking that all the code is compatible (as a duck type) with the methods of the QTextMixin class. I would welcome comments on this point from those more knowledgeable about mypy!

The initial annotation for the text wrappers was a union:
    StringTextWrapper | QTextMixin.

It was then natural and straightforward to make the StringTextWrapper a subclass of QTextMixin. As expected, mypy was then good with using just the QTextMixin annotation instead of the union. 

Two excellent new unit tests

The PR adds two new unit tests: TestNullGui.test_annotations and TestQtGui.test_annotations. The former runs in the null gui, as usual. The latter runs with the qt gui so that ivars such as c.frame.body are Qt (wrapper) widgets.

Both the virtual user idea and the g.checker functions were dead ends. They weren't nearly as revealing as I had hoped. In contrast, the two unit tests were much more helpful than I had expected. They concisely summarize all of Leo's widget and wrapper objects. They will likely be a valuable reference for future devs.

Many cleanups

I ran dozens of cff searches over the past few days. This study revealed a surprising amount of dead weight throughout Leo's gui code. The PR retires three (minor!) classes entirely, and retires about a dozen methods from various classes. Furthermore, the StringTextWrapper class now contains only 4 methods. It inherits all its other methods from the QTextMixin class.

Another cleanup removed unused (and contradictory) kwargs from several classes. mypy and pylint strongly "encouraged" these cleanups.

And one more cleanup. At long last, I added disambiguating headline comments for cursesGui.py and cursesGui2.py. These help a lot when looking at the results of cff searches! Why did I never add such comments before??

Summary

Leo's annotations now reveal why Leo can support multiple guis. Leo's core interacts with the gui only with the standard API that the QTextMixin class exposes. It's really as simple as that! See the Postscript for details.

Two new unit tests remove all doubt concerning the actual types of objects in both the qt gui and the null gui.

The PR removes about a score of obsolete classes, methods, and functions. Strictly speaking, all changes to Leo's API could be called breaking changes. I'll document those changes in the PR and in the 6.8.9 release notes.

It's way too late to merge the PR for this release. I'll merge the PR into devel soon after releasing Leo 6.8.8. I foresee no problems with these changes, but I'll move most (all?) deleted classes and routines into Leo's core.

Edward

P.S. It's now easy to see that there are only 5 qt wrapper classes.

Three wrappers are direct subclasses of QTextMixin:
    QLineEditWrapper, QScintillaWrapper, QTextEditWrapper.

Two wrappers are direct subclasses of QLineEditWrapper:
    QHeadlineWrapper and QMinibufferWrapper.

Finally, the sixth wrapper, StringTextWrapper, forms the basis of Leo's null gui.

EKR

David Szent-Györgyi

unread,
Apr 9, 2026, 5:40:58 PMApr 9
to leo-editor
Trying Hypothesis has been on my to-do list for a while. It might be of interest to you for Leo. From the GitHub page for the main branch

Hypothesis is the property-based testing library for Python. With Hypothesis, you write tests which should pass for all inputs in whatever range you describe, and let Hypothesis randomly choose which of those inputs to check - including edge cases you might not have thought about. . . .

This randomized testing can catch bugs and edge cases that you didn't think of and wouldn't have found. In addition, when Hypothesis does find a bug, it doesn't just report any failing example — it reports the simplest possible one. This makes property-based tests a powerful tool for debugging, as well as testing.

Edward K. Ream

unread,
Apr 10, 2026, 7:41:01 AMApr 10
to leo-e...@googlegroups.com
On Thu, Apr 9, 2026 at 4:41 PM David Szent-Györgyi <das...@gmail.com> wrote:
Trying Hypothesis has been on my to-do list for a while.

Thanks for the link!

Edward
Reply all
Reply to author
Forward
0 new messages