Skip to content

Commit

Permalink
Add __setitem__ to metadata object and rename _rename method (#289)
Browse files Browse the repository at this point in the history
* Make the API even more flexible

* Make pylint happy

* Fix MyPy
  • Loading branch information
qubixes authored Nov 25, 2024
1 parent 50293b4 commit 80f7018
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 5 deletions.
17 changes: 17 additions & 0 deletions docker/irods_client/tests/test_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,23 @@ def test_metadata_getitem(item_name, request):
meta.clear()


@mark.parametrize("item_name", ["collection", "dataobject"])
def test_metadata_setitem(item_name, request):
item = request.getfixturevalue(item_name)
meta = MetaData(item)
meta.clear()

meta.add("some_key", "some_value", "some_units")
meta["some_key"] = ("some_key", "new_value", "new_units")
meta["some_key"] = ("some_key", "new_value")

with pytest.raises(TypeError):
meta["some_key"] = "new_value"

with pytest.raises(ValueError):
meta["some_key"] = ("some_key", "new_value")


@mark.parametrize("item_name", ["collection", "dataobject"])
def test_metadata_rename(item_name, request, session):
item = request.getfixturevalue(item_name)
Expand Down
59 changes: 54 additions & 5 deletions ibridges/meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def find_all(self, key = ..., value = ..., units = ...):
all_items.append(meta_item)
return all_items

def __getitem__(self, key: Union[str, Sequence[str]]) -> MetaDataItem:
def __getitem__(self, key: Union[str, Sequence[Union[str, None]]]) -> MetaDataItem:
"""Access the metadata like a dictionary of tuples.
Parameters
Expand Down Expand Up @@ -142,6 +142,36 @@ def __getitem__(self, key: Union[str, Sequence[str]]) -> MetaDataItem:
"units as well, for example: meta[key, value, units].")
return all_items[0]

def __setitem__(self, key: Union[str, Sequence[Union[str, None]]], other: Sequence[str]):
"""Set metadata items like a dictionary of tuples.
Parameters
----------
key
The key to get the metadata for.
other
Key, value, units to set the metadata item to. Units is optional.
Raises
------
TypeError:
If the other parameter is a string.
ValueError:
If the item already exists.
Examples
--------
>>> meta["key"] = ("key", "new_value", "new_units")
>>> meta["key"] = ("new_key", "old_value")
"""
if isinstance(other, str):
raise TypeError("Cannot set the metadata item to a single string value. "
f"Use meta[{key}].key = \"{other}\" to change only the key "
"for example.")
self[key].update(*other)


def add(self, key: str, value: str, units: Optional[str] = None):
"""Add metadata to an item.
Expand Down Expand Up @@ -389,7 +419,7 @@ def key(self, new_key: str):
if new_key == self._prc_meta.name:
return
new_item_values = [new_key, self._prc_meta.value, self._prc_meta.units]
self._rename(new_item_values)
self.update(*new_item_values)

@property
def value(self) -> Optional[str]:
Expand All @@ -401,7 +431,7 @@ def value(self, new_value: Optional[str]):
if new_value == self._prc_meta.value:
return
new_item_values = [self._prc_meta.name, new_value, self._prc_meta.units]
self._rename(new_item_values)
self.update(*new_item_values)

@property
def units(self) -> Optional[str]:
Expand All @@ -413,7 +443,7 @@ def units(self, new_units: Optional[str]):
if new_units == self._prc_meta.units:
return
new_item_values = [self._prc_meta.name, self._prc_meta.value, new_units]
self._rename(new_item_values)
self.update(*new_item_values)

def __repr__(self) -> str:
"""Representation of the MetaDataItem."""
Expand All @@ -429,7 +459,26 @@ def __iter__(self) -> Iterator[Optional[str]]:
yield self.value
yield self.units

def _rename(self, new_item_key: Sequence[str]):
def update(self, new_key: str, new_value: str, new_units: Optional[str] = None):
"""Update the metadata item changing the key/value/units.
Parameters
----------
new_key:
New key to set the metadata item to.
new_value:
New value to set the metadata item to.
new_units:
New units to set the metadata item to, optional.
Raises
------
ValueError:
If the operation could not be completed because of permission error.
Or if the new to be created item already exists.
"""
new_item_key = (new_key, new_value, new_units)
try:
_new_item = self._ibridges_meta[new_item_key]
except KeyError:
Expand Down

0 comments on commit 80f7018

Please sign in to comment.