Repository navigation
Time value attribute incorrect when scale != epoch_scale - #4312
Conversation
There was a problem hiding this comment.
Is there a reason not just to use getattr(parent, self.epoch_scale)? (Or are you thinking ahead to when there will be a cache?).
There was a problem hiding this comment.
This is going to break if parent is None though. Meanwhile, since most of the other TimeFormat.value implementations don't even use the parent argument it seems like a lot of conceptual overhead added to support one special case. I suspect there's maybe some other way to work around this--even something like what @mhvk suggested of adding a method on the formatters that can be used internally by Time.value to do this (which would still just return self.value in most cases). But keep it an internal method.
There was a problem hiding this comment.
In other words, like @mhvk suggested have some kind of TimeFormatter._to_value() method that serves the purpose that's been tacked on to TimeFormatter.value here. The one difference is I would keep it an internal method.
There was a problem hiding this comment.
Is there a reason not just to use `? (Or are you thinking ahead to when there will be a cache?).
Just the converse, I'm thinking of the case right now where getattr(parent, self.epoch_scale) always makes a replica even if the scale is not changing. In the future when that is efficient then this code could be cleaned up. Since I really want this particular bug fixed for my own work (I use cxcsec), I was doing the minimal change.
There was a problem hiding this comment.
This is going to break if parent is None though.
Yup, I thought about that... so perhaps it would have been more correct to just make parent a positional arg?
|
@taldcroft - on the implementation, wouldn't it be cleaner to just have all the formats have a More generally, does the above now give the right answer? I'm not sure I would expect |
|
I don't fully understand what this is about, but changing the .value attribute everywhere to a method seems like a mess of a way to fix it, and isn't this backward incompatible? (Part of my problem is I haven't been following other development, so I don't know what epoch_scale is...) |
|
I felt OK changing |
|
On the bigger question of passing |
Yes, it must. |
|
@taldcroft - OK on the scale, On the implementation, I think you ended up with a mix of what @embray and I recommended. By analogy with One issue is stability of the interface (even though these are within the private |
There was a problem hiding this comment.
In practice, my suggestion would be
def to_value(self, parent=None):
# or **kwargs, followed by parent=kwargs.pop('parent', None)
if self.scale != self.epoch_scale:
if parent is None:
raise SomeException
tm = parent.replicate()
tm._set_scale(self.epoch_scale)
jd1, jd2 = tm._time.jd1, tm._time.jd2
else:
jd1, jd2 = self.jd1, self.jd2
time_from_epoch = ((jd1 - self.epoch.jd1) +
(jd2 - self.epoch.jd2)) / self.unit
return time_from_epoch
value = property(to_value)
There was a problem hiding this comment.
p.s. I think getattr(parent, scale) would still be fine here, since you already know that you have to change the scale, so there is no worry about loss of speed for the case that the scale is unchanged. Or am I missing something?
|
I realized I was making a big mistake of ignoring existing user-defined subclasses. Those subclasses will be defined with the release TimeFormat API that calls for a property named I've pushed the new strategy which is defining a base method In this way the diff footprint went down a lot, at the expense of a little added conceptual complexity. |
|
@taldcroft - it is indeed a little more indirect, but it does seem the best solution for ensuring nobody's code breaks. Do you think it is necessary to update the general documentation? My own sense is that with your |
|
@mhvk - the section on writing a custom format seems ok as is to me. As it says, to get much deeper it just makes sense to get into the code. |
|
@mhvk - are you good with this now? |
|
Yes, it all looks OK. Am merging... |
Time value attribute incorrect when scale != epoch_scale
Time value attribute incorrect when scale != epoch_scale
Time value attribute incorrect when scale != epoch_scale Conflicts: astropy/time/formats.py astropy/time/tests/test_basic.py
For
TimeFromEpochsubclasses there is a bug with thevalueattribute:The problem is that the comment below in
TimeFormat.valuedoesn't apply when accessingTime.valuedirectly (it is correct whenTime.__getattr__gets run for a format attribute):Options include patching
Time.valueto do the same munging thatTime.__getattr__does, or fixing theTimeFromEpoch.valueproperty. The latter is conceptually nicer, but I think it requires that the containedTimeFormatobject orTimeFormat.value()method has access to the parentTimeobject since scale transformations take place at that level.It looks like it might be pretty clean to change the
TimeFormat.valueproperty into a normal method that takes an optionalparentarg. SinceTime._timeis not public this should be OK, and the footprint of this change actually looks quite small.The
Time.__getattr__munging definitely a hack since it requires thatTimehas specific knowledge about one kind ofTimeFormatobject: