Skip to content

Commit 845b8d5

Browse files
authored
feat: avoid raising NoPropertiesProvidedException for optional parameters (#786)
the following classes' init no longer raise `NoPropertiesProvidedException`: * `cyclonedx.model.IdentifiableAction` * `cyclonedx.model.component.Commit` * `cyclonedx.model.component.ComponentEvidence` * `cyclonedx.model.component.Diff` * `cyclonedx.model.component.Pedigree` * `cyclonedx.model.issue.IssueTypeSource` * `cyclonedx.model.vulnerability.VulnerabilityAnalysis` * `cyclonedx.model.vulnerability.VulnerabilityCredits` * `cyclonedx.model.vulnerability.VulnerabilityRating` * `cyclonedx.model.vulnerability.VulnerabilitySource` --------- Signed-off-by: Indivar Mishra <[email protected]>
1 parent 208d5aa commit 845b8d5

7 files changed

+15
-82
lines changed

cyclonedx/model/__init__.py

+1-11
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,7 @@
3737
from sortedcontainers import SortedSet
3838

3939
from .._internal.compare import ComparableTuple as _ComparableTuple
40-
from ..exception.model import (
41-
InvalidLocaleTypeException,
42-
InvalidUriException,
43-
NoPropertiesProvidedException,
44-
UnknownHashTypeException,
45-
)
40+
from ..exception.model import InvalidLocaleTypeException, InvalidUriException, UnknownHashTypeException
4641
from ..exception.serialization import CycloneDxDeserializationException, SerializationOfUnexpectedValueException
4742
from ..schema.schema import (
4843
SchemaVersion1Dot0,
@@ -1180,11 +1175,6 @@ def __init__(
11801175
name: Optional[str] = None,
11811176
email: Optional[str] = None,
11821177
) -> None:
1183-
if not timestamp and not name and not email:
1184-
raise NoPropertiesProvidedException(
1185-
'At least one of `timestamp`, `name` or `email` must be provided for an `IdentifiableAction`.'
1186-
)
1187-
11881178
self.timestamp = timestamp
11891179
self.name = name
11901180
self.email = email

cyclonedx/model/component.py

+1-22
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from .._internal.bom_ref import bom_ref_from_str as _bom_ref_from_str
3030
from .._internal.compare import ComparablePackageURL as _ComparablePackageURL, ComparableTuple as _ComparableTuple
3131
from .._internal.hash import file_sha1sum as _file_sha1sum
32-
from ..exception.model import InvalidOmniBorIdException, InvalidSwhidException, NoPropertiesProvidedException
32+
from ..exception.model import InvalidOmniBorIdException, InvalidSwhidException
3333
from ..exception.serialization import (
3434
CycloneDxDeserializationException,
3535
SerializationOfUnexpectedValueException,
@@ -82,11 +82,6 @@ def __init__(
8282
committer: Optional[IdentifiableAction] = None,
8383
message: Optional[str] = None,
8484
) -> None:
85-
if not uid and not url and not author and not committer and not message:
86-
raise NoPropertiesProvidedException(
87-
'At least one of `uid`, `url`, `author`, `committer` or `message` must be provided for a `Commit`.'
88-
)
89-
9085
self.uid = uid
9186
self.url = url
9287
self.author = author
@@ -208,11 +203,6 @@ def __init__(
208203
licenses: Optional[Iterable[License]] = None,
209204
copyright: Optional[Iterable[Copyright]] = None,
210205
) -> None:
211-
if not licenses and not copyright:
212-
raise NoPropertiesProvidedException(
213-
'At least one of `licenses` or `copyright` must be supplied for a `ComponentEvidence`.'
214-
)
215-
216206
self.licenses = licenses or [] # type:ignore[assignment]
217207
self.copyright = copyright or [] # type:ignore[assignment]
218208

@@ -442,11 +432,6 @@ def __init__(
442432
text: Optional[AttachedText] = None,
443433
url: Optional[XsUri] = None,
444434
) -> None:
445-
if not text and not url:
446-
raise NoPropertiesProvidedException(
447-
'At least one of `text` or `url` must be provided for a `Diff`.'
448-
)
449-
450435
self.text = text
451436
self.url = url
452437

@@ -624,12 +609,6 @@ def __init__(
624609
patches: Optional[Iterable[Patch]] = None,
625610
notes: Optional[str] = None,
626611
) -> None:
627-
if not ancestors and not descendants and not variants and not commits and not patches and not notes:
628-
raise NoPropertiesProvidedException(
629-
'At least one of `ancestors`, `descendants`, `variants`, `commits`, `patches` or `notes` must be '
630-
'provided for `Pedigree`'
631-
)
632-
633612
self.ancestors = ancestors or [] # type:ignore[assignment]
634613
self.descendants = descendants or [] # type:ignore[assignment]
635614
self.variants = variants or [] # type:ignore[assignment]

cyclonedx/model/issue.py

-5
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
from sortedcontainers import SortedSet
2323

2424
from .._internal.compare import ComparableTuple as _ComparableTuple
25-
from ..exception.model import NoPropertiesProvidedException
2625
from . import XsUri
2726

2827

@@ -54,10 +53,6 @@ def __init__(
5453
name: Optional[str] = None,
5554
url: Optional[XsUri] = None,
5655
) -> None:
57-
if not name and not url:
58-
raise NoPropertiesProvidedException(
59-
'Neither `name` nor `url` were provided - at least one must be provided.'
60-
)
6156
self.name = name
6257
self.url = url
6358

cyclonedx/model/vulnerability.py

+6-24
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class BomTargetVersionRange:
6262
`version` and `version_range` are mutually exclusive.
6363
6464
.. note::
65-
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/#type_vulnerabilityType
65+
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/xml/#type_vulnerabilityType
6666
"""
6767

6868
def __init__(
@@ -219,7 +219,7 @@ class VulnerabilityAnalysis:
219219
Class that models the `analysis` sub-element of the `vulnerabilityType` complex type.
220220
221221
.. note::
222-
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/#type_vulnerabilityType
222+
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/xml/#type_vulnerabilityType
223223
"""
224224

225225
def __init__(
@@ -229,11 +229,6 @@ def __init__(
229229
responses: Optional[Iterable[ImpactAnalysisResponse]] = None,
230230
detail: Optional[str] = None,
231231
) -> None:
232-
if not state and not justification and not responses and not detail:
233-
raise NoPropertiesProvidedException(
234-
'At least one of state, justification, responses or detail must be provided for VulnerabilityAnalysis '
235-
'- none supplied'
236-
)
237232
self.state = state
238233
self.justification = justification
239234
self.responses = responses or [] # type:ignore[assignment]
@@ -408,18 +403,14 @@ class VulnerabilitySource:
408403
This type is used for multiple purposes in the CycloneDX schema.
409404
410405
.. note::
411-
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/#type_vulnerabilitySourceType
406+
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/xml/#type_vulnerabilitySourceType
412407
"""
413408

414409
def __init__(
415410
self, *,
416411
name: Optional[str] = None,
417412
url: Optional[XsUri] = None,
418413
) -> None:
419-
if not name and not url:
420-
raise NoPropertiesProvidedException(
421-
'Either name or url must be provided for a VulnerabilitySource - neither provided'
422-
)
423414
self.name = name
424415
self.url = url
425416

@@ -480,7 +471,7 @@ class VulnerabilityReference:
480471
intelligence.
481472
482473
.. note::
483-
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/#type_vulnerabilityType
474+
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/xml/#type_vulnerabilityType
484475
"""
485476

486477
def __init__(
@@ -723,7 +714,7 @@ class VulnerabilityRating:
723714
1.4 - see https://github.com/CycloneDX/specification/blob/master/schema/ext/vulnerability-1.0.xsd.
724715
725716
.. note::
726-
See `ratingType` in https://cyclonedx.org/docs/1.6/#ratingType
717+
See `ratingType` in https://cyclonedx.org/docs/1.6/xml/#ratingType
727718
728719
.. warning::
729720
As part of implementing support for CycloneDX schema version 1.4, the three score types defined in the schema
@@ -741,11 +732,6 @@ def __init__(
741732
vector: Optional[str] = None,
742733
justification: Optional[str] = None,
743734
) -> None:
744-
if not source and not score and not severity and not method and not vector and not justification:
745-
raise NoPropertiesProvidedException(
746-
'At least one property must be provided when creating a VulnerabilityRating - none supplied.'
747-
)
748-
749735
self.source = source
750736
self.score = score
751737
self.severity = severity
@@ -861,18 +847,14 @@ class VulnerabilityCredits:
861847
extension (in XML only).
862848
863849
.. note::
864-
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/#type_vulnerabilityType
850+
See the CycloneDX schema: https://cyclonedx.org/docs/1.6/xml/#type_vulnerabilityType
865851
"""
866852

867853
def __init__(
868854
self, *,
869855
organizations: Optional[Iterable[OrganizationalEntity]] = None,
870856
individuals: Optional[Iterable[OrganizationalContact]] = None,
871857
) -> None:
872-
if not organizations and not individuals:
873-
raise NoPropertiesProvidedException(
874-
'One of `organizations` or `individuals` must be populated - neither were'
875-
)
876858
self.organizations = organizations or [] # type:ignore[assignment]
877859
self.individuals = individuals or [] # type:ignore[assignment]
878860

tests/test_model.py

+2-8
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,7 @@
2424
from ddt import ddt, named_data
2525

2626
from cyclonedx._internal.compare import ComparableTuple
27-
from cyclonedx.exception.model import (
28-
InvalidLocaleTypeException,
29-
InvalidUriException,
30-
NoPropertiesProvidedException,
31-
UnknownHashTypeException,
32-
)
27+
from cyclonedx.exception.model import InvalidLocaleTypeException, InvalidUriException, UnknownHashTypeException
3328
from cyclonedx.model import (
3429
Copyright,
3530
Encoding,
@@ -309,8 +304,7 @@ def test_sort(self) -> None:
309304
class TestModelIdentifiableAction(TestCase):
310305

311306
def test_no_params(self) -> None:
312-
with self.assertRaises(NoPropertiesProvidedException):
313-
IdentifiableAction()
307+
IdentifiableAction() # Does not raise `NoPropertiesProvidedException`
314308

315309
def test_same(self) -> None:
316310
ts = datetime.datetime.utcnow()

tests/test_model_component.py

+4-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from typing import List
2020
from unittest import TestCase
2121

22-
from cyclonedx.exception.model import NoPropertiesProvidedException
2322
from cyclonedx.model import (
2423
AttachedText,
2524
Copyright,
@@ -57,8 +56,7 @@
5756
class TestModelCommit(TestCase):
5857

5958
def test_no_parameters(self) -> None:
60-
with self.assertRaises(NoPropertiesProvidedException):
61-
Commit()
59+
Commit() # Does not raise `NoPropertiesProvidedException`
6260

6361
def test_same(self) -> None:
6462
ia_comitter = IdentifiableAction(timestamp=datetime.datetime.utcnow(), name='The Committer')
@@ -287,8 +285,7 @@ def test_nested_components_2(self) -> None:
287285
class TestModelComponentEvidence(TestCase):
288286

289287
def test_no_params(self) -> None:
290-
with self.assertRaises(NoPropertiesProvidedException):
291-
ComponentEvidence()
288+
ComponentEvidence() # Does not raise `NoPropertiesProvidedException`
292289

293290
def test_same_1(self) -> None:
294291
ce_1 = ComponentEvidence(copyright=[Copyright(text='Commercial')])
@@ -312,8 +309,7 @@ def test_not_same_1(self) -> None:
312309
class TestModelDiff(TestCase):
313310

314311
def test_no_params(self) -> None:
315-
with self.assertRaises(NoPropertiesProvidedException):
316-
Diff()
312+
Diff() # Does not raise `NoPropertiesProvidedException`
317313

318314
def test_same(self) -> None:
319315
at = AttachedText(content='A very long diff')
@@ -437,8 +433,7 @@ def test_sort(self) -> None:
437433
class TestModelPedigree(TestCase):
438434

439435
def test_no_params(self) -> None:
440-
with self.assertRaises(NoPropertiesProvidedException):
441-
Pedigree()
436+
Pedigree() # does not raise `NoPropertiesProvidedException`
442437

443438
def test_same_1(self) -> None:
444439
p1 = get_pedigree_1()

tests/test_model_issue.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
from unittest import TestCase
1919

20-
from cyclonedx.exception.model import NoPropertiesProvidedException
2120
from cyclonedx.model import XsUri
2221
from cyclonedx.model.issue import IssueClassification, IssueType, IssueTypeSource
2322
from tests import reorder
@@ -63,8 +62,7 @@ def test_sort(self) -> None:
6362
class TestModelIssueTypeSource(TestCase):
6463

6564
def test_no_params(self) -> None:
66-
with self.assertRaises(NoPropertiesProvidedException):
67-
IssueTypeSource()
65+
IssueTypeSource() # Does not raise `NoPropertiesProvidedException`
6866

6967
def test_same(self) -> None:
7068
its_1 = IssueTypeSource(name='The Source', url=XsUri('https://cyclonedx.org'))

0 commit comments

Comments
 (0)