Recursive worker behind :meth:`FlattenMap.check_vs_selector` — kept at module level so the recursion stays on a plain dict and does not allocate intermediate :class:`FlattenMap` instances. :param flatten_map: current level of the flatten nested dict :type flatten_map: dict
(
flatten_map: dict,
selector: Union[set, dict, None],
selector_kind: str,
path: str,
)
| 190 | |
| 191 | |
| 192 | def walk_flatten_vs_selector( |
| 193 | flatten_map: dict, |
| 194 | selector: Union[set, dict, None], |
| 195 | selector_kind: str, |
| 196 | path: str, |
| 197 | ) -> None: |
| 198 | """ |
| 199 | Recursive worker behind :meth:`FlattenMap.check_vs_selector` — kept at |
| 200 | module level so the recursion stays on a plain dict and does not allocate |
| 201 | intermediate :class:`FlattenMap` instances. |
| 202 | |
| 203 | :param flatten_map: current level of the flatten nested dict |
| 204 | :type flatten_map: dict |
| 205 | :param selector: current level of include / exclude nested dict |
| 206 | :type selector: Union[set, dict, None] |
| 207 | :param selector_kind: "include" or "exclude" - used in error message |
| 208 | :type selector_kind: str |
| 209 | :param path: dunder path accumulator for the error message |
| 210 | :type path: str |
| 211 | """ |
| 212 | if not selector or not isinstance(selector, dict): |
| 213 | return |
| 214 | for key, value in flatten_map.items(): |
| 215 | sel = selector.get(key) |
| 216 | full_path = f"{path}__{key}" if path else key |
| 217 | if value is Ellipsis: |
| 218 | conflicts: Optional[set] = None |
| 219 | if isinstance(sel, dict): |
| 220 | conflicts = set(sel.keys()) - {...} |
| 221 | elif isinstance(sel, set): |
| 222 | conflicts = {item for item in sel if item is not ...} |
| 223 | if conflicts: |
| 224 | raise QueryDefinitionError( |
| 225 | f"Flatten conflict: relation '{full_path}' is flattened " |
| 226 | f"but {selector_kind} specifies children " |
| 227 | f"{sorted(conflicts)}. A flattened relation renders only " |
| 228 | f"its primary key and cannot have children selected." |
| 229 | ) |
| 230 | elif isinstance(value, dict): |
| 231 | walk_flatten_vs_selector( |
| 232 | flatten_map=value, |
| 233 | selector=sel, |
| 234 | selector_kind=selector_kind, |
| 235 | path=full_path, |
| 236 | ) |
| 237 | |
| 238 | |
| 239 | @dataclass |
no test coverage detected