Skip to content

Commit

Permalink
only instantiate get_spdx_licensing() once per module
Browse files Browse the repository at this point in the history
this takes quite some time and should be done as few times as possible

Signed-off-by: Armin Tänzer <armin.taenzer@tngtech.com>
  • Loading branch information
armintaenzertng committed Aug 22, 2023
1 parent 1ecc6f6 commit 9d74680
Show file tree
Hide file tree
Showing 17 changed files with 95 additions and 63 deletions.
13 changes: 7 additions & 6 deletions examples/spdx2_document_from_scratch.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
# The document currently does not describe anything. Let's create a package that we can add to it.
# The Package class has quite a few properties (have a look there!),
# but only name, spdx_id and download_location are mandatory in SPDX v2.3.
spdx_licensing = get_spdx_licensing() # this getter takes quite long and should be called as few times as possible
package = Package(
name="package name",
spdx_id="SPDXRef-Package",
Expand All @@ -65,9 +66,9 @@
Checksum(ChecksumAlgorithm.SHA1, "d6a770ba38583ed4bb4525bd96e50461655d2758"),
Checksum(ChecksumAlgorithm.MD5, "624c1abb3664f4b35547e7c73864ad24"),
],
license_concluded=get_spdx_licensing().parse("GPL-2.0-only OR MIT"),
license_info_from_files=[get_spdx_licensing().parse("GPL-2.0-only"), get_spdx_licensing().parse("MIT")],
license_declared=get_spdx_licensing().parse("GPL-2.0-only AND MIT"),
license_concluded=spdx_licensing.parse("GPL-2.0-only OR MIT"),
license_info_from_files=[spdx_licensing.parse("GPL-2.0-only"), spdx_licensing.parse("MIT")],
license_declared=spdx_licensing.parse("GPL-2.0-only AND MIT"),
license_comment="license comment",
copyright_text="Copyright 2022 Jane Doe",
description="package description",
Expand Down Expand Up @@ -100,8 +101,8 @@
Checksum(ChecksumAlgorithm.SHA1, "d6a770ba38583ed4bb4525bd96e50461655d2758"),
Checksum(ChecksumAlgorithm.MD5, "624c1abb3664f4b35547e7c73864ad24"),
],
license_concluded=get_spdx_licensing().parse("MIT"),
license_info_in_file=[get_spdx_licensing().parse("MIT")],
license_concluded=spdx_licensing.parse("MIT"),
license_info_in_file=[spdx_licensing.parse("MIT")],
copyright_text="Copyright 2022 Jane Doe",
)
file2 = File(
Expand All @@ -110,7 +111,7 @@
checksums=[
Checksum(ChecksumAlgorithm.SHA1, "d6a770ba38583ed4bb4525bd96e50461655d2759"),
],
license_concluded=get_spdx_licensing().parse("GPL-2.0-only"),
license_concluded=spdx_licensing.parse("GPL-2.0-only"),
)

# Assuming the package contains those two files, we create two CONTAINS relationships.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from spdx_tools.spdx.model import Document, SpdxNoAssertion, SpdxNone
from spdx_tools.spdx.validation.validation_message import SpdxElementType, ValidationContext, ValidationMessage

spdx_licensing = get_spdx_licensing()


def validate_license_expressions(
license_expressions: List[Union[LicenseExpression, SpdxNoAssertion, SpdxNone]], document: Document, parent_id: str
Expand Down Expand Up @@ -40,7 +42,7 @@ def validate_license_expression(
validation_messages = []
license_ref_ids: List[str] = [license_ref.license_id for license_ref in document.extracted_licensing_info]

for non_spdx_token in get_spdx_licensing().validate(license_expression).invalid_symbols:
for non_spdx_token in spdx_licensing.validate(license_expression).invalid_symbols:
if non_spdx_token not in license_ref_ids:
validation_messages.append(
ValidationMessage(
Expand All @@ -51,14 +53,14 @@ def validate_license_expression(
)

try:
get_spdx_licensing().parse(str(license_expression), validate=True, strict=True)
spdx_licensing.parse(str(license_expression), validate=True, strict=True)
except ExpressionParseError as err:
# This error is raised when an exception symbol is used as a license symbol and vice versa.
# So far, it only catches the first such error in the provided string.
validation_messages.append(ValidationMessage(f"{err}. for license_expression: {license_expression}", context))
except ExpressionError:
# This error is raised for invalid symbols within the license_expression, but it provides only a string of
# these. On the other hand, get_spdx_licensing().validate() gives an actual list of invalid symbols, so this is
# these. On the other hand, spdx_licensing.validate() gives an actual list of invalid symbols, so this is
# handled above.
pass

Expand Down
4 changes: 3 additions & 1 deletion src/spdx_tools/spdx/writer/rdf/license_expression_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from spdx_tools.spdx.model import SpdxNoAssertion, SpdxNone
from spdx_tools.spdx.rdfschema.namespace import LICENSE_NAMESPACE, SPDX_NAMESPACE

spdx_licensing = get_spdx_licensing()


def add_license_expression_or_none_or_no_assertion(
value: Union[
Expand Down Expand Up @@ -75,7 +77,7 @@ def add_license_expression_to_graph(


def license_or_exception_is_on_spdx_licensing_list(license_symbol: LicenseSymbol) -> bool:
symbol_info: ExpressionInfo = get_spdx_licensing().validate(license_symbol)
symbol_info: ExpressionInfo = spdx_licensing.validate(license_symbol)
return not symbol_info.errors


Expand Down
6 changes: 4 additions & 2 deletions src/spdx_tools/spdx3/bump_from_spdx2/license_expression.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
)
from spdx_tools.spdx.model import ExtractedLicensingInfo, SpdxNoAssertion, SpdxNone

spdx_licensing = get_spdx_licensing()


def bump_license_expression_or_none_or_no_assertion(
element: Union[LicenseExpression, SpdxNoAssertion, SpdxNone],
Expand Down Expand Up @@ -61,7 +63,7 @@ def bump_license_expression(
subject_addition=bump_license_exception(license_expression.exception_symbol, extracted_licensing_info),
)
if isinstance(license_expression, LicenseSymbol):
if not get_spdx_licensing().validate(license_expression).invalid_symbols:
if not spdx_licensing.validate(license_expression).invalid_symbols:
return ListedLicense(license_expression.key, license_expression.obj, "blank")
else:
for licensing_info in extracted_licensing_info:
Expand All @@ -80,7 +82,7 @@ def bump_license_expression(
def bump_license_exception(
license_exception: LicenseSymbol, extracted_licensing_info: List[ExtractedLicensingInfo]
) -> LicenseAddition:
if not get_spdx_licensing().validate(license_exception).invalid_symbols:
if not spdx_licensing.validate(license_exception).invalid_symbols:
return ListedLicenseException(license_exception.key, "", "")
else:
for licensing_info in extracted_licensing_info:
Expand Down
13 changes: 7 additions & 6 deletions tests/spdx/examples/test_spdx2_document_from_scratch.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def test_spdx2_document_from_scratch():
# The document currently does not describe anything. Let's create a package that we can add to it.
# The Package class has quite a few properties (have a look there!),
# but only name, spdx_id and download_location are mandatory in SPDX v2.3.
spdx_licensing = get_spdx_licensing() # this getter takes quite long and should be called as few times as possible
package = Package(
name="package name",
spdx_id="SPDXRef-Package",
Expand All @@ -67,9 +68,9 @@ def test_spdx2_document_from_scratch():
Checksum(ChecksumAlgorithm.SHA1, "d6a770ba38583ed4bb4525bd96e50461655d2758"),
Checksum(ChecksumAlgorithm.MD5, "624c1abb3664f4b35547e7c73864ad24"),
],
license_concluded=get_spdx_licensing().parse("GPL-2.0-only OR MIT"),
license_info_from_files=[get_spdx_licensing().parse("GPL-2.0-only"), get_spdx_licensing().parse("MIT")],
license_declared=get_spdx_licensing().parse("GPL-2.0-only AND MIT"),
license_concluded=spdx_licensing.parse("GPL-2.0-only OR MIT"),
license_info_from_files=[spdx_licensing.parse("GPL-2.0-only"), spdx_licensing.parse("MIT")],
license_declared=spdx_licensing.parse("GPL-2.0-only AND MIT"),
license_comment="license comment",
copyright_text="Copyright 2022 Jane Doe",
description="package description",
Expand Down Expand Up @@ -102,8 +103,8 @@ def test_spdx2_document_from_scratch():
Checksum(ChecksumAlgorithm.SHA1, "d6a770ba38583ed4bb4525bd96e50461655d2758"),
Checksum(ChecksumAlgorithm.MD5, "624c1abb3664f4b35547e7c73864ad24"),
],
license_concluded=get_spdx_licensing().parse("MIT"),
license_info_in_file=[get_spdx_licensing().parse("MIT")],
license_concluded=spdx_licensing.parse("MIT"),
license_info_in_file=[spdx_licensing.parse("MIT")],
copyright_text="Copyright 2022 Jane Doe",
)
file2 = File(
Expand All @@ -112,7 +113,7 @@ def test_spdx2_document_from_scratch():
checksums=[
Checksum(ChecksumAlgorithm.SHA1, "d6a770ba38583ed4bb4525bd96e50461655d2759"),
],
license_concluded=get_spdx_licensing().parse("GPL-2.0-only"),
license_concluded=spdx_licensing.parse("GPL-2.0-only"),
)

# Assuming the package contains those two files, we create two CONTAINS relationships.
Expand Down
17 changes: 10 additions & 7 deletions tests/spdx/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
Version,
)

spdx_licensing = get_spdx_licensing()


# Utility methods to create data model instances. All properties have valid defaults, so they don't need to be
# specified unless relevant for the test.

Expand Down Expand Up @@ -88,7 +91,7 @@ def file_fixture(
spdx_id="SPDXRef-File",
checksums=None,
file_types=None,
license_concluded=get_spdx_licensing().parse("MIT and GPL-2.0"),
license_concluded=spdx_licensing.parse("MIT and GPL-2.0"),
license_info_in_file=None,
license_comment="licenseComment",
copyright_text="copyrightText",
Expand All @@ -100,7 +103,7 @@ def file_fixture(
checksums = [checksum_fixture()] if checksums is None else checksums
file_types = [FileType.TEXT] if file_types is None else file_types
license_info_in_file = (
[get_spdx_licensing().parse("MIT"), get_spdx_licensing().parse("GPL-2.0"), SpdxNoAssertion()]
[spdx_licensing.parse("MIT"), spdx_licensing.parse("GPL-2.0"), SpdxNoAssertion()]
if license_info_in_file is None
else license_info_in_file
)
Expand Down Expand Up @@ -135,9 +138,9 @@ def package_fixture(
checksums=None,
homepage="https://homepage.com",
source_info="sourceInfo",
license_concluded=get_spdx_licensing().parse("MIT and GPL-2.0"),
license_concluded=spdx_licensing.parse("MIT and GPL-2.0"),
license_info_from_files=None,
license_declared=get_spdx_licensing().parse("MIT and GPL-2.0"),
license_declared=spdx_licensing.parse("MIT and GPL-2.0"),
license_comment="packageLicenseComment",
copyright_text="packageCopyrightText",
summary="packageSummary",
Expand All @@ -152,7 +155,7 @@ def package_fixture(
) -> Package:
checksums = [checksum_fixture()] if checksums is None else checksums
license_info_from_files = (
[get_spdx_licensing().parse("MIT"), get_spdx_licensing().parse("GPL-2.0"), SpdxNoAssertion()]
[spdx_licensing.parse("MIT"), spdx_licensing.parse("GPL-2.0"), SpdxNoAssertion()]
if license_info_from_files is None
else license_info_from_files
)
Expand Down Expand Up @@ -208,7 +211,7 @@ def snippet_fixture(
file_spdx_id="SPDXRef-File",
byte_range=(1, 2),
line_range=(3, 4),
license_concluded=get_spdx_licensing().parse("MIT and GPL-2.0"),
license_concluded=spdx_licensing.parse("MIT and GPL-2.0"),
license_info_in_snippet=None,
license_comment="snippetLicenseComment",
copyright_text="licenseCopyrightText",
Expand All @@ -217,7 +220,7 @@ def snippet_fixture(
attribution_texts=None,
) -> Snippet:
license_info_in_snippet = (
[get_spdx_licensing().parse("MIT"), get_spdx_licensing().parse("GPL-2.0"), SpdxNone()]
[spdx_licensing.parse("MIT"), spdx_licensing.parse("GPL-2.0"), SpdxNone()]
if license_info_in_snippet is None
else license_info_in_snippet
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
from spdx_tools.spdx.parser.error import SPDXParsingError
from spdx_tools.spdx.parser.jsonlikedict.license_expression_parser import LicenseExpressionParser

spdx_licensing = get_spdx_licensing()


@pytest.mark.parametrize(
"license_expression_str, expected_license",
[
("First License", get_spdx_licensing().parse("First License")),
("Second License", get_spdx_licensing().parse("Second License")),
("First License", spdx_licensing.parse("First License")),
("Second License", spdx_licensing.parse("Second License")),
("NOASSERTION", SpdxNoAssertion()),
("NONE", SpdxNone()),
],
Expand Down
6 changes: 4 additions & 2 deletions tests/spdx/parser/rdf/test_file_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from spdx_tools.spdx.parser.rdf.file_parser import parse_file
from spdx_tools.spdx.rdfschema.namespace import SPDX_NAMESPACE

spdx_licensing = get_spdx_licensing()


def test_parse_file():
graph = Graph().parse(os.path.join(os.path.dirname(__file__), "data/file_to_test_rdf_parser.rdf.xml"))
Expand All @@ -29,10 +31,10 @@ def test_parse_file():
assert file.comment == "fileComment"
assert file.copyright_text == "copyrightText"
assert file.contributors == ["fileContributor"]
assert file.license_concluded == get_spdx_licensing().parse("MIT AND GPL-2.0")
assert file.license_concluded == spdx_licensing.parse("MIT AND GPL-2.0")
TestCase().assertCountEqual(
file.license_info_in_file,
[get_spdx_licensing().parse("MIT"), get_spdx_licensing().parse("GPL-2.0"), SpdxNoAssertion()],
[spdx_licensing.parse("MIT"), spdx_licensing.parse("GPL-2.0"), SpdxNoAssertion()],
)
assert file.license_comment == "licenseComment"
assert file.notice == "fileNotice"
Expand Down
16 changes: 9 additions & 7 deletions tests/spdx/parser/rdf/test_license_expression_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from spdx_tools.spdx.parser.rdf.license_expression_parser import parse_license_expression
from spdx_tools.spdx.rdfschema.namespace import SPDX_NAMESPACE

spdx_licensing = get_spdx_licensing()


def test_license_expression_parser():
graph = Graph().parse(os.path.join(os.path.dirname(__file__), "data/file_to_test_rdf_parser.rdf.xml"))
Expand All @@ -19,7 +21,7 @@ def test_license_expression_parser():

license_expression = parse_license_expression(license_expression_node, graph, "https://some.namespace#")

assert license_expression == get_spdx_licensing().parse("GPL-2.0 AND MIT")
assert license_expression == spdx_licensing.parse("GPL-2.0 AND MIT")


def test_license_expression_parser_with_coupled_licenses():
Expand All @@ -30,19 +32,19 @@ def test_license_expression_parser_with_coupled_licenses():
packages_by_spdx_id = {package.spdx_id: package for package in doc.packages}
files_by_spdx_id = {file.spdx_id: file for file in doc.files}

assert packages_by_spdx_id["SPDXRef-Package"].license_declared == get_spdx_licensing().parse(
assert packages_by_spdx_id["SPDXRef-Package"].license_declared == spdx_licensing.parse(
"LGPL-2.0-only AND LicenseRef-3"
)
assert packages_by_spdx_id["SPDXRef-Package"].license_concluded == get_spdx_licensing().parse(
assert packages_by_spdx_id["SPDXRef-Package"].license_concluded == spdx_licensing.parse(
"LGPL-2.0-only OR LicenseRef-3"
)
TestCase().assertCountEqual(
packages_by_spdx_id["SPDXRef-Package"].license_info_from_files,
[
get_spdx_licensing().parse("GPL-2.0"),
get_spdx_licensing().parse("LicenseRef-1"),
get_spdx_licensing().parse("LicenseRef-2"),
spdx_licensing.parse("GPL-2.0"),
spdx_licensing.parse("LicenseRef-1"),
spdx_licensing.parse("LicenseRef-2"),
],
)

assert files_by_spdx_id["SPDXRef-JenaLib"].license_concluded == get_spdx_licensing().parse("LicenseRef-1")
assert files_by_spdx_id["SPDXRef-JenaLib"].license_concluded == spdx_licensing.parse("LicenseRef-1")
8 changes: 5 additions & 3 deletions tests/spdx/parser/rdf/test_package_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
from spdx_tools.spdx.parser.rdf.package_parser import parse_external_package_ref, parse_package
from spdx_tools.spdx.rdfschema.namespace import SPDX_NAMESPACE

spdx_licensing = get_spdx_licensing()


def test_package_parser():
graph = Graph().parse(os.path.join(os.path.dirname(__file__), "data/file_to_test_rdf_parser.rdf.xml"))
Expand All @@ -41,11 +43,11 @@ def test_package_parser():
assert package.files_analyzed is True
assert package.checksums == [Checksum(ChecksumAlgorithm.SHA1, "71c4025dd9897b364f3ebbb42c484ff43d00791c")]
assert package.source_info == "sourceInfo"
assert package.license_concluded == get_spdx_licensing().parse("MIT AND GPL-2.0")
assert package.license_declared == get_spdx_licensing().parse("MIT AND GPL-2.0")
assert package.license_concluded == spdx_licensing.parse("MIT AND GPL-2.0")
assert package.license_declared == spdx_licensing.parse("MIT AND GPL-2.0")
TestCase().assertCountEqual(
package.license_info_from_files,
[get_spdx_licensing().parse("MIT"), get_spdx_licensing().parse("GPL-2.0"), SpdxNoAssertion()],
[spdx_licensing.parse("MIT"), spdx_licensing.parse("GPL-2.0"), SpdxNoAssertion()],
)
assert package.license_comment == "packageLicenseComment"
assert package.copyright_text == "packageCopyrightText"
Expand Down
6 changes: 4 additions & 2 deletions tests/spdx/parser/rdf/test_snippet_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from spdx_tools.spdx.parser.rdf.snippet_parser import parse_ranges, parse_snippet
from spdx_tools.spdx.rdfschema.namespace import POINTER_NAMESPACE, SPDX_NAMESPACE

spdx_licensing = get_spdx_licensing()


def test_parse_snippet():
graph = Graph().parse(os.path.join(os.path.dirname(__file__), "data/file_to_test_rdf_parser.rdf.xml"))
Expand All @@ -26,10 +28,10 @@ def test_parse_snippet():
assert snippet.file_spdx_id == "SPDXRef-File"
assert snippet.byte_range == (1, 2)
assert snippet.line_range == (3, 4)
assert snippet.license_concluded == get_spdx_licensing().parse("MIT AND GPL-2.0")
assert snippet.license_concluded == spdx_licensing.parse("MIT AND GPL-2.0")
TestCase().assertCountEqual(
snippet.license_info_in_snippet,
[get_spdx_licensing().parse("MIT"), get_spdx_licensing().parse("GPL-2.0"), SpdxNoAssertion()],
[spdx_licensing.parse("MIT"), spdx_licensing.parse("GPL-2.0"), SpdxNoAssertion()],
)
assert snippet.license_comment == "snippetLicenseComment"
assert snippet.copyright_text == "licenseCopyrightText"
Expand Down
6 changes: 4 additions & 2 deletions tests/spdx/parser/tagvalue/test_file_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from spdx_tools.spdx.parser.tagvalue.parser import Parser
from tests.spdx.parser.tagvalue.test_creation_info_parser import DOCUMENT_STR

spdx_licensing = get_spdx_licensing()


def test_parse_file():
parser = Parser()
Expand Down Expand Up @@ -39,8 +41,8 @@ def test_parse_file():
assert spdx_file.attribution_texts == [
"Acknowledgements that might be required to be communicated in some contexts."
]
assert spdx_file.license_info_in_file == [get_spdx_licensing().parse("Apache-2.0"), SpdxNoAssertion()]
assert spdx_file.license_concluded == get_spdx_licensing().parse("Apache-2.0")
assert spdx_file.license_info_in_file == [spdx_licensing.parse("Apache-2.0"), SpdxNoAssertion()]
assert spdx_file.license_concluded == spdx_licensing.parse("Apache-2.0")


def test_parse_invalid_file():
Expand Down
6 changes: 4 additions & 2 deletions tests/spdx/parser/tagvalue/test_package_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from spdx_tools.spdx.parser.tagvalue.parser import Parser
from tests.spdx.parser.tagvalue.test_creation_info_parser import DOCUMENT_STR

spdx_licensing = get_spdx_licensing()


def test_parse_package():
parser = Parser()
Expand Down Expand Up @@ -57,9 +59,9 @@ def test_parse_package():
assert len(package.license_info_from_files) == 3
TestCase().assertCountEqual(
package.license_info_from_files,
[get_spdx_licensing().parse("Apache-1.0"), get_spdx_licensing().parse("Apache-2.0"), SpdxNone()],
[spdx_licensing.parse("Apache-1.0"), spdx_licensing.parse("Apache-2.0"), SpdxNone()],
)
assert package.license_concluded == get_spdx_licensing().parse("LicenseRef-2.0 AND Apache-2.0")
assert package.license_concluded == spdx_licensing.parse("LicenseRef-2.0 AND Apache-2.0")
assert package.files_analyzed is True
assert package.comment == "Comment on the package."
assert len(package.external_references) == 2
Expand Down
Loading

0 comments on commit 9d74680

Please sign in to comment.