|
21 | 21 | MultiMapAcc, |
22 | 22 | RefAcc, |
23 | 23 | ) |
| 24 | +from anndata.acc._parse_str import _check_vec |
24 | 25 | from anndata.compat import XVariable |
25 | 26 | from anndata.typing import InMemoryArray |
26 | 27 |
|
@@ -250,33 +251,56 @@ def __getitem__(self, k: str, /) -> ModAcc[R]: |
250 | 251 | def __repr__(self) -> str: |
251 | 252 | return "A" |
252 | 253 |
|
253 | | - def resolve(self, spec: str, *, strict: bool = True) -> R | None: |
| 254 | + def resolve( |
| 255 | + self, spec: str, *, strict: bool = True, vec: bool | None = None |
| 256 | + ) -> ( |
| 257 | + R |
| 258 | + | ModLayerAcc[R] |
| 259 | + | ModMultiAcc[R] |
| 260 | + | ModGraphAcc[R] |
| 261 | + | MultiAcc[R] |
| 262 | + | ModMapAcc[R] |
| 263 | + | GraphAcc[R] |
| 264 | + | ModAcc[R] |
| 265 | + | None |
| 266 | + ): |
254 | 267 | """Create :class:`~anndata.acc.AdRef` from a simplified string.""" |
255 | 268 | if not strict: |
256 | 269 | try: |
257 | | - self.resolve(spec) |
| 270 | + self.resolve(spec, vec=vec) |
258 | 271 | except ValueError: |
259 | 272 | return None |
260 | 273 |
|
261 | 274 | firstdot = spec.find(".") |
262 | 275 | if firstdot < 0: |
263 | | - raise ValueError(f"Cannot parse accessor {spec!r} that is not period-separated.") |
| 276 | + firstdot = None |
264 | 277 | firstattr = spec[:firstdot] |
265 | 278 | match firstattr: |
266 | 279 | case "mod": |
| 280 | + do_vec = firstdot is not None |
| 281 | + if not do_vec: |
| 282 | + _check_vec(spec, vec=vec, actual=do_vec) |
| 283 | + return self.mod |
| 284 | + |
267 | 285 | modend = spec.find(".", firstdot + 1) |
| 286 | + do_vec = modend >= 0 |
| 287 | + if not do_vec: |
| 288 | + modend = None |
| 289 | + _check_vec(spec, vec=vec, actual=do_vec) |
268 | 290 | mod = spec[firstdot + 1 : modend] |
269 | 291 | if not mod: |
270 | 292 | raise ValueError(f"Cannot parse accessor{spec!r} that has an empty modality.") |
271 | 293 | acc = self.mod[mod] |
272 | | - return super().resolve.__func__(acc, spec[modend + 1 :], strict=strict) |
| 294 | + return super().resolve.__func__(acc, spec[modend + 1 :], strict=strict, vec=vec) if do_vec else acc |
273 | 295 | case "obsmap" | "varmap": |
274 | | - if firstdot == len(spec): |
275 | | - raise ValueError(f"Cannot parse accessor{spec!r} that has an empty modality.") |
| 296 | + do_vec = firstdot is not None and firstdot < len(spec) |
| 297 | + _check_vec(spec, vec=vec, actual=do_vec) |
| 298 | + if not do_vec: |
| 299 | + return getattr(self, firstattr) |
276 | 300 | mod = spec[firstdot + 1 :] |
277 | 301 | return getattr(self, firstattr)[mod] |
278 | 302 | case _: |
279 | | - return super().resolve(spec, strict=strict) |
| 303 | + return super().resolve(spec, strict=strict, vec=vec) |
280 | 304 |
|
281 | 305 | def to_json(self, ref: R) -> list[str | int | None]: |
282 | 306 | """Serialize :class:`~anndata.acc.AdRef` to a JSON-compatible list. |
|
0 commit comments