-
Notifications
You must be signed in to change notification settings - Fork 47
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
Create return matcher for extensible return widget creation #355
Conversation
generally looks good! I think, if possible, I'd prefer not to have an entirely different module for return annotations. If you can point to the specific places that made you feel like you needed a fully different |
I don't know that there were any, that might just be my java background showing 😅 If we propagate the Do you want to leave the |
even more, can you think of specific scenarios where we want to map a given type to a different widget on the output than we would on the input? Most of the type->widget mappings kind of make sense for the value type (independent of whether it's an input or an output). The one exception might be that outputs should be in other words, I'm saying why can't we just add a new type for table here and be done with it? |
Sure, I mean one I think makes the least sense would be a Similarly, you might want a slider widget for a numerical input, but I don't think you'd want that for the output |
doesn't it though? If someone wrote:
wouldn't a checkbox that ticks and unticks itself as the result changed from True to false be as reasonable of a default as any? I see that you're using I do think that anything that requires further input (like the filedialog for pathlib.Path) is a good example of something that doesn't make sense as an output. Lemme ponder this one a bit :) |
423dbd4
to
aaf93c4
Compare
@tlambert03 I condensed the two type matchers into one module, but there are still two matchers. I did actually find a difference between the two that wasn't just a difference in return widget; I get test failures in other tests if I use this block in return widget matching. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is looking good @gselzer! Thank you also for the lovely tests.
I've made few minor comments about naming and API. But other than that I think it's very close!
magicgui/type_map.py
Outdated
def get_widget_class( | ||
value: Any = None, | ||
annotation: type | None = None, | ||
is_input: bool = None, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is technically a breaking API change, since this is a public function and this changes the order of positional args. (not to mention the fact that the current default of is_input=None
will change this function to return widgets by default). Can we put this after options
, change the name to is_result
(to match the current wording used elsewhere of result_widget
, and use a default value of is_result=False
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the suggested change and rebased it into the commit that added this so that we wouldn't have any commits where is_input
existed. Please let me know what you think.
@@ -20,6 +20,7 @@ def create_widget( | |||
label=None, | |||
gui_only=False, | |||
app=None, | |||
is_input: bool = True, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see other comment, move after options
and change to is_result=False
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the suggested change and rebased it into the commit that added this so that we wouldn't have any commits where is_input
existed. Please let me know what you think.
also, looks like there's one last failing test: https://github.com/napari/magicgui/runs/4913849327?check_suite_focus=true#step:6:296 |
@tlambert03 I don't understand that test failure. Why is a function in |
3f240cc
to
7def48e
Compare
ah, because of a poorly designed test causing side effects over there :) in line ~446 of test_magicgui.py, add this try/finally, and pop the registered types. register_type(int, return_callback=check_value)
register_type(Base, return_callback=check_value)
try:
@magicgui
def func(a=1) -> int:
return a
func()
with pytest.raises(AssertionError):
func(3)
@magicgui
def func2(a=1) -> Sub:
return a
func2()
finally:
from magicgui.type_map import _RETURN_CALLBACKS
_RETURN_CALLBACKS.pop(int)
_RETURN_CALLBACKS.pop(Base) (if this happens again, I can deal with this on a more global level) |
7608595
to
f401c5f
Compare
Gotcha, that seems to have fixed it on my side @tlambert03. Let me know what you think |
Codecov Report
@@ Coverage Diff @@
## main #355 +/- ##
==========================================
- Coverage 90.35% 90.21% -0.15%
==========================================
Files 29 29
Lines 3349 3402 +53
==========================================
+ Hits 3026 3069 +43
- Misses 323 333 +10
Continue to review full report at Codecov.
|
f5311b7
to
91554a8
Compare
Otherwise, the calls to pop() do nothing
They interfere with our ability to resolve ForwardRefs.
As pointed out by @tlambert03, we can just use the single TypeMatcher alias
With the work done by @tlambert03, we can now remove the ignores for mypy
bcb4c27
to
b5b13a6
Compare
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for this @gselzer! very handy addition!
This PR introduces a class
ReturnMatcher
, an analogue ofTypeMatcher
for widgets displaying function outputs.As of now, there are only two
ReturnMatcher
s written. One supports "simple" types viawidgets.LineEdit
. The other supports "tabular" types viawidgets.Table
. There is nothing preventing us from writing more of these to support other types.The default return widget is a
widgets.LineEdit
, chosen to best align with previous behavior.