-
-
Notifications
You must be signed in to change notification settings - Fork 0
Fill in the macro implementation #227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
c73816a
9a60ed9
8fe1804
54e98d7
88318cb
4e99ff9
9f777ef
291a92b
3bcd048
bddfdbf
8071b43
94fdc71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| from sentry_streams_k8s.merge import TypeMismatchError | ||
| from sentry_streams_k8s.pipeline_step import PipelineStep, PipelineStepContext | ||
|
|
||
| __all__ = ["PipelineStep", "PipelineStepContext", "TypeMismatchError"] |
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| """Dictionary merging utilities for Kubernetes manifest templates.""" | ||
|
|
||
| import copy | ||
| from typing import Any | ||
|
|
||
|
|
||
| class TypeMismatchError(TypeError): | ||
| """Raised when attempting to merge incompatible types in deepmerge.""" | ||
|
|
||
| pass | ||
|
|
||
|
|
||
| def deepmerge(base: dict[str, Any], override: dict[str, Any]) -> dict[str, Any]: | ||
| """ | ||
| Deep merge two dictionaries with specific semantics for Kubernetes manifests. | ||
| Merge semantics: | ||
| - Simple types (str, int, bool, None): override replaces base | ||
| - Dictionaries: recursively merge | ||
| - Lists: concatenate (append override elements to base) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why does this append instead of replacing?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I followed the patch semantics of kubectl patch https://kubernetes.io/docs/tasks/manage-kubernetes-objects/update-api-object-kubectl-patch/#notes-on-the-strategic-merge-patch. In this specific case scenarios for this choices are:
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, makes sense. |
||
| - Type mismatches (e.g., dict + list, dict + str): raises TypeMismatchError | ||
| Returns: | ||
| A new dictionary with merged values (base and override are not mutated) | ||
| Raises: | ||
| TypeMismatchError: When attempting to merge incompatible types | ||
| (e.g., trying to merge a dict with a list, or a list with a string) | ||
| Examples: | ||
| >>> base = {"a": 1, "b": {"c": 2}} | ||
| >>> override = {"b": {"d": 3}, "e": 4} | ||
| >>> deepmerge(base, override) | ||
| {'a': 1, 'b': {'c': 2, 'd': 3}, 'e': 4} | ||
| >>> base = {"volumes": [{"name": "vol1"}]} | ||
| >>> override = {"volumes": [{"name": "vol2"}]} | ||
| >>> deepmerge(base, override) | ||
| {'volumes': [{'name': 'vol1'}, {'name': 'vol2'}]} | ||
| >>> base = {"key": {"nested": "value"}} | ||
| >>> override = {"key": "string"} | ||
| >>> deepmerge(base, override) | ||
| Traceback (most recent call last): | ||
| ... | ||
| TypeMismatchError: Cannot merge key 'key': base type is dict but override type is str | ||
| """ | ||
| result = copy.deepcopy(base) | ||
|
|
||
| for key, override_value in override.items(): | ||
| if key not in result: | ||
| result[key] = copy.deepcopy(override_value) | ||
| else: | ||
| base_value = result[key] | ||
|
|
||
| # Both base and override have this key | ||
| if isinstance(base_value, dict) and isinstance(override_value, dict): | ||
| result[key] = deepmerge(base_value, override_value) | ||
| elif isinstance(base_value, list) and isinstance(override_value, list): | ||
| result[key] = base_value + copy.deepcopy(override_value) | ||
| elif type(base_value) is not type(override_value): | ||
| raise TypeMismatchError( | ||
| f"Cannot merge key '{key}': base type is {type(base_value)} but override type is {type(override_value)}" | ||
| ) | ||
| else: | ||
| result[key] = copy.deepcopy(override_value) | ||
|
|
||
| return result | ||
Uh oh!
There was an error while loading. Please reload this page.