Skip to content
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

Allow Switch Interpretation to Apply Many Interpretations In Each Branch #48

Merged
merged 1 commit into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/docs/reference/interpretations.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ The switch interpretation allows you to define multiple interpretations that wil
| Parameter Name | Required? | Type | Description |
|---------------- |----------- |------------ |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| switch_on | Yes | ValueProvider | The value provider that will be evaluated for each source node. The value of the value provider will be used to determine which interpretation to apply. |
| interpretations | Yes | Dictionary | Contains the interpretations that will be applied. The keys represent the values of the `switch_on` parameter. The values represent the interpretations that will be applied. |
| interpretations | Yes | Dictionary | Contains the interpretations that will be applied. The keys represent the values of the `switch_on` parameter. The values represent the interpretations that will be applied. Each value may also be a list of interpretations. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love me some documentation updates...

| default | No | Dictionary | Contains the default interpretation that will be applied if no interpretation has the same value as the value of the `switch_on` parameter. |
46 changes: 31 additions & 15 deletions nodestream/interpreting/interpretations/switch_interpretation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Any, Dict
from typing import Any, Dict, List

from ...pipeline.value_providers import (
ProviderContext,
Expand Down Expand Up @@ -29,6 +29,16 @@ class SwitchInterpretation(
"fail_on_unhandled",
)

@staticmethod
def guarantee_interpretation_list_from_file_data(file_data) -> List[Interpretation]:
if isinstance(file_data, list):
return [
Interpretation.from_file_data(**interpretation)
for interpretation in file_data
]

return [Interpretation.from_file_data(**file_data)]

def __init__(
self,
switch_on: StaticValueOrValueProvider,
Expand All @@ -39,28 +49,34 @@ def __init__(
):
self.switch_on = ValueProvider.guarantee_value_provider(switch_on)
self.interpretations = {
field_value: Interpretation.from_file_data(**interpretation)
field_value: self.guarantee_interpretation_list_from_file_data(
interpretation
)
for field_value, interpretation in cases.items()
}
self.default = Interpretation.from_file_data(**default) if default else None
self.default = (
self.guarantee_interpretation_list_from_file_data(default)
if default
else None
)
self.normalization = normalization or {}
self.fail_on_unhandled = fail_on_unhandled

def all_subordinate_components(self):
yield from self.interpretations.values()
for child in self.interpretations.values():
yield from child
if self.default:
yield self.default
yield from self.default

def interpret(self, context: ProviderContext):
value_to_look_for = self.switch_on.normalize_single_value(
context, **self.normalization
)
if value_to_look_for not in self.interpretations:
if self.default:
self.default.interpret(context)
return
key = self.switch_on.normalize_single_value(context, **self.normalization)
interpretations = self.interpretations.get(key, self.default)

if interpretations is None:
if self.fail_on_unhandled:
raise UnhandledBranchError(value_to_look_for)
raise UnhandledBranchError(key)
else:
return
return self.interpretations[value_to_look_for].interpret(context)
interpretations = []

for interpretation in interpretations:
interpretation.interpret(context)
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,15 @@ def test_missing_without_default_without_error(blank_context):
properties = blank_context.desired_ingest.source.properties
assert_that(properties, not_(has_entry("success", True)))
assert_that(properties, not_(has_entry("random", True)))


def test_switch_with_multiple_interpretations(blank_context):
subject = SwitchInterpretation(
switch_on="foo",
cases={"foo": [INTERPRETATION_USED_AS_HIT, INTERPRETATION_FOR_RANDOM]},
fail_on_unhandled=False,
)
subject.interpret(blank_context)
properties = blank_context.desired_ingest.source.properties
assert_that(properties, has_entry("success", True))
assert_that(properties, has_entry("random", True))