|
2 | 2 |
|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
| 5 | +import random |
5 | 6 | from abc import ABC |
6 | 7 | from abc import abstractmethod |
7 | 8 | from contextlib import suppress |
8 | 9 | from typing import TYPE_CHECKING |
| 10 | +from typing import Any |
9 | 11 | from typing import Iterable |
10 | 12 | from typing import Optional |
11 | 13 | from typing import Sequence |
@@ -211,7 +213,14 @@ def __hash__(self) -> int: |
211 | 213 | def resolve(self, node: JSONPathNode) -> Iterable[JSONPathNode]: |
212 | 214 | """Select all items from a array/list or values from a dict/object.""" |
213 | 215 | if isinstance(node.value, dict): |
214 | | - for key, val in node.value.items(): |
| 216 | + if self.env.nondeterministic: |
| 217 | + _items = list(node.value.items()) |
| 218 | + random.shuffle(_items) |
| 219 | + items: Iterable[Any] = iter(_items) |
| 220 | + else: |
| 221 | + items = node.value.items() |
| 222 | + |
| 223 | + for key, val in items: |
215 | 224 | _node = JSONPathNode( |
216 | 225 | value=val, |
217 | 226 | parts=node.parts + (key,), |
@@ -257,10 +266,17 @@ def __eq__(self, __value: object) -> bool: |
257 | 266 | def __hash__(self) -> int: |
258 | 267 | return hash((str(self.expression), self.token)) |
259 | 268 |
|
260 | | - def resolve(self, node: JSONPathNode) -> Iterable[JSONPathNode]: |
| 269 | + def resolve(self, node: JSONPathNode) -> Iterable[JSONPathNode]: # noqa: PLR0912 |
261 | 270 | """Select array/list items or dict/object values where with a filter.""" |
262 | 271 | if isinstance(node.value, dict): |
263 | | - for key, val in node.value.items(): |
| 272 | + if self.env.nondeterministic: |
| 273 | + _items = list(node.value.items()) |
| 274 | + random.shuffle(_items) |
| 275 | + items: Iterable[Any] = iter(_items) |
| 276 | + else: |
| 277 | + items = node.value.items() |
| 278 | + |
| 279 | + for key, val in items: |
264 | 280 | context = FilterContext( |
265 | 281 | env=self.env, |
266 | 282 | current=val, |
|
0 commit comments