Skip to content

Commit

Permalink
support integer-1.1 and ndarray-1.1
Browse files Browse the repository at this point in the history
fixes an issue with integer where InterType instead of cls
was used during class instantiation which resulted in objects
being created with the incorrect version. Prior code (that only
had one integer version, 1.0) did not suffer from issues because
of this bug.

fixes #1245 by removing the use of super in NDArrayType and adding
an exception to check for incompatible use of super in classes of
type ExtensionTypeMeta.
  • Loading branch information
braingram committed Nov 30, 2022
1 parent ad66971 commit 690eb5d
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 4 deletions.
3 changes: 2 additions & 1 deletion asdf/tags/core/integer.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class IntegerType(AsdfType):

name = "core/integer"
version = "1.0.0"
supported_versions = {"1.0.0", "1.1.0"}

_value_cache = dict()

Expand Down Expand Up @@ -96,7 +97,7 @@ def from_tree(cls, tree, ctx):
if tree["sign"] == "-":
value = -value

return IntegerType(value)
return cls(value)

def __int__(self):
return int(self._value)
Expand Down
11 changes: 8 additions & 3 deletions asdf/tags/core/ndarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ def ascii_to_unicode(x):
class NDArrayType(AsdfType):
name = "core/ndarray"
version = "1.0.0"
supported_versions = {"1.0.0", "1.1.0"}
types = [np.ndarray, ma.MaskedArray]

def __init__(self, source, shape, dtype, offset, strides, order, mask, asdffile):
Expand Down Expand Up @@ -372,10 +373,10 @@ def __getattribute__(self, name):
# can cause problems when the array is passed to other
# libraries.
# See https://github.com/asdf-format/asdf/issues/1015
if name in ("name", "version"):
if name in ("name", "version", "supported_versions"):
raise AttributeError(f"'{self.__class__.name}' object has no attribute '{name}'")
else:
return super().__getattribute__(name)
return AsdfType.__getattribute__(self, name)

@classmethod
def from_tree(cls, node, ctx):
Expand Down Expand Up @@ -564,6 +565,9 @@ def __operation__(self, *args):
return __operation__


classes_to_modify = NDArrayType.__versioned_siblings + [
NDArrayType,
]
for op in [
"__neg__",
"__pos__",
Expand Down Expand Up @@ -628,7 +632,8 @@ def __operation__(self, *args):
"__delitem__",
"__contains__",
]:
setattr(NDArrayType, op, _make_operation(op))
[setattr(cls, op, _make_operation(op)) for cls in classes_to_modify]
del classes_to_modify


def _get_ndim(instance):
Expand Down
9 changes: 9 additions & 0 deletions asdf/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ def __new__(mcls, name, bases, attrs):
new_attrs["version"] = version
new_attrs["supported_versions"] = set()
new_attrs["_latest_version"] = cls.version
if "__classcell__" in new_attrs:
raise RuntimeError(
"Subclasses of ExtensionTypeMeta that define "
"supported_versions cannot used super() to call "
"parent class functions. super() creates a "
"__classcell__ closure that cannot be duplicated "
"during creation of versioned siblings. "
"See https://github.com/asdf-format/asdf/issues/1245"
)
siblings.append(ExtensionTypeMeta.__new__(mcls, name, bases, new_attrs))
setattr(cls, "__versioned_siblings", siblings)

Expand Down

0 comments on commit 690eb5d

Please sign in to comment.