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

Extend key_item to handle attribute arrays #4

Merged
merged 5 commits into from
Jan 19, 2024
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
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
name: Build
name: build
on:
pull_request:
branches:
- master

jobs:
build:
name: Build
name: build
runs-on: ubuntu-latest
steps:
- name: Check out the codebase.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: molecule
name: pytest

on:
pull_request:
Expand All @@ -10,7 +10,7 @@ on:

jobs:
molecule:
name: molecule
name: pytest
runs-on: ubuntu-latest
steps:
- name: Check out the codebase
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
name: Release
name: release
on:
push:
tags:
- "*"

jobs:
release:
name: Release
name: release
runs-on: ubuntu-latest
steps:
- name: Check out the codebase.
Expand Down
2 changes: 1 addition & 1 deletion galaxy.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
namespace: nephelaiio
name: plugins
version: 0.0.2
version: 0.0.3
readme: README.md
authors:
- Ted Cook <[email protected]>
Expand Down
50 changes: 37 additions & 13 deletions plugins/filter/custom_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,22 +379,49 @@ def merge_item(item, key_attr):

def key_item(item, key_attr, remove_key=True):
"""
Processes an item (dictionary) by separating out a specified key-value pair,
and optionally removing that key from the original item.
Extracts a value from the given item using a specified key or nested keys, and returns
this value along with a modified copy of the original item.

Args:
item (dict): The dictionary to process.
key_attr: The key to separate and optionally remove from `item`.
remove_key (bool, optional): If True, removes `key_attr` from `item`. Default is True.
Parameters:
- item (dict or similar): The item from which to extract the value. It should be a
dictionary or a dictionary-like object.
- key_attr (int, float, str, bool, list, tuple): The key or nested keys used to extract
the value from the item. If it's a list or tuple, it is treated as nested keys.
- remove_key (bool, optional): If True, the key is removed from the copied item.
Default is True. Note: This option is not applicable for nested keys.

Returns:
list: A list containing the value of `key_attr` and the modified item.
- list: A list containing two elements:
1. The value extracted from the item using the key(s).
2. A deep copy of the item, potentially with the key removed.

Raises:
- ValueError: If 'remove_key' is True for nested attributes or if 'key_attr' is
neither a scalar nor a list/tuple.

Example:
>>> item = {'a': {'b': 2}}
>>> key_item(item, ['a', 'b'], False)
[2, {'a': {'b': 2}}]

>>> key_item(item, 'a')
[{'b': 2}, {}]

Note:
- The function assumes that the nested keys correctly point to a value in the item.
"""

new_item = copy.deepcopy(item)
if remove_key:
del new_item[key_attr]
return [item[key_attr], new_item]
if isinstance(key_attr, (list, tuple)):
if remove_key:
raise ValueError("remove_key must be False for nested attributes")
_nested_attr = functools.reduce(lambda x, k: x[k], key_attr, item)
return [_nested_attr, new_item]
if isinstance(key_attr, (int, float, str, bool)):
if remove_key:
del new_item[key_attr]
return [item[key_attr], new_item]
raise ValueError("key_attr must be scalar or list")


def dict_to_list(d, key_attr):
Expand Down Expand Up @@ -641,9 +668,6 @@ def is_any_true(xs):

Returns:
bool: True if any element in the iterable is true, False otherwise.

Note:
This function uses a lambda function in conjunction with functools.reduce for evaluation.
"""

return functools.reduce(lambda x, y: x or y, map(lambda x: bool(x), xs), False) # pylint: disable=unnecessary-lambda
Expand Down
21 changes: 21 additions & 0 deletions tests/test_filter.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ def test_to_dict():
assert to_dict("a", {"a": "first", "b": "second"}) == {"a": "first", "b": "second"}
assert to_dict("a", {"a": "first", "b": "%s"}) == {"a": "first", "b": "a"}
assert to_dict("a", {"%s_1": "first", "%s_2": "%s"}) == {"a_1": "first", "a_2": "a"}
assert to_dict("a", {"%s_1": "first", "%s_2": "%s"}) == {"a_1": "first", "a_2": "a"}


def test_map_format():
Expand Down Expand Up @@ -161,6 +162,14 @@ def test_key_item():
d = {"a": "first", "b": "second"}
assert key_item(d, "a") == ["first", {"b": "second"}]
assert key_item(d, "b") == ["second", {"a": "first"}]
e = {"b": "second"}
f = {"a": e}
assert key_item(f, ["a", "b"], False) == ["second", f]
assert key_item(f, ["a"], False) == [e, f]
with pytest.raises(KeyError):
key_item(d, ["na"], False)
with pytest.raises(ValueError):
key_item(d, ["na"])


def test_dict_to_list():
Expand All @@ -179,6 +188,18 @@ def test_list_to_dict():
"a": {"content": "first", "key": "a"},
"b": {"content": "second", "key": "b"},
}
e = [
{"a": {"b": "first"}},
{"a": {"b": "second"}},
]
assert list_to_dict(e, ["a", "b"], False) == {
"first": {"a": {"b": "first"}},
"second": {"a": {"b": "second"}}
}
with pytest.raises(KeyError):
list_to_dict(e, ["a", "c"], False)
with pytest.raises(ValueError):
list_to_dict(e, ["a", "c"])


def test_to_kv():
Expand Down