|
30 | 30 | ) |
31 | 31 |
|
32 | 32 | if TYPE_CHECKING: |
33 | | - from collections.abc import Sequence |
| 33 | + from collections.abc import Callable, Sequence |
34 | 34 |
|
35 | 35 | from ._core import Feature |
36 | 36 | from ._types import KeyPart |
@@ -316,20 +316,8 @@ def remove(self, *keys: KeyPart, prune: bool = False) -> Document: |
316 | 316 | def append(self, *keys: KeyPart, value: Any) -> Document: |
317 | 317 | """Append a single item to the sequence at path.""" |
318 | 318 | route = _make_route(keys) |
319 | | - op = Op.append(value) |
320 | | - patch = Patch(route=route, operation=op) |
321 | | - try: |
322 | | - return self._apply_patches([patch]) |
323 | | - except PatchError as e: |
324 | | - kind = _classify_patch_error(e) |
325 | | - if kind == _PatchErrorKind.FLOW_SEQUENCE: |
326 | | - current = self[keys] |
327 | | - new_list = [*list(current), value] |
328 | | - replace_op = Op.replace(new_list) |
329 | | - return self._apply_patches([Patch(route=route, operation=replace_op)]) |
330 | | - if kind == _PatchErrorKind.NOT_A_SEQUENCE: |
331 | | - raise NodeTypeError(str(e)) from None |
332 | | - raise |
| 319 | + patch = Patch(route=route, operation=Op.append(value)) |
| 320 | + return self._with_flow_seq_fallback(keys, [patch], lambda lst: [*lst, value]) |
333 | 321 |
|
334 | 322 | def insert(self, *keys: KeyPart, index: int, value: Any) -> Document: |
335 | 323 | """Insert an item at a specific position in the sequence at path. |
@@ -361,15 +349,25 @@ def extend_list(self, *keys: KeyPart, values: Sequence[Any]) -> Document: |
361 | 349 | return self |
362 | 350 | route = _make_route(keys) |
363 | 351 | patches = [Patch(route=route, operation=Op.append(v)) for v in values] |
| 352 | + return self._with_flow_seq_fallback(keys, patches, lambda lst: [*lst, *values]) |
| 353 | + |
| 354 | + def _with_flow_seq_fallback( |
| 355 | + self, |
| 356 | + keys: tuple[KeyPart, ...], |
| 357 | + patches: list[Patch], |
| 358 | + fallback_fn: Callable[[list[Any]], list[Any]], |
| 359 | + ) -> Document: |
| 360 | + """Apply patches, falling back to get→mutate→replace for flow sequences.""" |
364 | 361 | try: |
365 | 362 | return self._apply_patches(patches) |
366 | 363 | except PatchError as e: |
367 | 364 | kind = _classify_patch_error(e) |
368 | 365 | if kind == _PatchErrorKind.FLOW_SEQUENCE: |
369 | | - current = self[keys] |
370 | | - new_list = [*list(current), *values] |
371 | | - replace_op = Op.replace(new_list) |
372 | | - return self._apply_patches([Patch(route=route, operation=replace_op)]) |
| 366 | + new_list = fallback_fn(list(self[keys])) |
| 367 | + route = _make_route(keys) |
| 368 | + return self._apply_patches( |
| 369 | + [Patch(route=route, operation=Op.replace(new_list))] |
| 370 | + ) |
373 | 371 | if kind == _PatchErrorKind.NOT_A_SEQUENCE: |
374 | 372 | raise NodeTypeError(str(e)) from None |
375 | 373 | raise |
|
0 commit comments