Skip to content

Commit 4842828

Browse files
authored
feat!: ignore unknown properties when deserializing (#853)
when deserializing JSON: ignore unknown/unsupported properties when deserializing XML: ignore unknown/unsupported attributes and elements this is considered a **BREAKING Change**, as the old behavior was to throw an error when deserializing unknown/unsupported features - which no longer happens, instead, unknown/unsupported features are simply ignored. ----- - fixes #850 ----- --------- Signed-off-by: Jan Kowalleck <[email protected]>
1 parent 2cfb3d6 commit 4842828

19 files changed

+104
-60
lines changed

cyclonedx/model/__init__.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,7 @@ def deserialize(cls, o: Any) -> ExternalReferenceType:
676676
return ExternalReferenceType(o)
677677

678678

679-
@serializable.serializable_class
679+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
680680
class XsUri(serializable.helpers.BaseHelper):
681681
"""
682682
Helper class that allows us to perform validation on data strings that are defined as xs:anyURI
@@ -802,7 +802,7 @@ def is_bom_link(self) -> bool:
802802
return self._uri.startswith(_BOM_LINK_PREFIX)
803803

804804

805-
@serializable.serializable_class
805+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
806806
class ExternalReference:
807807
"""
808808
This is our internal representation of an ExternalReference complex type that can be used in multiple places within
@@ -914,7 +914,7 @@ def __repr__(self) -> str:
914914
return f'<ExternalReference {self.type.name}, {self.url}>'
915915

916916

917-
@serializable.serializable_class
917+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
918918
class Property:
919919
"""
920920
This is our internal representation of `propertyType` complex type that can be used in multiple places within
@@ -989,7 +989,7 @@ def __repr__(self) -> str:
989989
return f'<Property name={self.name}>'
990990

991991

992-
@serializable.serializable_class
992+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
993993
class NoteText:
994994
"""
995995
This is our internal representation of the Note.text complex type that can be used in multiple places within
@@ -1081,7 +1081,7 @@ def __repr__(self) -> str:
10811081
return f'<NoteText content_type={self.content_type}, encoding={self.encoding}>'
10821082

10831083

1084-
@serializable.serializable_class
1084+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
10851085
class Note:
10861086
"""
10871087
This is our internal representation of the Note complex type that can be used in multiple places within
@@ -1166,7 +1166,7 @@ def __repr__(self) -> str:
11661166
return f'<Note id={id(self)}, locale={self.locale}>'
11671167

11681168

1169-
@serializable.serializable_class
1169+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
11701170
class IdentifiableAction:
11711171
"""
11721172
This is our internal representation of the `identifiableActionType` complex type.
@@ -1252,7 +1252,7 @@ def __repr__(self) -> str:
12521252
return f'<IdentifiableAction name={self.name}, email={self.email}>'
12531253

12541254

1255-
@serializable.serializable_class
1255+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
12561256
class Copyright:
12571257
"""
12581258
This is our internal representation of the `copyrightsType` complex type.

cyclonedx/model/bom.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
from packageurl import PackageURL
5656

5757

58-
@serializable.serializable_class
58+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
5959
class BomMetaData:
6060
"""
6161
This is our internal representation of the metadata complex type within the CycloneDX standard.
@@ -314,7 +314,7 @@ def __repr__(self) -> str:
314314
return f'<BomMetaData timestamp={self.timestamp}, component={self.component}>'
315315

316316

317-
@serializable.serializable_class(ignore_during_deserialization=['$schema', 'bom_format', 'spec_version'])
317+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
318318
class Bom:
319319
"""
320320
This is our internal representation of a bill-of-materials (BOM).

cyclonedx/model/bom_ref.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
_T_BR = TypeVar('_T_BR', bound='BomRef')
2929

3030

31-
@serializable.serializable_class
31+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
3232
class BomRef(serializable.helpers.BaseHelper):
3333
"""
3434
An identifier that can be used to reference objects elsewhere in the BOM.

cyclonedx/model/component.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
from .release_note import ReleaseNotes
6767

6868

69-
@serializable.serializable_class
69+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
7070
class Commit:
7171
"""
7272
Our internal representation of the `commitType` complex type.
@@ -326,7 +326,7 @@ def deserialize(cls, o: Any) -> ComponentType:
326326
return ComponentType(o)
327327

328328

329-
@serializable.serializable_class
329+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
330330
class Diff:
331331
"""
332332
Our internal representation of the `diffType` complex type.
@@ -408,7 +408,7 @@ class PatchClassification(str, Enum):
408408
UNOFFICIAL = 'unofficial'
409409

410410

411-
@serializable.serializable_class
411+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
412412
class Patch:
413413
"""
414414
Our internal representation of the `patchType` complex type.
@@ -498,7 +498,7 @@ def __repr__(self) -> str:
498498
return f'<Patch type={self.type}, id={id(self)}>'
499499

500500

501-
@serializable.serializable_class
501+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
502502
class Pedigree:
503503
"""
504504
Our internal representation of the `pedigreeType` complex type.
@@ -661,7 +661,7 @@ def __repr__(self) -> str:
661661
return f'<Pedigree id={id(self)}, hash={hash(self)}>'
662662

663663

664-
@serializable.serializable_class
664+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
665665
class Swid:
666666
"""
667667
Our internal representation of the `swidType` complex type.
@@ -813,7 +813,7 @@ def __repr__(self) -> str:
813813
return f'<Swid tagId={self.tag_id}, name={self.name}, version={self.version}>'
814814

815815

816-
@serializable.serializable_class
816+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
817817
class OmniborId(serializable.helpers.BaseHelper):
818818
"""
819819
Helper class that allows us to perform validation on data strings that must conform to
@@ -872,7 +872,7 @@ def __str__(self) -> str:
872872
return self._id
873873

874874

875-
@serializable.serializable_class
875+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
876876
class Swhid(serializable.helpers.BaseHelper):
877877
"""
878878
Helper class that allows us to perform validation on data strings that must conform to
@@ -931,7 +931,7 @@ def __str__(self) -> str:
931931
return self._id
932932

933933

934-
@serializable.serializable_class
934+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
935935
class Component(Dependable):
936936
"""
937937
This is our internal representation of a Component within a Bom.

cyclonedx/model/component_evidence.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class AnalysisTechnique(str, Enum):
7575
OTHER = 'other'
7676

7777

78-
@serializable.serializable_class
78+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
7979
class Method:
8080
"""
8181
Represents a method used to extract and/or analyze evidence.
@@ -181,7 +181,7 @@ def xml_denormalize(cls, o: 'XmlElement', *,
181181
return [BomRef(value=t.get('ref')) for t in o]
182182

183183

184-
@serializable.serializable_class
184+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
185185
class Identity:
186186
"""
187187
Our internal representation of the `identityType` complex type.
@@ -288,7 +288,7 @@ def __repr__(self) -> str:
288288
f' methods={self.methods}, tools={self.tools}>'
289289

290290

291-
@serializable.serializable_class
291+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
292292
class Occurrence:
293293
"""
294294
Our internal representation of the `occurrenceType` complex type.
@@ -423,7 +423,7 @@ def __repr__(self) -> str:
423423
return f'<Occurrence location={self.location}, line={self.line}, symbol={self.symbol}>'
424424

425425

426-
@serializable.serializable_class
426+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
427427
class CallStackFrame:
428428
"""
429429
Represents an individual frame in a call stack.
@@ -567,7 +567,7 @@ def __repr__(self) -> str:
567567
f' line={self.line}, column={self.column}, full_filename={self.full_filename}>'
568568

569569

570-
@serializable.serializable_class
570+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
571571
class CallStack:
572572
"""
573573
Our internal representation of the `callStackType` complex type.
@@ -622,7 +622,7 @@ def __repr__(self) -> str:
622622
return f'<CallStack frames={len(self.frames)}>'
623623

624624

625-
@serializable.serializable_class
625+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
626626
class ComponentEvidence:
627627
"""
628628
Our internal representation of the `componentEvidenceType` complex type.

cyclonedx/model/contact.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from .bom_ref import BomRef
3030

3131

32-
@serializable.serializable_class
32+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
3333
class PostalAddress:
3434
"""
3535
This is our internal representation of the `postalAddressType` complex type that can be used in multiple places
@@ -187,7 +187,7 @@ def __repr__(self) -> str:
187187
return f'<PostalAddress bom-ref={self.bom_ref}, street_address={self.street_address}, country={self.country}>'
188188

189189

190-
@serializable.serializable_class
190+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
191191
class OrganizationalContact:
192192
"""
193193
This is our internal representation of the `organizationalContact` complex type that can be used in multiple places
@@ -277,7 +277,7 @@ def __repr__(self) -> str:
277277
return f'<OrganizationalContact name={self.name}, email={self.email}, phone={self.phone}>'
278278

279279

280-
@serializable.serializable_class
280+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
281281
class OrganizationalEntity:
282282
"""
283283
This is our internal representation of the `organizationalEntity` complex type that can be used in multiple places

cyclonedx/model/crypto.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ class CryptoFunction(str, Enum):
263263
UNKNOWN = 'unknown'
264264

265265

266-
@serializable.serializable_class
266+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
267267
class AlgorithmProperties:
268268
"""
269269
This is our internal representation of the cryptoPropertiesType.algorithmProperties ENUM type within the CycloneDX
@@ -514,7 +514,7 @@ def __repr__(self) -> str:
514514
return f'<AlgorithmProperties primitive={self.primitive}, execution_environment={self.execution_environment}>'
515515

516516

517-
@serializable.serializable_class
517+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
518518
class CertificateProperties:
519519
"""
520520
This is our internal representation of the `cryptoPropertiesType.certificateProperties` complex type within
@@ -746,7 +746,7 @@ class RelatedCryptoMaterialState(str, Enum):
746746
SUSPENDED = 'suspended'
747747

748748

749-
@serializable.serializable_class
749+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
750750
class RelatedCryptoMaterialSecuredBy:
751751
"""
752752
This is our internal representation of the `cryptoPropertiesType.relatedCryptoMaterialProperties.securedBy` complex
@@ -817,7 +817,7 @@ def __repr__(self) -> str:
817817
return f'<RelatedCryptoMaterialSecuredBy mechanism={self.mechanism}, algorithm_ref={self.algorithm_ref}>'
818818

819819

820-
@serializable.serializable_class
820+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
821821
class RelatedCryptoMaterialProperties:
822822
"""
823823
This is our internal representation of the `cryptoPropertiesType.relatedCryptoMaterialProperties` complex type
@@ -1086,7 +1086,7 @@ class ProtocolPropertiesType(str, Enum):
10861086
UNKNOWN = 'unknown'
10871087

10881088

1089-
@serializable.serializable_class
1089+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
10901090
class ProtocolPropertiesCipherSuite:
10911091
"""
10921092
This is our internal representation of the `cryptoPropertiesType.protocolProperties.cipherSuites.cipherSuite`
@@ -1179,7 +1179,7 @@ def __repr__(self) -> str:
11791179
return f'<ProtocolPropertiesCipherSuite name={self.name}>'
11801180

11811181

1182-
@serializable.serializable_class
1182+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
11831183
class Ikev2TransformTypes:
11841184
"""
11851185
This is our internal representation of the `cryptoPropertiesType.protocolProperties.ikev2TransformTypes`
@@ -1321,7 +1321,7 @@ def __repr__(self) -> str:
13211321
return f'<Ikev2TransformTypes esn={self.esn}>'
13221322

13231323

1324-
@serializable.serializable_class
1324+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
13251325
class ProtocolProperties:
13261326
"""
13271327
This is our internal representation of the `cryptoPropertiesType.protocolProperties` complex type within
@@ -1447,7 +1447,7 @@ def __repr__(self) -> str:
14471447
return f'<ProtocolProperties type={self.type}, version={self.version}>'
14481448

14491449

1450-
@serializable.serializable_class
1450+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
14511451
class CryptoProperties:
14521452
"""
14531453
This is our internal representation of the `cryptoPropertiesType` complex type within CycloneDX standard.

cyclonedx/model/definition.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
_T_CreId = TypeVar('_T_CreId', bound='CreId')
3636

3737

38-
@serializable.serializable_class
38+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
3939
class CreId(serializable.helpers.BaseHelper):
4040
"""
4141
Helper class that allows us to perform validation on data strings that must conform to
@@ -89,7 +89,7 @@ def __str__(self) -> str:
8989
return self._id
9090

9191

92-
@serializable.serializable_class
92+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
9393
class Requirement:
9494
"""
9595
A requirement comprising a standard.
@@ -282,7 +282,7 @@ def __repr__(self) -> str:
282282
f'title={self.title}, text={self.text}, parent={self.parent}>'
283283

284284

285-
@serializable.serializable_class
285+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
286286
class Level:
287287
"""
288288
Level of compliance for a standard.
@@ -397,7 +397,7 @@ def __repr__(self) -> str:
397397
f'title={self.title}, description={self.description}>'
398398

399399

400-
@serializable.serializable_class
400+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
401401
class Standard:
402402
"""
403403
A standard of regulations, industry or organizational-specific standards, maturity models, best practices,
@@ -574,7 +574,10 @@ def __repr__(self) -> str:
574574
f'description={self.description}, owner={self.owner}>'
575575

576576

577-
@serializable.serializable_class(name='definitions')
577+
@serializable.serializable_class(
578+
name='definitions',
579+
ignore_unknown_during_deserialization=True
580+
)
578581
class Definitions:
579582
"""
580583
The repository for definitions

cyclonedx/model/dependency.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def deserialize(cls, o: Any) -> set['Dependency']:
4747
return dependencies
4848

4949

50-
@serializable.serializable_class
50+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
5151
class Dependency:
5252
"""
5353
Models a Dependency within a BOM.

cyclonedx/model/issue.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class IssueClassification(str, Enum):
3939
SECURITY = 'security'
4040

4141

42-
@serializable.serializable_class
42+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
4343
class IssueTypeSource:
4444
"""
4545
This is our internal representation ofa source within the IssueType complex type that can be used in multiple
@@ -108,7 +108,7 @@ def __repr__(self) -> str:
108108
return f'<IssueTypeSource name={self._name}, url={self.url}>'
109109

110110

111-
@serializable.serializable_class
111+
@serializable.serializable_class(ignore_unknown_during_deserialization=True)
112112
class IssueType:
113113
"""
114114
This is our internal representation of an IssueType complex type that can be used in multiple places within

0 commit comments

Comments
 (0)