Skip to content

Remove ordereddict io.ascii - #16240

Closed
MridulS wants to merge 10 commits into
astropy:mainfrom
MridulS:remove-ordereddict-io.ascii
Closed

MridulS wants to merge 10 commits into
astropy:mainfrom
MridulS:remove-ordereddict-io.ascii

Conversation

@MridulS

@MridulS MridulS commented Mar 26, 2024

Copy link
Copy Markdown
Contributor

Description

This builds on top of #15496, the commit 085fcd0 has the changes to make the tests happy. One is changing the MetaData default factory to a dict instead of OrderedDict and other (more controversial) one is to change the YAML representation of the dump. From what I gather the main reason for the failure was the addition of the omap tags which are added by custom astropy dumpers/loaders for OrderedDict and not for a normal python dict.

But this is a breaking change as it does change the YAML representation, so if someone reads an old serialized object it will be read in a normal dictionary and not a ordered dict. If we do tweak the representation we should get rid of the custom logic for handling ordereddicts in AstropyDumper/Loader.

This also forces all the dictionary objects to preserve insertion order in the YAML output, which wasn't guaranteed before.

I think it may make sense to do astropy/table in this PR too to make sure everything is in one place.

Fixes #

  • By checking this box, the PR author has requested that maintainers do NOT use the "Squash and Merge" button. Maintainers should respect this when possible; however, the final decision is at the discretion of the maintainer that merges the PR.

alexandrecesarba and others added 10 commits March 26, 2024 17:58
This pull request removes OrderedDict from files in io.ascii.

The files are: core.py , daophot.py , ecsv.py , fastbasic.py , ipac.py and test_read.py.
The OrderedDicts are normal dictionaries now.
 Applying the suggested change in meta.py. Now sort_keys is False, since yaml does not preserve order.

Suggested by: @dhomeier and @mhvk
Applying @dhomeier suggested changes defining sort_keys as False instead of default_flow_style
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Astropy! 🌌 This checklist is meant to remind the package maintainers who will review this pull request of some common things to look for.

  • Do the proposed changes actually accomplish desired goals?
  • Do the proposed changes follow the Astropy coding guidelines?
  • Are tests added/updated as required? If so, do they follow the Astropy testing guidelines?
  • Are docs added/updated as required? If so, do they follow the Astropy documentation guidelines?
  • Is rebase and/or squash necessary? If so, please provide the author with appropriate instructions. Also see instructions for rebase and squash.
  • Did the CI pass? If no, are the failures related? If you need to run daily and weekly cron jobs as part of the PR, please apply the "Extra CI" label. Codestyle issues can be fixed by the bot.
  • Is a change log needed? If yes, did the change log check pass? If no, add the "no-changelog-entry-needed" label. If this is a manual backport, use the "skip-changelog-checks" label unless special changelog handling is necessary.
  • Is this a big PR that makes a "What's new?" entry worthwhile and if so, is (1) a "what's new" entry included in this PR and (2) the "whatsnew-needed" label applied?
  • At the time of adding the milestone, if the milestone set requires a backport to release branch(es), apply the appropriate "backport-X.Y.x" label(s) before merge.

@neutrinoceros

Copy link
Copy Markdown
Contributor

If it's building on top of a draft PR I suggest drafting this one too !

@taldcroft

Copy link
Copy Markdown
Member

@MridulS - the change to MetaData is likely to cause too many problems. The YAML representation of this is bigger than just astropy. A few things to note:

  • In YAML the key order is explicitly not ordered. So even if one Python implementation happens to write them out in order this does not guarantee anything with other readers. https://yaml.org/spec/1.2.2/#3221-mapping-key-order
  • The ECSV spec explicitly calls out !!omap as the serialization type for meta. This cannot be changed without a change to APE-6. There are other non-Python reader/writers for ECSV so such a change is not likely to be approved unless there is a very strong driver. https://github.com/astropy/astropy-APEs/blob/main/APE6.rst

@MridulS

MridulS commented Mar 26, 2024

Copy link
Copy Markdown
Contributor Author

The ECSV spec explicitly calls out !!omap as the serialization type for meta. This cannot be changed without a change to APE-6. There are other non-Python reader/writers for ECSV so such a change is not likely to be approved unless there is a very strong driver. https://github.com/astropy/astropy-APEs/blob/main/APE6.rst

Woops, did not see that! I guess OrderedDict needs to be there. I don't think it is going away from CPython anytime soon. The only main gain here would be the performance gain. Vanilla dict is supposed to be much more efficient than OrderedDict

@taldcroft

Copy link
Copy Markdown
Member

The only main gain here would be the performance gain. Vanilla dict is supposed to be much more efficient than OrderedDict

I haven't done profiling but I would be a bit surprised if meta handling is a substantial factor in performance for many real-world applications.

@MridulS

MridulS commented Mar 27, 2024

Copy link
Copy Markdown
Contributor Author

I haven't done profiling but I would be a bit surprised if meta handling is a substantial factor in performance for many real-world applications.

Yeah I was thinking more about Table wide usage of OrderedDict, like in TableColumns too, but maybe the abstraction is far enough. I should run some benchmarks :)

@nstarman nstarman Mar 28, 2024 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm good with all the cosmology changes so long as the resulting files adhere to the ECSV standard!

@taldcroft

Copy link
Copy Markdown
Member

@MridulS - I was poking around the code and wondered about an idea to use OrderedDict only at the interface with YAML, in that way preserving the !!omap tag. I have not tested this, but you could try these changes:

➜  astropy git:(main) ✗ git diff
diff --git a/astropy/table/meta.py b/astropy/table/meta.py
index 3af1c64cab..20883641c5 100644
--- a/astropy/table/meta.py
+++ b/astropy/table/meta.py
@@ -76,7 +76,7 @@ def _construct_odict(load, node):
       >>> yaml.load('''!!omap [ foo: bar, mumble: quux, baz : gorp ]''')  # doctest: +SKIP
       OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')])
     """
-    omap = OrderedDict()
+    omap = {}
     yield omap
     if not isinstance(node, yaml.SequenceNode):
         raise yaml.constructor.ConstructorError(
@@ -269,7 +269,7 @@ def _get_col_attributes(col):
         ("unit", lambda x: x is not None, str),
         ("format", lambda x: x is not None, None),
         ("description", lambda x: x is not None, None),
-        ("meta", lambda x: x, None),
+        ("meta", lambda x: OrderedDict(x), None),
     ):
         col_attr = getattr(col.info, attr)
         if nontrivial(col_attr):
@@ -302,7 +302,7 @@ def get_yaml_from_table(table):
     """
     header = {"cols": list(table.columns.values())}
     if table.meta:
-        header["meta"] = table.meta
+        header["meta"] = OrderedDict(table.meta)
 
     return get_yaml_from_header(header)

@taldcroft

Copy link
Copy Markdown
Member

With the changes above, you should also revert the changes that add sort_keys=False. That should no longer be necessary and this will hopefully reduce the change footprint even further. The goal is for this PR to be minimally impacting and not break any unit or doc tests. (That's the goal, we'll see about reality).

# datatype:
# - {name: name, datatype: string}
...
# meta: !!omap

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does this mean for people with older ESCV files with this !!omap though? Will their files no longer load with this patch? I think this was discussed before elsewhere but I don't have time to dig it up right now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah removing that was a bad idea 😅

This is continued in #16250 (closing this PR).

@pllim pllim modified the milestones: v6.1.0, v7.0.0 Mar 29, 2024
@pllim pllim added API change PRs and issues that change an existing API, possibly requiring a deprecation period Refactoring labels Mar 29, 2024
@MridulS MridulS closed this Mar 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

API change PRs and issues that change an existing API, possibly requiring a deprecation period cosmology io.ascii io.misc Refactoring table utils

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

7 participants