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