Skip to content

Commit a213628

Browse files
authored
Merge branch '9.0.0-dev' into refactor/rename-spdx-is_compound_expression
2 parents 0103482 + cdb5698 commit a213628

File tree

8 files changed

+68
-80
lines changed

8 files changed

+68
-80
lines changed

CHANGELOG.md

Lines changed: 4 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,14 @@
22

33

44

5-
## v9.0.0-rc.1 (2025-02-12)
5+
## v8.8.0 (2025-02-12)
66

7-
### Breaking
8-
9-
* feat!: BomRef affect equality/comparisson (#754)
10-
11-
For some this is considered a bug-fix, for others this is a feature - it
12-
is a breaking change anyway since it modifies the order of things.
13-
14-
----
15-
16-
TODO:
17-
- [x] **every** symbol that has a property `bom-ref` MUST utilize it for
18-
dunder methods `hash`,`eq`,`gt`,`lt`,...
19-
- [x] add new test cases from #753
20-
- [x] add new test cases from #540
21-
- [x] add new test cases from #677
22-
- [x] create new tests snapshots (if applicable)
23-
24-
----
25-
26-
> [!important]
27-
> depends on #755
28-
29-
supersedes #678
30-
closes #678
31-
32-
fixes #753
33-
fixes #540
34-
fixes #677
35-
36-
---------
37-
38-
Signed-off-by: wkoot <[email protected]>
39-
Signed-off-by: Jan Kowalleck <[email protected]>
40-
Co-authored-by: wkoot <[email protected]> ([`46bc3f5`](https://github.com/CycloneDX/cyclonedx-python-lib/commit/46bc3f53b9302159b7fa684d3cf78b08928ba731))
41-
42-
* chore(deps)!: `py-serializable==^1.1.1` -> `^2.0.0` (#775)
43-
44-
bump to `py-serializable` v2.0.0:
45-
<https://github.com/madpah/serializable/releases/tag/v2.0.0>
46-
This is considered a breaking change, as downstream users might rely on
47-
the same package's previous version.
48-
49-
Signed-off-by: Jan Kowalleck <[email protected]> ([`7c20c8e`](https://github.com/CycloneDX/cyclonedx-python-lib/commit/7c20c8e44fbc3de2942dd2f2ad298be2bd17614b))
7+
### Feature
508

51-
* refactor!: streamline comparison/hashing functions (#755)
9+
* feat: add `cyclonedx.model.crypto.ProtocolProperties.crypto_refs` (#767)
5210

53-
we have different methods of object comparison here and there, some work
54-
on tuples, other on hashes, other on different structures.
55-
56-
this PR streamlines this.
57-
58-
these changes might cause breaking changes for downstream users.
59-
60-
---------
6111

62-
Signed-off-by: Jan Kowalleck <jan.kowalleck@gmail.com> ([`fd9b755`](https://github.com/CycloneDX/cyclonedx-python-lib/commit/fd9b7559a49bdaf3f6d9fe9fea54db8a65958c01))
12+
Signed-off-by: Indivar Mishra <indimishra@gmail.com> ([`beb35f5`](https://github.com/CycloneDX/cyclonedx-python-lib/commit/beb35f55e3e75d625db45e4ff084dee02e919ef6))
6313

6414

6515
## v8.7.0 (2025-02-06)

cyclonedx/model/contact.py

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -254,23 +254,23 @@ def phone(self) -> Optional[str]:
254254
def phone(self, phone: Optional[str]) -> None:
255255
self._phone = phone
256256

257+
def __comparable_tuple(self) -> _ComparableTuple:
258+
return _ComparableTuple((
259+
self.name, self.email, self.phone
260+
))
261+
257262
def __eq__(self, other: object) -> bool:
258263
if isinstance(other, OrganizationalContact):
259-
return hash(other) == hash(self)
264+
return self.__comparable_tuple() == other.__comparable_tuple()
260265
return False
261266

262267
def __lt__(self, other: Any) -> bool:
263268
if isinstance(other, OrganizationalContact):
264-
return _ComparableTuple((
265-
self.name, self.email, self.phone
266-
)) < _ComparableTuple((
267-
other.name, other.email, other.phone
268-
))
269+
return self.__comparable_tuple() < other.__comparable_tuple()
269270
return NotImplemented
270271

271272
def __hash__(self) -> int:
272-
# TODO
273-
return hash((self.name, self.phone, self.email))
273+
return hash(self.__comparable_tuple())
274274

275275
def __repr__(self) -> str:
276276
return f'<OrganizationalContact name={self.name}, email={self.email}, phone={self.phone}>'
@@ -364,19 +364,23 @@ def contacts(self) -> 'SortedSet[OrganizationalContact]':
364364
def contacts(self, contacts: Iterable[OrganizationalContact]) -> None:
365365
self._contacts = SortedSet(contacts)
366366

367+
def __comparable_tuple(self) -> _ComparableTuple:
368+
return _ComparableTuple((
369+
self.name, _ComparableTuple(self.urls), _ComparableTuple(self.contacts)
370+
))
371+
367372
def __eq__(self, other: object) -> bool:
368373
if isinstance(other, OrganizationalEntity):
369-
return hash(other) == hash(self)
374+
return self.__comparable_tuple() == other.__comparable_tuple()
370375
return False
371376

372377
def __lt__(self, other: Any) -> bool:
373378
if isinstance(other, OrganizationalEntity):
374-
return hash(self) < hash(other)
379+
return self.__comparable_tuple() < other.__comparable_tuple()
375380
return NotImplemented
376381

377382
def __hash__(self) -> int:
378-
# TODO
379-
return hash((self.name, tuple(self.urls), tuple(self.contacts)))
383+
return hash(self.__comparable_tuple())
380384

381385
def __repr__(self) -> str:
382386
return f'<OrganizationalEntity name={self.name}>'

cyclonedx/model/crypto.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -494,16 +494,20 @@ def nist_quantum_security_level(self, nist_quantum_security_level: Optional[int]
494494
)
495495
self._nist_quantum_security_level = nist_quantum_security_level
496496

497+
def __comparable_tuple(self) -> _ComparableTuple:
498+
return _ComparableTuple((
499+
self.primitive, self._parameter_set_identifier, self.curve, self.execution_environment,
500+
self.implementation_platform, _ComparableTuple(self.certification_levels), self.mode, self.padding,
501+
_ComparableTuple(self.crypto_functions), self.classical_security_level, self.nist_quantum_security_level,
502+
))
503+
497504
def __eq__(self, other: object) -> bool:
498505
if isinstance(other, AlgorithmProperties):
499-
return hash(other) == hash(self)
506+
return self.__comparable_tuple() == other.__comparable_tuple()
500507
return False
501508

502509
def __hash__(self) -> int:
503-
# TODO
504-
return hash((self.primitive, self._parameter_set_identifier, self.curve, self.execution_environment,
505-
self.implementation_platform, tuple(self.certification_levels), self.mode, self.padding,
506-
tuple(self.crypto_functions), self.classical_security_level, self.nist_quantum_security_level,))
510+
return hash(self.__comparable_tuple())
507511

508512
def __repr__(self) -> str:
509513
return f'<AlgorithmProperties primitive={self.primitive}, execution_environment={self.execution_environment}>'
@@ -1336,11 +1340,13 @@ def __init__(
13361340
version: Optional[str] = None,
13371341
cipher_suites: Optional[Iterable[ProtocolPropertiesCipherSuite]] = None,
13381342
ikev2_transform_types: Optional[Ikev2TransformTypes] = None,
1343+
crypto_refs: Optional[Iterable[BomRef]] = None,
13391344
) -> None:
13401345
self.type = type
13411346
self.version = version
13421347
self.cipher_suites = cipher_suites or [] # type:ignore[assignment]
13431348
self.ikev2_transform_types = ikev2_transform_types
1349+
self.crypto_refs = crypto_refs or [] # type:ignore[assignment]
13441350

13451351
@property
13461352
@serializable.xml_sequence(10)
@@ -1403,9 +1409,29 @@ def ikev2_transform_types(self) -> Optional[Ikev2TransformTypes]:
14031409
def ikev2_transform_types(self, ikev2_transform_types: Optional[Ikev2TransformTypes]) -> None:
14041410
self._ikev2_transform_types = ikev2_transform_types
14051411

1412+
@property
1413+
@serializable.xml_array(serializable.XmlArraySerializationType.FLAT, 'cryptoRef')
1414+
@serializable.json_name('cryptoRefArray')
1415+
def crypto_refs(self) -> 'SortedSet[BomRef]':
1416+
"""
1417+
A list of protocol-related cryptographic assets.
1418+
1419+
Returns:
1420+
`Iterable[BomRef]`
1421+
"""
1422+
return self._crypto_refs
1423+
1424+
@crypto_refs.setter
1425+
def crypto_refs(self, crypto_refs: Iterable[BomRef]) -> None:
1426+
self._crypto_refs = SortedSet(crypto_refs)
1427+
14061428
def __comparable_tuple(self) -> _ComparableTuple:
14071429
return _ComparableTuple((
1408-
self.type, self.version, _ComparableTuple(self.cipher_suites), self.ikev2_transform_types
1430+
self.type,
1431+
self.version,
1432+
_ComparableTuple(self.cipher_suites),
1433+
self.ikev2_transform_types,
1434+
_ComparableTuple(self.crypto_refs)
14091435
))
14101436

14111437
def __eq__(self, other: object) -> bool:

cyclonedx/model/vulnerability.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -461,22 +461,23 @@ def url(self) -> Optional[XsUri]:
461461
def url(self, url: Optional[XsUri]) -> None:
462462
self._url = url
463463

464+
def __comparable_tuple(self) -> _ComparableTuple:
465+
return _ComparableTuple((
466+
self.name, self.url
467+
))
468+
464469
def __eq__(self, other: object) -> bool:
465470
if isinstance(other, VulnerabilitySource):
466-
return hash(other) == hash(self)
471+
return self.__comparable_tuple() == other.__comparable_tuple()
467472
return False
468473

469474
def __lt__(self, other: Any) -> bool:
470475
if isinstance(other, VulnerabilitySource):
471-
return _ComparableTuple((
472-
self.name, self.url
473-
)) < _ComparableTuple((
474-
other.name, other.url
475-
))
476+
return self.__comparable_tuple() < other.__comparable_tuple()
476477
return NotImplemented
477478

478479
def __hash__(self) -> int:
479-
return hash((self.name, self.url))
480+
return hash(self.__comparable_tuple())
480481

481482
def __repr__(self) -> str:
482483
return f'<VulnerabilityAdvisory name={self.name}, url={self.url}>'

tests/_data/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ def get_crypto_properties_protocol() -> CryptoProperties:
239239
]
240240
)
241241
],
242+
crypto_refs=[BomRef('for-test-2'), BomRef('for-test-1')],
242243
),
243244
oid='an-oid-here'
244245
)

tests/_data/snapshots/get_bom_v1_6_with_crypto_protocol-1.6.json.bin

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
"name": "TLS_CHACHA20_POLY1305_SHA256"
3939
}
4040
],
41+
"cryptoRefArray": [
42+
"for-test-1",
43+
"for-test-2"
44+
],
4145
"type": "tls",
4246
"version": "1.3"
4347
}

tests/_data/snapshots/get_bom_v1_6_with_crypto_protocol-1.6.xml.bin

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
</identifiers>
4545
</cipherSuite>
4646
</cipherSuites>
47+
<cryptoRef>for-test-1</cryptoRef>
48+
<cryptoRef>for-test-2</cryptoRef>
4749
</protocolProperties>
4850
<oid>an-oid-here</oid>
4951
</cryptoProperties>

tests/test_deserialize_json.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ def test_regression_issue764(self) -> None:
116116

117117
def test_regression_issue690(self) -> None:
118118
"""
119-
regressio test for issue#690.
119+
regression test for issue#690.
120120
see https://github.com/CycloneDX/cyclonedx-python-lib/issues/690
121121
"""
122122
json_file = join(OWN_DATA_DIRECTORY, 'json',

0 commit comments

Comments
 (0)