Skip to content

Commit

Permalink
chore: docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
phil65 committed Nov 4, 2024
1 parent 2073ce7 commit 53d2234
Showing 1 changed file with 78 additions and 4 deletions.
82 changes: 78 additions & 4 deletions src/jinjarope/deepmerge.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""Module for deep merging of data structures with customizable merge strategies."""

from __future__ import annotations

from typing import TYPE_CHECKING, TypeVar
Expand All @@ -11,19 +13,55 @@


def merge_dict(merger: DeepMerger, source: Mapping, target: Mapping) -> Mapping:
"""Merge two mappings recursively.
Args:
merger: The DeepMerger instance handling the merge operation
source: The source mapping whose values take precedence
target: The target mapping to merge into
Returns:
A new dictionary containing the merged key-value pairs
Example:
```python
merger = DeepMerger()
source = {"a": {"b": 1}}
target = {"a": {"c": 2}}
merge_dict(merger, source, target)
# {'a': {'b': 1, 'c': 2}}
```
"""
result = dict(target)
for key, source_value in source.items():
target_value = result[key] if key in result else type(source_value)()
target_value = result.get(key, type(source_value)())
try:
value = merger.merge(source_value, target_value)
except TypeError:
# can't merge, so overwrite
# If values can't be merged, use source value
value = source_value
result[key] = value
return result


def merge_list(merger: DeepMerger, source: list, target: list) -> list:
"""Concatenate two lists.
Args:
merger: The DeepMerger instance handling the merge operation
source: The source list to append
target: The target list to merge into
Returns:
A new list containing all elements from both lists
Example:
```python
merger = DeepMerger()
merge_list(merger, [3, 4], [1, 2])
# [1, 2, 3, 4]
```
"""
return target + source


Expand All @@ -34,13 +72,49 @@ def merge_list(merger: DeepMerger, source: list, target: list) -> list:


class DeepMerger:
mergers = DEFAULT_MERGERS
"""A class that handles deep merging of data structures.
The merger can be customized by providing different merge strategies for different types.

Check failure on line 77 in src/jinjarope/deepmerge.py

View workflow job for this annotation

GitHub Actions / test (3.12)

Ruff (E501)

src/jinjarope/deepmerge.py:77:91: E501 Line too long (93 > 90)
Attributes:
mergers: A dictionary mapping types to their corresponding merge functions
Example:
```python
merger = DeepMerger()
source = {"a": {"b": 1}}
target = {"a": {"c": 2}}
merger.merge(source, target)
# {'a': {'b': 1, 'c': 2}}
```
"""

mergers: dict[type[Any], Callable[..., Any]] = DEFAULT_MERGERS

Check failure on line 92 in src/jinjarope/deepmerge.py

View workflow job for this annotation

GitHub Actions / test (3.12)

Ruff (F821)

src/jinjarope/deepmerge.py:92:24: F821 Undefined name `Any`

Check failure on line 92 in src/jinjarope/deepmerge.py

View workflow job for this annotation

GitHub Actions / test (3.12)

Ruff (F821)

src/jinjarope/deepmerge.py:92:44: F821 Undefined name `Any`

def __init__(self, mergers: dict[type, Callable] | None = None):
def __init__(
self, mergers: dict[type[Any], Callable[..., Any]] | None = None

Check failure on line 95 in src/jinjarope/deepmerge.py

View workflow job for this annotation

GitHub Actions / test (3.12)

Ruff (F821)

src/jinjarope/deepmerge.py:95:34: F821 Undefined name `Any`

Check failure on line 95 in src/jinjarope/deepmerge.py

View workflow job for this annotation

GitHub Actions / test (3.12)

Ruff (F821)

src/jinjarope/deepmerge.py:95:54: F821 Undefined name `Any`
) -> None:
"""Initialize the DeepMerger with custom merge strategies.
Args:
mergers: Optional dictionary of type-specific merge functions
"""
if mergers is not None:
self.mergers = mergers

def merge(self, source: T, target: T) -> T:
"""Merge two objects of the same type.
Args:
source: The source object whose values take precedence
target: The target object to merge into
Returns:
The merged object
Raises:
TypeError: If the types cannot be merged
"""
source_type = type(source)
target_type = type(target)
merger = self.mergers.get(target_type)
Expand Down

0 comments on commit 53d2234

Please sign in to comment.