-
-
Notifications
You must be signed in to change notification settings - Fork 14
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
Initial draft of interface definition #142
base: main
Are you sure you want to change the base?
Conversation
@pllim @eteq -- this is clearly incomplete but I'm curious to get your reaction. It turns out that a |
This is the first I have heard of |
I only heard about |
There is a fine line between being too strict or too flexible. Too strict, you will have a hard time adopting new backend. Too flexible, people cannot swap backend without everything breaking. But then again, at a glance, it is hard to see just how comparable this is to abstract class. How about pushing on with some real implementation of a few important methods, so we can compare? |
edf546e
to
41d3335
Compare
p.s. Hmm there are conflicts for some reason. |
41d3335
to
1e71af4
Compare
1e71af4
to
dccf354
Compare
Fixed, thanks for catching |
This has a mostly-implemented Whether we end up providing a bqplot viewer, it was useful to try to implement this with a viewer that is not at all astronomy-focused. I hadn't realized how much the current reference implementation depends on the astro-specific nature of Of the unimplemented items there are two things I don't know how to do:
I did try this with 500k markers and it was fine when using bqplot's |
How do you get the bqplot image widget to display? I cannot get it to work and I don't see any example notebook for bqplot backend here. |
RESERVED_MARKER_SET_NAMES = ['all'] | ||
|
||
|
||
class _AstroImage(ipw.VBox): |
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.
It is really confusing to have the API split between _AstroImage
and the official ImageWidget
.
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 was trying to put as little as possible in ImageWidget
that depended on the details of the backend implementation in the hope that we could factor some backend-indpenedent stuff out. The dividing line between the two got a little unclear, though.
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.
Yeah... At some point in my past effort, I just ended up not splitting them but rather hide the backend specific stuff with leading underscore. 😹
Not sure what the issues were -- I'll have a chance to do more work on this tomorrow afternoon. |
A few reactions: In concept I really like this. (Although I might also be falling into the "new and shiny" trap...) I do very much like the fact that this will make it a lot easier for backend implementers to have their astrowidgets backend be the same class as their "normal" object if they want to. It's technically also possible with a abstract class like #126, but I think this is better in that there's less to go wrong in initialization, etc, given that widget implementations already be embedded in complex class hierarchies. And as #126 shows, we really are more interested in astrowidgets as an interface API than a "is a/has a" relationship that subclasses are nominally supposed to follow. Now the downside: the So what I think I settle on is I like this but only with the addition of some clear machinery that's basically "the tests to run to see if you match the interface". Ideally this would be as simple as telling backend implementers write a unit test that looks like this:
or similar, which basically does what this PR's two api test suites do. Of course that still doesn't check that a UI has the correct behvaior, but it's probably just too complex for us to implement any sort of meaningful generic UI-testing tool. |
|
||
def test_consistent_interface(): | ||
iw = ImageWidget() | ||
assert isinstance(iw, ImageViewerInterface) |
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.
Does this actually do the test of whether the API matches with no code changes needed in the ginga object at all? If so, that's very magical! (in a good way)
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.
Yes -- it does not check signatures, etc, but it makes sure that all of the properties/methods are there.
In some out-of-band discussion, @mwcraig, @pllim, and I concluded we want to go in this direction at least to start with over a abstract/subclass approach like that from #126. But some of the machinery from #126 should be ported over here - especially the documentation of the API/intent and the testing framework from there. |
19cfcb0
to
24cb2cf
Compare
self._image.scales['image'].colors = colors | ||
|
||
def save_png(self, filename): | ||
self._figure.save_png(filename) |
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 actually pops up a file dialog, not quite what we want?
fd2f284
to
07c047d
Compare
TST: Update test matrix and added a test. DOC: Re-organized doc and notebooks. DOC: Update example notebooks
DOC: Cannot use automodapi for Ginga API because we need to inherit docstring. DOC: Do not display inherited members because too confusing. [ci skip]
The base class is gone now that we are switching to a Protocol instead
6f14f09
to
82a7844
Compare
The underlying design has been superseded by #162 but I am leaving this open in case there are some stuff here you still want to move to follow-up PRs after that one. Turning this into draft for now. |
This is the beginning of an alternative to #126 using
typing.Protocol
to define the interface instead of an abstract base class. The test at https://github.com/astropy/astrowidgets/compare/main...mwcraig:interface-definition?expand=1#diff-06b6503d76a97db0c1f54a2065996b518f9e862f9f2fcd158fb3a04c2963d321R17 effectively checks that all of the required attributes and/or methods are present.This does NOT include the changes in the API introduced in #126 yet (that adds a
viewer
attribute and renames some of the marker-related methods) or the change in #140 (renamingoffset_to
tooffset_by
and changing the behavior).I'm leaning towards a protocol instead of abstract class because it seems to maximize flexibility: with no changes to the current
ImageWidget
class at all, or changes in how it subclasses, we can verify that it, at least in principle, satisfies the protocol. Different backends can subclass from whatever they want but still promise to deliver the interface.Different implementations can choose different routes for representing the attributes and that is fine. For example, an ipywidgets-based implementation will make many of the attributes
traitlets
so that they can be linked together to provide synced viewers. A glue-based implementation may have some other method, and some other implementation may implement them as properties with setters.Todo
Protocol
related to markers are either commented out or need to be revised.Protocol
or anABC
is irrelevant to this) or moves to its own, separately versioned repo.Protocol
or anABC
.Fix remaining bqplot test failures and xfails/skips:
test_cuts
fails becausehistogram
isn't inautocut_options
...not sure it needs to be or what it is (there is nothistogram
astropyInterval
)test_marking_operations
fails because the bqplot version only adds a marker name if there are markers, and removes the name if there are no markers for it, so it always raises aValueError
for no markers. The ginga version warns if a marker name is in the list of marker names but there are no markers with that name.scroll_pan
test passes there is no way to make bqplot actuallyscroll_pan
that I have found yet.click_center
does not actually work even though the test passeszoom_level
is0
.Fix these GUI issues in bqplot viewer
cursor
does not change where it is located.SkyCoord
does not properly center image -- actually it does, but coordinate in the test notebook needs to be in Galactic coordinates to match the image WCS.zoom_level
to 1 recenters the viewer and moves the center out of the FOVstretch_options
is an attribute errorstretch
does not change the displayautocut_options
is an attribute error__str__
forcuts
is just the__repr__
for the underlying astropyInterval
cuts
to a tuple failscuts
to a name (e.g.zscale
) failsclick_center
does not actually do anything -- clicking does not centerstart_marking
failsadd_markers
fails