Skip to content

Commit

Permalink
Merge pull request #1139 from astrofrog/fix-serialization-coordinate-…
Browse files Browse the repository at this point in the history
…link

Fail to save session after using advanced link function
  • Loading branch information
astrofrog authored Oct 10, 2016
2 parents f1a062c + c8983ef commit b325e86
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 22 deletions.
16 changes: 12 additions & 4 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,15 @@ Full changelog
==============

v0.9.0 (unreleased)
-----------------
-------------------

* Fix serialization of celestial coordinate link functions. Classes
inheriting from MultiLink should now call MultiLink.__init__ with
individual components (not grouped into left/right) then the create_links
method with the components separated into left/right and the methods for
forward/backward transformation. The original behavior can be retained
by using the ``multi_link`` function instead of the ``MultiLink`` class.
[#1139]

* Improve support for spectral cubes. [#1075]

Expand Down Expand Up @@ -55,7 +63,7 @@ v0.9.0 (unreleased)

* Added a command-line option, ``--no-maximized``, that prevents glue
from opening up with the application window maximized. [#1093, #1126]

* When opening multiple files in one go, if one of the files fails to
read, the error will now indicate which file failed. [#1104]

Expand All @@ -64,10 +72,10 @@ v0.9.0 (unreleased)

* Fixed a bug that caused the functionality to execute scripts (glue -x) to not
work in Python 3. [#1101, #1114]

* The minimum supported version of Astropy is now 1.0, and the minimum
supported version of IPython is now 1.0. [#1076]

* Show world coordinates and units in the cube slicer. [#1059, #1068]

* Fix errors that occurred when selecting categorical data. [#1069]
Expand Down
2 changes: 1 addition & 1 deletion glue/core/component_link.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from glue.core.util import join_component_view


__all__ = ['ComponentLink', 'BinaryComponentLink']
__all__ = ['ComponentLink', 'BinaryComponentLink', 'CoordinateComponentLink']


def identity(x):
Expand Down
25 changes: 22 additions & 3 deletions glue/core/link_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,15 @@ class MultiLink(LinkCollection):
objects.
"""

def __init__(self, cids_left, cids_right, forwards=None, backwards=None):
cids_left = list(map(_toid, cids_left))
cids_right = list(map(_toid, cids_right))
cids = None

def __init__(self, *args):
self.cids = args

def create_links(self, cids_left, cids_right, forwards=None, backwards=None):

if self.cids is None:
raise Exception("MultiLink.__init__ was not called before creating links")

if forwards is None and backwards is None:
raise TypeError("Must supply either forwards or backwards")
Expand All @@ -139,6 +145,19 @@ def __init__(self, cids_left, cids_right, forwards=None, backwards=None):
func = PartialResult(backwards, i, name_prefix=self.__class__.__name__ + ".")
self.append(ComponentLink(cids_right, l, func))

def __gluestate__(self, context):
return {'cids': [context.id(cid) for cid in self.cids]}

@classmethod
def __setgluestate__(cls, rec, context):
return cls(*[context.object(cid) for cid in rec['cids']])


def multi_link(cids_left, cids_right, forwards=None, backwards=None):
ml = MultiLink(cids_left + cids_right)
ml.create_links(cids_left, cids_right, forwards=forwards, backwards=backwards)
return ml


class LinkAligned(LinkCollection):

Expand Down
24 changes: 21 additions & 3 deletions glue/core/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,11 @@ def load(rec, context)

if six.PY2:
literals += (long,)
literals += (np.ScalarType,)


literals += np.ScalarType



# We need to make sure that we don't break backward-compatibility when we move
# classes/functions around in Glue, so we have a file that maps the old paths to
Expand Down Expand Up @@ -253,7 +257,7 @@ def id(self, obj):
if isinstance(obj, six.string_types):
return 'st__%s' % obj

if isinstance(obj, literals):
if type(obj) in literals:
return obj

oid = id(obj)
Expand Down Expand Up @@ -291,7 +295,7 @@ def do(self, obj):
if isinstance(obj, six.string_types):
return 'st__' + obj

if isinstance(obj, literals):
if type(obj) in literals:
return obj

oid = id(obj)
Expand All @@ -305,6 +309,8 @@ def do(self, obj):

if isinstance(obj, types.FunctionType):
result['_type'] = 'types.FunctionType'
elif isinstance(obj, types.MethodType):
result['_type'] = 'types.MethodType'
else:
result['_type'] = "%s.%s" % (type(obj).__module__,
type(obj).__name__)
Expand Down Expand Up @@ -852,6 +858,18 @@ def _load_function(rec, context):
return lookup_class_with_patches(rec['function'])


@saver(types.MethodType)
def _save_method(method, context):
# Note: this only works for methods for which the class can be serialized
return {'instance': context.id(method.__self__), 'method': method.__name__}


@loader(types.MethodType)
def _load_method(rec, context):
instance = context.object(rec['instance'])
return getattr(instance, rec['method'])


@saver(core.Session)
def _save_session(session, context):
# we will rely on GlueApplication to re-populate
Expand Down
10 changes: 5 additions & 5 deletions glue/core/tests/test_link_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from glue.core import ComponentID, Data, Component, DataCollection

from .. import link_helpers as lh
from ..link_helpers import (LinkTwoWay, MultiLink,
from ..link_helpers import (LinkTwoWay, multi_link,
LinkSame, LinkAligned)


Expand Down Expand Up @@ -44,7 +44,7 @@ def test_LinkTwoWay():


def test_multilink_forwards():
result = MultiLink([R, D], [L, B], forwards)
result = multi_link([R, D], [L, B], forwards)
assert len(result) == 2
check_link(result[0], [R, D], L)
check_link(result[1], [R, D], B)
Expand All @@ -53,7 +53,7 @@ def test_multilink_forwards():


def test_multilink_backwards():
result = MultiLink([R, D], [L, B], backwards=backwards)
result = multi_link([R, D], [L, B], backwards=backwards)
assert len(result) == 2
check_link(result[0], [L, B], R)
check_link(result[1], [L, B], D)
Expand All @@ -62,7 +62,7 @@ def test_multilink_backwards():


def test_multilink_forwards_backwards():
result = MultiLink([R, D], [L, B], forwards, backwards)
result = multi_link([R, D], [L, B], forwards, backwards)
assert len(result) == 4
check_link(result[0], [R, D], L)
check_link(result[1], [R, D], B)
Expand All @@ -76,7 +76,7 @@ def test_multilink_forwards_backwards():

def test_multilink_nofunc():
with pytest.raises(TypeError) as exc:
MultiLink([R, D], [L, B])
multi_link([R, D], [L, B])
assert exc.value.args[0] == "Must supply either forwards or backwards"


Expand Down
3 changes: 2 additions & 1 deletion glue/dialogs/link_editor/qt/link_equation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from qtpy import PYSIDE
from glue import core
from glue.utils import nonpartial
from glue.utils.qt import load_ui
from glue.utils.qt import load_ui, messagebox_on_error

__all__ = ['LinkEquation']

Expand Down Expand Up @@ -210,6 +210,7 @@ def function(self, val):
raise KeyError("No function or helper found %s" % [val])
self._ui.function.setCurrentIndex(pos)

@messagebox_on_error("Failed to create links")
def links(self):
""" Create ComponentLinks from the state of the widget
Expand Down
6 changes: 3 additions & 3 deletions glue/plugins/coordinate_helpers/link_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class BaseCelestialMultiLink(MultiLink):
frame_out = None

def __init__(self, in_lon, in_lat, out_lon, out_lat):
MultiLink.__init__(self, [in_lon, in_lat],
[out_lon, out_lat],
self.forward, self.backward)
super(BaseCelestialMultiLink, self).__init__(in_lon, in_lat, out_lon, out_lat)
self.create_links([in_lon, in_lat], [out_lon, out_lat],
forwards=self.forward, backwards=self.backward)

def forward(self, in_lon, in_lat):
c = self.frame_in(in_lon * u.deg, in_lat * u.deg)
Expand Down
8 changes: 8 additions & 0 deletions glue/plugins/coordinate_helpers/tests/test_link_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from glue.core import ComponentID
from glue.core.tests.test_link_helpers import check_link, check_using
from glue.core.tests.test_state import clone

from ..link_helpers import (Galactic_to_FK5, FK4_to_FK5, ICRS_to_FK5,
Galactic_to_FK4, ICRS_to_FK4, ICRS_to_Galactic)
Expand Down Expand Up @@ -56,3 +57,10 @@ def test_conversion(conv_class, expected):
check_using(result[1], (x, y), expected[0][1])
check_using(result[2], (x, y), expected[1][0])
check_using(result[3], (x, y), expected[1][1])

# Check that state saving works

check_using(clone(result[0]), (x, y), expected[0][0])
check_using(clone(result[1]), (x, y), expected[0][1])
check_using(clone(result[2]), (x, y), expected[1][0])
check_using(clone(result[3]), (x, y), expected[1][1])
4 changes: 2 additions & 2 deletions glue/qglue.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def parse_data(data, label):


def parse_links(dc, links):
from glue.core.link_helpers import MultiLink
from glue.core.link_helpers import multi_link
from glue.core import ComponentLink

data = dict((d.label, d) for d in dc)
Expand Down Expand Up @@ -134,7 +134,7 @@ def find_cid(s):
result.append(ComponentLink(f, t, u))
else:
t = [find_cid(item) for item in t]
result += MultiLink(f, t, u, u2)
result += multi_link(f, t, u, u2)

return result

Expand Down

0 comments on commit b325e86

Please sign in to comment.