Repository navigation
[#11094] Deprecate and remove use of OrderedDescriptor - #11099
Conversation
|
Looks like I forgot to update my master branch because I didn't have #11090 incorporated yet. I'll rebase. |
mhvk
left a comment
There was a problem hiding this comment.
Looks all good to me - nice to have things simpler and less hidden (well, really there are hidden inside python now, of course...).
Does indeed need an entry under "API changes"
|
Great - thanks @embray! Agreed that this looks good and just requires a changelog entry. |
|
Not a huge deal, but I believe this PR results in incorrect behavior when a frame class subclasses two different subclasses of |
|
Here you go: >>> from astropy.coordinates import BaseCoordinateFrame, Attribute
>>> class Frame1(BaseCoordinateFrame):
>>> attr1 = Attribute()
>>> class Frame2(BaseCoordinateFrame):
>>> attr2 = Attribute()
>>> class Frame3(Frame1, Frame2):
>>> pass
>>> Frame3.frame_attributes
{'attr1': <astropy.coordinates.attributes.Attribute at 0x1bfded96248>}Note that For comparison, on >>> Frame3.frame_attributes
OrderedDict([('attr1',
<astropy.coordinates.attributes.Attribute at 0x29bb9e74348>),
('attr2',
<astropy.coordinates.attributes.Attribute at 0x29bbad9dbc8>)]) |
|
(Oops, accidentally pushed commits for a different branch) |
|
Thanks for the example @ayshih. I had thought about this case, but since it didn't happen to come up in any of the Astropy tests I assumed it maybe wasn't a usecase that was needed. Maybe it just wasn't tested because this case was tested implicitly by the use of OrderedDescriptor. But I completely agree with you on how this should work. I'll fix it and add a test. |
|
Out of curiosity @ayshih, what would be the use case of subclassing two different frames? |
|
(Also, gh-11098 was merged, so this could be rebased) |
|
@astrojuanlu thanks for the heads up, will do. I'm also curious about @ayshih's use case of multiple inheritance of frames, but nevertheless they're right that it's a regression over the previous version that should be fixed. I'll try to finish that now. |
|
Rebased and fixed the multiple inheritance case. |
|
Fixed the style check and added changelog entry. |
|
In the changelog I referenced the original issue number, not the PR number. Is that what we're doing now? |
| copy.deepcopy(repr_info)) | ||
|
|
||
| # Set the frame attributes | ||
| # TODO: Should this be made to use readonly_prop_factory as well or |
There was a problem hiding this comment.
The current functionality allows overriding .frame_attributes. Not that it's a good idea to allow this, but I think it's fine to leave functionality as is for now and reconsider this in a separate issue/PR.
This comment has been minimized.
This comment has been minimized.
I don't think those failures are caused by this PR! |
|
You are right! Seems to be from #11108 that just got merged before this was rebased. Or due to upstream changes and the timing is coincidental. |
|
Wait... Ugh, I think it is due to Scipy 1.6.0 that just got released. I'll submit a stop gap PR (see #11201). |
|
Just a 🎆 from the sidelines (will light some real ones later...) |
In principle, this could be useful for using class inheritance to manage common frame attributes. For example, there could be a base class that adds the In practice, Astropy already has cases of subclassing two different frames, although this may be a design oversight. Any frame created by >>> import astropy.units as u
>>> from astropy.coordinates import SkyCoord, SkyOffsetFrame
>>> sc = SkyCoord(0*u.deg, 0*u.deg, frame='hcrs')
>>> so = SkyOffsetFrame(origin=sc)
>>> so
<SkyOffsetHCRS Frame (obstime=J2000.000, rotation=0.0 deg, origin=<HCRS Coordinate (obstime=J2000.000): (ra, dec) in deg
(0., 0.)>)>
>>> so.__class__.__bases__
(astropy.coordinates.builtin_frames.skyoffset.SkyOffsetFrame,
astropy.coordinates.builtin_frames.hcrs.HCRS)
>>> so.frame_attributes
OrderedDict([('obstime',
<astropy.coordinates.attributes.TimeAttribute at 0x18959ce1e88>),
('rotation',
<astropy.coordinates.attributes.QuantityAttribute at 0x18959cfb708>),
('origin',
<astropy.coordinates.attributes.CoordinateAttribute at 0x18959df5b88>)]) |
|
Re |
Parameter.__set_name__ is used to set the names of Parameters upon class initialization. As before, the Model._parameters_ dict is intialized in _ModelMeta.__new__ (which can't easily be replaced with __init_subclass__ as it has other functionalities). Although the removed function astropy.utils.misc.get_parameters was technically public, it was arguably an implementation detail of astropy.modeling.core and never should have been there; it is easily replaced now with a one-liner.
astropy.coordinates Now frame_attributes is simply set in FrameMeta.__new__, and Attribute uses __set_name__. A bit of other minor simplification in FrameMeta.__new__
… that I somehow missed.
…l, fixing a regression from the previous version (since OrderedDescriptorContainer did this automatically) It should not be necessary to walk the entire MRO since this merging of Attributes is already performed cumulatively by each base class's __init_subclass__.
|
Fixed changelog conflict. |
|
OK, just checked again and this all looks great. Let's get it in! |
Fixes #11094. Builds on top of #11098 but they could be separated I think.
Note, this does not attempt to remove any metaclasses in favor of__init_subclass__as discussed somewhat in #11090. That should be handled elsewhere for coordinatesCompletes the work of #11090 to remove
FrameMetasince it is no longer used.