From f6b39f10d575b0b6e752dbd20fe4a48b8b4eaf14 Mon Sep 17 00:00:00 2001 From: Jan Kowalleck Date: Fri, 17 Jan 2025 12:48:57 +0100 Subject: [PATCH] wip Signed-off-by: Jan Kowalleck --- cyclonedx/model/definition.py | 38 +++++++++++++++++++------------- cyclonedx/model/service.py | 24 +++++++++++--------- cyclonedx/model/vulnerability.py | 9 ++++++++ 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/cyclonedx/model/definition.py b/cyclonedx/model/definition.py index 417fd0c1..0a58758b 100644 --- a/cyclonedx/model/definition.py +++ b/cyclonedx/model/definition.py @@ -53,21 +53,27 @@ def __init__( self.owner = owner self.external_references = external_references or [] # type:ignore[assignment] + @staticmethod + def __comparable_tuple(o: 'Standard') -> _ComparableTuple: + return _ComparableTuple(( + o.bom_ref, + o.name, o.version, + o.description, o.owner, + _ComparableTuple(o.external_references) + )) + def __lt__(self, other: Any) -> bool: if isinstance(other, Standard): - return (_ComparableTuple((self.bom_ref, self.name, self.version)) - < _ComparableTuple((other.bom_ref, other.name, other.version))) + return self.__comparable_tuple(self) < self.__comparable_tuple(other) return NotImplemented def __eq__(self, other: object) -> bool: if isinstance(other, Standard): - return hash(other) == hash(self) + return self.__comparable_tuple(self) == self.__comparable_tuple(other) return False def __hash__(self) -> int: - return hash(( - self.bom_ref, self.name, self.version, self.description, self.owner, tuple(self.external_references) - )) + return hash(self.__comparable_tuple(self)) def __repr__(self) -> str: return f' None: def __bool__(self) -> bool: return len(self._standards) > 0 - def __eq__(self, other: object) -> bool: - if not isinstance(other, Definitions): - return False - - return self._standards == other._standards + @staticmethod + def __comparable_tuple(o: 'Definitions') -> _ComparableTuple: + return _ComparableTuple(o._standards) - def __hash__(self) -> int: - return hash((tuple(self._standards))) + def __eq__(self, other: object) -> bool: + if isinstance(other, Definitions): + return self.__comparable_tuple(self) == self.__comparable_tuple(other) + return False def __lt__(self, other: Any) -> bool: if isinstance(other, Definitions): - return (_ComparableTuple(self._standards) - < _ComparableTuple(other.standards)) + return self.__comparable_tuple(self) < self.__comparable_tuple(other) return NotImplemented + def __hash__(self) -> int: + return hash(self.__comparable_tuple(self)) + def __repr__(self) -> str: return '' diff --git a/cyclonedx/model/service.py b/cyclonedx/model/service.py index 9e6af564..d098513f 100644 --- a/cyclonedx/model/service.py +++ b/cyclonedx/model/service.py @@ -354,26 +354,28 @@ def release_notes(self) -> Optional[ReleaseNotes]: def release_notes(self, release_notes: Optional[ReleaseNotes]) -> None: self._release_notes = release_notes + @staticmethod + def __comparable_tuple(o: 'Service') -> _ComparableTuple: + return _ComparableTuple(( + o.bom_ref, # see https://github.com/CycloneDX/cyclonedx-python-lib/issues/753 + o.authenticated, _ComparableTuple(o.data), o.description, _ComparableTuple(o.endpoints), + _ComparableTuple(o.external_references), o.group, _ComparableTuple(o.licenses), o.name, + _ComparableTuple(o.properties), o.provider, o.release_notes, _ComparableTuple(o.services), o.version, + o.x_trust_boundary + )) + def __eq__(self, other: object) -> bool: if isinstance(other, Service): - return hash(other) == hash(self) + return self.__comparable_tuple(self) == self.__comparable_tuple(other) return False def __lt__(self, other: Any) -> bool: if isinstance(other, Service): - return _ComparableTuple(( - self.group, self.name, self.version - )) < _ComparableTuple(( - other.group, other.name, other.version - )) + return self.__comparable_tuple(self) < self.__comparable_tuple(other) return NotImplemented def __hash__(self) -> int: - return hash(( - self.authenticated, tuple(self.data), self.description, tuple(self.endpoints), - tuple(self.external_references), self.group, tuple(self.licenses), self.name, tuple(self.properties), - self.provider, self.release_notes, tuple(self.services), self.version, self.x_trust_boundary - )) + return hash(self.__comparable_tuple(self)) def __repr__(self) -> str: return f'' diff --git a/cyclonedx/model/vulnerability.py b/cyclonedx/model/vulnerability.py index 0b7cdc1d..3836e86d 100644 --- a/cyclonedx/model/vulnerability.py +++ b/cyclonedx/model/vulnerability.py @@ -1308,6 +1308,15 @@ def properties(self) -> 'SortedSet[Property]': def properties(self, properties: Iterable[Property]) -> None: self._properties = SortedSet(properties) + @staticmethod + def __comparable_tuple(o: 'Vulnerability') -> _ComparableTuple: + return _ComparableTuple(( + o.bom_ref, o.id, o.description, + o.source, _ComparableTuple(o.references), _ComparableTuple(o.ratings), _ComparableTuple(o.cwes), + o.detail, o.recommendation, o.workaround, _ComparableTuple(o.advisories), o.created, o.published, + o.updated, o.credits, o.tools, o.analysis, _ComparableTuple(o.affects), _ComparableTuple(o.properties) + )) + def __eq__(self, other: object) -> bool: if isinstance(other, Vulnerability): return hash(other) == hash(self)