Merge a ``base`` item with an ``override`` item. Both ``base`` and ``override`` are converted to dictionaries if possible. Sets are converted to dictionaries with the sets entries as keys and Ellipsis as values. Each key-value pair existing in ``base`` is m
(cls, base: Any, override: Any, intersect: bool = False)
| 561 | |
| 562 | @classmethod |
| 563 | def merge(cls, base: Any, override: Any, intersect: bool = False) -> Any: |
| 564 | """ |
| 565 | Merge a ``base`` item with an ``override`` item. |
| 566 | |
| 567 | Both ``base`` and ``override`` are converted to dictionaries if possible. |
| 568 | Sets are converted to dictionaries with the sets entries as keys and |
| 569 | Ellipsis as values. |
| 570 | |
| 571 | Each key-value pair existing in ``base`` is merged with ``override``, |
| 572 | while the rest of the key-value pairs are updated recursively with this function. |
| 573 | |
| 574 | Merging takes place based on the "union" of keys if ``intersect`` is |
| 575 | set to ``False`` (default) and on the intersection of keys if |
| 576 | ``intersect`` is set to ``True``. |
| 577 | """ |
| 578 | override = cls._coerce_value(override) |
| 579 | base = cls._coerce_value(base) |
| 580 | if override is None: |
| 581 | return base |
| 582 | if cls.is_true(base) or base is None: |
| 583 | return override |
| 584 | if cls.is_true(override): |
| 585 | return base if intersect else override |
| 586 | |
| 587 | # intersection or union of keys while preserving ordering: |
| 588 | if intersect: |
| 589 | merge_keys = [k for k in base if k in override] + [k for k in override if k in base] |
| 590 | else: |
| 591 | merge_keys = list(base) + [k for k in override if k not in base] |
| 592 | |
| 593 | merged: 'DictIntStrAny' = {} |
| 594 | for k in merge_keys: |
| 595 | merged_item = cls.merge(base.get(k), override.get(k), intersect=intersect) |
| 596 | if merged_item is not None: |
| 597 | merged[k] = merged_item |
| 598 | |
| 599 | return merged |
| 600 | |
| 601 | @staticmethod |
| 602 | def _coerce_items(items: Union['AbstractSetIntStr', 'MappingIntStrAny']) -> 'MappingIntStrAny': |