diff --git a/CHANGELOG.md b/CHANGELOG.md index e1fd615a09ae8023f21bebe404a99c70951bb5c3..90fd8f1105b14ae838a69b19cb400c50b608aaa5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * New setup extra `test` which installs the dependencies for testing. ### Changed ### +* Renamed the `filter` function of Container, ParentList and PropertyList to `filter_by_identity`. ### Deprecated ### diff --git a/src/doc/tutorials/complex_data_models.rst b/src/doc/tutorials/complex_data_models.rst index 168cf3b9f0d6839ed8f78beb01ae24fb9d489e88..873c8bd5af542bb73a6f19fb25fa238fbee500a3 100644 --- a/src/doc/tutorials/complex_data_models.rst +++ b/src/doc/tutorials/complex_data_models.rst @@ -100,29 +100,29 @@ entities. A short example: properties = r.properties # As r only has one property with id 101, this returns a list containing only p1_1 - properties.filter(pid=101) + properties.filter_by_identity(pid=101) # Result: [p1_1] # Filtering with name="Property 1" returns both p1_1 and p1_2, as they share their name - properties.filter(name="Property 1") + properties.filter_by_identity(name="Property 1") # Result: [p1_1, p1_2] # If both name and pid are given, matching is based only on pid for all entities that have an id - properties.filter(pid="102", name="Other Property") + properties.filter_by_identity(pid="102", name="Other Property") # Result: [p2_1, p2_2, p2_3] - # However, filtering with name="Property 1" and id=101 returns both p1_1 and p1_2, because + # However, filter_by_identity with name="Property 1" and id=101 returns both p1_1 and p1_2, because # p1_2 does not have an id and matches the name - properties.filter(pid="101", name="Property 1") + properties.filter_by_identity(pid="101", name="Property 1") # Result: [p1_1, p1_2] # We can also filter using an entity, in which case the name and id of the entity are used: - properties.filter(pid="102", name="Property 2") == properties.filter(p2_1) + properties.filter_by_identity(pid="102", name="Property 2") == properties.filter_by_identity(p2_1) # Result: True # If we only need properties that match both id and name, we can set the parameter # conjunction to True: - properties.filter(pid="102", name="Property 2", conjunction=True) + properties.filter_by_identity(pid="102", name="Property 2", conjunction=True) # Result: [p2_1] The filter function of ParentList works analogously. diff --git a/src/linkahead/apiutils.py b/src/linkahead/apiutils.py index 1aa127d31d6456076ffdd6dc5b591c3bb2f7b0b7..b2a612faea1616c64b7e78575156abccfdb29e61 100644 --- a/src/linkahead/apiutils.py +++ b/src/linkahead/apiutils.py @@ -386,7 +386,7 @@ def compare_entities(entity0: Optional[Entity] = None, for prop in entity0.properties: # ToDo: Would making id default break anything? key = prop.name if prop.name is not None else prop.id - matching = entity1.properties.filter(prop) + matching = entity1.properties.filter_by_identity(prop) if len(matching) == 0: # entity1 has prop, entity0 does not diff[0]["properties"][key] = {} @@ -440,7 +440,7 @@ def compare_entities(entity0: Optional[Entity] = None, for prop in entity1.properties: key = prop.name if prop.name is not None else prop.id # check how often the property appears in entity0 - num_prop_in_ent0 = len(entity0.properties.filter(prop)) + num_prop_in_ent0 = len(entity0.properties.filter_by_identity(prop)) if num_prop_in_ent0 == 0: # property is only present in entity0 - add to diff diff[1]["properties"][key] = {} @@ -455,7 +455,7 @@ def compare_entities(entity0: Optional[Entity] = None, (1, entity1.parents, entity0)]: for parent in parents: key = parent.name if parent.name is not None else parent.id - matching = other_entity.parents.filter(parent) + matching = other_entity.parents.filter_by_identity(parent) if len(matching) == 0: diff[index]["parents"].append(key) continue diff --git a/src/linkahead/common/models.py b/src/linkahead/common/models.py index 1caa6a4de14fc6551aa7cfe940c2074be80a1281..526a6f43d5658458053bfda5b0a831410196587f 100644 --- a/src/linkahead/common/models.py +++ b/src/linkahead/common/models.py @@ -2562,7 +2562,11 @@ class PropertyList(list): return xml2str(xml) - def filter(self, prop: Optional[Property] = None, + def filter(self, *args, **kwargs): + warnings.warn(DeprecationWarning("This function was renamed to filter_by_identity.")) + return self.filter(*args, **kwargs) + + def filter_by_identity(self, prop: Optional[Property] = None, pid: Union[None, str, int] = None, name: Optional[str] = None, conjunction: bool = False) -> list: @@ -2570,7 +2574,7 @@ class PropertyList(list): Return all Properties from the given PropertyList that match the selection criteria. - Please refer to the documentation of _filter_entity_list for a detailed + Please refer to the documentation of _filter_entity_list_by_identity for a detailed description of behaviour. Params @@ -2593,7 +2597,7 @@ class PropertyList(list): matches : list List containing all matching Properties """ - return _filter_entity_list(self, pid=pid, name=name, entity=prop, + return _filter_entity_list_by_identity(self, pid=pid, name=name, entity=prop, conjunction=conjunction) def _get_entity_by_cuid(self, cuid: str): @@ -2731,7 +2735,11 @@ class ParentList(list): return xml2str(xml) - def filter(self, parent: Optional[Parent] = None, + def filter(self, *args, **kwargs): + warnings.warn(DeprecationWarning("This function was renamed to filter_by_identity.")) + return self.filter(*args, **kwargs) + + def filter_by_identity(self, parent: Optional[Parent] = None, pid: Union[None, str, int] = None, name: Optional[str] = None, conjunction: bool = False) -> list: @@ -2739,7 +2747,7 @@ class ParentList(list): Return all Parents from the given ParentList that match the selection criteria. - Please refer to the documentation of _filter_entity_list for a detailed + Please refer to the documentation of _filter_entity_list_by_identity for a detailed description of behaviour. Params @@ -2762,7 +2770,7 @@ class ParentList(list): matches : list List containing all matching Parents """ - return _filter_entity_list(self, pid=pid, name=name, entity=parent, + return _filter_entity_list_by_identity(self, pid=pid, name=name, entity=parent, conjunction=conjunction) def remove(self, parent: Union[Entity, int, str]): @@ -5537,7 +5545,7 @@ def delete(ids: Union[list[int], range], raise_exception_on_error: bool = True): return c.delete(raise_exception_on_error=raise_exception_on_error) -def _filter_entity_list(listobject: list[Entity], +def _filter_entity_list_by_identity(listobject: list[Entity], entity: Optional[Entity] = None, pid: Union[None, str, int] = None, name: Optional[str] = None, diff --git a/unittests/test_entity.py b/unittests/test_entity.py index 2127ce028f4de55b8ef0ca704c1e69959c24ba82..e946fd40b8ea95c9f493b5e8f1e12457b2739a72 100644 --- a/unittests/test_entity.py +++ b/unittests/test_entity.py @@ -161,7 +161,7 @@ def test_property_list(): pl.append(p3) -def test_filter(): +def test_filter_by_identity(): rt1 = RecordType(id=100) rt2 = RecordType(id=101, name="RT") rt3 = RecordType(name="") @@ -184,7 +184,7 @@ def test_filter(): for coll in [entity.properties, entity.parents]: for ent in test_ents: assert ent not in coll - assert ent not in coll.filter(ent) + assert ent not in coll.filter_by_identity(ent) # Checks with each type t, t_props, t_pars = entity, entity.properties, entity.parents @@ -194,23 +194,23 @@ def test_filter(): tp1 = t.properties[-1] t.add_property(p3) tp3 = t.properties[-1] - assert len(t_props.filter(pid=100)) == 1 - assert tp1 in t_props.filter(pid=100) - assert len(t_props.filter(pid="100")) == 1 - assert tp1 in t_props.filter(pid="100") - assert len(t_props.filter(pid=101, name="RT")) == 1 - assert tp3 in t_props.filter(pid=101, name="RT") + assert len(t_props.filter_by_identity(pid=100)) == 1 + assert tp1 in t_props.filter_by_identity(pid=100) + assert len(t_props.filter_by_identity(pid="100")) == 1 + assert tp1 in t_props.filter_by_identity(pid="100") + assert len(t_props.filter_by_identity(pid=101, name="RT")) == 1 + assert tp3 in t_props.filter_by_identity(pid=101, name="RT") for entity in [rt1, p2, r1, r2]: - assert entity not in t_props.filter(pid=100) - assert tp1 in t_props.filter(entity) + assert entity not in t_props.filter_by_identity(pid=100) + assert tp1 in t_props.filter_by_identity(entity) # Check that direct addition (not wrapped) works t_props.append(p2) tp2 = t_props[-1] - assert tp2 in t_props.filter(pid=100) - assert tp2 not in t_props.filter(pid=101, name="RT") + assert tp2 in t_props.filter_by_identity(pid=100) + assert tp2 not in t_props.filter_by_identity(pid=101, name="RT") for entity in [rt1, r1, r2]: - assert entity not in t_props.filter(pid=100) - assert tp2 in t_props.filter(entity) + assert entity not in t_props.filter_by_identity(pid=100) + assert tp2 in t_props.filter_by_identity(entity) # Parents # Filtering with both name and id @@ -218,67 +218,67 @@ def test_filter(): tr3 = t.parents[-1] t.add_parent(r5) tr5 = t.parents[-1] - assert tr3 in t_pars.filter(pid=101) - assert tr5 not in t_pars.filter(pid=101) - assert tr3 not in t_pars.filter(name="R") - assert tr5 in t_pars.filter(name="R") - assert tr3 in t_pars.filter(pid=101, name="R") - assert tr5 not in t_pars.filter(pid=101, name="R") - assert tr3 not in t_pars.filter(pid=104, name="RT") - assert tr5 in t_pars.filter(pid=104, name="RT") - assert tr3 not in t_pars.filter(pid=105, name="T") - assert tr5 not in t_pars.filter(pid=105, name="T") + assert tr3 in t_pars.filter_by_identity(pid=101) + assert tr5 not in t_pars.filter_by_identity(pid=101) + assert tr3 not in t_pars.filter_by_identity(name="R") + assert tr5 in t_pars.filter_by_identity(name="R") + assert tr3 in t_pars.filter_by_identity(pid=101, name="R") + assert tr5 not in t_pars.filter_by_identity(pid=101, name="R") + assert tr3 not in t_pars.filter_by_identity(pid=104, name="RT") + assert tr5 in t_pars.filter_by_identity(pid=104, name="RT") + assert tr3 not in t_pars.filter_by_identity(pid=105, name="T") + assert tr5 not in t_pars.filter_by_identity(pid=105, name="T") # Works also without id / name and with duplicate parents for ent in test_ents: t.add_parent(ent) for ent in t_pars: - assert ent in t_pars.filter(ent) + assert ent in t_pars.filter_by_identity(ent) # Grid-Based r7 = Record() r7.add_property(Property()).add_property(name="A").add_property(name="B") r7.add_property(id=27).add_property(id=27, name="A").add_property(id=27, name="B") r7.add_property(id=43).add_property(id=43, name="A").add_property(id=43, name="B") - assert len(r7.properties.filter(pid=27)) == 3 - assert len(r7.properties.filter(pid=43)) == 3 - assert len(r7.properties.filter(pid=43, conjunction=True)) == 3 - assert len(r7.properties.filter(name="A")) == 3 - assert len(r7.properties.filter(name="B")) == 3 - assert len(r7.properties.filter(name="B", conjunction=True)) == 3 - assert len(r7.properties.filter(pid=1, name="A")) == 1 - assert len(r7.properties.filter(pid=1, name="A", conjunction=True)) == 0 - assert len(r7.properties.filter(pid=27, name="B")) == 4 - assert len(r7.properties.filter(pid=27, name="B", conjunction=True)) == 1 - assert len(r7.properties.filter(pid=27, name="C")) == 3 - assert len(r7.properties.filter(pid=27, name="C", conjunction=True)) == 0 + assert len(r7.properties.filter_by_identity(pid=27)) == 3 + assert len(r7.properties.filter_by_identity(pid=43)) == 3 + assert len(r7.properties.filter_by_identity(pid=43, conjunction=True)) == 3 + assert len(r7.properties.filter_by_identity(name="A")) == 3 + assert len(r7.properties.filter_by_identity(name="B")) == 3 + assert len(r7.properties.filter_by_identity(name="B", conjunction=True)) == 3 + assert len(r7.properties.filter_by_identity(pid=1, name="A")) == 1 + assert len(r7.properties.filter_by_identity(pid=1, name="A", conjunction=True)) == 0 + assert len(r7.properties.filter_by_identity(pid=27, name="B")) == 4 + assert len(r7.properties.filter_by_identity(pid=27, name="B", conjunction=True)) == 1 + assert len(r7.properties.filter_by_identity(pid=27, name="C")) == 3 + assert len(r7.properties.filter_by_identity(pid=27, name="C", conjunction=True)) == 0 # Entity based filtering behaves the same - assert (r7.properties.filter(pid=27) == - r7.properties.filter(Property(id=27))) - assert (r7.properties.filter(pid=43, conjunction=True) == - r7.properties.filter(Property(id=43), conjunction=True)) - assert (r7.properties.filter(name="A") == - r7.properties.filter(Property(name="A"))) - assert (r7.properties.filter(name="B") == - r7.properties.filter(Property(name="B"))) - assert (r7.properties.filter(name="B", conjunction=True) == - r7.properties.filter(Property(name="B"), conjunction=True)) - assert (r7.properties.filter(pid=1, name="A") == - r7.properties.filter(Property(id=1, name="A"))) - assert (r7.properties.filter(pid=1, name="A", conjunction=True) == - r7.properties.filter(Property(id=1, name="A"), conjunction=True)) - assert (r7.properties.filter(pid=27, name="B") == - r7.properties.filter(Property(id=27, name="B"))) - assert (r7.properties.filter(pid=27, name="B", conjunction=True) == - r7.properties.filter(Property(id=27, name="B"), conjunction=True)) - assert (r7.properties.filter(pid=27, name="C") == - r7.properties.filter(Property(id=27, name="C"))) - assert (r7.properties.filter(pid=27, name="C", conjunction=True) == - r7.properties.filter(Property(id=27, name="C"), conjunction=True)) + assert (r7.properties.filter_by_identity(pid=27) == + r7.properties.filter_by_identity(Property(id=27))) + assert (r7.properties.filter_by_identity(pid=43, conjunction=True) == + r7.properties.filter_by_identity(Property(id=43), conjunction=True)) + assert (r7.properties.filter_by_identity(name="A") == + r7.properties.filter_by_identity(Property(name="A"))) + assert (r7.properties.filter_by_identity(name="B") == + r7.properties.filter_by_identity(Property(name="B"))) + assert (r7.properties.filter_by_identity(name="B", conjunction=True) == + r7.properties.filter_by_identity(Property(name="B"), conjunction=True)) + assert (r7.properties.filter_by_identity(pid=1, name="A") == + r7.properties.filter_by_identity(Property(id=1, name="A"))) + assert (r7.properties.filter_by_identity(pid=1, name="A", conjunction=True) == + r7.properties.filter_by_identity(Property(id=1, name="A"), conjunction=True)) + assert (r7.properties.filter_by_identity(pid=27, name="B") == + r7.properties.filter_by_identity(Property(id=27, name="B"))) + assert (r7.properties.filter_by_identity(pid=27, name="B", conjunction=True) == + r7.properties.filter_by_identity(Property(id=27, name="B"), conjunction=True)) + assert (r7.properties.filter_by_identity(pid=27, name="C") == + r7.properties.filter_by_identity(Property(id=27, name="C"))) + assert (r7.properties.filter_by_identity(pid=27, name="C", conjunction=True) == + r7.properties.filter_by_identity(Property(id=27, name="C"), conjunction=True)) # Name only matching and name overwrite r8 = Record().add_property(name="A").add_property(name="B").add_property(name="B") r8.add_property(Property(name="A"), name="B") r8.add_property(Property(name="A", id=12), name="C") - assert len(r8.properties.filter(name="A")) == 1 - assert len(r8.properties.filter(name="B")) == 3 - assert len(r8.properties.filter(name="C")) == 1 - assert len(r8.properties.filter(pid=12)) == 1 + assert len(r8.properties.filter_by_identity(name="A")) == 1 + assert len(r8.properties.filter_by_identity(name="B")) == 3 + assert len(r8.properties.filter_by_identity(name="C")) == 1 + assert len(r8.properties.filter_by_identity(pid=12)) == 1