Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make all the valued containers subclass ValueWidget #663

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

hanjinliu
Copy link
Contributor

Closes #372 #661

Now this works:

from magicgui.widgets import FileEdit, PushButton
from magicgui.widgets.bases import ValueWidget

assert isinstance(PushButton(), ValueWidget)
assert isinstance(FileEdit(), ValueWidget)

I had to refactor more than I first thought. The major problem was that ValueWidget had ValueWidgetProtocol before, which is not compatible with container-like widgets (e.g. there's no _mgui_get_value for FileEdit). In this PR, I made ValueWidget more abstract: it only implements the basic interface for getting/setting values, thus independent of backends. PrimitiveValueWidget is the class that require backends, which is identical to the former ValueWidget. Besides, I introduced _BaseContainerWidget for ValuedContainerWidget because many methods of ContainerWidget is not publicly needed for value widgets (e.g. we never use insert for FileEdit).

Inheritance map is now like below.

Widget ----------------> ValueWidget --> PrimitiveValueWidget --> Label, LineEdit, Image etc.
   |                        |
   v                        v
_BaseContainerWidget --> ValuedContainerWidget -----------------> FileEdit, RangeEdit, ListEdit etc.
   |
   v
ContainerWidget ------------------------------------------------> Container

Notes:

  • EmptyWidget is now a ValuedContainerWidget because it's simply an empty container. Backend implementation of EmptyWidget is no longer needed.
  • ValueWidget now inherits ABC because abstractmethod get_value and set_value are needed. This means if one made a Qt widget and magicgui interface like
    class QMyWidget(QBaseValueWidget): ...
    
    class MyWidget(ValueWidget):
        def __init__(self, **kwargs):
            kwargs["widget_type"] = QMyWidget
            super().__init__(**kwargs)
    then it fails with TypeError due to undefined abstract methods.

Please let me know what you think.

Copy link

codecov bot commented Aug 1, 2024

Codecov Report

Attention: Patch coverage is 91.62996% with 19 lines in your changes missing coverage. Please review.

Project coverage is 89.02%. Comparing base (058d63c) to head (b55c3a7).

Files with missing lines Patch % Lines
src/magicgui/widgets/_concrete.py 83.09% 12 Missing ⚠️
src/magicgui/widgets/bases/_container_widget.py 93.80% 7 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #663      +/-   ##
==========================================
- Coverage   89.16%   89.02%   -0.15%     
==========================================
  Files          39       39              
  Lines        4746     4721      -25     
==========================================
- Hits         4232     4203      -29     
- Misses        514      518       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@tlambert03
Copy link
Member

tlambert03 commented Aug 2, 2024

this looks like a great start @hanjinliu, the one thing I'm not thrilled about is the changing of the meaning of ValueWidget to PrimitiveValueWidget... it's a breaking change to expect everyone to now inherit from PrimitiveValueWidget, and as you can see it breaks your own magic-class tests here. I'd rather use a shared base class like ValueWidgetBase and have it not be the case that isinstance(TupleWidget(), ValueWidget) than to rename all ValueWidgets

@hanjinliu
Copy link
Contributor Author

That makes sense. Keeping ValueWidget in the same state is definitely safer.
The magic-class tests failed by the isinstance check of ValueWidget but I think this should be fixed on my side (this is due to the update in EmpytWidget).
The recent breaking change in griffe affects the docs test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

All value-like Container widgets should inherit from ValueWidget
2 participants