Skip to content

Commit

Permalink
Fix that awkward arrays in an awyward array view could not be modified.
Browse files Browse the repository at this point in the history
I solved the issue described in the previous commit by adding
logic to `AlignedViewMixin` that can copy objects of a certain type
(for now only awkward arrays) upon view creation.
  • Loading branch information
grst committed Sep 8, 2023
1 parent 4b34598 commit fdeff90
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 5 deletions.
24 changes: 20 additions & 4 deletions anndata/_core/aligned_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,27 @@ class AlignedViewMixin:
parent_mapping: Mapping[str, V]
"""The object this is a view of."""

copied_objects: Mapping[str, V]
"""Objects that are copied at view creation, because they natively support copy on write"""

is_view = True

def __getitem__(self, key: str) -> V:
return as_view(
_subset(self.parent_mapping[key], self.subset_idx),
ElementRef(self.parent, self.attrname, (key,)),
)
try:
return self.copied_objects[key]
# key might not exist, or copied_objects might not yet be initialized
except (KeyError, AttributeError):
return as_view(
_subset(self.parent_mapping[key], self.subset_idx),
ElementRef(self.parent, self.attrname, (key,)),
)

def _copy_objects(self):
"""For some objects (Awkward arrays) we want to store a copy of the slice at view creation."""
self.copied_objects = {}
for key, value in self.parent_mapping.items():
if isinstance(value, AwkArray):
self.copied_objects[key] = AwkArray(self[key])

def __setitem__(self, key: str, value: V):
value = self._validate_value(value, key) # Validate before mutating
Expand Down Expand Up @@ -286,9 +300,11 @@ def __init__(
subset_idx: OneDIdx,
):
self.parent_mapping = parent_mapping
self.copied_objects = {}
self._parent = parent_view
self.subset_idx = subset_idx
self._axis = parent_mapping._axis
self._copy_objects()


AxisArraysBase._view_class = AxisArraysView
Expand Down
2 changes: 1 addition & 1 deletion anndata/_core/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def as_view_awkarray(array, view_args):
# shallow copy of the original. This implies that setting a record field on a slice never modifies the original.
# Other fields than records are entirely immutable anyway.
# See also https://github.com/scverse/anndata/issues/1035#issuecomment-1687619270.
return array
return AwkArray(array)


@as_view.register(CupyArray)
Expand Down

0 comments on commit fdeff90

Please sign in to comment.