Skip to content

Commit 48266f3

Browse files
committed
Prototype serializing Table/QTable with the ASDF core table tag
1 parent b532105 commit 48266f3

File tree

4 files changed

+81
-10
lines changed

4 files changed

+81
-10
lines changed

asdf_astropy/__init__.py

+6
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@
44
from ._astropy_init import * # noqa: F403
55

66
# ----------------------------------------------------------------------------
7+
8+
def configure_core_table_support(asdf_config):
9+
from .extensions import CORE_TABLE_EXTENSIONS
10+
11+
for extension in CORE_TABLE_EXTENSIONS:
12+
asdf_config.add_extension(extension)

asdf_astropy/converters/table/table.py

+41-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from asdf.extension import Converter
22
from asdf.tags.core.ndarray import NDArrayType
3+
from asdf.tagged import TaggedDict
34

45

56
class ColumnConverter(Converter):
@@ -45,18 +46,52 @@ def from_yaml_tree(self, node, tag, ctx):
4546

4647

4748
class AsdfTableConverter(Converter):
48-
tags = ("tag:stsci.edu:asdf/core/table-*",)
49-
types = ()
50-
51-
def to_yaml_tree(self, obj, tag, ctx):
52-
msg = "astropy does not support writing astropy.table.Table with the ASDF table-1.0.0 tag"
53-
raise NotImplementedError(msg)
49+
tags = (
50+
"tag:stsci.edu:asdf/core/table-1.0.0",
51+
"tag:stsci.edu:asdf/core/table-1.1.0",
52+
)
53+
types = (
54+
"astropy.table.table.Table",
55+
"astropy.table.table.QTable",
56+
)
5457

5558
def from_yaml_tree(self, node, tag, ctx):
5659
from astropy.table import Table
5760

5861
return Table(node["columns"], meta=node.get("meta"))
5962

63+
def to_yaml_tree(self, obj, tag, ctx):
64+
from astropy.table import Column, QTable, Table
65+
66+
if isinstance(obj, QTable):
67+
obj = Table(obj)
68+
69+
for column in obj.columns.values():
70+
if not isinstance(column, Column):
71+
msg = f"The ASDF table converter does not support columns of type '{type(column)}'";
72+
raise NotImplementedError(msg)
73+
74+
node = {
75+
"columns": [c for c in obj.columns.values()]
76+
}
77+
78+
if obj.meta:
79+
node["meta"] = obj.meta
80+
81+
return node
82+
83+
84+
class AsdfTableConverterReadOnly(AsdfTableConverter):
85+
types = ()
86+
87+
def to_yaml_tree(self, obj, tag, ctx):
88+
msg = (
89+
"The default configuration of asdf-astropy does not support writing "
90+
f"astropy.table.Table with the {tag} tag. "
91+
"Call asdf_astropy.configure_core_table_support(asdf.get_config()) to use the ASDF core table tags."
92+
)
93+
raise NotImplementedError(msg)
94+
6095

6196
class AstropyTableConverter(Converter):
6297
tags = ("tag:astropy.org:astropy/table/table-*",)

asdf_astropy/converters/table/tests/test_table.py

+20
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import warnings
22

33
import asdf
4+
import asdf_astropy
45
import astropy.units as u
56
import numpy as np
67
import pytest
@@ -270,3 +271,22 @@ def test_asdf_table():
270271
assert table["c"].name == "c"
271272
assert table["c"].description == "The target name"
272273
assert_array_equal(table["c"].data, np.array([b"d", b"e", b"f"]))
274+
275+
276+
def test_write_asdf_table(tmp_path):
277+
with asdf.config_context() as config:
278+
asdf_astropy.configure_core_table_support(config)
279+
280+
table = Table()
281+
table["a"] = [1, 2]
282+
table["b"] = ["x", "y"]
283+
284+
helpers.assert_table_roundtrip(table, tmp_path)
285+
286+
file_path = tmp_path / "test_tag.asdf"
287+
with asdf.AsdfFile() as af:
288+
af["table"] = table
289+
af.write_to(file_path)
290+
291+
with asdf.open(file_path, _force_raw_types=True) as af:
292+
assert af["table"]._tag.startswith("tag:stsci.edu:asdf/core/table-")

asdf_astropy/extensions.py

+14-4
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from .converters.coordinates.sky_coord import SkyCoordConverter
1515
from .converters.coordinates.spectral_coord import SpectralCoordConverter
1616
from .converters.fits.fits import AsdfFitsConverter, AstropyFitsConverter
17-
from .converters.table.table import AsdfTableConverter, AstropyTableConverter, ColumnConverter, NdarrayMixinConverter
17+
from .converters.table.table import AsdfTableConverter, AsdfTableConverterReadOnly, AstropyTableConverter, ColumnConverter, NdarrayMixinConverter
1818
from .converters.time.time import TimeConverter
1919
from .converters.time.time_delta import TimeDeltaConverter
2020
from .converters.transform.compound import CompoundConverter
@@ -516,11 +516,15 @@
516516
QuantityConverter(),
517517
TimeConverter(),
518518
ColumnConverter(),
519-
AsdfTableConverter(),
519+
AsdfTableConverterReadOnly(),
520520
AsdfFitsConverter(),
521521
]
522522

523-
UNIT_CONVETERS = [
523+
CORE_TABLE_CONVERTERS = [
524+
AsdfTableConverter(),
525+
]
526+
527+
UNIT_CONVERTERS = [
524528
UnitConverter(),
525529
EquivalencyConverter(),
526530
MagUnitConverter(),
@@ -542,8 +546,14 @@
542546
CompoundManifestExtension(
543547
[
544548
ManifestExtension.from_uri(u, converters=CORE_CONVERTERS),
545-
ManifestExtension.from_uri("asdf://astropy.org/astropy/manifests/units-1.0.0", converters=UNIT_CONVETERS),
549+
ManifestExtension.from_uri("asdf://astropy.org/astropy/manifests/units-1.0.0", converters=UNIT_CONVERTERS),
546550
],
547551
)
548552
for u in CORE_MANIFEST_URIS
549553
]
554+
555+
556+
CORE_TABLE_EXTENSIONS = [
557+
ManifestExtension.from_uri(u, converters=CORE_TABLE_CONVERTERS)
558+
for u in CORE_MANIFEST_URIS
559+
]

0 commit comments

Comments
 (0)