Repository navigation
Switch "representation" to "representation_type" in coordinates - #6873
Conversation
|
Hi there @adrn 👋 - thanks for the pull request! I'm just a friendly 🤖 that checks for issues related to the changelog and making sure that this pull request is milestoned and labeled correctly. This is mainly intended for the maintainers, so if you are not a maintainer you can ignore this, and a maintainer will let you know if any action is required on your part 😃. Everything looks good from my point of view! 👍 If there are any issues with this message, please report them here. |
mhvk
left a comment
There was a problem hiding this comment.
Looks like a good start, but a few too many replacements of _cls... Also, a general question that I think we should raise an exception if both representation and representation_type are present.
A more general question is whether at least for the properties we can already have a AstropyPendingDeprecation warning. (I must admit I'm less sure about the keyword case, at least for representation=<some-string> as that may well be in quite wide usage, so we'd at the very least have to be very slow - maybe pending now, deprecation in 4.0, removal in 5.0).
| ---------- | ||
| representation : `BaseRepresentation` or None | ||
| A representation object or `None` to have no data (or use the other | ||
| representation_type : `BaseRepresentation` or None |
There was a problem hiding this comment.
I think this one should be changed to data - since here you are allowed to put in a BaseRepresentation instance.
Although I always found it annoying that in fact the initializer is *args. But that is independent of this PR?
There was a problem hiding this comment.
Yea, the *args thing annoys me too...I wonder if there is any way to use the metaclass to hack the signature? Sounds a little scary though. But yea, I think outside of the scope of this PR.
| Coordinates, with names that depend on the subclass. | ||
| differential_cls : `BaseDifferential`, dict, optional | ||
| Coordinate components, with names that depend on the subclass. | ||
| differential_type : `BaseDifferential`, dict, optional |
There was a problem hiding this comment.
And above you need to add representation_type (as in the initializer below).
I also note that the line is confusing: it should be
differential_type: `BaseDifferential` subclass, str, dict, optional
| # TODO: this is here for backwards compatibility. It should be possible | ||
| # to use either the kwarg representation_type, or representation. | ||
| # In future versions, we will raise a deprecation warning here: | ||
| representation_type = kwargs.pop('representation', representation_type) |
There was a problem hiding this comment.
This should be an error if representation_type is given as well. So,
if 'representation' in kwargs:
if representation_type is not None:
raise
representation_type = kwargs.pop('representation')
|
|
||
| # TODO: we should be able to deal with an instance, not just a | ||
| # class or string for representation and differential_cls. | ||
| # class or string for representation and differential_type. |
There was a problem hiding this comment.
This comment is actually misleading, as currently the class is able to deal with an instance for representation (i.e., the first argument can be a BaseRepresentation instance. So, the question would be whether we should be able to deal with a Differential instance as well. Personally, I don't think this is necessary - one can just pass in a representation with differential already attached.
| elif self.representation: | ||
| representation_cls = self.representation | ||
| elif self.representation_type: | ||
| representation_type = self.representation_type |
There was a problem hiding this comment.
I think here it is actually clearer to stick with representation_cls = self.get_representation_cls() (i.e., use the getter), because the whole stanza below deals with something known to be a class.
| Can only be passed in as a keyword argument. | ||
|
|
||
| differential_cls : `BaseDifferential`, dict, optional | ||
| differential_type : `BaseDifferential`, dict, optional |
There was a problem hiding this comment.
Strange that the str option was missing again. See comment for Baseframe in that it also should be BaseDifferential subclass. I guess this holds for all other frames too. Sigh.
It may be worth using astropy.utils.decorators.format_doc...
There was a problem hiding this comment.
OK, I sucked it up and overhauled all of the docstrings to use format_doc. I did it in a single commit, so it's probably easiest to look at the diff for that commit...
| coord_kwargs = {} | ||
| if 'representation' in kwargs: | ||
| coord_kwargs['representation'] = _get_repr_cls(kwargs['representation']) | ||
| kwargs['representation_type'] = kwargs.pop('representation') |
There was a problem hiding this comment.
I'd raise if representation_type is present already in kwargs
| # TODO: deprecate this in future | ||
| if 'representation' in kwargs: | ||
| valid_kwargs['representation'] = _get_repr_cls(kwargs.pop('representation')) | ||
| valid_kwargs['representation_type'] = _get_repr_cls( |
There was a problem hiding this comment.
Again, raise if representation_type is already present.
| # TODO: deprecate this in future | ||
| if 'representation' in kwargs: | ||
| frame = frame_cls(representation=_get_repr_cls(kwargs['representation'])) | ||
| repr_cls = _get_repr_cls(kwargs['representation']) |
There was a problem hiding this comment.
And again. Also, I'd set representation_type as you have above. It does seem like you could make a mini-helper function _normalize_representation_type(kwargs)...
| icrs = ICRS(ra=1*u.deg, dec=60*u.deg, | ||
| pm_ra=10*u.mas/u.yr, pm_dec=-11*u.mas/u.yr, | ||
| differential_cls=r.UnitSphericalDifferential) | ||
| differential_type=r.UnitSphericalDifferential) |
There was a problem hiding this comment.
Hmm, don't we test passing in a string?
|
I do need to check this works with SunPy. The change will mean some refactoring for us when we are astropy >= 3.0 only. (Which will not be our next release as we have one more 2.7 release scheduled) |
|
@Cadair This PR shouldn't break sunpy (we should test this when I get farther along) as it doesn't deprecate or remove using " |
0567c3c to
9adfa35
Compare
|
OK I think I addressed @mhvk's comments. The diffs are pretty ugly - sorry about that...One major thing I did (in 653395e) is to overhaul the builtin frame docstrings to use the I added a test for backwards compatibility, and improved one of the frame initialization tests that tries a bunch of valid argument combinations. Next commit(s) will be documentation updates. |
|
From a brief scan of diffs from the API perspective this looks good to me and matches how we discussed handling this at the coordination meeting. Thanks! @Cadair - your SunPy testing will be crucial as the idea we agreed on is that this change should not break any code right now, even testing that is being strict about warnings. (I.e. in this release there won't even be pending deprecation warnings, just doc / example updates that reflect the new preferred API). @mhvk - yes, the idea is to take this very slowly. |
|
This change should be explicitly discussed somewhere in the narrative docs. Maybe a |
mhvk
left a comment
There was a problem hiding this comment.
This looks good; only small comments left.
| # This then causes the dictionary key check to fail (i.e. | ||
| # comparison against `diff._get_deriv_key()`) | ||
| data._differentials.update({'s': diff}) | ||
| # data = data.with_differentials({'s': diff}) |
There was a problem hiding this comment.
Commented-out code should be removed!
| return out | ||
|
|
||
|
|
||
| def _normalize_representation_type(kwargs): |
There was a problem hiding this comment.
Move this to baseframe, use it there as well, and import it here? Would help ensure that we deprecate at the same time.
| # TODO: deprecate these in future | ||
| @property | ||
| def representation(self): | ||
| return self.frame.representation |
There was a problem hiding this comment.
Might leave these as is, again to ensure we do things at the same time.
| repr_gal = repr(gal) | ||
|
|
||
| for k in kwargs: | ||
| if '_type' in k: |
There was a problem hiding this comment.
Why? Shouldn't only differential_type be skipped?
Cadair
left a comment
There was a problem hiding this comment.
This appears to cause no obvious issues with SunPy.
eteq
left a comment
There was a problem hiding this comment.
I think I found the problem that was making the tests fail and pushed up a commit. Assuming that works I'm happy with this aside from two things:
- Needs a changelog entry (both as a "new feature" and an API change
- I agree with @taldcroft that it's worth just a few-sentence note in the narrative docs on what happened here.
| # This is here for backwards compatibility. It should be possible | ||
| # to use either the kwarg representation_type, or representation. | ||
| # TODO: In future versions, we will raise a deprecation warning here: | ||
| _normalize_representation_type(kwargs) |
There was a problem hiding this comment.
this looks to me to be the source of all the failures: _normalize_representation_type is expecting representation_type to be in the kwargs, but it isn't - it's a separate stand-alone keyword. If I add this immediately above:
if 'representation' in kwargs:
representation_type = kwargs.pop('representation')
most of the tests begin to pass. So from that I derived the commit I pushed up to this branch that I hope should get the tests all passing.
|
Why does this need a changelog entry in new features? I added a line in the API changes section. Can you add one to new features if you think it is necessary? Your commit seems to have fixed the build failures - thanks |
7244e19 to
d2355dd
Compare
|
Also, I ran out of time: this still needs a few sentences in the documentation to explain the change. I can do this much later tonight unless someone gets to it first. |
d2355dd to
baa34f0
Compare
|
Oof, that was a pretty nasty rebase. I think I cleaned up any possible issues, but it would be good for someone to take a look at the line changes again. The main files with conflicts were I also added a |
[ci skip]
|
(I guess I didn't say this above, but I looked and other than a changelog tweak it looked good to me - @adrn seems to have strong rebase-fu!) |
The context is: the frame classes and
SkyCoordaccept arepresentation=keyword and have a.representationattribute (and similar fordifferential), but these are the class, not the underlying representation object (that is.data). This has confused me, @eteq, and at least a few users, so we have a long term plan of deprecating and removing these attributes in favor ofrepresentation_typeanddifferential_type.This is something we discussed in the lead up to v2.0 and then recently at the coordination meeting.
This still needs:
representationat least) just to make sure that they still pass with the new attribute name / keyword.This fixes #6591