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

Add namespace keyword to avu method #108

Merged
merged 1 commit into from
Aug 11, 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
24 changes: 17 additions & 7 deletions src/partisan/irods.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ def without_namespace(self):

@property
def attribute(self):
"""The attribute, including namespace, if any. The namespace an attribute are
"""The attribute, including namespace, if any. The namespace and attribute are
separated by AVU.SEPARATOR."""
if self._namespace:
return f"{self._namespace}{AVU.SEPARATOR}{self._attribute}"
Expand Down Expand Up @@ -1314,33 +1314,41 @@ def exists(self, timeout=None, tries=1) -> bool:
"""
return self._exists(timeout=timeout, tries=tries)

def avu(self, attr: str, timeout=None, tries=1) -> AVU:
def avu(self, attr: Any, namespace=None, timeout=None, tries=1) -> AVU:
"""Return an unique AVU from the item's metadata, given an attribute, or raise
an error.

Args:
attr: The attribute of the expected AVU.
attr: The attribute of the expected AVU. This must be the bare attribute
string, without any namespace.
namespace: The namespace of the expected AVU. Optional.
timeout: Operation timeout in seconds.
tries: Number of times to try the operation.

Returns:

"""
# Allows convenient use of args that have string representations which are AVU attributes
attr = str(attr)

# Construct a dummy AVU as a convenience to get namespaced attribute string
ns_attr = AVU(attr, "dummy", namespace=namespace).attribute
avus = [
avu
for avu in self.metadata(timeout=timeout, tries=tries)
if avu.attribute == attr
if avu.attribute == ns_attr
]

ns_msg = f" in namespace '{namespace}'" if namespace else ""
if not avus:
raise ValueError(
f"Metadata of {self} did not contain any AVU with "
f"attribute '{attr}'"
f"attribute '{attr}'{ns_msg}"
)
if len(avus) > 1:
raise ValueError(
f"Metadata of '{self}' contained more than one AVU with "
f"attribute '{attr}': {avus}"
f"attribute '{attr}'{ns_msg}: {avus}"
)

return avus[0]
Expand All @@ -1358,7 +1366,9 @@ def has_metadata(self, *avus: AVU, timeout=None, tries=1) -> bool:
return set(avus).issubset(self.metadata(timeout=timeout, tries=tries))

def has_metadata_attrs(self, *attrs: str, timeout=None, tries=1) -> bool:
"""Return True if all the argument attributes are in the item's metadata.
"""Return True if all the argument attributes are in the item's metadata. The
caller must set the namespace(s) appropriately on the attrs before calling this
methods as each attribute many have different (or no) namespace.

Args:
*attrs: One or more attributes to test.
Expand Down
90 changes: 79 additions & 11 deletions tests/test_irods.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,19 +421,53 @@ def test_meta_rem_collection(self, simple_collection):
@m.it("Can be searched for an AVU with an unique attribute")
def test_avu_collection(self, simple_collection):
coll = Collection(simple_collection)
avu = AVU("abcde", "12345")
attr = "abcde"
avu = AVU(attr, "12345")

with pytest.raises(ValueError, match="did not contain any AVU with attribute"):
coll.avu("abcde")
coll.avu(attr)
coll.add_metadata(avu)

assert coll.avu("abcde") == avu
assert coll.avu(attr) == avu

coll.add_metadata(AVU("abcde", "67890"))
coll.add_metadata(AVU(attr, "67890"))
with pytest.raises(
ValueError, match="contained more than one AVU with attribute"
):
coll.avu("abcde")
coll.avu(attr)

@m.it("Can be searched for an AVU with an unique namespaced attribute")
def test_avu_collection_ns(self, simple_collection):
coll = Collection(simple_collection)
attr = "abcde"
ns = "test"
avu = AVU(attr, "12345", namespace=ns)

with pytest.raises(
ValueError, match=f"did not contain any AVU with attribute '{attr}'"
):
coll.avu(attr)
with pytest.raises(
ValueError,
match=f"did not contain any AVU with attribute '{attr}' in namespace '{ns}'",
):
coll.avu(attr, namespace=ns)

coll.add_metadata(avu)

with pytest.raises(
ValueError, match=f"did not contain any AVU with attribute '{attr}'"
):
coll.avu(attr)

assert coll.avu(attr, namespace=ns) == avu

other_ns = "other"
with pytest.raises(
ValueError,
match=f"did not contain any AVU with attribute '{attr}' in namespace '{other_ns}'",
):
coll.avu(attr, namespace=other_ns)

@m.it("Can be found by its metadata")
def test_meta_query_collection(self, simple_collection):
Expand Down Expand Up @@ -842,21 +876,55 @@ def test_rem_meta_data_object(self, simple_data_object):
), "removing data object metadata is idempotent"

@m.it("Can be searched for an AVU with an unique attribute")
def test_avu_collection(self, simple_data_object):
def test_avu_data_object(self, simple_data_object):
obj = DataObject(simple_data_object)
avu = AVU("abcde", "12345")
attr = "abcde"
avu = AVU(attr, "12345")

with pytest.raises(ValueError, match="did not contain any AVU with attribute"):
obj.avu("abcde")
obj.avu(attr)
obj.add_metadata(avu)

assert obj.avu("abcde") == avu
assert obj.avu(attr) == avu

obj.add_metadata(AVU("abcde", "67890"))
obj.add_metadata(AVU(attr, "67890"))
with pytest.raises(
ValueError, match="contained more than one AVU with attribute"
):
obj.avu("abcde")
obj.avu(attr)

@m.it("Can be searched for an AVU with an unique namespaced attribute")
def test_avu_data_object_ns(self, simple_data_object):
obj = DataObject(simple_data_object)
attr = "abcde"
ns = "test"
avu = AVU(attr, "12345", namespace=ns)

with pytest.raises(
ValueError, match=f"did not contain any AVU with attribute '{attr}'"
):
obj.avu(attr)
with pytest.raises(
ValueError,
match=f"did not contain any AVU with attribute '{attr}' in namespace '{ns}'",
):
obj.avu(attr, namespace=ns)

obj.add_metadata(avu)

with pytest.raises(
ValueError, match=f"did not contain any AVU with attribute '{attr}'"
):
obj.avu(attr)

assert obj.avu(attr, namespace=ns) == avu

other_ns = "other"
with pytest.raises(
ValueError,
match=f"did not contain any AVU with attribute '{attr}' in namespace '{other_ns}'",
):
obj.avu(attr, namespace=other_ns)

@m.it("Can have metadata superseded")
def test_supersede_meta_data_object(self, simple_data_object):
Expand Down
Loading