Skip to content

Commit 62f6b97

Browse files
committed
Minimally disruptive change to Protocol
1 parent 2c6c338 commit 62f6b97

File tree

8 files changed

+501
-35
lines changed

8 files changed

+501
-35
lines changed

astrowidgets/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
from ._astropy_init import * # noqa
77
# ----------------------------------------------------------------------------
88

9-
from .core import * # noqa
9+
from .ginga import * # noqa
File renamed without changes.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from typing import Protocol, runtime_checkable, Any
2+
from abc import abstractmethod
3+
4+
# Allowed locations for cursor display
5+
ALLOWED_CURSOR_LOCATIONS = ['top', 'bottom', None]
6+
7+
# List of marker names that are for internal use only
8+
RESERVED_MARKER_SET_NAMES = ['all']
9+
10+
__all__ = [
11+
'ImageViewerInterface',
12+
'ALLOWED_CURSOR_LOCATIONS',
13+
'RESERVED_MARKER_SET_NAMES'
14+
]
15+
16+
17+
@runtime_checkable
18+
class ImageViewerInterface(Protocol):
19+
# This are attributes, not methods. The type annotations are there
20+
# to make sure Protocol knows they are attributes. Python does not
21+
# do any checking at all of these types.
22+
click_center: bool
23+
click_drag: bool
24+
scroll_pan: bool
25+
image_width: int
26+
image_height: int
27+
zoom_level: float
28+
marker: Any
29+
cuts: Any
30+
stretch: str
31+
# viewer: Any
32+
33+
# The methods, grouped loosely by purpose
34+
35+
# Methods for loading data
36+
@abstractmethod
37+
def load_fits(self, file):
38+
raise NotImplementedError
39+
40+
@abstractmethod
41+
def load_array(self, array):
42+
raise NotImplementedError
43+
44+
@abstractmethod
45+
def load_nddata(self, data):
46+
raise NotImplementedError
47+
48+
# Saving contents of the view and accessing the view
49+
@abstractmethod
50+
def save(self, filename):
51+
raise NotImplementedError
52+
53+
# Marker-related methods
54+
@abstractmethod
55+
def start_marking(self):
56+
raise NotImplementedError
57+
58+
@abstractmethod
59+
def stop_marking(self):
60+
raise NotImplementedError
61+
62+
@abstractmethod
63+
def add_markers(self):
64+
raise NotImplementedError
65+
66+
@abstractmethod
67+
def remove_all_markers(self):
68+
raise NotImplementedError
69+
70+
@abstractmethod
71+
def remove_markers_by_name(self, marker_name=None):
72+
raise NotImplementedError
73+
74+
@abstractmethod
75+
def get_all_markers(self):
76+
raise NotImplementedError
77+
78+
@abstractmethod
79+
def get_markers_by_name(self, marker_name=None):
80+
raise NotImplementedError
81+
82+
# Methods that modify the view
83+
@abstractmethod
84+
def center_on(self):
85+
raise NotImplementedError
86+
87+
@abstractmethod
88+
def offset_by(self):
89+
raise NotImplementedError
90+
91+
@abstractmethod
92+
def zoom(self):
93+
raise NotImplementedError

astrowidgets/tests/test_api.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,30 @@
1010

1111
from ginga.ColorDist import ColorDistBase
1212

13-
from ..core import ImageWidget, ALLOWED_CURSOR_LOCATIONS
13+
from ..ginga import ImageWidget, ALLOWED_CURSOR_LOCATIONS
1414

1515

16-
def test_load_fits():
16+
def test_load_fits(): # yep
1717
image = ImageWidget()
1818
data = np.random.random([100, 100])
1919
hdu = fits.PrimaryHDU(data=data)
2020
image.load_fits(hdu)
2121

2222

23-
def test_load_nddata():
23+
def test_load_nddata(): # yep
2424
image = ImageWidget()
2525
data = np.random.random([100, 100])
2626
nddata = NDData(data)
2727
image.load_nddata(nddata)
2828

2929

30-
def test_load_array():
30+
def test_load_array(): # yep
3131
image = ImageWidget()
3232
data = np.random.random([100, 100])
3333
image.load_array(data)
3434

3535

36-
def test_center_on():
36+
def test_center_on(): # yep
3737
image = ImageWidget()
3838
x = 10
3939
y = 10
@@ -48,7 +48,7 @@ def test_offset_to():
4848
image.offset_to(dx, dy)
4949

5050

51-
def test_offset_by():
51+
def test_offset_by(): # yep
5252
image = ImageWidget()
5353

5454
# Pixels
@@ -66,48 +66,48 @@ def test_offset_by():
6666
image.offset_by(1 * u.arcsec, 1)
6767

6868

69-
def test_zoom_level():
69+
def test_zoom_level(): # yep
7070
image = ImageWidget()
7171
image.zoom_level = 5
7272
assert image.zoom_level == 5
7373

7474

75-
def test_zoom():
75+
def test_zoom(): # yep
7676
image = ImageWidget()
7777
image.zoom_level = 3
7878
val = 2
7979
image.zoom(val)
8080
assert image.zoom_level == 6
8181

8282

83-
@pytest.mark.xfail(reason='Not implemented yet')
83+
@pytest.mark.xfail(reason='Not implemented yet') # Nope, note even sure what this is
8484
def test_select_points():
8585
image = ImageWidget()
8686
image.select_points()
8787

8888

89-
def test_get_selection():
89+
def test_get_selection(): # Um, how is this testing a selection?!?
9090
image = ImageWidget()
9191
marks = image.get_markers()
9292
assert isinstance(marks, Table) or marks is None
9393

9494

95-
def test_stop_marking():
95+
def test_stop_marking(): # In test_marking_options
9696
image = ImageWidget()
9797
# This is not much of a test...
9898
image.stop_marking(clear_markers=True)
9999
assert image.get_markers() is None
100100
assert image.is_marking is False
101101

102102

103-
def test_is_marking():
103+
def test_is_marking(): # In test_marking_options
104104
image = ImageWidget()
105105
assert image.is_marking in [True, False]
106106
with pytest.raises(AttributeError):
107107
image.is_marking = True
108108

109109

110-
def test_start_marking():
110+
def test_start_marking(): # In test_marking_options
111111
image = ImageWidget()
112112

113113
# Setting these to check that start_marking affects them.
@@ -142,23 +142,23 @@ def test_start_marking():
142142
assert image.click_drag
143143

144144

145-
def test_add_markers():
145+
def test_add_markers(): # In test_marking_options
146146
image = ImageWidget()
147147
table = Table(data=np.random.randint(0, 100, [5, 2]),
148148
names=['x', 'y'], dtype=('int', 'int'))
149149
image.add_markers(table, x_colname='x', y_colname='y',
150150
skycoord_colname='coord')
151151

152152

153-
def test_set_markers():
153+
def test_set_markers(): # In test_marking_options
154154
image = ImageWidget()
155155
image.marker = {'color': 'yellow', 'radius': 10, 'type': 'cross'}
156156
assert 'cross' in str(image.marker)
157157
assert 'yellow' in str(image.marker)
158158
assert '10' in str(image.marker)
159159

160160

161-
def test_reset_markers():
161+
def test_reset_markers(): # In test_marking_options
162162
image = ImageWidget()
163163
# First test: this shouldn't raise any errors
164164
# (it also doesn't *do* anything...)
@@ -177,7 +177,7 @@ def test_reset_markers():
177177
image.get_markers(marker_name='test2')
178178

179179

180-
def test_remove_markers():
180+
def test_remove_markers(): # In test_marking_options
181181
image = ImageWidget()
182182
# Add a tag name...
183183
image._marktags.add(image._default_mark_tag_name)
@@ -186,7 +186,7 @@ def test_remove_markers():
186186
assert 'arf' in str(e.value)
187187

188188

189-
def test_stretch():
189+
def test_stretch(): # yep
190190
image = ImageWidget()
191191
with pytest.raises(ValueError) as e:
192192
image.stretch = 'not a valid value'
@@ -196,7 +196,7 @@ def test_stretch():
196196
assert isinstance(image.stretch, (ColorDistBase))
197197

198198

199-
def test_cuts():
199+
def test_cuts(): # yep
200200
image = ImageWidget()
201201

202202
# An invalid string should raise an error
@@ -219,7 +219,7 @@ def test_cuts():
219219
assert image.cuts == (10, 100)
220220

221221

222-
def test_colormap():
222+
def test_colormap(): # yep
223223
image = ImageWidget()
224224
cmap_desired = 'gray'
225225
cmap_list = image.colormap_options
@@ -228,7 +228,7 @@ def test_colormap():
228228
image.set_colormap(cmap_desired)
229229

230230

231-
def test_cursor():
231+
def test_cursor(): # yep
232232
image = ImageWidget()
233233
assert image.cursor in ALLOWED_CURSOR_LOCATIONS
234234
with pytest.raises(ValueError):
@@ -237,7 +237,7 @@ def test_cursor():
237237
assert image.cursor == 'bottom'
238238

239239

240-
def test_click_drag():
240+
def test_click_drag(): # yep
241241
image = ImageWidget()
242242
# Set this to ensure that click_drag turns it off
243243
image._click_center = True
@@ -260,7 +260,7 @@ def test_click_drag():
260260
assert 'Interactive marking' in str(e.value)
261261

262262

263-
def test_click_center():
263+
def test_click_center(): # yep
264264
image = ImageWidget()
265265
assert (image.click_center is True) or (image.click_center is False)
266266

@@ -283,7 +283,7 @@ def test_click_center():
283283
image.click_center = False
284284

285285

286-
def test_scroll_pan():
286+
def test_scroll_pan(): # yep
287287
image = ImageWidget()
288288

289289
# Make sure scroll_pan is actually settable
@@ -292,13 +292,13 @@ def test_scroll_pan():
292292
assert image.scroll_pan is val
293293

294294

295-
def test_save(tmp_path):
295+
def test_save(tmp_path): # yep
296296
image = ImageWidget()
297297
filename = 'woot.png'
298298
image.save(tmp_path / filename)
299299

300300

301-
def test_width_height():
301+
def test_width_height(): # yep
302302
image = ImageWidget(image_width=250, image_height=100)
303303
assert image.image_width == 250
304304
assert image.image_height == 100

astrowidgets/tests/test_image_widget.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from astropy.nddata import CCDData
88
from astropy.coordinates import SkyCoord
99

10-
from ..core import ImageWidget, RESERVED_MARKER_SET_NAMES
10+
from ..ginga import ImageWidget, RESERVED_MARKER_SET_NAMES
1111

1212

1313
def _make_fake_ccd(with_wcs=True):
@@ -42,7 +42,7 @@ def _make_fake_ccd(with_wcs=True):
4242
return CCDData(data=fake_image, wcs=wcs, unit='adu')
4343

4444

45-
def test_setting_image_width_height():
45+
def test_setting_image_width_height(): # yep
4646
image = ImageWidget()
4747
width = 200
4848
height = 300
@@ -51,7 +51,7 @@ def test_setting_image_width_height():
5151
assert image._viewer.get_window_size() == (width, height)
5252

5353

54-
def test_add_marker_does_not_modify_input_table():
54+
def test_add_marker_does_not_modify_input_table(): # in test_marking_operations
5555
# Regression test for #45
5656
# Adding markers should not modify the input data table
5757
image = ImageWidget(image_width=300, image_height=300,
@@ -67,7 +67,7 @@ def test_add_marker_does_not_modify_input_table():
6767
assert (in_table == orig_table).all()
6868

6969

70-
def test_adding_markers_as_world_recovers_with_get_markers():
70+
def test_adding_markers_as_world_recovers_with_get_markers(): # yep
7171
"""
7272
Make sure that our internal conversion from world to pixel
7373
coordinates doesn't mess anything up.
@@ -128,7 +128,7 @@ def test_move_callback_includes_offset():
128128
assert float(y_out) == data_y + offset
129129

130130

131-
def test_can_add_markers_with_names():
131+
def test_can_add_markers_with_names(): # in test_marking_operations?
132132
"""
133133
Test a few things related to naming marker sets
134134
"""
@@ -185,7 +185,7 @@ def test_can_add_markers_with_names():
185185
assert image._interactive_marker_set_name in image._marktags
186186

187187

188-
def test_mark_with_reserved_name_raises_error():
188+
def test_mark_with_reserved_name_raises_error(): # in test_marking_operations
189189
npix_side = 200
190190
image = ImageWidget(image_width=npix_side,
191191
image_height=npix_side)
@@ -258,7 +258,7 @@ def test_unknown_marker_name_error():
258258
assert f"No markers named '{bad_name}'" in str(e.value)
259259

260260

261-
def test_marker_name_has_no_marks_warning():
261+
def test_marker_name_has_no_marks_warning(): # in test_marking_operations
262262
"""
263263
Regression test for https://github.com/astropy/astrowidgets/issues/97
264264
@@ -301,7 +301,7 @@ def test_empty_marker_name_works_with_all():
301301
assert 'empty' not in marks['marker name']
302302

303303

304-
def test_add_single_marker():
304+
def test_add_single_marker(): # in test_marking_operations
305305
"""
306306
Test a few things related to naming marker sets
307307
"""

0 commit comments

Comments
 (0)