spdx_tools.spdx.parser.jsonlikedict.package_parser

  1# SPDX-FileCopyrightText: 2022 spdx contributors
  2#
  3# SPDX-License-Identifier: Apache-2.0
  4from datetime import datetime
  5
  6from beartype.typing import Dict, List, Optional, Union
  7from license_expression import LicenseExpression
  8
  9from spdx_tools.spdx.datetime_conversions import datetime_from_str
 10from spdx_tools.spdx.model import (
 11    Actor,
 12    ExternalPackageRef,
 13    ExternalPackageRefCategory,
 14    Package,
 15    PackagePurpose,
 16    PackageVerificationCode,
 17    SpdxNoAssertion,
 18    SpdxNone,
 19)
 20from spdx_tools.spdx.parser.actor_parser import ActorParser
 21from spdx_tools.spdx.parser.error import SPDXParsingError
 22from spdx_tools.spdx.parser.jsonlikedict.checksum_parser import ChecksumParser
 23from spdx_tools.spdx.parser.jsonlikedict.dict_parsing_functions import (
 24    append_parsed_field_or_log_error,
 25    json_str_to_enum_name,
 26    parse_field_or_log_error,
 27    parse_field_or_no_assertion,
 28    parse_field_or_no_assertion_or_none,
 29)
 30from spdx_tools.spdx.parser.jsonlikedict.license_expression_parser import LicenseExpressionParser
 31from spdx_tools.spdx.parser.logger import Logger
 32from spdx_tools.spdx.parser.parsing_functions import (
 33    construct_or_raise_parsing_error,
 34    raise_parsing_error_if_logger_has_messages,
 35)
 36
 37
 38class PackageParser:
 39    logger: Logger
 40    actor_parser: ActorParser
 41    checksum_parser: ChecksumParser
 42    license_expression_parser: LicenseExpressionParser
 43
 44    def __init__(self):
 45        self.actor_parser = ActorParser()
 46        self.checksum_parser = ChecksumParser()
 47        self.license_expression_parser = LicenseExpressionParser()
 48        self.logger = Logger()
 49
 50    def parse_package(self, package_dict: Dict) -> Package:
 51        logger = Logger()
 52        name: Optional[str] = package_dict.get("name")
 53        spdx_id: Optional[str] = package_dict.get("SPDXID")
 54        attribution_texts: List[str] = package_dict.get("attributionTexts", [])
 55
 56        built_date: Optional[datetime] = parse_field_or_log_error(
 57            logger, package_dict.get("builtDate"), datetime_from_str
 58        )
 59
 60        checksums = parse_field_or_log_error(
 61            logger, package_dict.get("checksums"), self.checksum_parser.parse_checksum, field_is_list=True
 62        )
 63        comment: Optional[str] = package_dict.get("comment")
 64        copyright_text: Optional[Union[str, SpdxNoAssertion, SpdxNone]] = parse_field_or_no_assertion_or_none(
 65            package_dict.get("copyrightText")
 66        )
 67        description: Optional[str] = package_dict.get("description")
 68        download_location: Optional[Union[str, SpdxNoAssertion, SpdxNone]] = parse_field_or_no_assertion_or_none(
 69            package_dict.get("downloadLocation")
 70        )
 71
 72        external_refs: List[ExternalPackageRef] = parse_field_or_log_error(
 73            logger, package_dict.get("externalRefs"), self.parse_external_refs
 74        )
 75
 76        files_analyzed: Optional[Union[bool, str]] = package_dict.get("filesAnalyzed")
 77
 78        if files_analyzed is None:  # default value is True
 79            files_analyzed = True
 80        elif isinstance(files_analyzed, str):  # XML does not support boolean typed values
 81            if files_analyzed.lower() == "true":
 82                files_analyzed = True
 83            elif files_analyzed.lower() == "false":
 84                files_analyzed = False
 85
 86        homepage: Optional[Union[str, SpdxNoAssertion, SpdxNone]] = parse_field_or_no_assertion_or_none(
 87            package_dict.get("homepage")
 88        )
 89        license_comments: Optional[str] = package_dict.get("licenseComments")
 90        license_concluded = parse_field_or_log_error(
 91            logger, package_dict.get("licenseConcluded"), self.license_expression_parser.parse_license_expression
 92        )
 93
 94        license_declared: Optional[Union[LicenseExpression, SpdxNoAssertion, SpdxNone]] = parse_field_or_log_error(
 95            logger, package_dict.get("licenseDeclared"), self.license_expression_parser.parse_license_expression
 96        )
 97
 98        license_info_from_file: List[Union[LicenseExpression, SpdxNoAssertion, SpdxNone]] = parse_field_or_log_error(
 99            logger,
100            package_dict.get("licenseInfoFromFiles"),
101            self.license_expression_parser.parse_license_expression,
102            field_is_list=True,
103        )
104        originator: Optional[Union[Actor, SpdxNoAssertion]] = parse_field_or_log_error(
105            logger,
106            package_dict.get("originator"),
107            lambda x: parse_field_or_no_assertion(x, self.actor_parser.parse_actor),
108        )
109        package_file_name: Optional[str] = package_dict.get("packageFileName")
110
111        package_verification_code: Optional[PackageVerificationCode] = parse_field_or_log_error(
112            logger, package_dict.get("packageVerificationCode"), self.parse_package_verification_code
113        )
114        primary_package_purpose: Optional[PackagePurpose] = parse_field_or_log_error(
115            logger, package_dict.get("primaryPackagePurpose"), self.parse_primary_package_purpose
116        )
117
118        release_date: Optional[datetime] = parse_field_or_log_error(
119            logger, package_dict.get("releaseDate"), datetime_from_str
120        )
121        source_info: Optional[str] = package_dict.get("sourceInfo")
122        summary: Optional[str] = package_dict.get("summary")
123        supplier: Optional[Union[Actor, SpdxNoAssertion]] = parse_field_or_log_error(
124            logger,
125            package_dict.get("supplier"),
126            lambda x: parse_field_or_no_assertion(x, self.actor_parser.parse_actor),
127        )
128        valid_until_date: Optional[datetime] = parse_field_or_log_error(
129            logger, package_dict.get("validUntilDate"), datetime_from_str
130        )
131
132        version_info: Optional[str] = package_dict.get("versionInfo")
133        raise_parsing_error_if_logger_has_messages(logger, "Package")
134
135        package = construct_or_raise_parsing_error(
136            Package,
137            dict(
138                spdx_id=spdx_id,
139                name=name,
140                download_location=download_location,
141                version=version_info,
142                file_name=package_file_name,
143                supplier=supplier,
144                originator=originator,
145                files_analyzed=files_analyzed,
146                verification_code=package_verification_code,
147                checksums=checksums,
148                homepage=homepage,
149                source_info=source_info,
150                license_concluded=license_concluded,
151                license_info_from_files=license_info_from_file,
152                license_declared=license_declared,
153                license_comment=license_comments,
154                copyright_text=copyright_text,
155                summary=summary,
156                description=description,
157                comment=comment,
158                external_references=external_refs,
159                attribution_texts=attribution_texts,
160                primary_package_purpose=primary_package_purpose,
161                release_date=release_date,
162                built_date=built_date,
163                valid_until_date=valid_until_date,
164            ),
165        )
166
167        return package
168
169    def parse_external_refs(self, external_ref_dicts: List[Dict]) -> List[ExternalPackageRef]:
170        external_refs = []
171        for external_ref_dict in external_ref_dicts:
172            external_refs = append_parsed_field_or_log_error(
173                self.logger, external_refs, external_ref_dict, self.parse_external_ref
174            )
175        return external_refs
176
177    def parse_external_ref(self, external_ref_dict: Dict) -> ExternalPackageRef:
178        logger = Logger()
179        ref_category = parse_field_or_log_error(
180            logger, external_ref_dict.get("referenceCategory"), self.parse_external_ref_category
181        )
182        ref_locator: Optional[str] = external_ref_dict.get("referenceLocator")
183        ref_type: Optional[str] = external_ref_dict.get("referenceType")
184        comment: Optional[str] = external_ref_dict.get("comment")
185        raise_parsing_error_if_logger_has_messages(logger, "ExternalPackageRef")
186        external_ref = construct_or_raise_parsing_error(
187            ExternalPackageRef,
188            dict(category=ref_category, reference_type=ref_type, locator=ref_locator, comment=comment),
189        )
190
191        return external_ref
192
193    @staticmethod
194    def parse_external_ref_category(external_ref_category_str: str) -> ExternalPackageRefCategory:
195        try:
196            external_ref_category = ExternalPackageRefCategory[json_str_to_enum_name(external_ref_category_str)]
197        except KeyError:
198            raise SPDXParsingError([f"Invalid ExternalPackageRefCategory: {external_ref_category_str}"])
199
200        return external_ref_category
201
202    @staticmethod
203    def parse_package_verification_code(verification_code_dict: Dict) -> PackageVerificationCode:
204        excluded_files: List[str] = verification_code_dict.get("packageVerificationCodeExcludedFiles", [])
205        verification_code_value: Optional[str] = verification_code_dict.get("packageVerificationCodeValue")
206
207        package_verification_code = construct_or_raise_parsing_error(
208            PackageVerificationCode, dict(value=verification_code_value, excluded_files=excluded_files)
209        )
210
211        return package_verification_code
212
213    @staticmethod
214    def parse_primary_package_purpose(primary_package_purpose: str) -> PackagePurpose:
215        try:
216            return PackagePurpose[json_str_to_enum_name(primary_package_purpose)]
217        except KeyError:
218            raise SPDXParsingError([f"Invalid PrimaryPackagePurpose: {primary_package_purpose}"])
class PackageParser:
 39class PackageParser:
 40    logger: Logger
 41    actor_parser: ActorParser
 42    checksum_parser: ChecksumParser
 43    license_expression_parser: LicenseExpressionParser
 44
 45    def __init__(self):
 46        self.actor_parser = ActorParser()
 47        self.checksum_parser = ChecksumParser()
 48        self.license_expression_parser = LicenseExpressionParser()
 49        self.logger = Logger()
 50
 51    def parse_package(self, package_dict: Dict) -> Package:
 52        logger = Logger()
 53        name: Optional[str] = package_dict.get("name")
 54        spdx_id: Optional[str] = package_dict.get("SPDXID")
 55        attribution_texts: List[str] = package_dict.get("attributionTexts", [])
 56
 57        built_date: Optional[datetime] = parse_field_or_log_error(
 58            logger, package_dict.get("builtDate"), datetime_from_str
 59        )
 60
 61        checksums = parse_field_or_log_error(
 62            logger, package_dict.get("checksums"), self.checksum_parser.parse_checksum, field_is_list=True
 63        )
 64        comment: Optional[str] = package_dict.get("comment")
 65        copyright_text: Optional[Union[str, SpdxNoAssertion, SpdxNone]] = parse_field_or_no_assertion_or_none(
 66            package_dict.get("copyrightText")
 67        )
 68        description: Optional[str] = package_dict.get("description")
 69        download_location: Optional[Union[str, SpdxNoAssertion, SpdxNone]] = parse_field_or_no_assertion_or_none(
 70            package_dict.get("downloadLocation")
 71        )
 72
 73        external_refs: List[ExternalPackageRef] = parse_field_or_log_error(
 74            logger, package_dict.get("externalRefs"), self.parse_external_refs
 75        )
 76
 77        files_analyzed: Optional[Union[bool, str]] = package_dict.get("filesAnalyzed")
 78
 79        if files_analyzed is None:  # default value is True
 80            files_analyzed = True
 81        elif isinstance(files_analyzed, str):  # XML does not support boolean typed values
 82            if files_analyzed.lower() == "true":
 83                files_analyzed = True
 84            elif files_analyzed.lower() == "false":
 85                files_analyzed = False
 86
 87        homepage: Optional[Union[str, SpdxNoAssertion, SpdxNone]] = parse_field_or_no_assertion_or_none(
 88            package_dict.get("homepage")
 89        )
 90        license_comments: Optional[str] = package_dict.get("licenseComments")
 91        license_concluded = parse_field_or_log_error(
 92            logger, package_dict.get("licenseConcluded"), self.license_expression_parser.parse_license_expression
 93        )
 94
 95        license_declared: Optional[Union[LicenseExpression, SpdxNoAssertion, SpdxNone]] = parse_field_or_log_error(
 96            logger, package_dict.get("licenseDeclared"), self.license_expression_parser.parse_license_expression
 97        )
 98
 99        license_info_from_file: List[Union[LicenseExpression, SpdxNoAssertion, SpdxNone]] = parse_field_or_log_error(
100            logger,
101            package_dict.get("licenseInfoFromFiles"),
102            self.license_expression_parser.parse_license_expression,
103            field_is_list=True,
104        )
105        originator: Optional[Union[Actor, SpdxNoAssertion]] = parse_field_or_log_error(
106            logger,
107            package_dict.get("originator"),
108            lambda x: parse_field_or_no_assertion(x, self.actor_parser.parse_actor),
109        )
110        package_file_name: Optional[str] = package_dict.get("packageFileName")
111
112        package_verification_code: Optional[PackageVerificationCode] = parse_field_or_log_error(
113            logger, package_dict.get("packageVerificationCode"), self.parse_package_verification_code
114        )
115        primary_package_purpose: Optional[PackagePurpose] = parse_field_or_log_error(
116            logger, package_dict.get("primaryPackagePurpose"), self.parse_primary_package_purpose
117        )
118
119        release_date: Optional[datetime] = parse_field_or_log_error(
120            logger, package_dict.get("releaseDate"), datetime_from_str
121        )
122        source_info: Optional[str] = package_dict.get("sourceInfo")
123        summary: Optional[str] = package_dict.get("summary")
124        supplier: Optional[Union[Actor, SpdxNoAssertion]] = parse_field_or_log_error(
125            logger,
126            package_dict.get("supplier"),
127            lambda x: parse_field_or_no_assertion(x, self.actor_parser.parse_actor),
128        )
129        valid_until_date: Optional[datetime] = parse_field_or_log_error(
130            logger, package_dict.get("validUntilDate"), datetime_from_str
131        )
132
133        version_info: Optional[str] = package_dict.get("versionInfo")
134        raise_parsing_error_if_logger_has_messages(logger, "Package")
135
136        package = construct_or_raise_parsing_error(
137            Package,
138            dict(
139                spdx_id=spdx_id,
140                name=name,
141                download_location=download_location,
142                version=version_info,
143                file_name=package_file_name,
144                supplier=supplier,
145                originator=originator,
146                files_analyzed=files_analyzed,
147                verification_code=package_verification_code,
148                checksums=checksums,
149                homepage=homepage,
150                source_info=source_info,
151                license_concluded=license_concluded,
152                license_info_from_files=license_info_from_file,
153                license_declared=license_declared,
154                license_comment=license_comments,
155                copyright_text=copyright_text,
156                summary=summary,
157                description=description,
158                comment=comment,
159                external_references=external_refs,
160                attribution_texts=attribution_texts,
161                primary_package_purpose=primary_package_purpose,
162                release_date=release_date,
163                built_date=built_date,
164                valid_until_date=valid_until_date,
165            ),
166        )
167
168        return package
169
170    def parse_external_refs(self, external_ref_dicts: List[Dict]) -> List[ExternalPackageRef]:
171        external_refs = []
172        for external_ref_dict in external_ref_dicts:
173            external_refs = append_parsed_field_or_log_error(
174                self.logger, external_refs, external_ref_dict, self.parse_external_ref
175            )
176        return external_refs
177
178    def parse_external_ref(self, external_ref_dict: Dict) -> ExternalPackageRef:
179        logger = Logger()
180        ref_category = parse_field_or_log_error(
181            logger, external_ref_dict.get("referenceCategory"), self.parse_external_ref_category
182        )
183        ref_locator: Optional[str] = external_ref_dict.get("referenceLocator")
184        ref_type: Optional[str] = external_ref_dict.get("referenceType")
185        comment: Optional[str] = external_ref_dict.get("comment")
186        raise_parsing_error_if_logger_has_messages(logger, "ExternalPackageRef")
187        external_ref = construct_or_raise_parsing_error(
188            ExternalPackageRef,
189            dict(category=ref_category, reference_type=ref_type, locator=ref_locator, comment=comment),
190        )
191
192        return external_ref
193
194    @staticmethod
195    def parse_external_ref_category(external_ref_category_str: str) -> ExternalPackageRefCategory:
196        try:
197            external_ref_category = ExternalPackageRefCategory[json_str_to_enum_name(external_ref_category_str)]
198        except KeyError:
199            raise SPDXParsingError([f"Invalid ExternalPackageRefCategory: {external_ref_category_str}"])
200
201        return external_ref_category
202
203    @staticmethod
204    def parse_package_verification_code(verification_code_dict: Dict) -> PackageVerificationCode:
205        excluded_files: List[str] = verification_code_dict.get("packageVerificationCodeExcludedFiles", [])
206        verification_code_value: Optional[str] = verification_code_dict.get("packageVerificationCodeValue")
207
208        package_verification_code = construct_or_raise_parsing_error(
209            PackageVerificationCode, dict(value=verification_code_value, excluded_files=excluded_files)
210        )
211
212        return package_verification_code
213
214    @staticmethod
215    def parse_primary_package_purpose(primary_package_purpose: str) -> PackagePurpose:
216        try:
217            return PackagePurpose[json_str_to_enum_name(primary_package_purpose)]
218        except KeyError:
219            raise SPDXParsingError([f"Invalid PrimaryPackagePurpose: {primary_package_purpose}"])
def parse_package(self, package_dict: dict) -> spdx_tools.spdx.model.package.Package:
 51    def parse_package(self, package_dict: Dict) -> Package:
 52        logger = Logger()
 53        name: Optional[str] = package_dict.get("name")
 54        spdx_id: Optional[str] = package_dict.get("SPDXID")
 55        attribution_texts: List[str] = package_dict.get("attributionTexts", [])
 56
 57        built_date: Optional[datetime] = parse_field_or_log_error(
 58            logger, package_dict.get("builtDate"), datetime_from_str
 59        )
 60
 61        checksums = parse_field_or_log_error(
 62            logger, package_dict.get("checksums"), self.checksum_parser.parse_checksum, field_is_list=True
 63        )
 64        comment: Optional[str] = package_dict.get("comment")
 65        copyright_text: Optional[Union[str, SpdxNoAssertion, SpdxNone]] = parse_field_or_no_assertion_or_none(
 66            package_dict.get("copyrightText")
 67        )
 68        description: Optional[str] = package_dict.get("description")
 69        download_location: Optional[Union[str, SpdxNoAssertion, SpdxNone]] = parse_field_or_no_assertion_or_none(
 70            package_dict.get("downloadLocation")
 71        )
 72
 73        external_refs: List[ExternalPackageRef] = parse_field_or_log_error(
 74            logger, package_dict.get("externalRefs"), self.parse_external_refs
 75        )
 76
 77        files_analyzed: Optional[Union[bool, str]] = package_dict.get("filesAnalyzed")
 78
 79        if files_analyzed is None:  # default value is True
 80            files_analyzed = True
 81        elif isinstance(files_analyzed, str):  # XML does not support boolean typed values
 82            if files_analyzed.lower() == "true":
 83                files_analyzed = True
 84            elif files_analyzed.lower() == "false":
 85                files_analyzed = False
 86
 87        homepage: Optional[Union[str, SpdxNoAssertion, SpdxNone]] = parse_field_or_no_assertion_or_none(
 88            package_dict.get("homepage")
 89        )
 90        license_comments: Optional[str] = package_dict.get("licenseComments")
 91        license_concluded = parse_field_or_log_error(
 92            logger, package_dict.get("licenseConcluded"), self.license_expression_parser.parse_license_expression
 93        )
 94
 95        license_declared: Optional[Union[LicenseExpression, SpdxNoAssertion, SpdxNone]] = parse_field_or_log_error(
 96            logger, package_dict.get("licenseDeclared"), self.license_expression_parser.parse_license_expression
 97        )
 98
 99        license_info_from_file: List[Union[LicenseExpression, SpdxNoAssertion, SpdxNone]] = parse_field_or_log_error(
100            logger,
101            package_dict.get("licenseInfoFromFiles"),
102            self.license_expression_parser.parse_license_expression,
103            field_is_list=True,
104        )
105        originator: Optional[Union[Actor, SpdxNoAssertion]] = parse_field_or_log_error(
106            logger,
107            package_dict.get("originator"),
108            lambda x: parse_field_or_no_assertion(x, self.actor_parser.parse_actor),
109        )
110        package_file_name: Optional[str] = package_dict.get("packageFileName")
111
112        package_verification_code: Optional[PackageVerificationCode] = parse_field_or_log_error(
113            logger, package_dict.get("packageVerificationCode"), self.parse_package_verification_code
114        )
115        primary_package_purpose: Optional[PackagePurpose] = parse_field_or_log_error(
116            logger, package_dict.get("primaryPackagePurpose"), self.parse_primary_package_purpose
117        )
118
119        release_date: Optional[datetime] = parse_field_or_log_error(
120            logger, package_dict.get("releaseDate"), datetime_from_str
121        )
122        source_info: Optional[str] = package_dict.get("sourceInfo")
123        summary: Optional[str] = package_dict.get("summary")
124        supplier: Optional[Union[Actor, SpdxNoAssertion]] = parse_field_or_log_error(
125            logger,
126            package_dict.get("supplier"),
127            lambda x: parse_field_or_no_assertion(x, self.actor_parser.parse_actor),
128        )
129        valid_until_date: Optional[datetime] = parse_field_or_log_error(
130            logger, package_dict.get("validUntilDate"), datetime_from_str
131        )
132
133        version_info: Optional[str] = package_dict.get("versionInfo")
134        raise_parsing_error_if_logger_has_messages(logger, "Package")
135
136        package = construct_or_raise_parsing_error(
137            Package,
138            dict(
139                spdx_id=spdx_id,
140                name=name,
141                download_location=download_location,
142                version=version_info,
143                file_name=package_file_name,
144                supplier=supplier,
145                originator=originator,
146                files_analyzed=files_analyzed,
147                verification_code=package_verification_code,
148                checksums=checksums,
149                homepage=homepage,
150                source_info=source_info,
151                license_concluded=license_concluded,
152                license_info_from_files=license_info_from_file,
153                license_declared=license_declared,
154                license_comment=license_comments,
155                copyright_text=copyright_text,
156                summary=summary,
157                description=description,
158                comment=comment,
159                external_references=external_refs,
160                attribution_texts=attribution_texts,
161                primary_package_purpose=primary_package_purpose,
162                release_date=release_date,
163                built_date=built_date,
164                valid_until_date=valid_until_date,
165            ),
166        )
167
168        return package
def parse_external_refs( self, external_ref_dicts: list[dict]) -> list[spdx_tools.spdx.model.package.ExternalPackageRef]:
170    def parse_external_refs(self, external_ref_dicts: List[Dict]) -> List[ExternalPackageRef]:
171        external_refs = []
172        for external_ref_dict in external_ref_dicts:
173            external_refs = append_parsed_field_or_log_error(
174                self.logger, external_refs, external_ref_dict, self.parse_external_ref
175            )
176        return external_refs
def parse_external_ref( self, external_ref_dict: dict) -> spdx_tools.spdx.model.package.ExternalPackageRef:
178    def parse_external_ref(self, external_ref_dict: Dict) -> ExternalPackageRef:
179        logger = Logger()
180        ref_category = parse_field_or_log_error(
181            logger, external_ref_dict.get("referenceCategory"), self.parse_external_ref_category
182        )
183        ref_locator: Optional[str] = external_ref_dict.get("referenceLocator")
184        ref_type: Optional[str] = external_ref_dict.get("referenceType")
185        comment: Optional[str] = external_ref_dict.get("comment")
186        raise_parsing_error_if_logger_has_messages(logger, "ExternalPackageRef")
187        external_ref = construct_or_raise_parsing_error(
188            ExternalPackageRef,
189            dict(category=ref_category, reference_type=ref_type, locator=ref_locator, comment=comment),
190        )
191
192        return external_ref
@staticmethod
def parse_external_ref_category( external_ref_category_str: str) -> spdx_tools.spdx.model.package.ExternalPackageRefCategory:
194    @staticmethod
195    def parse_external_ref_category(external_ref_category_str: str) -> ExternalPackageRefCategory:
196        try:
197            external_ref_category = ExternalPackageRefCategory[json_str_to_enum_name(external_ref_category_str)]
198        except KeyError:
199            raise SPDXParsingError([f"Invalid ExternalPackageRefCategory: {external_ref_category_str}"])
200
201        return external_ref_category
@staticmethod
def parse_package_verification_code( verification_code_dict: dict) -> spdx_tools.spdx.model.package.PackageVerificationCode:
203    @staticmethod
204    def parse_package_verification_code(verification_code_dict: Dict) -> PackageVerificationCode:
205        excluded_files: List[str] = verification_code_dict.get("packageVerificationCodeExcludedFiles", [])
206        verification_code_value: Optional[str] = verification_code_dict.get("packageVerificationCodeValue")
207
208        package_verification_code = construct_or_raise_parsing_error(
209            PackageVerificationCode, dict(value=verification_code_value, excluded_files=excluded_files)
210        )
211
212        return package_verification_code
@staticmethod
def parse_primary_package_purpose( primary_package_purpose: str) -> spdx_tools.spdx.model.package.PackagePurpose:
214    @staticmethod
215    def parse_primary_package_purpose(primary_package_purpose: str) -> PackagePurpose:
216        try:
217            return PackagePurpose[json_str_to_enum_name(primary_package_purpose)]
218        except KeyError:
219            raise SPDXParsingError([f"Invalid PrimaryPackagePurpose: {primary_package_purpose}"])