From 2db9754aa8881bee78a9e3d67e49eca1f21fb1bf Mon Sep 17 00:00:00 2001 From: Jayaram Kancherla Date: Mon, 10 Nov 2025 14:47:06 -0800 Subject: [PATCH 1/4] Fix max domain errors --- src/cellarr_array/core/helpers.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cellarr_array/core/helpers.py b/src/cellarr_array/core/helpers.py index df2236c..05eafde 100644 --- a/src/cellarr_array/core/helpers.py +++ b/src/cellarr_array/core/helpers.py @@ -107,7 +107,13 @@ def create_cellarray( for name, s, dt in zip(dim_names, shape, dim_dtypes): if np.issubdtype(dt, np.integer): domain = (0, 0 if s == 0 else s - 1) - tile = min(1 if s == 0 else s // 2, config.tile_capacity // 2) + is_max_domain = s == np.iinfo(dt).max + if is_max_domain: + # If domain is maxed out, we cannot set a tile extent + # or TileDB will fail on domain expansion. + tile = None + else: + tile = min(1 if s == 0 else s // 2, config.tile_capacity // 2) dim_dtype = dt else: # Assumes string or object dtype domain = (None, None) From d653e16429e693b399d80b7da1350fb481c192ab Mon Sep 17 00:00:00 2001 From: Jayaram Kancherla Date: Mon, 10 Nov 2025 14:48:03 -0800 Subject: [PATCH 2/4] Update changelog version --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b893092..ea53ec0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Version 0.3.0 - 0.3.1 +## Version 0.3.0 - 0.3.2 - Support for string dimensions when creating cellarr arrays. - Support query conditions for slice operations. From a7885d942e93e1660ee42d22b35c8aa6771b8e55 Mon Sep 17 00:00:00 2001 From: Jayaram Kancherla Date: Mon, 10 Nov 2025 15:24:40 -0800 Subject: [PATCH 3/4] linting --- src/cellarr_array/core/base.py | 6 ++++++ src/cellarr_array/core/helpers.py | 5 ++++- src/cellarr_array/core/sparse.py | 1 - 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cellarr_array/core/base.py b/src/cellarr_array/core/base.py index 76abbbd..24dcd29 100644 --- a/src/cellarr_array/core/base.py +++ b/src/cellarr_array/core/base.py @@ -172,6 +172,7 @@ def dim_names(self) -> List[str]: if self._dim_names is None: with self.open_array(mode="r") as A: self._dim_names = [dim.name for dim in A.schema.domain] + return self._dim_names @property @@ -180,6 +181,7 @@ def attr_names(self) -> List[str]: if self._attr_names is None: with self.open_array(mode="r") as A: self._attr_names = [A.schema.attr(i).name for i in range(A.schema.nattr)] + return self._attr_names @property @@ -196,6 +198,7 @@ def shape(self) -> Tuple[int, ...]: # We use a large number as a placeholder for slicing purposes. shape_list.append(2**63 - 1) self._shape = tuple(shape_list) + return self._shape @property @@ -208,6 +211,7 @@ def nonempty_domain(self) -> Optional[Tuple[Any, ...]]: self._nonempty_domain = None else: self._nonempty_domain = tuple(ned) if isinstance(ned[0], tuple) else (ned,) + return self._nonempty_domain @property @@ -217,6 +221,7 @@ def ndim(self) -> int: with self.open_array(mode="r") as A: self._ndim = A.schema.ndim # self._ndim = len(self.shape) + return self._ndim @property @@ -225,6 +230,7 @@ def dim_dtypes(self) -> List[np.dtype]: if self._dim_dtypes is None: with self.open_array(mode="r") as A: self._dim_dtypes = [dim.dtype for dim in A.schema.domain] + return self._dim_dtypes @contextmanager diff --git a/src/cellarr_array/core/helpers.py b/src/cellarr_array/core/helpers.py index 05eafde..a378af4 100644 --- a/src/cellarr_array/core/helpers.py +++ b/src/cellarr_array/core/helpers.py @@ -71,6 +71,7 @@ def create_cellarray( if attr_dtype is None: attr_dtype = np.float32 + if isinstance(attr_dtype, str): attr_dtype = np.dtype(attr_dtype) @@ -91,6 +92,7 @@ def create_cellarray( if shape is None: shape = tuple(np.iinfo(dt).max if np.issubdtype(dt, np.integer) else None for dt in dim_dtypes) + if None in shape: shape = tuple( np.iinfo(dt).max if s is None and np.issubdtype(dt, np.integer) else s for s, dt in zip(shape, dim_dtypes) @@ -99,7 +101,6 @@ def create_cellarray( if dim_names is None: dim_names = [f"dim_{i}" for i in range(len(shape))] - # Validate all input lengths if not (len(shape) == len(dim_dtypes) == len(dim_names)): raise ValueError("Lengths of 'shape', 'dim_dtypes', and 'dim_names' must match.") @@ -107,6 +108,7 @@ def create_cellarray( for name, s, dt in zip(dim_names, shape, dim_dtypes): if np.issubdtype(dt, np.integer): domain = (0, 0 if s == 0 else s - 1) + is_max_domain = s == np.iinfo(dt).max if is_max_domain: # If domain is maxed out, we cannot set a tile extent @@ -114,6 +116,7 @@ def create_cellarray( tile = None else: tile = min(1 if s == 0 else s // 2, config.tile_capacity // 2) + dim_dtype = dt else: # Assumes string or object dtype domain = (None, None) diff --git a/src/cellarr_array/core/sparse.py b/src/cellarr_array/core/sparse.py index 9007772..d23e69b 100644 --- a/src/cellarr_array/core/sparse.py +++ b/src/cellarr_array/core/sparse.py @@ -178,7 +178,6 @@ def _to_sparse_format( raise RuntimeError("Internal error: Coordinate remap dictionary not found.") new_coords.append(np.array([remap_dict[val] for val in global_coords])) - elif origins_or_maps[i] is not None: new_coords.append(global_coords - origins_or_maps[i]) else: From 5ae68c12ce8590f5debbfda1b02298b55e4367c6 Mon Sep 17 00:00:00 2001 From: Jayaram Kancherla Date: Mon, 10 Nov 2025 15:25:19 -0800 Subject: [PATCH 4/4] update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea53ec0..1dd49bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Support query conditions for slice operations. - Added unique dim values. Only supported for sparse arrays. - Fix a minor bug causing memory leaks on large sparse arrays. +- Fix an issue when domain is max dimension. - EOL for Python 3.9 ## Version 0.2.0