From 1847ecb7e8e8c3d38954d2a9bf9eae793019b898 Mon Sep 17 00:00:00 2001 From: Helio Chissini de Castro Date: Thu, 12 Mar 2026 11:48:06 +0100 Subject: [PATCH 1/2] fix(snippets): Move snippet choice classes to match upstream Signed-off-by: Helio Chissini de Castro --- src/ort/models/config/repository_configuration.py | 2 +- src/ort/models/config/{ => snippet}/snippet_choices.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/ort/models/config/{ => snippet}/snippet_choices.py (84%) diff --git a/src/ort/models/config/repository_configuration.py b/src/ort/models/config/repository_configuration.py index d58c7b6..586124c 100644 --- a/src/ort/models/config/repository_configuration.py +++ b/src/ort/models/config/repository_configuration.py @@ -11,7 +11,7 @@ from .package_configuration import PackageConfiguration from .repository_analyzer_configuration import RepositoryAnalyzerConfiguration from .resolutions import Resolutions -from .snippet_choices import SnippetChoices +from .snippet.snippet_choices import SnippetChoices class RepositoryConfiguration(BaseModel): diff --git a/src/ort/models/config/snippet_choices.py b/src/ort/models/config/snippet/snippet_choices.py similarity index 84% rename from src/ort/models/config/snippet_choices.py rename to src/ort/models/config/snippet/snippet_choices.py index 64ddc4f..5d34aa3 100644 --- a/src/ort/models/config/snippet_choices.py +++ b/src/ort/models/config/snippet/snippet_choices.py @@ -3,8 +3,8 @@ from pydantic import BaseModel, ConfigDict, Field -from .snippet.snippet_choice import SnippetChoice -from .snippet.snippet_provenance import SnippetProvenance +from .snippet_choice import SnippetChoice +from .snippet_provenance import SnippetProvenance class SnippetChoices(BaseModel): From 8f53544c7da3b92397b3074a1da2ee8b04b9c522 Mon Sep 17 00:00:00 2001 From: Helio Chissini de Castro Date: Thu, 12 Mar 2026 17:39:09 +0100 Subject: [PATCH 2/2] feat(evaluator): Add support for evaluator result. - Enum conversions are treated by a base class do do proper mapping. - Added a utility to load ort yaml with specialized treatment to invalid entries. - Ort run classes now derive of a common class Signed-off-by: Helio Chissini de Castro --- examples/ort_result.py | 5 +- examples/repo_config.py | 5 +- pyproject.toml | 8 +- src/ort/__init__.py | 3 + src/ort/models/advisor_capability.py | 4 +- src/ort/models/advisor_details.py | 19 +- src/ort/models/advisor_run.py | 24 +- src/ort/models/analyzer_run.py | 23 +- src/ort/models/base_run.py | 28 + src/ort/models/config/issue_resolution.py | 9 +- .../models/config/issue_resolution_reason.py | 4 +- src/ort/models/config/path_exclude.py | 9 +- src/ort/models/config/path_exclude_reason.py | 4 +- src/ort/models/config/path_include.py | 9 +- src/ort/models/config/path_include_reason.py | 4 +- .../models/config/rule_violation_reason.py | 4 +- .../config/rule_violation_resolution.py | 9 +- src/ort/models/config/scope_exclude.py | 8 +- src/ort/models/config/scope_exclude_reason.py | 4 +- .../models/config/snippet/snippet_choice.py | 18 +- .../config/snippet/snippet_choice_reason.py | 4 +- .../models/config/vulnerability_resolution.py | 9 +- .../config/vulnerability_resolution_reason.py | 4 +- src/ort/models/dependency_graph_node.py | 12 +- src/ort/models/evaluator_run.py | 19 + src/ort/models/issue.py | 8 +- src/ort/models/license_source.py | 23 + src/ort/models/ort_result.py | 8 +- src/ort/models/package_linkage.py | 4 +- src/ort/models/rule_violation.py | 50 + src/ort/models/severity.py | 23 + src/ort/severity.py | 4 +- src/ort/utils/__init__.py | 11 +- src/ort/utils/convert_enum.py | 18 - src/ort/utils/spdx/spdx_expression.py | 4 +- src/ort/utils/validated_enum.py | 34 + src/ort/utils/yaml_loader.py | 43 + tests/data/evaluation-result.yml | 2567 +++++++++++++++++ tests/test_evaluator_run.py | 212 ++ tests/utils/load_yaml_config.py | 5 +- uv.lock | 171 +- 41 files changed, 3156 insertions(+), 278 deletions(-) create mode 100644 src/ort/models/base_run.py create mode 100644 src/ort/models/evaluator_run.py create mode 100644 src/ort/models/license_source.py create mode 100644 src/ort/models/rule_violation.py create mode 100644 src/ort/models/severity.py delete mode 100644 src/ort/utils/convert_enum.py create mode 100644 src/ort/utils/validated_enum.py create mode 100644 src/ort/utils/yaml_loader.py create mode 100644 tests/data/evaluation-result.yml create mode 100644 tests/test_evaluator_run.py diff --git a/examples/ort_result.py b/examples/ort_result.py index cf80bdd..9728440 100644 --- a/examples/ort_result.py +++ b/examples/ort_result.py @@ -6,11 +6,10 @@ from pathlib import Path import click -import yaml from pydantic import ValidationError from rich.pretty import pprint -from ort import OrtResult +from ort import OrtResult, ort_yaml_load logger = logging.getLogger() @@ -26,7 +25,7 @@ def main( ) -> None: try: with Path(datafile).open() as fd: - data = yaml.safe_load(fd) + data = ort_yaml_load(fd) parsed = OrtResult(**data) if analyzer: pprint(parsed.analyzer) diff --git a/examples/repo_config.py b/examples/repo_config.py index a6c8083..d2f7b58 100644 --- a/examples/repo_config.py +++ b/examples/repo_config.py @@ -6,11 +6,10 @@ from pathlib import Path import click -import yaml from pydantic import ValidationError from rich.pretty import pprint -from ort import RepositoryConfiguration +from ort import RepositoryConfiguration, ort_yaml_load logger = logging.getLogger() @@ -20,7 +19,7 @@ def main(datafile: str) -> None: try: with Path(datafile).open() as fd: - data = yaml.safe_load(fd) + data = ort_yaml_load(fd) parsed = RepositoryConfiguration(**data) pprint(parsed) except ValidationError as e: diff --git a/pyproject.toml b/pyproject.toml index 6b81b8d..9a10fee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "uv_build" [project] name = "python-ort" -version = "0.6.6" +version = "0.7.0" description = "A Python Ort model serialization library" readme = "README.md" license = "MIT" @@ -35,11 +35,11 @@ module-root = "src" [dependency-groups] dev = [ - "datamodel-code-generator[http]>=0.54.0", + "datamodel-code-generator[http]>=0.55.0", "pytest>=9.0.2", "rich>=14.3.3", - "ruff>=0.15.4", - "ty>=0.0.20", + "ruff>=0.15.5", + "ty>=0.0.21", "types-pyyaml>=6.0.12.20250915", ] diff --git a/src/ort/__init__.py b/src/ort/__init__.py index f78d4b8..b6eb503 100644 --- a/src/ort/__init__.py +++ b/src/ort/__init__.py @@ -5,9 +5,12 @@ from .models.analyzer_result import AnalyzerResult from .models.config.repository_configuration import RepositoryConfiguration from .models.ort_result import OrtResult +from .utils.yaml_loader import OrtYamlLoader, ort_yaml_load __all__ = [ "AnalyzerResult", + "OrtYamlLoader", "RepositoryConfiguration", "OrtResult", + "ort_yaml_load", ] diff --git a/src/ort/models/advisor_capability.py b/src/ort/models/advisor_capability.py index dd9d5f5..6d45656 100644 --- a/src/ort/models/advisor_capability.py +++ b/src/ort/models/advisor_capability.py @@ -2,10 +2,10 @@ # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class AdvisorCapability(IntEnum): +class AdvisorCapability(ValidatedIntEnum): """ An enum class that defines the capabilities of a specific advisor implementation. diff --git a/src/ort/models/advisor_details.py b/src/ort/models/advisor_details.py index 59e5433..48237bb 100644 --- a/src/ort/models/advisor_details.py +++ b/src/ort/models/advisor_details.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from pydantic import BaseModel, ConfigDict, Field, field_validator +from pydantic import BaseModel, ConfigDict, Field from ort.models import AdvisorCapability @@ -22,20 +22,3 @@ class AdvisorDetails(BaseModel): description="The capabilities of the used advisor. This property indicates, which kind of findings" "are retrieved by the advisor." ) - - @field_validator("capabilities", mode="before") - @classmethod - def convert_capability(cls, v): - def _convert(item): - if isinstance(item, str): - try: - return AdvisorCapability[item] - except KeyError: - raise ValueError(f"Invalid capability: {item}") - return item - - if isinstance(v, (list, set)): - return {_convert(item) for item in v} - if isinstance(v, str): - return _convert(v) - return v diff --git a/src/ort/models/advisor_run.py b/src/ort/models/advisor_run.py index 8832c95..33ca2e7 100644 --- a/src/ort/models/advisor_run.py +++ b/src/ort/models/advisor_run.py @@ -1,35 +1,21 @@ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from datetime import datetime -from pydantic import BaseModel, ConfigDict, Field - -from ort.models import AdvisorResult -from ort.models.config.advisor_configuration import AdvisorConfiguration -from ort.utils.environment import Environment +from pydantic import Field +from .advisor_result import AdvisorResult +from .base_run import BaseRun +from .config.advisor_configuration import AdvisorConfiguration from .identifier import Identifier -class AdvisorRun(BaseModel): +class AdvisorRun(BaseRun): """ Type alias for a function that allows filtering of [AdvisorResult]s. """ - model_config = ConfigDict( - extra="forbid", - ) - start_time: datetime = Field( - description="The time the advisor was started.", - ) - end_time: datetime = Field( - description="The time the advisor has finished.", - ) - environment: Environment = Field( - description="The [Environment] in which the advisor was executed.", - ) config: AdvisorConfiguration = Field( description="The [AdvisorConfiguration] used for this run.", ) diff --git a/src/ort/models/analyzer_run.py b/src/ort/models/analyzer_run.py index 1eeea99..f2a3678 100644 --- a/src/ort/models/analyzer_run.py +++ b/src/ort/models/analyzer_run.py @@ -1,33 +1,20 @@ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from datetime import datetime -from pydantic import BaseModel, ConfigDict, Field +from pydantic import Field -from ort.models import AnalyzerResult -from ort.models.config.analyzer_configuration import AnalyzerConfiguration -from ort.utils.environment import Environment +from .analyzer_result import AnalyzerResult +from .base_run import BaseRun +from .config.analyzer_configuration import AnalyzerConfiguration -class AnalyzerRun(BaseModel): +class AnalyzerRun(BaseRun): """ The summary of a single run of the analyzer. """ - model_config = ConfigDict( - extra="forbid", - ) - start_time: datetime = Field( - description="The time the analyzer was started.", - ) - end_time: datetime = Field( - description="The time the analyzer has finished.", - ) - environment: Environment = Field( - description="The [Environment] in which the analyzer was executed.", - ) config: AnalyzerConfiguration = Field( description="The [AnalyzerConfiguration] used for this run.", ) diff --git a/src/ort/models/base_run.py b/src/ort/models/base_run.py new file mode 100644 index 0000000..2e0026c --- /dev/null +++ b/src/ort/models/base_run.py @@ -0,0 +1,28 @@ +# SPDX-FileCopyrightText: 2025 Helio Chissini de Castro +# SPDX-License-Identifier: MIT + +from datetime import datetime + +from pydantic import BaseModel, ConfigDict, Field + +from ort.utils.environment import Environment + + +class BaseRun(BaseModel): + """ + The summary of a single run of the analyzer. + + """ + + model_config = ConfigDict( + extra="forbid", + ) + start_time: datetime = Field( + description="The time the analyzer was started.", + ) + end_time: datetime = Field( + description="The time the analyzer has finished.", + ) + environment: Environment = Field( + description="The [Environment] in which the analyzer was executed.", + ) diff --git a/src/ort/models/config/issue_resolution.py b/src/ort/models/config/issue_resolution.py index 9e37bac..1e93e2b 100644 --- a/src/ort/models/config/issue_resolution.py +++ b/src/ort/models/config/issue_resolution.py @@ -2,9 +2,7 @@ # SPDX-License-Identifier: MIT -from pydantic import BaseModel, ConfigDict, Field, field_validator - -from ort.utils import convert_enum +from pydantic import BaseModel, ConfigDict, Field from .issue_resolution_reason import IssueResolutionReason @@ -32,8 +30,3 @@ class IssueResolution(BaseModel): comment: str = Field( description="A comment to further explain why the [reason] is applicable here.", ) - - @field_validator("reason", mode="before") - @classmethod - def validate_reason(cls, value): - return convert_enum(IssueResolutionReason, value) diff --git a/src/ort/models/config/issue_resolution_reason.py b/src/ort/models/config/issue_resolution_reason.py index e943724..86cf4d1 100644 --- a/src/ort/models/config/issue_resolution_reason.py +++ b/src/ort/models/config/issue_resolution_reason.py @@ -1,10 +1,10 @@ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class IssueResolutionReason(IntEnum): +class IssueResolutionReason(ValidatedIntEnum): """ Possible reasons for resolving an Issue using an IssueResolution. diff --git a/src/ort/models/config/path_exclude.py b/src/ort/models/config/path_exclude.py index a313e44..4155503 100644 --- a/src/ort/models/config/path_exclude.py +++ b/src/ort/models/config/path_exclude.py @@ -2,9 +2,7 @@ # SPDX-License-Identifier: MIT -from pydantic import BaseModel, ConfigDict, Field, field_validator - -from ort.utils import convert_enum +from pydantic import BaseModel, ConfigDict, Field from .path_exclude_reason import PathExcludeReason @@ -32,8 +30,3 @@ class PathExclude(BaseModel): default_factory=str, description="A comment to further explain why the [reason] is applicable here.", ) - - @field_validator("reason", mode="before") - @classmethod - def validate_reason(cls, value): - return convert_enum(PathExcludeReason, value) diff --git a/src/ort/models/config/path_exclude_reason.py b/src/ort/models/config/path_exclude_reason.py index 4750f29..4a47eb5 100644 --- a/src/ort/models/config/path_exclude_reason.py +++ b/src/ort/models/config/path_exclude_reason.py @@ -1,10 +1,10 @@ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class PathExcludeReason(IntEnum): +class PathExcludeReason(ValidatedIntEnum): """ Possible reasons for excluding a path. diff --git a/src/ort/models/config/path_include.py b/src/ort/models/config/path_include.py index 7955996..098d378 100644 --- a/src/ort/models/config/path_include.py +++ b/src/ort/models/config/path_include.py @@ -2,9 +2,7 @@ # SPDX-License-Identifier: MIT -from pydantic import BaseModel, ConfigDict, Field, field_validator - -from ort.utils import convert_enum +from pydantic import BaseModel, ConfigDict, Field from .path_include_reason import PathIncludeReason @@ -32,8 +30,3 @@ class PathInclude(BaseModel): default_factory=str, description="A comment to further explain why the [reason] is applicable here.", ) - - @field_validator("reason", mode="before") - @classmethod - def validate_reason(cls, value): - return convert_enum(PathIncludeReason, value) diff --git a/src/ort/models/config/path_include_reason.py b/src/ort/models/config/path_include_reason.py index 972c1ba..ed9548f 100644 --- a/src/ort/models/config/path_include_reason.py +++ b/src/ort/models/config/path_include_reason.py @@ -1,10 +1,10 @@ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class PathIncludeReason(IntEnum): +class PathIncludeReason(ValidatedIntEnum): """ Possible reasons for including a path. diff --git a/src/ort/models/config/rule_violation_reason.py b/src/ort/models/config/rule_violation_reason.py index 6571aef..858b19b 100644 --- a/src/ort/models/config/rule_violation_reason.py +++ b/src/ort/models/config/rule_violation_reason.py @@ -1,10 +1,10 @@ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class RuleViolationResolutionReason(IntEnum): +class RuleViolationResolutionReason(ValidatedIntEnum): """ Properties: CANT_FIX_EXCEPTION: diff --git a/src/ort/models/config/rule_violation_resolution.py b/src/ort/models/config/rule_violation_resolution.py index e58634f..8d462ac 100644 --- a/src/ort/models/config/rule_violation_resolution.py +++ b/src/ort/models/config/rule_violation_resolution.py @@ -2,9 +2,7 @@ # SPDX-License-Identifier: MIT -from pydantic import BaseModel, ConfigDict, Field, field_validator - -from ort.utils import convert_enum +from pydantic import BaseModel, ConfigDict, Field from .rule_violation_reason import RuleViolationResolutionReason @@ -32,8 +30,3 @@ class RuleViolationResolution(BaseModel): comment: str = Field( description="A comment to further explain why the [reason] is applicable here.", ) - - @field_validator("reason", mode="before") - @classmethod - def validate_reason(cls, value): - return convert_enum(RuleViolationResolutionReason, value) diff --git a/src/ort/models/config/scope_exclude.py b/src/ort/models/config/scope_exclude.py index 792be3e..fb08370 100644 --- a/src/ort/models/config/scope_exclude.py +++ b/src/ort/models/config/scope_exclude.py @@ -2,10 +2,9 @@ # SPDX-License-Identifier: MIT -from pydantic import BaseModel, ConfigDict, Field, field_validator +from pydantic import BaseModel, ConfigDict, Field from ort.models.config.scope_exclude_reason import ScopeExcludeReason -from ort.utils import convert_enum class ScopeExclude(BaseModel): @@ -29,8 +28,3 @@ class ScopeExclude(BaseModel): default_factory=str, description="A comment to further explain why the [reason] is applicable here.", ) - - @field_validator("reason", mode="before") - @classmethod - def validate_reason(cls, value): - return convert_enum(ScopeExcludeReason, value) diff --git a/src/ort/models/config/scope_exclude_reason.py b/src/ort/models/config/scope_exclude_reason.py index 7c1b683..ab115ab 100644 --- a/src/ort/models/config/scope_exclude_reason.py +++ b/src/ort/models/config/scope_exclude_reason.py @@ -2,10 +2,10 @@ # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class ScopeExcludeReason(IntEnum): +class ScopeExcludeReason(ValidatedIntEnum): """ Possible reasons for excluding a scope. diff --git a/src/ort/models/config/snippet/snippet_choice.py b/src/ort/models/config/snippet/snippet_choice.py index 31cb8ec..6c9c91c 100644 --- a/src/ort/models/config/snippet/snippet_choice.py +++ b/src/ort/models/config/snippet/snippet_choice.py @@ -1,9 +1,7 @@ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from pydantic import BaseModel, ConfigDict, Field, field_validator - -from ort.utils import convert_enum +from pydantic import BaseModel, ConfigDict, Field from ....types.purl_type import PurlType from ...text_location import TextLocation @@ -46,11 +44,6 @@ class Choice(BaseModel): description="An optional comment describing the snippet choice.", ) - @field_validator("reason", mode="before") - @classmethod - def validate_reason(cls, value): - return convert_enum(SnippetChoiceReason, value) - class SnippetChoice(BaseModel): """ @@ -68,12 +61,3 @@ class SnippetChoice(BaseModel): ..., description="The snippet criteria to make the snippet choice.", ) - - # @model_validator(mode="before") - # @classmethod - # def validate_snippet_choice(cls, v): - # print(v) - # breakpoint() - # if not isinstance(v, dict): - # raise ValueError("SnippetChoice must be a dictionary.") - # return v diff --git a/src/ort/models/config/snippet/snippet_choice_reason.py b/src/ort/models/config/snippet/snippet_choice_reason.py index 6e352ae..83d2a5c 100644 --- a/src/ort/models/config/snippet/snippet_choice_reason.py +++ b/src/ort/models/config/snippet/snippet_choice_reason.py @@ -1,10 +1,10 @@ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class SnippetChoiceReason(IntEnum): +class SnippetChoiceReason(ValidatedIntEnum): """ The reason for which the snippet choice has been made. diff --git a/src/ort/models/config/vulnerability_resolution.py b/src/ort/models/config/vulnerability_resolution.py index f995233..a9a9942 100644 --- a/src/ort/models/config/vulnerability_resolution.py +++ b/src/ort/models/config/vulnerability_resolution.py @@ -2,9 +2,7 @@ # SPDX-License-Identifier: MIT -from pydantic import BaseModel, ConfigDict, Field, field_validator - -from ort.utils import convert_enum +from pydantic import BaseModel, ConfigDict, Field from .vulnerability_resolution_reason import VulnerabilityResolutionReason @@ -31,8 +29,3 @@ class VulnerabilityResolution(BaseModel): comment: str = Field( description="A comment to further explain why the [reason] is applicable here.", ) - - @field_validator("reason", mode="before") - @classmethod - def validate_reason(cls, value): - return convert_enum(VulnerabilityResolutionReason, value) diff --git a/src/ort/models/config/vulnerability_resolution_reason.py b/src/ort/models/config/vulnerability_resolution_reason.py index 3d13d40..4285743 100644 --- a/src/ort/models/config/vulnerability_resolution_reason.py +++ b/src/ort/models/config/vulnerability_resolution_reason.py @@ -1,10 +1,10 @@ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class VulnerabilityResolutionReason(IntEnum): +class VulnerabilityResolutionReason(ValidatedIntEnum): """ Possible reasons for resolving a Vulnerability using a VulnerabilityResolution. diff --git a/src/ort/models/dependency_graph_node.py b/src/ort/models/dependency_graph_node.py index e25bcc7..0b7ef46 100644 --- a/src/ort/models/dependency_graph_node.py +++ b/src/ort/models/dependency_graph_node.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MIT -from pydantic import BaseModel, ConfigDict, Field, field_validator +from pydantic import BaseModel, ConfigDict, Field from .issue import Issue from .package_linkage import PackageLinkage @@ -42,13 +42,3 @@ class DependencyGraphNode(BaseModel): issues: list[Issue] = Field( default_factory=list, description="A list of Issue objects that occurred handling this dependency." ) - - @field_validator("linkage", mode="before") - @classmethod - def convert_linkage(cls, v): - if isinstance(v, str): - try: - return PackageLinkage[v] - except KeyError: - raise ValueError(f"Invalid linkage: {v}") - return v diff --git a/src/ort/models/evaluator_run.py b/src/ort/models/evaluator_run.py new file mode 100644 index 0000000..0014817 --- /dev/null +++ b/src/ort/models/evaluator_run.py @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2026 Helio Chissini de Castro +# SPDX-License-Identifier: MIT + + +from pydantic import Field + +from .base_run import BaseRun +from .rule_violation import RuleViolation + + +class EvaluatorRun(BaseRun): + """ + The summary of a single run of the evaluator. + """ + + violations: list[RuleViolation] = Field( + default_factory=list, + description="The list of rule violations found by the evaluator.", + ) diff --git a/src/ort/models/issue.py b/src/ort/models/issue.py index a949226..fa9249f 100644 --- a/src/ort/models/issue.py +++ b/src/ort/models/issue.py @@ -4,10 +4,9 @@ from datetime import datetime -from pydantic import BaseModel, ConfigDict, Field, field_validator +from pydantic import BaseModel, ConfigDict, Field from ort.severity import Severity -from ort.utils import convert_enum class Issue(BaseModel): @@ -35,8 +34,3 @@ class Issue(BaseModel): default=None, description="The affected file or directory the issue is limited to, if any.", ) - - @field_validator("severity", mode="before") - @classmethod - def convert_severity(cls, v): - return convert_enum(Severity, v) diff --git a/src/ort/models/license_source.py b/src/ort/models/license_source.py new file mode 100644 index 0000000..e60fb44 --- /dev/null +++ b/src/ort/models/license_source.py @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2026 Helio Chissini de Castro +# SPDX-License-Identifier: MIT + +from ..utils.validated_enum import ValidatedIntEnum + + +class LicenseSource(ValidatedIntEnum): + """ + The source where a license originates from. + + properties: + CONCLUDED: + Licenses which are part of the [concluded license][Package.concludedLicense] of a [Package]. + DECLARED: + Licenses which are part of the [(processed)][Package.declaredLicensesProcessed] + [declared licenses][Package.declaredLicenses] of a [Package]. + DETECTED: + Licenses which were detected by a license scanner. + """ + + CONCLUDED = 1 + DECLARED = 2 + DETECTED = 3 diff --git a/src/ort/models/ort_result.py b/src/ort/models/ort_result.py index 0632c5f..80ad442 100644 --- a/src/ort/models/ort_result.py +++ b/src/ort/models/ort_result.py @@ -1,4 +1,4 @@ -# SPDX-FileCopyrightText: 2025 Helio Chissini de Castro +# SPDX-FileCopyrightText: 2025 Helio Chissini de Castro +# SPDX-License-Identifier: MIT + + +from pydantic import BaseModel, Field + +from .identifier import Identifier +from .license_source import LicenseSource +from .severity import Severity + + +class RuleViolation(BaseModel): + """ + A violation of a rule found during evaluation. + """ + + model_config = { + "extra": "forbid", + } + + rule: str = Field(description=("The identifier of the rule that found this violation.")) + + pkg: Identifier | None = Field( + default=None, + description=("The identifier of the package that caused this rule violation."), + ) + + license: str | None = Field( + default=None, + description=( + "The name of the license that caused this rule " + "violation. Can be null if the rule does not work on " + "licenses." + ), + ) + + license_sources: set[LicenseSource] = Field( + default_factory=set, + description=("The sources of the license. Can be empty if the rule does not work on licenses."), + ) + + severity: Severity = Field(description="The severity of the rule violation.") + + message: str = Field(description="A message explaining the rule violation.") + + how_to_fix: str = Field( + description=( + "A text explaining how the rule violation can be fixed. Renderers should support Markdown syntax." + ), + ) diff --git a/src/ort/models/severity.py b/src/ort/models/severity.py new file mode 100644 index 0000000..541a490 --- /dev/null +++ b/src/ort/models/severity.py @@ -0,0 +1,23 @@ +# SPDX-FileCopyrightText: 2026 Helio Chissini de Castro +# SPDX-License-Identifier: MIT + + +from ..utils.validated_enum import ValidatedIntEnum + + +class Severity(ValidatedIntEnum): + """ + A generic class describing a severity, e.g. of issues, sorted from least severe to most severe. + + properties: + HINT: + A hint is something that is provided for information only. + WARNING: + A warning is something that should be addressed. + ERROR: + An error is something that has to be addressed. + """ + + HINT = 1 + WARNING = 2 + ERROR = 3 diff --git a/src/ort/severity.py b/src/ort/severity.py index de3e387..198ebc8 100644 --- a/src/ort/severity.py +++ b/src/ort/severity.py @@ -1,10 +1,10 @@ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class Severity(IntEnum): +class Severity(ValidatedIntEnum): """ A generic class describing a severity, e.g. of issues, sorted from least severe to most severe. diff --git a/src/ort/utils/__init__.py b/src/ort/utils/__init__.py index d6bcaa2..960631e 100644 --- a/src/ort/utils/__init__.py +++ b/src/ort/utils/__init__.py @@ -1,12 +1,15 @@ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from ort.utils.convert_enum import convert_enum -from ort.utils.environment import Environment -from ort.utils.processed_declared_license import ProcessedDeclaredLicense +from .environment import Environment +from .processed_declared_license import ProcessedDeclaredLicense +from .validated_enum import ValidatedIntEnum +from .yaml_loader import OrtYamlLoader, ort_yaml_load __all__ = [ - "convert_enum", "Environment", + "OrtYamlLoader", "ProcessedDeclaredLicense", + "ValidatedIntEnum", + "ort_yaml_load", ] diff --git a/src/ort/utils/convert_enum.py b/src/ort/utils/convert_enum.py deleted file mode 100644 index bc7b5c1..0000000 --- a/src/ort/utils/convert_enum.py +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Helio Chissini de Castro -# SPDX-License-Identifier: MIT - - -def convert_enum(enum_cls, v): - def _convert(item): - if isinstance(item, str): - try: - return enum_cls[item] - except KeyError: - raise ValueError(f"Invalid value for {enum_cls.__name__}: {item}") - return item - - if isinstance(v, (list, set)): - return {_convert(item) for item in v} - if isinstance(v, str): - return _convert(v) - return v diff --git a/src/ort/utils/spdx/spdx_expression.py b/src/ort/utils/spdx/spdx_expression.py index 1e9a468..4665edc 100644 --- a/src/ort/utils/spdx/spdx_expression.py +++ b/src/ort/utils/spdx/spdx_expression.py @@ -1,10 +1,10 @@ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro # SPDX-License-Identifier: MIT -from enum import IntEnum +from ort.utils.validated_enum import ValidatedIntEnum -class SpdxExpression(IntEnum): +class SpdxExpression(ValidatedIntEnum): """ The level of strictness to apply when validating an SpdxExpression. diff --git a/src/ort/utils/validated_enum.py b/src/ort/utils/validated_enum.py new file mode 100644 index 0000000..9ea3acf --- /dev/null +++ b/src/ort/utils/validated_enum.py @@ -0,0 +1,34 @@ +# SPDX-FileCopyrightText: 2026 Helio Chissini de Castro +# SPDX-License-Identifier: MIT + +from enum import IntEnum +from typing import Any + +from pydantic import GetCoreSchemaHandler +from pydantic_core import CoreSchema, core_schema + + +class ValidatedIntEnum(IntEnum): + """ + IntEnum base class with built-in Pydantic validation for string names. + """ + + @classmethod + def __get_pydantic_core_schema__( + cls, + source_type: Any, + handler: GetCoreSchemaHandler, + ) -> CoreSchema: + def validate(value: Any) -> ValidatedIntEnum: + if isinstance(value, cls): + return value + if isinstance(value, str): + try: + return cls[value] + except KeyError: + raise ValueError(f"Invalid value for {cls.__name__}: {value}") + if isinstance(value, int): + return cls(value) + raise ValueError(f"Invalid value for {cls.__name__}: {value}") + + return core_schema.no_info_plain_validator_function(validate) diff --git a/src/ort/utils/yaml_loader.py b/src/ort/utils/yaml_loader.py new file mode 100644 index 0000000..56faad1 --- /dev/null +++ b/src/ort/utils/yaml_loader.py @@ -0,0 +1,43 @@ +# SPDX-FileCopyrightText: 2026 Helio Chissini de Castro +# SPDX-License-Identifier: MIT + +from typing import Any + +import yaml + +# Prefer the C-accelerated SafeLoader when available (5-10x faster). +try: + _BaseLoader = yaml.CSafeLoader +except AttributeError: + _BaseLoader = yaml.SafeLoader + + +class OrtYamlLoader(_BaseLoader): # type: ignore[misc] + """A YAML loader that handles ORT-specific custom tags. + + ORT result files may contain custom YAML tags like + ``!<.PostgresStorageConfiguration>`` which are not supported by the + standard safe loader. This loader silently treats any unknown tag as + a plain mapping/sequence/scalar so the data can still be parsed. + + Uses the C-accelerated SafeLoader when available for better performance. + """ + + +# Register a multi-constructor that matches every unknown tag and +# delegates to the default safe constructors based on node type. +OrtYamlLoader.add_multi_constructor( + "", + lambda loader, suffix, node: ( + loader.construct_mapping(node, deep=True) + if isinstance(node, yaml.MappingNode) + else loader.construct_sequence(node, deep=True) + if isinstance(node, yaml.SequenceNode) + else loader.construct_scalar(node) + ), +) + + +def ort_yaml_load(stream: Any) -> Any: + """Load a YAML document using the ORT-aware loader.""" + return yaml.load(stream, Loader=OrtYamlLoader) # noqa: S506 diff --git a/tests/data/evaluation-result.yml b/tests/data/evaluation-result.yml new file mode 100644 index 0000000..130e6fb --- /dev/null +++ b/tests/data/evaluation-result.yml @@ -0,0 +1,2567 @@ +--- +repository: + vcs: + type: "Git" + url: "https://github.com/heliocastro/python-ort" + revision: "15544ad032100f4f6bda18c9db6be0f489c50070" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/heliocastro/python-ort.git" + revision: "15544ad032100f4f6bda18c9db6be0f489c50070" + path: "" + config: + analyzer: + enabled_package_managers: + - "PIP" + excludes: + paths: + - pattern: "tests/data/**" + reason: "TEST_OF" + comment: "Test data" +analyzer: + start_time: "2026-03-04T17:46:56.154492Z" + end_time: "2026-03-04T17:47:01.466348Z" + environment: + ort_version: "80.0.0" + build_jdk: "21.0.10+7-LTS" + java_version: "21.0.10" + os: "Mac OS X" + processors: 12 + max_memory: 6442450944 + variables: + ORT_CONFIG_DIR: "/Users/dhxbwm7/data/ort-config" + HOME: "/Users/dhxbwm7" + SHELL: "/bin/zsh" + TERM: "xterm-ghostty" + JAVA_HOME: "/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home" + GOPATH: "/Users/dhxbwm7/.local/toolchains/golang" + config: + allow_dynamic_versions: false + enabled_package_managers: + - "PIP" + skip_excluded: false + result: + projects: + - id: "PIP::requirements.txt:15544ad032100f4f6bda18c9db6be0f489c50070" + definition_file_path: "requirements.txt" + declared_licenses: [] + declared_licenses_processed: {} + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/heliocastro/python-ort.git" + revision: "15544ad032100f4f6bda18c9db6be0f489c50070" + path: "" + homepage_url: "" + scope_names: + - "install" + packages: + - id: "PyPI::annotated-types:0.7.0" + purl: "pkg:pypi/annotated-types@0.7.0" + authors: + - "Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com>, Samuel\ + \ Colvin , Zac Hatfield-Dodds " + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "Reusable constraint types to use with typing.Annotated" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl" + hash: + value: "1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz" + hash: + value: "aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/annotated-types/annotated-types.git" + revision: "" + path: "" + - id: "PyPI::anyio:4.12.1" + purl: "pkg:pypi/anyio@4.12.1" + authors: + - "Alex Grönholm " + declared_licenses: [] + declared_licenses_processed: {} + description: "High-level concurrency and networking framework on top of asyncio\ + \ or Trio" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl" + hash: + value: "d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/96/f0/5eb65b2bb0d09ac6776f2eb54adee6abe8228ea05b20a5ad0e4945de8aac/anyio-4.12.1.tar.gz" + hash: + value: "41cfcc3a4c85d3f05c932da7c26d0201ac36f72abd4435ba90d0464a3ffed703" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::argcomplete:3.6.3" + purl: "pkg:pypi/argcomplete@3.6.3" + authors: + - "Andrey Kislyuk " + declared_licenses: + - "Apache Software License" + declared_licenses_processed: + spdx_expression: "Apache-2.0" + mapped: + Apache Software License: "Apache-2.0" + description: "Bash tab completion for argparse" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl" + hash: + value: "f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/38/61/0b9ae6399dd4a58d8c1b1dc5a27d6f2808023d0b5dd3104bb99f45a33ff6/argcomplete-3.6.3.tar.gz" + hash: + value: "62e8ed4fd6a45864acc8235409461b72c9a28ee785a2011cc5eb78318786c89c" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/kislyuk/argcomplete.git" + revision: "" + path: "" + - id: "PyPI::black:26.1.0" + purl: "pkg:pypi/black@26.1.0" + authors: + - "Łukasz Langa " + declared_licenses: [] + declared_licenses_processed: {} + description: "The uncompromising code formatter." + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/e4/3d/51bdb3ecbfadfaf825ec0c75e1de6077422b4afa2091c6c9ba34fbfc0c2d/black-26.1.0-py3-none-any.whl" + hash: + value: "1054e8e47ebd686e078c0bb0eaf31e6ce69c966058d122f2c0c950311f9f3ede" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/13/88/560b11e521c522440af991d46848a2bde64b5f7202ec14e1f46f9509d328/black-26.1.0.tar.gz" + hash: + value: "d294ac3340eef9c9eb5d29288e96dc719ff269a88e27b396340459dd85da4c58" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::certifi:2026.2.25" + purl: "pkg:pypi/certifi@2026.2.25" + authors: + - "Kenneth Reitz " + declared_licenses: + - "MPL-2.0" + - "Mozilla Public License 2.0 (MPL 2.0)" + declared_licenses_processed: + spdx_expression: "MPL-2.0" + mapped: + Mozilla Public License 2.0 (MPL 2.0): "MPL-2.0" + description: "Python package for providing Mozilla's CA Bundle." + homepage_url: "https://github.com/certifi/python-certifi" + binary_artifact: + url: "https://files.pythonhosted.org/packages/9a/3c/c17fb3ca2d9c3acff52e30b309f538586f9f5b9c9cf454f3845fc9af4881/certifi-2026.2.25-py3-none-any.whl" + hash: + value: "027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz" + hash: + value: "e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/certifi/python-certifi.git" + revision: "" + path: "" + - id: "PyPI::click:8.3.1" + purl: "pkg:pypi/click@8.3.1" + declared_licenses: [] + declared_licenses_processed: {} + description: "Composable command line interface toolkit" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl" + hash: + value: "981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz" + hash: + value: "12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/pallets/click.git" + revision: "" + path: "" + - id: "PyPI::datamodel-code-generator:0.54.0" + purl: "pkg:pypi/datamodel-code-generator@0.54.0" + authors: + - "Koudai Aono " + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "Datamodel Code Generator" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/2b/d9/fd646ea4ae48e374817b2750f5e678a5bf6e10d8924f09cf4cce86a81607/datamodel_code_generator-0.54.0-py3-none-any.whl" + hash: + value: "3156df7a7e8fa5a7c9a6d50836e5ba5abe0532f6b71eee6d73a0c8e1fb5b7e47" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/be/43/2640cd5293fb5430528166908d6439cf3321bc1c54de5fe58ef100b143a1/datamodel_code_generator-0.54.0.tar.gz" + hash: + value: "2b183598d049e265146a8224c35d1bb96a80a641ea8ecd2a82e6a0e97b56da6b" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/koxudaxi/datamodel-code-generator.git" + revision: "" + path: "" + - id: "PyPI::genson:1.3.0" + purl: "pkg:pypi/genson@1.3.0" + authors: + - "Jon Wolverton " + declared_licenses: + - "MIT" + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "GenSON is a powerful, user-friendly JSON Schema generator." + homepage_url: "https://github.com/wolverdude/genson/" + binary_artifact: + url: "https://files.pythonhosted.org/packages/f8/5c/e226de133afd8bb267ec27eead9ae3d784b95b39a287ed404caab39a5f50/genson-1.3.0-py3-none-any.whl" + hash: + value: "468feccd00274cc7e4c09e84b08704270ba8d95232aa280f65b986139cec67f7" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/c5/cf/2303c8ad276dcf5ee2ad6cf69c4338fd86ef0f471a5207b069adf7a393cf/genson-1.3.0.tar.gz" + hash: + value: "e02db9ac2e3fd29e65b5286f7135762e2cd8a986537c075b06fc5f1517308e37" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/wolverdude/genson.git" + revision: "" + path: "" + - id: "PyPI::h11:0.16.0" + purl: "pkg:pypi/h11@0.16.0" + authors: + - "Nathaniel J. Smith " + declared_licenses: + - "MIT" + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" + homepage_url: "https://github.com/python-hyper/h11" + binary_artifact: + url: "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl" + hash: + value: "63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz" + hash: + value: "4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/python-hyper/h11.git" + revision: "" + path: "" + - id: "PyPI::httpcore:1.0.9" + purl: "pkg:pypi/httpcore@1.0.9" + authors: + - "Tom Christie " + declared_licenses: + - "BSD License" + declared_licenses_processed: + unmapped: + - "BSD License" + description: "A minimal low-level HTTP client." + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl" + hash: + value: "2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz" + hash: + value: "6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/encode/httpcore.git" + revision: "" + path: "" + - id: "PyPI::httpx:0.28.1" + purl: "pkg:pypi/httpx@0.28.1" + authors: + - "Tom Christie " + declared_licenses: + - "BSD License" + - "BSD-3-Clause" + declared_licenses_processed: + spdx_expression: "BSD-3-Clause" + mapped: + BSD License: "BSD-3-Clause" + description: "The next generation HTTP client." + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl" + hash: + value: "d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz" + hash: + value: "75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/encode/httpx.git" + revision: "" + path: "" + - id: "PyPI::idna:3.11" + purl: "pkg:pypi/idna@3.11" + authors: + - "Kim Davies " + declared_licenses: [] + declared_licenses_processed: {} + description: "Internationalized Domain Names in Applications (IDNA)" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl" + hash: + value: "771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz" + hash: + value: "795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/kjd/idna.git" + revision: "" + path: "" + - id: "PyPI::inflect:7.5.0" + purl: "pkg:pypi/inflect@7.5.0" + authors: + - "Paul Dyson " + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "Correctly generate plurals, singular nouns, ordinals, indefinite\ + \ articles" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/8a/eb/427ed2b20a38a4ee29f24dbe4ae2dafab198674fe9a85e3d6adf9e5f5f41/inflect-7.5.0-py3-none-any.whl" + hash: + value: "2aea70e5e70c35d8350b8097396ec155ffd68def678c7ff97f51aa69c1d92344" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/78/c6/943357d44a21fd995723d07ccaddd78023eace03c1846049a2645d4324a3/inflect-7.5.0.tar.gz" + hash: + value: "faf19801c3742ed5a05a8ce388e0d8fe1a07f8d095c82201eb904f5d27ad571f" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/jaraco/inflect.git" + revision: "" + path: "" + - id: "PyPI::iniconfig:2.3.0" + purl: "pkg:pypi/iniconfig@2.3.0" + authors: + - "Ronny Pfannschmidt , Holger Krekel " + declared_licenses: [] + declared_licenses_processed: {} + description: "brain-dead simple config-ini parsing" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl" + hash: + value: "f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz" + hash: + value: "c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::isort:7.0.0" + purl: "pkg:pypi/isort@7.0.0" + authors: + - "Timothy Crosley , staticdev " + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "A Python utility / library to sort Python imports." + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/7f/ed/e3705d6d02b4f7aea715a353c8ce193efd0b5db13e204df895d38734c244/isort-7.0.0-py3-none-any.whl" + hash: + value: "1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/63/53/4f3c058e3bace40282876f9b553343376ee687f3c35a525dc79dbd450f88/isort-7.0.0.tar.gz" + hash: + value: "5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::jinja2:3.1.6" + purl: "pkg:pypi/jinja2@3.1.6" + declared_licenses: + - "BSD License" + declared_licenses_processed: + unmapped: + - "BSD License" + description: "A very fast and expressive template engine." + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl" + hash: + value: "85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz" + hash: + value: "0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/pallets/jinja.git" + revision: "" + path: "" + - id: "PyPI::markdown-it-py:4.0.0" + purl: "pkg:pypi/markdown-it-py@4.0.0" + authors: + - "Chris Sewell " + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "Python port of markdown-it. Markdown parsing, done right!" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl" + hash: + value: "87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz" + hash: + value: "cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::markupsafe:3.0.3" + purl: "pkg:pypi/markupsafe@3.0.3" + declared_licenses: [] + declared_licenses_processed: {} + description: "Safely add untrusted strings to HTML/XML markup." + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl" + hash: + value: "8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz" + hash: + value: "722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/pallets/markupsafe.git" + revision: "" + path: "" + - id: "PyPI::mdurl:0.1.2" + purl: "pkg:pypi/mdurl@0.1.2" + authors: + - "Taneli Hukkinen " + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "Markdown URL utilities" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl" + hash: + value: "84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz" + hash: + value: "bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::more-itertools:10.8.0" + purl: "pkg:pypi/more-itertools@10.8.0" + authors: + - "Erik Rose " + declared_licenses: [] + declared_licenses_processed: {} + description: "More routines for operating on iterables, beyond itertools" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/a4/8e/469e5a4a2f5855992e425f3cb33804cc07bf18d48f2db061aec61ce50270/more_itertools-10.8.0-py3-none-any.whl" + hash: + value: "52d4362373dcf7c52546bc4af9a86ee7c4579df9a8dc268be0a2f949d376cc9b" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/ea/5d/38b681d3fce7a266dd9ab73c66959406d565b3e85f21d5e66e1181d93721/more_itertools-10.8.0.tar.gz" + hash: + value: "f638ddf8a1a0d134181275fb5d58b086ead7c6a72429ad725c67503f13ba30bd" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::mypy-extensions:1.1.0" + purl: "pkg:pypi/mypy-extensions@1.1.0" + authors: + - "The mypy developers " + declared_licenses: [] + declared_licenses_processed: {} + description: "Type system extensions for programs checked with the mypy type\ + \ checker." + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl" + hash: + value: "1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz" + hash: + value: "52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::packageurl-python:0.17.6" + purl: "pkg:pypi/packageurl-python@0.17.6" + authors: + - "the purl authors" + declared_licenses: + - "MIT" + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "A purl aka. Package URL parser and builder" + homepage_url: "https://github.com/package-url/packageurl-python" + binary_artifact: + url: "https://files.pythonhosted.org/packages/b1/2f/c7277b7615a93f51b5fbc1eacfc1b75e8103370e786fd8ce2abf6e5c04ab/packageurl_python-0.17.6-py3-none-any.whl" + hash: + value: "31a85c2717bc41dd818f3c62908685ff9eebcb68588213745b14a6ee9e7df7c9" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/f5/d6/3b5a4e3cfaef7a53869a26ceb034d1ff5e5c27c814ce77260a96d50ab7bb/packageurl_python-0.17.6.tar.gz" + hash: + value: "1252ce3a102372ca6f86eb968e16f9014c4ba511c5c37d95a7f023e2ca6e5c25" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/package-url/packageurl-python.git" + revision: "" + path: "" + - id: "PyPI::packaging:26.0" + purl: "pkg:pypi/packaging@26.0" + authors: + - "Donald Stufft " + declared_licenses: [] + declared_licenses_processed: {} + description: "Core utilities for Python packages" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl" + hash: + value: "b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz" + hash: + value: "00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/pypa/packaging.git" + revision: "" + path: "" + - id: "PyPI::pathspec:1.0.4" + purl: "pkg:pypi/pathspec@1.0.4" + authors: + - "\"Caleb P. Burns\" " + declared_licenses: + - "Mozilla Public License 2.0 (MPL 2.0)" + declared_licenses_processed: + spdx_expression: "MPL-2.0" + mapped: + Mozilla Public License 2.0 (MPL 2.0): "MPL-2.0" + description: "Utility library for gitignore style pattern matching of file paths." + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl" + hash: + value: "fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz" + hash: + value: "0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/cpburnz/python-pathspec.git" + revision: "" + path: "" + - id: "PyPI::platformdirs:4.9.2" + purl: "pkg:pypi/platformdirs@4.9.2" + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "A small Python package for determining appropriate platform-specific\ + \ dirs, e.g. a `user data dir`." + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl" + hash: + value: "9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/1b/04/fea538adf7dbbd6d186f551d595961e564a3b6715bdf276b477460858672/platformdirs-4.9.2.tar.gz" + hash: + value: "9a33809944b9db043ad67ca0db94b14bf452cc6aeaac46a88ea55b26e2e9d291" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/tox-dev/platformdirs.git" + revision: "" + path: "" + - id: "PyPI::pluggy:1.6.0" + purl: "pkg:pypi/pluggy@1.6.0" + authors: + - "Holger Krekel " + declared_licenses: + - "MIT" + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "plugin and hook calling mechanisms for python" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl" + hash: + value: "e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz" + hash: + value: "7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::pydantic:2.12.5" + purl: "pkg:pypi/pydantic@2.12.5" + authors: + - "Samuel Colvin , Eric Jolibois ,\ + \ Hasan Ramezani , Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com>,\ + \ Terrence Dorsey , David Montague ,\ + \ Serge Matveenko , Marcelo Trylesinski ,\ + \ Sydney Runkle , David Hewitt ,\ + \ Alex Hall , Victorien Plot , Douwe\ + \ Maan " + declared_licenses: [] + declared_licenses_processed: {} + description: "# Pydantic Validation" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl" + hash: + value: "e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz" + hash: + value: "4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/pydantic/pydantic.git" + revision: "" + path: "" + - id: "PyPI::pydantic-core:2.41.5" + purl: "pkg:pypi/pydantic-core@2.41.5" + authors: + - "Samuel Colvin , Adrian Garcia Badaracco <1755071+adriangb@users.noreply.github.com>,\ + \ David Montague , David Hewitt ,\ + \ Sydney Runkle , Victorien Plot " + declared_licenses: [] + declared_licenses_processed: {} + description: "Core functionality for Pydantic validation and serialization" + homepage_url: "https://github.com/pydantic/pydantic-core" + binary_artifact: + url: "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + hash: + value: "406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz" + hash: + value: "08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/pydantic/pydantic-core.git" + revision: "" + path: "" + - id: "PyPI::pygments:2.19.2" + purl: "pkg:pypi/pygments@2.19.2" + authors: + - "Georg Brandl " + declared_licenses: + - "BSD License" + - "BSD-2-Clause" + declared_licenses_processed: + spdx_expression: "BSD-2-Clause" + mapped: + BSD License: "BSD-2-Clause" + description: "Pygments" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl" + hash: + value: "86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz" + hash: + value: "636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/pygments/pygments.git" + revision: "" + path: "" + - id: "PyPI::pytest:9.0.2" + purl: "pkg:pypi/pytest@9.0.2" + authors: + - "Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris Bruynooghe, Brianna\ + \ Laugher, Florian Bruhin, Others (See AUTHORS)" + declared_licenses: [] + declared_licenses_processed: {} + description: "pytest: simple powerful testing with Python" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl" + hash: + value: "711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz" + hash: + value: "75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/pytest-dev/pytest.git" + revision: "" + path: "" + - id: "PyPI::pytokens:0.4.1" + purl: "pkg:pypi/pytokens@0.4.1" + authors: + - "Tushar Sadhwani " + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "# pytokens" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/e0/d2/afe5c7f8607018beb99971489dbb846508f1b8f351fcefc225fcf4b2adc0/pytokens-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl" + hash: + value: "29d1d8fb1030af4d231789959f21821ab6325e463f0503a61d204343c9b355d1" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/b6/34/b4e015b99031667a7b960f888889c5bd34ef585c85e1cb56a594b92836ac/pytokens-0.4.1.tar.gz" + hash: + value: "292052fe80923aae2260c073f822ceba21f3872ced9a68bb7953b348e561179a" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::pyyaml:6.0.3" + purl: "pkg:pypi/pyyaml@6.0.3" + authors: + - "Kirill Simonov " + declared_licenses: + - "MIT" + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "YAML parser and emitter for Python" + homepage_url: "https://pyyaml.org/" + binary_artifact: + url: "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl" + hash: + value: "0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz" + hash: + value: "d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/yaml/pyyaml.git" + revision: "" + path: "" + - id: "PyPI::rich:14.3.3" + purl: "pkg:pypi/rich@14.3.3" + authors: + - "Will McGugan " + declared_licenses: + - "MIT" + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "Render rich text, tables, progress bars, syntax highlighting,\ + \ markdown and more to the terminal" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/14/25/b208c5683343959b670dc001595f2f3737e051da617f66c31f7c4fa93abc/rich-14.3.3-py3-none-any.whl" + hash: + value: "793431c1f8619afa7d3b52b2cdec859562b950ea0d4b6b505397612db8d5362d" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/b3/c6/f3b320c27991c46f43ee9d856302c70dc2d0fb2dba4842ff739d5f46b393/rich-14.3.3.tar.gz" + hash: + value: "b8daa0b9e4eef54dd8cf7c86c03713f53241884e814f4e2f5fb342fe520f639b" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::ruff:0.15.4" + purl: "pkg:pypi/ruff@0.15.4" + authors: + - "\"Astral Software Inc.\" " + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "" + homepage_url: "https://docs.astral.sh/ruff" + binary_artifact: + url: "https://files.pythonhosted.org/packages/ff/90/bf134f4c1e5243e62690e09d63c55df948a74084c8ac3e48a88468314da6/ruff-0.15.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + hash: + value: "451a2e224151729b3b6c9ffb36aed9091b2996fe4bdbd11f47e27d8f2e8888ec" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/da/31/d6e536cdebb6568ae75a7f00e4b4819ae0ad2640c3604c305a0428680b0c/ruff-0.15.4.tar.gz" + hash: + value: "3412195319e42d634470cc97aa9803d07e9d5c9223b99bcb1518f0c725f26ae1" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::ty:0.0.20" + purl: "pkg:pypi/ty@0.0.20" + authors: + - "\"Astral Software Inc.\" " + declared_licenses: + - "MIT License" + declared_licenses_processed: + spdx_expression: "MIT" + mapped: + MIT License: "MIT" + description: "An extremely fast Python type checker, written in Rust." + homepage_url: "https://github.com/astral-sh/ty/" + binary_artifact: + url: "https://files.pythonhosted.org/packages/32/a0/a532c2048533347dff48e9ca98bd86d2c224356e101688a8edaf8d6973fb/ty-0.0.20-py3-none-musllinux_1_2_x86_64.whl" + hash: + value: "d52f7c9ec6e363e094b3c389c344d5a140401f14a77f0625e3f28c21918552f5" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/56/95/8de69bb98417227b01f1b1d743c819d6456c9fd140255b6124b05b17dfd6/ty-0.0.20.tar.gz" + hash: + value: "ebba6be7974c14efbb2a9adda6ac59848f880d7259f089dfa72a093039f1dcc6" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/astral-sh/ty.git" + revision: "" + path: "" + - id: "PyPI::typeguard:4.5.1" + purl: "pkg:pypi/typeguard@4.5.1" + authors: + - "Alex Grönholm " + declared_licenses: [] + declared_licenses_processed: {} + description: "Run-time type checker for Python" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/91/88/b55b3117287a8540b76dbdd87733808d4d01c8067a3b339408c250bb3600/typeguard-4.5.1-py3-none-any.whl" + hash: + value: "44d2bf329d49a244110a090b55f5f91aa82d9a9834ebfd30bcc73651e4a8cc40" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/2b/e8/66e25efcc18542d58706ce4e50415710593721aae26e794ab1dec34fb66f/typeguard-4.5.1.tar.gz" + hash: + value: "f6f8ecbbc819c9bc749983cc67c02391e16a9b43b8b27f15dc70ed7c4a007274" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::types-pyyaml:6.0.12.20250915" + purl: "pkg:pypi/types-pyyaml@6.0.12.20250915" + declared_licenses: [] + declared_licenses_processed: {} + description: "## Typing stubs for PyYAML" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/bd/e0/1eed384f02555dde685fff1a1ac805c1c7dcb6dd019c916fe659b1c1f9ec/types_pyyaml-6.0.12.20250915-py3-none-any.whl" + hash: + value: "e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/7e/69/3c51b36d04da19b92f9e815be12753125bd8bc247ba0470a982e6979e71c/types_pyyaml-6.0.12.20250915.tar.gz" + hash: + value: "0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::typing-extensions:4.15.0" + purl: "pkg:pypi/typing-extensions@4.15.0" + authors: + - "\"Guido van Rossum, Jukka Lehtosalo, Łukasz Langa, Michael Lee\" " + declared_licenses: [] + declared_licenses_processed: {} + description: "Backported and Experimental Type Hints for Python 3.9+" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl" + hash: + value: "f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz" + hash: + value: "0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "" + url: "" + revision: "" + path: "" + - id: "PyPI::typing-inspection:0.4.2" + purl: "pkg:pypi/typing-inspection@0.4.2" + authors: + - "Victorien Plot " + declared_licenses: [] + declared_licenses_processed: {} + description: "Runtime typing introspection tools" + homepage_url: "" + binary_artifact: + url: "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl" + hash: + value: "4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7" + algorithm: "SHA-256" + source_artifact: + url: "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz" + hash: + value: "ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464" + algorithm: "SHA-256" + vcs: + type: "" + url: "" + revision: "" + path: "" + vcs_processed: + type: "Git" + url: "https://github.com/pydantic/typing-inspection.git" + revision: "" + path: "" + dependency_graphs: + PIP: + packages: + - "PyPI::annotated-types:0.7.0" + - "PyPI::anyio:4.12.1" + - "PyPI::argcomplete:3.6.3" + - "PyPI::black:26.1.0" + - "PyPI::certifi:2026.2.25" + - "PyPI::click:8.3.1" + - "PyPI::datamodel-code-generator:0.54.0" + - "PyPI::genson:1.3.0" + - "PyPI::h11:0.16.0" + - "PyPI::httpcore:1.0.9" + - "PyPI::httpx:0.28.1" + - "PyPI::idna:3.11" + - "PyPI::inflect:7.5.0" + - "PyPI::iniconfig:2.3.0" + - "PyPI::isort:7.0.0" + - "PyPI::jinja2:3.1.6" + - "PyPI::markdown-it-py:4.0.0" + - "PyPI::markupsafe:3.0.3" + - "PyPI::mdurl:0.1.2" + - "PyPI::more-itertools:10.8.0" + - "PyPI::mypy-extensions:1.1.0" + - "PyPI::packageurl-python:0.17.6" + - "PyPI::packaging:26.0" + - "PyPI::pathspec:1.0.4" + - "PyPI::platformdirs:4.9.2" + - "PyPI::pluggy:1.6.0" + - "PyPI::pydantic-core:2.41.5" + - "PyPI::pydantic:2.12.5" + - "PyPI::pygments:2.19.2" + - "PyPI::pytest:9.0.2" + - "PyPI::pytokens:0.4.1" + - "PyPI::pyyaml:6.0.3" + - "PyPI::rich:14.3.3" + - "PyPI::ruff:0.15.4" + - "PyPI::ty:0.0.20" + - "PyPI::typeguard:4.5.1" + - "PyPI::types-pyyaml:6.0.12.20250915" + - "PyPI::typing-extensions:4.15.0" + - "PyPI::typing-inspection:0.4.2" + scopes: + :requirements.txt:15544ad032100f4f6bda18c9db6be0f489c50070:install: + - root: 6 + - root: 10 + - root: 21 + - root: 29 + - root: 32 + - root: 33 + - root: 34 + - root: 36 + nodes: + - pkg: 2 + - pkg: 5 + - pkg: 20 + - pkg: 22 + - pkg: 23 + - pkg: 24 + - pkg: 30 + - pkg: 3 + - pkg: 7 + - pkg: 19 + - pkg: 37 + - pkg: 35 + - pkg: 12 + - pkg: 14 + - pkg: 17 + - pkg: 15 + - {} + - pkg: 26 + - pkg: 38 + - pkg: 27 + - pkg: 31 + - pkg: 6 + - pkg: 11 + - pkg: 1 + - pkg: 4 + - pkg: 8 + - pkg: 9 + - pkg: 10 + - pkg: 21 + - pkg: 13 + - pkg: 25 + - pkg: 28 + - pkg: 29 + - pkg: 18 + - pkg: 16 + - pkg: 32 + - pkg: 33 + - pkg: 34 + - pkg: 36 + edges: + - from: 7 + to: 1 + - from: 7 + to: 2 + - from: 7 + to: 3 + - from: 7 + to: 4 + - from: 7 + to: 5 + - from: 7 + to: 6 + - from: 11 + to: 10 + - from: 12 + to: 9 + - from: 12 + to: 11 + - from: 15 + to: 14 + - from: 17 + to: 10 + - from: 18 + to: 10 + - from: 19 + to: 10 + - from: 19 + to: 16 + - from: 19 + to: 17 + - from: 19 + to: 18 + - from: 21 + to: 0 + - from: 21 + to: 3 + - from: 21 + to: 7 + - from: 21 + to: 8 + - from: 21 + to: 12 + - from: 21 + to: 13 + - from: 21 + to: 15 + - from: 21 + to: 19 + - from: 21 + to: 20 + - from: 23 + to: 22 + - from: 26 + to: 24 + - from: 26 + to: 25 + - from: 27 + to: 22 + - from: 27 + to: 23 + - from: 27 + to: 24 + - from: 27 + to: 26 + - from: 32 + to: 3 + - from: 32 + to: 29 + - from: 32 + to: 30 + - from: 32 + to: 31 + - from: 34 + to: 33 + - from: 35 + to: 31 + - from: 35 + to: 34 +scanner: + start_time: "2026-03-04T17:47:15.577755Z" + end_time: "2026-03-04T17:47:25.818236Z" + environment: + ort_version: "80.0.0" + build_jdk: "21.0.10+7-LTS" + java_version: "21.0.10" + os: "Mac OS X" + processors: 12 + max_memory: 6442450944 + variables: + ORT_CONFIG_DIR: "/Users/dhxbwm7/data/ort-config" + HOME: "/Users/dhxbwm7" + SHELL: "/bin/zsh" + TERM: "xterm-ghostty" + JAVA_HOME: "/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home" + GOPATH: "/Users/dhxbwm7/.local/toolchains/golang" + config: + skip_concluded: true + skip_excluded: true + include_files_without_findings: false + archive: + enabled: true + detected_license_mapping: + BSD (Three Clause License): "BSD-3-clause" + CPL-1.0: "EPL-2.0" + EPL-1.0: "EPL-2.0" + LicenseRef-scancode-agpl-generic-additional-terms: "NOASSERTION" + LicenseRef-scancode-free-unknown: "NOASSERTION" + LicenseRef-scancode-generic-cla: "NOASSERTION" + LicenseRef-scancode-generic-exception: "NOASSERTION" + LicenseRef-scancode-generic-export-compliance: "NOASSERTION" + LicenseRef-scancode-generic-tos: "NOASSERTION" + LicenseRef-scancode-generic-trademark: "NOASSERTION" + LicenseRef-scancode-gpl-generic-additional-terms: "NOASSERTION" + LicenseRef-scancode-other-copyleft: "NOASSERTION" + LicenseRef-scancode-other-permissive: "NOASSERTION" + LicenseRef-scancode-patent-disclaimer: "NOASSERTION" + LicenseRef-scancode-unknown: "NOASSERTION" + LicenseRef-scancode-unknown-license-reference: "NOASSERTION" + LicenseRef-scancode-unknown-spdx: "NOASSERTION" + LicenseRef-scancode-warranty-disclaimer: "NOASSERTION" + file_list_storage: + file_storage: null + postgres_storage: null + scanners: + ScanCode: + options: + commandLine: "--copyright,--license,--info,--strip-root,--timeout,600" + commandLineNonConfig: "--processes,3" + preferFileLicense: "true" + SCANOSS: + options: + apiUrl: "https://url/api/v1/scanoss" + writeToStorage: "true" + storages: + postgres: !<.PostgresStorageConfiguration> + connection: + url: "jdbc:postgresql://127.0.0.1:5888/ort?sslmode=disable" + schema: "public" + username: "postgres" + sslmode: "false" + type: "PROVENANCE_BASED" + storage_readers: + - "postgres" + storage_writers: + - "postgres" + ignore_patterns: + - "**/*.ort.yml" + - "**/*.spdx.yml" + - "**/*.spdx.yaml" + - "**/*.spdx.json" + - "**/META-INF/DEPENDENCIES" + - "**/META-INF/DEPENDENCIES.txt" + - "**/META-INF/NOTICE" + - "**/META-INF/NOTICE.txt" + provenance_storage: + file_storage: null + postgres_storage: null + provenances: + - id: "PIP::requirements.txt:15544ad032100f4f6bda18c9db6be0f489c50070" + package_provenance: + vcs_info: + type: "Git" + url: "https://github.com/heliocastro/python-ort.git" + revision: "15544ad032100f4f6bda18c9db6be0f489c50070" + path: "" + resolved_revision: "15544ad032100f4f6bda18c9db6be0f489c50070" + scan_results: + - provenance: + vcs_info: + type: "Git" + url: "https://github.com/heliocastro/python-ort.git" + revision: "15544ad032100f4f6bda18c9db6be0f489c50070" + path: "" + resolved_revision: "15544ad032100f4f6bda18c9db6be0f489c50070" + scanner: + name: "SCANOSS" + version: "0.12.1" + configuration: "" + summary: + start_time: "2026-03-04T17:47:21.487708Z" + end_time: "2026-03-04T17:47:23.583070Z" + snippets: + - source_location: + path: "src/ort/models/analyzer_result.py" + start_line: 16 + end_line: 41 + snippets: + - score: 60.0 + location: + path: "model/src/main/kotlin/AnalyzerResult.kt" + start_line: 31 + end_line: 56 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "86eb0bcdef039e1cde377c92f5b7c44c" + file_url: "https://api.osskb.org/file_contents/86eb0bcdef039e1cde377c92f5b7c44c" + source_hash: "92e61aa942e07cd9a4f2532e009a5de7" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/defect.py" + start_line: 13 + end_line: 85 + snippets: + - score: 83.0 + location: + path: "model/src/main/kotlin/Defect.kt" + start_line: 30 + end_line: 102 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "a80685f3fb8d8d3a7baf0f90dc5db31f" + file_url: "https://api.osskb.org/file_contents/a80685f3fb8d8d3a7baf0f90dc5db31f" + source_hash: "f9e2684212ccee7ab121a13ac73c51b5" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/dependency_graph.py" + start_line: 18 + end_line: 88 + snippets: + - score: 71.0 + location: + path: "main/DependencyGraph.kt" + start_line: 40 + end_line: 110 + provenance: + vcs_info: + type: "" + url: "https://mvnrepository.com/artifact/org.ossreviewtoolkit/model" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:maven/org.ossreviewtoolkit/model" + license: "Apache-2.0" + additional_data: + file_hash: "8c98907b15d954e2d352a7913c167799" + file_url: "https://api.osskb.org/file_contents/8c98907b15d954e2d352a7913c167799" + source_hash: "e3a96f9afc3c8f99358c0cf8a8d2a9e0" + related_purls: "pkg:github/oss-review-toolkit/ort" + - source_location: + path: "src/ort/models/dependency_graph_edge.py" + start_line: 12 + end_line: 17 + snippets: + - score: 17.0 + location: + path: "main/DependencyGraph.kt" + start_line: 386 + end_line: 391 + provenance: + vcs_info: + type: "" + url: "https://mvnrepository.com/artifact/org.ossreviewtoolkit/model" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:maven/org.ossreviewtoolkit/model" + license: "Apache-2.0" + additional_data: + file_hash: "8c98907b15d954e2d352a7913c167799" + file_url: "https://api.osskb.org/file_contents/8c98907b15d954e2d352a7913c167799" + source_hash: "4e86dbe0ea99364f34f3e33f4de0f825" + related_purls: "pkg:github/oss-review-toolkit/ort" + - source_location: + path: "src/ort/models/dependency_graph_node.py" + start_line: 13 + end_line: 40 + snippets: + - score: 52.0 + location: + path: "main/DependencyGraph.kt" + start_line: 349 + end_line: 376 + provenance: + vcs_info: + type: "" + url: "https://mvnrepository.com/artifact/org.ossreviewtoolkit/model" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:maven/org.ossreviewtoolkit/model" + license: "Apache-2.0" + additional_data: + file_hash: "8c98907b15d954e2d352a7913c167799" + file_url: "https://api.osskb.org/file_contents/8c98907b15d954e2d352a7913c167799" + source_hash: "58e1b6afcdc0f18779b9928f0a7efae7" + related_purls: "pkg:github/oss-review-toolkit/ort" + - source_location: + path: "src/ort/models/dependency_reference.py" + start_line: 15 + end_line: 49 + snippets: + - score: 66.0 + location: + path: "main/DependencyGraph.kt" + start_line: 296 + end_line: 330 + provenance: + vcs_info: + type: "" + url: "https://mvnrepository.com/artifact/org.ossreviewtoolkit/model" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:maven/org.ossreviewtoolkit/model" + license: "Apache-2.0" + additional_data: + file_hash: "8c98907b15d954e2d352a7913c167799" + file_url: "https://api.osskb.org/file_contents/8c98907b15d954e2d352a7913c167799" + source_hash: "b30825e16d3b333667168d4d1e7ae1f8" + related_purls: "pkg:github/oss-review-toolkit/ort" + - source_location: + path: "src/ort/models/identifier.py" + start_line: 16 + end_line: 57 + snippets: + - score: 61.0 + location: + path: "model/src/main/kotlin/Identifier.kt" + start_line: 33 + end_line: 74 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "7da74d446ce8d940a10cdd3e1ff0a81e" + file_url: "https://api.osskb.org/file_contents/7da74d446ce8d940a10cdd3e1ff0a81e" + source_hash: "8743e380ef7c44147e374e249ef19951" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/ort_result.py" + start_line: 14 + end_line: 42 + snippets: + - score: 66.0 + location: + path: "model/src/main/kotlin/OrtResult.kt" + start_line: 37 + end_line: 65 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "03091fe83a238c941ac233b79a5ecae1" + file_url: "https://api.osskb.org/file_contents/03091fe83a238c941ac233b79a5ecae1" + source_hash: "7cb6822cfad4ce6beb2f4ab00d7dd406" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/package.py" + start_line: 17 + end_line: 116 + snippets: + - score: 75.0 + location: + path: "model/src/main/kotlin/Package.kt" + start_line: 34 + end_line: 133 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "8618e1d6994aeed61904246d43ca5db0" + file_url: "https://api.osskb.org/file_contents/8618e1d6994aeed61904246d43ca5db0" + source_hash: "c21384e85970ca2f1ade3103b35c4a5b" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/package_curation_data.py" + start_line: 42 + end_line: 47 + snippets: + - score: 9.0 + location: + path: "hermine-cdf47b34/hermine/cube/utils/ort.py" + start_line: 42 + end_line: 47 + provenance: + vcs_info: + type: "Git" + url: "https://gitlab.com/hermine-project/hermine.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:gitlab/hermine-project/hermine" + license: "AGPL-3.0-only" + additional_data: + file_hash: "45f5b0ec20f4143273d9333530df7792" + file_url: "https://api.osskb.org/file_contents/45f5b0ec20f4143273d9333530df7792" + source_hash: "3d28cb07717fb1097ad86ec18416e38d" + - source_location: + path: "src/ort/models/package_linkage.py" + start_line: 15 + end_line: 27 + snippets: + - score: 37.0 + location: + path: "model/src/main/kotlin/PackageLinkage.kt" + start_line: 27 + end_line: 39 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "68eb07ceac82f5f73eb651e11ce400e3" + file_url: "https://api.osskb.org/file_contents/68eb07ceac82f5f73eb651e11ce400e3" + source_hash: "b8a12cc358df01f32d25c5713dc5223f" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/package_reference.py" + start_line: 14 + end_line: 28 + snippets: + - score: 43.0 + location: + path: "PackageReference.kt" + start_line: 32 + end_line: 46 + provenance: + vcs_info: + type: "" + url: "https://mvnrepository.com/artifact/org.ossreviewtoolkit/model" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:maven/org.ossreviewtoolkit/model" + license: "Apache-2.0" + additional_data: + file_hash: "570a5657aeb89804bbe6486dde07be75" + file_url: "https://api.osskb.org/file_contents/570a5657aeb89804bbe6486dde07be75" + source_hash: "6de5f0299efa1d1852fde5353f5aed75" + related_purls: "pkg:github/oss-review-toolkit/ort" + - source_location: + path: "src/ort/models/project.py" + start_line: 16 + end_line: 42 + snippets: + - score: 40.0 + location: + path: "main/Project.kt" + start_line: 35 + end_line: 61 + provenance: + vcs_info: + type: "" + url: "https://mvnrepository.com/artifact/org.ossreviewtoolkit/model" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:maven/org.ossreviewtoolkit/model" + license: "Apache-2.0" + additional_data: + file_hash: "cfaaa208ff90c7a8479b9b38515df788" + file_url: "https://api.osskb.org/file_contents/cfaaa208ff90c7a8479b9b38515df788" + source_hash: "f407fe60c178ba0d5d258ee5e9403200" + related_purls: "pkg:github/oss-review-toolkit/ort" + - source_location: + path: "src/ort/models/project.py" + start_line: 66 + end_line: 73 + snippets: + - score: 40.0 + location: + path: "main/Project.kt" + start_line: 95 + end_line: 102 + provenance: + vcs_info: + type: "" + url: "https://mvnrepository.com/artifact/org.ossreviewtoolkit/model" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:maven/org.ossreviewtoolkit/model" + license: "Apache-2.0" + additional_data: + file_hash: "cfaaa208ff90c7a8479b9b38515df788" + file_url: "https://api.osskb.org/file_contents/cfaaa208ff90c7a8479b9b38515df788" + source_hash: "f407fe60c178ba0d5d258ee5e9403200" + related_purls: "pkg:github/oss-review-toolkit/ort" + - source_location: + path: "src/ort/models/repository.py" + start_line: 15 + end_line: 41 + snippets: + - score: 63.0 + location: + path: "model/src/main/kotlin/Repository.kt" + start_line: 30 + end_line: 56 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "40420fa7a341cd263ffc0ee4a7b471fa" + file_url: "https://api.osskb.org/file_contents/40420fa7a341cd263ffc0ee4a7b471fa" + source_hash: "499dabe5913351e42b979c38bb90d592" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/root_dependency_index.py" + start_line: 10 + end_line: 25 + snippets: + - score: 60.0 + location: + path: "main/DependencyGraph.kt" + start_line: 259 + end_line: 274 + provenance: + vcs_info: + type: "" + url: "https://mvnrepository.com/artifact/org.ossreviewtoolkit/model" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:maven/org.ossreviewtoolkit/model" + license: "Apache-2.0" + additional_data: + file_hash: "8c98907b15d954e2d352a7913c167799" + file_url: "https://api.osskb.org/file_contents/8c98907b15d954e2d352a7913c167799" + source_hash: "f70f4ac917ada56d223e53312e185e28" + related_purls: "pkg:github/oss-review-toolkit/ort" + - source_location: + path: "src/ort/models/scope.py" + start_line: 20 + end_line: 32 + snippets: + - score: 33.0 + location: + path: "model/src/main/kotlin/Scope.kt" + start_line: 31 + end_line: 43 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "84b7d302ccf1409cef20efc041ae4059" + file_url: "https://api.osskb.org/file_contents/84b7d302ccf1409cef20efc041ae4059" + source_hash: "acb3d24c640adf52086661a8e7be49bd" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/vcsinfo.py" + start_line: 14 + end_line: 36 + snippets: + - score: 61.0 + location: + path: "model/src/main/kotlin/VcsInfo.kt" + start_line: 29 + end_line: 51 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "2a2b721be46df363cf984150bf5c8490" + file_url: "https://api.osskb.org/file_contents/2a2b721be46df363cf984150bf5c8490" + source_hash: "d5b2718f926cedd34933718b690a06af" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/vcsinfo_curation_data.py" + start_line: 14 + end_line: 36 + snippets: + - score: 61.0 + location: + path: "model/src/main/kotlin/VcsInfo.kt" + start_line: 29 + end_line: 51 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "2a2b721be46df363cf984150bf5c8490" + file_url: "https://api.osskb.org/file_contents/2a2b721be46df363cf984150bf5c8490" + source_hash: "24d2d3c36318e9b69073ea3fc3f805f9" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/models/vcstype.py" + start_line: 17 + end_line: 23 + snippets: + - score: 12.0 + location: + path: "model/src/main/kotlin/VcsType.kt" + start_line: 26 + end_line: 32 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0" + additional_data: + file_hash: "2e470524aa05f79e718f331f7b453e9f" + file_url: "https://api.osskb.org/file_contents/2e470524aa05f79e718f331f7b453e9f" + source_hash: "4c5acbdc02c2cca189b8f08733fb3bc7" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + - source_location: + path: "src/ort/types/purl_type.py" + start_line: 6 + end_line: 23 + snippets: + - score: 60.0 + location: + path: "vo/models/xml/generics.py" + start_line: 8 + end_line: 25 + provenance: + vcs_info: + type: "" + url: "https://pypi.org/project/vo-models" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:pypi/vo-models" + license: "MIT" + additional_data: + file_hash: "49dfa8931b7708d7f371941e68d425fc" + file_url: "https://api.osskb.org/file_contents/49dfa8931b7708d7f371941e68d425fc" + source_hash: "b11352ed06bcc34831104c1acfaad8e6" + related_purls: "pkg:github/spacetelescope/vo-models" + - source_location: + path: "src/ort/utils/spdx/spdx_expression.py" + start_line: 13 + end_line: 23 + snippets: + - score: 35.0 + location: + path: "utils/spdx/src/main/kotlin/SpdxExpression.kt" + start_line: 41 + end_line: 51 + provenance: + vcs_info: + type: "Git" + url: "https://github.com/oss-review-toolkit/ort.git" + revision: "" + path: "" + resolved_revision: "." + purl: "pkg:github/oss-review-toolkit/ort" + license: "Apache-2.0 AND Classpath-exception-2.0 AND LicenseRef-scancode-unknown-license-reference" + additional_data: + file_hash: "30069e5b95d1b874cb7389cc086f7027" + file_url: "https://api.osskb.org/file_contents/30069e5b95d1b874cb7389cc086f7027" + source_hash: "a60f43a9d2b39352d391dab0f2e7d6aa" + related_purls: "pkg:maven/org.ossreviewtoolkit/scanner" + scanners: + PIP::requirements.txt:15544ad032100f4f6bda18c9db6be0f489c50070: + - "SCANOSS" + files: + - provenance: + vcs_info: + type: "Git" + url: "https://github.com/heliocastro/python-ort.git" + revision: "15544ad032100f4f6bda18c9db6be0f489c50070" + path: "" + resolved_revision: "15544ad032100f4f6bda18c9db6be0f489c50070" + files: + - path: ".github/dependabot.yml" + sha1: "05390588a40f5e1f8b2c9807377968d00476c433" + - path: ".github/workflows/build.yml" + sha1: "2a54c71e9d679ef252d496d3fb936e8ebe94ce42" + - path: ".github/workflows/commit_checks.yaml" + sha1: "35574db17a33d8557847c7676001d494c67b9656" + - path: ".github/workflows/publish.yml" + sha1: "fa90ebe73ab9ce91da1e84c0c15c77daaee8911d" + - path: ".github/workflows/testing.yml" + sha1: "7878c37830871e267a6edad9d7a0b5fa7d562147" + - path: ".gitignore" + sha1: "b7796693dfd9ff6ea255e65e09468fb02566f781" + - path: ".ort.yml" + sha1: "2a584908c35b5d3cf16ffc7f0de36d8f6fb46a9f" + - path: ".pre-commit-config.yaml" + sha1: "324d2a0ea863257927e0938f9b3839e0190b24c7" + - path: "LICENSE" + sha1: "48634f2855bdffa2d5ba1febf4c42209308e90c5" + - path: "README.md" + sha1: "b8a5d57861df7d4eb499eff7b063e21109aa20d6" + - path: "examples/model_relation_test.py" + sha1: "7b7bb074c43dece119ba0162868667f49f298b9b" + - path: "examples/ort_result.py" + sha1: "de93ee0ffa5157dce68a37d27fba042c2fa2cb05" + - path: "examples/repo_config.py" + sha1: "0d1590cffcee90313de67bd08d708e9ef8b31adb" + - path: "licenses/ort/LICENSE" + sha1: "c00ef43045659b53da5d71d49b8cd7e528c9d55b" + - path: "py.typed" + sha1: "da39a3ee5e6b4b0d3255bfef95601890afd80709" + - path: "pyproject.toml" + sha1: "4f12efe3623c0e3d88ccc258e0f2b57aed712280" + - path: "schemas/analyzer-configuration-schema.json" + sha1: "0b7f8a2af3b840e65b715fa89447af35fbf3e323" + - path: "schemas/package-manager-configuration-schema.json" + sha1: "17cbcf79dd75162df1bdc7d3998a9a13005c3c93" + - path: "schemas/package-managers-schema.json" + sha1: "566f7b6b9007f6afaefdb5592a2a30a5ee615275" + - path: "schemas/repository-configuration-schema.json" + sha1: "7e3b9182bca3857ea915f92e7eab5d74beb2eb36" + - path: "scripts/header" + sha1: "94b14a2fca31a46e55fa869240b3d6d4ec019e57" + - path: "scripts/model_generate" + sha1: "68377beea526f439f195f184a65c1ae8e33b5781" + - path: "src/ort/__init__.py" + sha1: "7d368f43b41760884586433aefbd5c90ba47b3b0" + - path: "src/ort/models/__init__.py" + sha1: "dedc5d977d7027676364ad2e58b1c48d88567aec" + - path: "src/ort/models/advisor_capability.py" + sha1: "dcce1989a6e2ed390cefbcefb266f86bf6d3217e" + - path: "src/ort/models/advisor_details.py" + sha1: "b787803e6cda422ef95529e75798297f1c6f9da3" + - path: "src/ort/models/advisor_result.py" + sha1: "0a8716e402cfab9e77ac5ad64b0db42cf89ec23a" + - path: "src/ort/models/advisor_run.py" + sha1: "ec19ec37702f705f8d3d6a855594b445cfd7136e" + - path: "src/ort/models/advisor_summary.py" + sha1: "17cca5de3c0d81e1e9883435140fa638a854ed27" + - path: "src/ort/models/analyzer_result.py" + sha1: "e4a2d62a1459f577153216e91fac211571c582cd" + - path: "src/ort/models/analyzer_run.py" + sha1: "788d735c332a45130b4a0086545ca86d3138b67e" + - path: "src/ort/models/config/advisor_configuration.py" + sha1: "ce837a89fe46da9eb417e897113ad5d9529996d0" + - path: "src/ort/models/config/analyzer_configuration.py" + sha1: "750f08d431964e00901190ff037562b5dd4f4acf" + - path: "src/ort/models/config/curations.py" + sha1: "11983ad2beba134362ecfd9477e1b3133261ea8c" + - path: "src/ort/models/config/excludes.py" + sha1: "64a5664fad72b142f788fe9ebd197b11baac7b45" + - path: "src/ort/models/config/includes.py" + sha1: "098f8feeb50173dffdc53cf147cc74f6bff7cf5c" + - path: "src/ort/models/config/issue_resolution.py" + sha1: "c59c511092b1f3fcf6d8cd5acbf9d14d31262310" + - path: "src/ort/models/config/issue_resolution_reason.py" + sha1: "d760bd54de27f6a56c781a9c6ccc930542ae6653" + - path: "src/ort/models/config/license_choice.py" + sha1: "f1c811ac1de4522e88cc3fb3a16572d50c94d711" + - path: "src/ort/models/config/license_finding_curation.py" + sha1: "512bdb76591f39a5efb82bf431c53ecd433779ec" + - path: "src/ort/models/config/license_finding_curation_reason.py" + sha1: "6666a63b90eddfc9d81a22105fed9bd598a31afa" + - path: "src/ort/models/config/package_configuration.py" + sha1: "32d81d5b621e3b61b877c24d17953a97967c6529" + - path: "src/ort/models/config/package_manager_configuration.py" + sha1: "360a4abca1b9fc212cccf5de88153e671f96ab5a" + - path: "src/ort/models/config/path_exclude.py" + sha1: "2d07738addd1534b503d7368978333d4f585c179" + - path: "src/ort/models/config/path_exclude_reason.py" + sha1: "88d1f8c27bd3d2501491017a3c20e0762a956e15" + - path: "src/ort/models/config/path_include.py" + sha1: "68f41d61ffd3a66528ac63ee5b2baa997f16c8a0" + - path: "src/ort/models/config/path_include_reason.py" + sha1: "d2593856d884895666bd28f13c789e0bb2b32647" + - path: "src/ort/models/config/repository_analyzer_configuration.py" + sha1: "209149ea3e6c66b092409196d179d2552b3b9ebc" + - path: "src/ort/models/config/repository_configuration.py" + sha1: "c009df0b0800749400a67f3cd9b11522f22d04b7" + - path: "src/ort/models/config/resolutions.py" + sha1: "2cb9ee02fd267f62555494daf09364d4d4b4bb4d" + - path: "src/ort/models/config/rule_violation_reason.py" + sha1: "968d63323ef82da2acbdff93fe837fb8ff1e67d8" + - path: "src/ort/models/config/rule_violation_resolution.py" + sha1: "2418f78098382d40bd99f1efa3487378c55e4480" + - path: "src/ort/models/config/scope_exclude.py" + sha1: "b2ed80e812e878ca2466b96aedcbe071817fab18" + - path: "src/ort/models/config/scope_exclude_reason.py" + sha1: "eb76dd2004ef3a854db6e93db9b5c6d4765cf68d" + - path: "src/ort/models/config/snippet/Provenance.py" + sha1: "9d4a7a12f7270fb46b7519a15959b8422f218c48" + - path: "src/ort/models/config/snippet/snippet_choice.py" + sha1: "1cb17d62cb97fe13e6107023fd7d5caa5c29ba9c" + - path: "src/ort/models/config/snippet/snippet_choice_reason.py" + sha1: "742d81e27ecb6548360eda410314716da5102895" + - path: "src/ort/models/config/vcsmatcher.py" + sha1: "6444d689235ebab9a6bf962f9ef7939383444368" + - path: "src/ort/models/config/vulnerability_resolution.py" + sha1: "ca658cc201e3334165a38596454f40e9b93f166a" + - path: "src/ort/models/config/vulnerability_resolution_reason.py" + sha1: "8a40ad978c49e29cd611b2d394a8186e280467d5" + - path: "src/ort/models/defect.py" + sha1: "47312ee69d0d0da76b15d54431a0f1e9f9a103d0" + - path: "src/ort/models/dependency_graph.py" + sha1: "00b4cbf8b773229f15ebf4a5c1f3d620f58c3029" + - path: "src/ort/models/dependency_graph_edge.py" + sha1: "a46ddde2c540ae448e4287397b789d7d03172de9" + - path: "src/ort/models/dependency_graph_node.py" + sha1: "ffd7c521bc40af46cb3fcbf5f95f6f43e4a5f4ec" + - path: "src/ort/models/dependency_reference.py" + sha1: "24013df2aab819e21ec7eb71484886d5a46272d3" + - path: "src/ort/models/hash.py" + sha1: "534a0a473155263e79e71f92da80a073a5309e1e" + - path: "src/ort/models/hash_algorithm.py" + sha1: "9b46c6c149efec54f5d8e04944b27da54ec22b14" + - path: "src/ort/models/identifier.py" + sha1: "658f474c817b9fa255fc31fec0317503e898ba53" + - path: "src/ort/models/issue.py" + sha1: "a7591a08ce0ee763a8265e7f819712c217b01ea1" + - path: "src/ort/models/ort_result.py" + sha1: "a931096f6864acfa30658762732d033652bbd39a" + - path: "src/ort/models/package.py" + sha1: "3f0c139c07c763b7a532950d6ba2e5fd7cb4e3c7" + - path: "src/ort/models/package_curation.py" + sha1: "382029c5aaa9f979acc39b703c77d98f48f5939b" + - path: "src/ort/models/package_curation_data.py" + sha1: "756bdf06bb68e2c18a0a2225f14c02cb4e0a0c90" + - path: "src/ort/models/package_linkage.py" + sha1: "8377fccb601904d7389606620746c8f081d28d33" + - path: "src/ort/models/package_reference.py" + sha1: "e9363fac0b33b6bec07dd065e5a368e669d44efb" + - path: "src/ort/models/project.py" + sha1: "52f1a4917e4ac861d1293db4e5f8ee5b39f58482" + - path: "src/ort/models/remote_artifact.py" + sha1: "40cc6e752bc663153aeb1ef1f4dd76f37e40c6d4" + - path: "src/ort/models/repository.py" + sha1: "ea344d785d682270d5593046e0d06aa11d7075b4" + - path: "src/ort/models/resolutions.py" + sha1: "8981002ac6938797847860c175bc75253a4e4700" + - path: "src/ort/models/root_dependency_index.py" + sha1: "0bff1e0146eb463ace2c5d1a731563954713b9be" + - path: "src/ort/models/scope.py" + sha1: "d5b60393ccf90ea7693d3e65261a02c0ea04b5df" + - path: "src/ort/models/source_code_origin.py" + sha1: "56b8c3ad911689c15e5edf6099230ec51b3ad15c" + - path: "src/ort/models/text_location.py" + sha1: "92ba674cb17c8124c0d9e89a63f1218ea99a61b5" + - path: "src/ort/models/vcsinfo.py" + sha1: "74b0e4ed6a93979898333d1c78a77d2e4f2af782" + - path: "src/ort/models/vcsinfo_curation_data.py" + sha1: "e588ea8c86af759dc16f448ecb3827b57103273c" + - path: "src/ort/models/vcstype.py" + sha1: "91a1412a232994071d404430ffcf78e848c2ba33" + - path: "src/ort/models/vulnerabilities/__init__.py" + sha1: "a5c46f51dafe1f61982fdbf5082e62a282582f25" + - path: "src/ort/models/vulnerabilities/cvss2_rating.py" + sha1: "bcc12cd990c0d1d6e53cc5525a7c7e23c440af05" + - path: "src/ort/models/vulnerabilities/cvss3_rating.py" + sha1: "8bbcc5112917c9861d69c0cb8bffdf78570b334f" + - path: "src/ort/models/vulnerabilities/cvss4_rating.py" + sha1: "3c0da57e400533040b95a1f81da299ab37cc697f" + - path: "src/ort/models/vulnerabilities/vulnerability.py" + sha1: "2f682e1a4771eafa592b4962c9d1cd93f87660cc" + - path: "src/ort/models/vulnerabilities/vulnerability_reference.py" + sha1: "65b2f8c6092f64c7e06f5ed2ef3de1e84e1fb14b" + - path: "src/ort/severity.py" + sha1: "c1419c192986f868bca4bec34d7a8bd9453c9003" + - path: "src/ort/types/__init__.py" + sha1: "da39a3ee5e6b4b0d3255bfef95601890afd80709" + - path: "src/ort/types/purl_type.py" + sha1: "f43aa399006497502165b091806239d88f1eae28" + - path: "src/ort/utils/__init__.py" + sha1: "22da2eeeefaa2536b6255e45bdc689442ec5be16" + - path: "src/ort/utils/convert_enum.py" + sha1: "2ddab30ef827f88022447fb4e2c28045de532a9f" + - path: "src/ort/utils/environment.py" + sha1: "dba2a26dd997afacd3501a26290166e0de17df83" + - path: "src/ort/utils/processed_declared_license.py" + sha1: "f776db751101d4fd67bb2d79dbd8d5aa8b5604fc" + - path: "src/ort/utils/spdx/__init__.py" + sha1: "da39a3ee5e6b4b0d3255bfef95601890afd80709" + - path: "src/ort/utils/spdx/spdx_expression.py" + sha1: "1bb58cdd7808ceeaba2697dbada5e37986fc43a3" + - path: "src/ort/utils/spdx/spdx_license_choice.py" + sha1: "fa0cb20901a5c210be5e6b3248fc2d879f4f85f8" + - path: "tests/__init__.py" + sha1: "da39a3ee5e6b4b0d3255bfef95601890afd80709" + - path: "tests/data/advisor/advisor_result.yml" + sha1: "a8ec6cd0b4ef5180f3f41441c8e91ba58d3cadb2" + - path: "tests/data/advisor/advisor_result_defects.yml" + sha1: "7dd3c512123b52fa0838be962215743b3526be84" + - path: "tests/data/analyzer-result.yml" + sha1: "4591704e7ba8187bbc8c3d54f1b0c10d6ff74e54" + - path: "tests/data/example_curations.yml" + sha1: "94e7c21e1cfd1c3b34d2a512fb46f70a76015a05" + - path: "tests/data/example_simple_curation.yml" + sha1: "29f9c05b9d72d2e70764a30c3b47790e00137820" + - path: "tests/data/ort_config_reference.yml" + sha1: "8dca4defcab047cf39a78f4f345d2d758f70aec3" + - path: "tests/data/ort_configuration_reference.yml" + sha1: "6747e40bcd7085921459bc2848b0d3af60e93c2d" + - path: "tests/data/repo_config/example_simple_package_config.yml" + sha1: "61fe4651661e89ba9a7dc9fae7683cc5a9aaada7" + - path: "tests/data/repo_config/only_include.yml" + sha1: "3b1cd6b788dc1e5ef1beecd7cf34599509b63cf6" + - path: "tests/data/repo_config/only_include_reason_fail.yml" + sha1: "e209966a058a4bc61d6a882821c75b26278c2258" + - path: "tests/data/repo_config/str_boolean.ort.yml" + sha1: "62299b8f293b18f7a5d98caf0407a633bc03446f" + - path: "tests/test_advisor_capability.py" + sha1: "a5c1f1b120b5ec4d547eea43c1136d04ce524374" + - path: "tests/test_advisor_details.py" + sha1: "d73a0b98a67b4ac45c118ff895040623d984abe0" + - path: "tests/test_advisor_result.py" + sha1: "ce3b151ffea641a582a2ea4c3d6da65cdc38d747" + - path: "tests/test_cvss_ratings.py" + sha1: "a23d336d7697a14f9332d7228f10ec7cad02559d" + - path: "tests/test_package_configuration.py" + sha1: "9811bd7d4acf62250885b50df23752b882ee01fc" + - path: "tests/test_package_curation.py" + sha1: "3f2518c5938f7089fe2cd8c940a7d8f23dd05038" + - path: "tests/test_repo_config_files.py" + sha1: "238abd752d7e0f256f986a6e67fce52e9ad88400" + - path: "tests/test_repository_analyzer_config.py" + sha1: "ab867142ffe71ad29f33ec5fee6136a6f5db8ab0" + - path: "tests/test_repository_configuration.py" + sha1: "62f451ce3f5fe8a7258408f80ecd9aade73aa9d9" + - path: "tests/test_vulnerability_reference.py" + sha1: "2d40fca5026770c3d563c1e2be8c7aef32d30637" + - path: "tests/utils/__init__.py" + sha1: "da39a3ee5e6b4b0d3255bfef95601890afd80709" + - path: "tests/utils/load_yaml_config.py" + sha1: "880be5e98ffbd3816527577035a12180ba711dc9" + - path: "uv.lock" + sha1: "24fa33c969bb48c967f3e1c22a836bc6251b08ee" +advisor: null +evaluator: + start_time: "2026-03-12T15:08:05.460355Z" + end_time: "2026-03-12T15:08:08.568584Z" + environment: + ort_version: "81.1.0-008.sha.6d867a5" + build_jdk: "21.0.10" + java_version: "21.0.10" + os: "Mac OS X" + processors: 12 + max_memory: 6442450944 + variables: + ORT_CONFIG_DIR: "/Users/dhxbwm7/data/ort-config" + HOME: "/Users/dhxbwm7" + SHELL: "/bin/zsh" + TERM: "xterm-ghostty" + JAVA_HOME: "/opt/homebrew/opt/openjdk@21/libexec/openjdk.jdk/Contents/Home" + GOPATH: "/Users/dhxbwm7/.local/toolchains/golang" + violations: + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::packaging:26.0" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::packaging:26.0'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::pytest:9.0.2" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::pytest:9.0.2'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::typing-inspection:0.4.2" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::typing-inspection:0.4.2'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::click:8.3.1" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::click:8.3.1'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::markupsafe:3.0.3" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::markupsafe:3.0.3'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::mypy-extensions:1.1.0" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::mypy-extensions:1.1.0'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::pydantic-core:2.41.5" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::pydantic-core:2.41.5'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::black:26.1.0" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::black:26.1.0'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::types-pyyaml:6.0.12.20250915" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::types-pyyaml:6.0.12.20250915'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::idna:3.11" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::idna:3.11'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::pydantic:2.12.5" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::pydantic:2.12.5'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::more-itertools:10.8.0" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::more-itertools:10.8.0'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::anyio:4.12.1" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::anyio:4.12.1'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::iniconfig:2.3.0" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::iniconfig:2.3.0'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::typing-extensions:4.15.0" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::typing-extensions:4.15.0'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." + - rule: "NO_LICENSE_IN_DEPENDENCY" + pkg: "PyPI::typeguard:4.5.1" + license: null + license_sources: [] + severity: "ERROR" + message: "No license information is available for dependency 'PyPI::typeguard:4.5.1'." + how_to_fix: "If the dependency indeed is unlicensed, it must not be used. Otherwise,\ + \ please conclude the appropriate license with a package curation." +resolved_configuration: + package_configurations: [] + package_curations: + - provider: + id: "RepositoryConfiguration" + curations: [] + - provider: + id: "DefaultDir" + curations: + - id: "PyPI::packaging:" + curations: + comment: "Mapping declared license based on\nhttps://github.com/pypa/packaging/blob/20.9/LICENSE,\n\ + https://github.com/pypa/packaging/blob/20.9/LICENSE.BSD,\nhttps://github.com/pypa/packaging/blob/20.9/LICENSE.APACHE\ + \ and\nhttps://github.com/pypa/packaging/blob/20.9/setup.py#L56-L57.\n" + declared_license_mapping: + Apache Software License: "Apache-2.0 OR BSD-2-Clause" + BSD License: "Apache-2.0 OR BSD-2-Clause" + - id: "PyPI::markupsafe:" + curations: + comment: "Mapping declared license based on\nhttps://github.com/pallets/markupsafe/blob/1.1.0/LICENSE.rst,\n\ + https://github.com/pallets/markupsafe/blob/1.1.0/setup.py#L62 and\nhttps://github.com/pallets/markupsafe/blob/1.1.0/setup.py#L73.\n" + declared_license_mapping: + BSD: "BSD-3-Clause" + BSD License: "BSD-3-Clause" + - id: "PyPI::certifi:2026.2.25" + curations: + comment: "Set the source artifact to be scanned as the package metadata including\ + \ its repository url / source artifact\ncannot be retrieved" + source_artifact: + url: "https://files.pythonhosted.org/packages/af/2d/7bf41579a8986e348fa033a31cdd0e4121114f6bce2457e8876010b092dd/certifi-2026.2.25.tar.gz" + hash: + value: "1583dc0160782da8326204a90d7f5861" + algorithm: "MD5" + - id: "PyPI::pygments:" + curations: + comment: "Mapping declared license based on\nhttps://github.com/pygments/pygments/blob/2.16.1/LICENSE,\n\ + https://github.com/pygments/pygments/blob/2.16.1/pyproject.toml#L10 and\n\ + https://github.com/pygments/pygments/blob/2.16.1/pyproject.toml#L28.\n" + declared_license_mapping: + BSD License: "BSD-2-Clause" + - id: "PyPI::pluggy:1.6.0" + curations: + comment: "Set the source artifact to be scanned as the package metadata including\ + \ its repository url / source artifact\ncannot be retrieved." + source_artifact: + url: "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz" + hash: + value: "54391218af778acb006c2d915085d469" + algorithm: "MD5" + - id: "PyPI::click:" + curations: + comment: "Mapping declared license based on\nhttps://github.com/pallets/click/blob/6.4/LICENSE\ + \ and\nhttps://github.com/pallets/click/blob/6.4/setup.py#L24.\n" + declared_license_mapping: + BSD License: "BSD-3-Clause" + - id: "PyPI::httpx:" + curations: + comment: "Mapping declared license based on\nhttps://github.com/encode/httpx/blob/0.28.0/LICENSE.md\ + \ and\nhttps://github.com/encode/httpx/blob/0.28.0/pyproject.toml#L8.\n" + declared_license_mapping: + BSD License: "BSD-3-Clause" + - id: "PyPI::idna:" + curations: + comment: "Mapping declared license based on\nhttps://github.com/kjd/idna/blob/v3.2/LICENSE.md,\n\ + https://github.com/kjd/idna/blob/v3.2/setup.py#L32 and\nhttps://github.com/kjd/idna/blob/v3.2/setup.py#L38.\n" + declared_license_mapping: + BSD License: "BSD-3-Clause" + - id: "PyPI::httpcore:" + curations: + comment: "Mapping declared license based on\nhttps://github.com/encode/httpcore/blob/1.0.9/LICENSE.md,\n\ + https://github.com/encode/httpcore/blob/1.0.9/pyproject.toml#L9 and\nhttps://github.com/encode/httpcore/blob/1.0.9/pyproject.toml#L20.\n" + declared_license_mapping: + BSD License: "BSD-3-Clause" + - id: "PyPI::jinja2:" + curations: + comment: "Mapping declared license based on\nhttps://github.com/pallets/jinja/blob/2.9.5/LICENSE,\n\ + https://github.com/pallets/jinja/blob/2.9.5/setup.py#L45 and\nhttps://github.com/pallets/jinja/blob/2.9.5/setup.py#L57.\n" + declared_license_mapping: + BSD: "BSD-3-Clause" + BSD License: "BSD-3-Clause" + - id: "PyPI::types-pyyaml:6.0.12.20250915" + curations: + comment: "Set the source artifact to be scanned as the package metadata including\ + \ its repository url / source artifact\ncannot be retrieved." + source_artifact: + url: "https://files.pythonhosted.org/packages/7e/69/3c51b36d04da19b92f9e815be12753125bd8bc247ba0470a982e6979e71c/types_pyyaml-6.0.12.20250915.tar.gz" + hash: + value: "f248b64422846c25626c6287d5d13355" + algorithm: "MD5" + - provider: + id: "DefaultFile" + curations: [] + resolutions: {} diff --git a/tests/test_evaluator_run.py b/tests/test_evaluator_run.py new file mode 100644 index 0000000..a1e86e1 --- /dev/null +++ b/tests/test_evaluator_run.py @@ -0,0 +1,212 @@ +# SPDX-FileCopyrightText: 2026 Helio Chissini de Castro +# SPDX-License-Identifier: MIT + +from datetime import datetime, timezone + +import pytest +from pydantic import ValidationError + +from ort.models.evaluator_run import EvaluatorRun +from ort.models.rule_violation import RuleViolation +from ort.models.severity import Severity +from ort.utils.environment import Environment +from tests.utils.load_yaml_config import load_yaml_config + + +def _make_environment() -> Environment: + """Create a minimal Environment for testing.""" + return Environment( + ort_version="81.1.0", + build_jdk="21.0.10", + java_version="21.0.10", + os="Mac OS X", + processors=12, + max_memory=6442450944, + ) + + +def _make_violation() -> RuleViolation: + """Create a minimal RuleViolation for testing.""" + return RuleViolation( + rule="NO_LICENSE_IN_DEPENDENCY", + pkg="PyPI::packaging:26.0", # ty: ignore[invalid-argument-type] + severity=Severity.ERROR, + message="No license information is available for dependency 'PyPI::packaging:26.0'.", + how_to_fix="Please conclude the appropriate license with a package curation.", + ) + + +def test_evaluator_run_valid_minimal(): + """Test creating a minimal valid EvaluatorRun with no violations.""" + run = EvaluatorRun( + start_time=datetime(2026, 3, 12, 15, 8, 5, tzinfo=timezone.utc), + end_time=datetime(2026, 3, 12, 15, 8, 8, tzinfo=timezone.utc), + environment=_make_environment(), + ) + if run.violations != []: + pytest.fail(f"Expected empty violations, got {run.violations}") + if run.start_time.year != 2026: + pytest.fail(f"Expected year 2026, got {run.start_time.year}") + if not (run.end_time > run.start_time): + pytest.fail("Expected end_time to be after start_time") + + +def test_evaluator_run_valid_with_violations(): + """Test creating an EvaluatorRun with a list of violations.""" + violation = _make_violation() + run = EvaluatorRun( + start_time=datetime(2026, 3, 12, 15, 8, 5, tzinfo=timezone.utc), + end_time=datetime(2026, 3, 12, 15, 8, 8, tzinfo=timezone.utc), + environment=_make_environment(), + violations=[violation], + ) + if len(run.violations) != 1: + pytest.fail(f"Expected 1 violation, got {len(run.violations)}") + if run.violations[0].rule != "NO_LICENSE_IN_DEPENDENCY": + pytest.fail(f"Expected rule 'NO_LICENSE_IN_DEPENDENCY', got '{run.violations[0].rule}'") + if run.violations[0].severity != Severity.ERROR: + pytest.fail(f"Expected severity ERROR, got {run.violations[0].severity}") + + +def test_evaluator_run_valid_with_multiple_violations(): + """Test creating an EvaluatorRun with multiple violations.""" + violations = [ + RuleViolation( + rule="NO_LICENSE_IN_DEPENDENCY", + pkg="PyPI::packaging:26.0", # ty: ignore[invalid-argument-type] + severity=Severity.ERROR, + message="No license for packaging.", + how_to_fix="Add license curation.", + ), + RuleViolation( + rule="SOME_WARNING_RULE", + severity=Severity.WARNING, + message="A warning was raised.", + how_to_fix="Review the warning.", + ), + ] + run = EvaluatorRun( + start_time=datetime(2026, 1, 1, 0, 0, 0, tzinfo=timezone.utc), + end_time=datetime(2026, 1, 1, 0, 1, 0, tzinfo=timezone.utc), + environment=_make_environment(), + violations=violations, + ) + if len(run.violations) != 2: + pytest.fail(f"Expected 2 violations, got {len(run.violations)}") + if run.violations[1].severity != Severity.WARNING: + pytest.fail(f"Expected severity WARNING, got {run.violations[1].severity}") + if run.violations[1].pkg is not None: + pytest.fail(f"Expected pkg to be None, got {run.violations[1].pkg}") + + +def test_evaluator_run_invalid_missing_start_time(): + """Test that missing start_time raises a ValidationError.""" + with pytest.raises(ValidationError): + EvaluatorRun( + end_time=datetime(2026, 3, 12, 15, 8, 8, tzinfo=timezone.utc), + environment=_make_environment(), + ) # ty: ignore[missing-argument] + + +def test_evaluator_run_invalid_missing_end_time(): + """Test that missing end_time raises a ValidationError.""" + with pytest.raises(ValidationError): + EvaluatorRun( + start_time=datetime(2026, 3, 12, 15, 8, 5, tzinfo=timezone.utc), + environment=_make_environment(), + ) # ty: ignore[missing-argument] + + +def test_evaluator_run_invalid_missing_environment(): + """Test that missing environment raises a ValidationError.""" + with pytest.raises(ValidationError): + EvaluatorRun( + start_time=datetime(2026, 3, 12, 15, 8, 5, tzinfo=timezone.utc), + end_time=datetime(2026, 3, 12, 15, 8, 8, tzinfo=timezone.utc), + ) # ty: ignore[missing-argument] + + +def test_evaluator_run_invalid_extra_field(): + """Test that extra fields are rejected due to extra='forbid'.""" + with pytest.raises(ValidationError): + EvaluatorRun( + start_time=datetime(2026, 3, 12, 15, 8, 5, tzinfo=timezone.utc), + end_time=datetime(2026, 3, 12, 15, 8, 8, tzinfo=timezone.utc), + environment=_make_environment(), + unknown_field="value", # ty: ignore[unknown-argument] + ) + + +def test_evaluator_run_invalid_violations_type(): + """Test that a non-list violations value raises a ValidationError.""" + with pytest.raises(ValidationError): + EvaluatorRun( + start_time=datetime(2026, 3, 12, 15, 8, 5, tzinfo=timezone.utc), + end_time=datetime(2026, 3, 12, 15, 8, 8, tzinfo=timezone.utc), + environment=_make_environment(), + violations="not_a_list", # ty: ignore[invalid-argument-type] + ) + + +def test_evaluator_run_invalid_violation_entry(): + """Test that an invalid item in violations raises a ValidationError.""" + with pytest.raises(ValidationError): + EvaluatorRun( + start_time=datetime(2026, 3, 12, 15, 8, 5, tzinfo=timezone.utc), + end_time=datetime(2026, 3, 12, 15, 8, 8, tzinfo=timezone.utc), + environment=_make_environment(), + violations=[{"rule": "MISSING_REQUIRED_FIELDS"}], # ty: ignore[invalid-argument-type] + ) + + +def test_evaluator_run_invalid_start_time_type(): + """Test that an invalid start_time type raises a ValidationError.""" + with pytest.raises(ValidationError): + EvaluatorRun( + start_time="not-a-date", # ty: ignore[invalid-argument-type] + end_time=datetime(2026, 3, 12, 15, 8, 8, tzinfo=timezone.utc), + environment=_make_environment(), + ) + + +def test_evaluator_run_invalid_environment_type(): + """Test that an invalid environment type raises a ValidationError.""" + with pytest.raises(ValidationError): + EvaluatorRun( + start_time=datetime(2026, 3, 12, 15, 8, 5, tzinfo=timezone.utc), + end_time=datetime(2026, 3, 12, 15, 8, 8, tzinfo=timezone.utc), + environment="not_an_environment", # ty: ignore[invalid-argument-type] + ) + + +def test_evaluator_run_from_yaml(): + """Test loading a full EvaluatorRun from YAML test data.""" + config_data = load_yaml_config("evaluation-result.yml") + + evaluator_data = config_data.get("evaluator") + if evaluator_data is None: + pytest.fail("Expected 'evaluator' key in YAML data") + + try: + run = EvaluatorRun(**evaluator_data) + except ValidationError as e: + pytest.fail(f"Failed to instantiate EvaluatorRun from YAML: {e}") + + if run.environment.ort_version != "81.1.0-008.sha.6d867a5": + pytest.fail(f"Expected ort_version '81.1.0-008.sha.6d867a5', got '{run.environment.ort_version}'") + if run.environment.os != "Mac OS X": + pytest.fail(f"Expected os 'Mac OS X', got '{run.environment.os}'") + if run.environment.processors != 12: + pytest.fail(f"Expected 12 processors, got {run.environment.processors}") + if len(run.violations) < 1: + pytest.fail(f"Expected at least 1 violation, got {len(run.violations)}") + if run.violations[0].rule != "NO_LICENSE_IN_DEPENDENCY": + pytest.fail(f"Expected first rule 'NO_LICENSE_IN_DEPENDENCY', got '{run.violations[0].rule}'") + if run.violations[0].severity != Severity.ERROR: + pytest.fail(f"Expected severity ERROR, got {run.violations[0].severity}") + if run.violations[0].license is not None: + pytest.fail(f"Expected license to be None, got {run.violations[0].license}") + if run.violations[0].license_sources != set(): + pytest.fail(f"Expected empty license_sources, got {run.violations[0].license_sources}") + if str(run.violations[0].pkg) != "PyPI::packaging:26.0": + pytest.fail(f"Expected pkg 'PyPI::packaging:26.0', got '{run.violations[0].pkg}'") diff --git a/tests/utils/load_yaml_config.py b/tests/utils/load_yaml_config.py index 727b816..7e6ef3f 100644 --- a/tests/utils/load_yaml_config.py +++ b/tests/utils/load_yaml_config.py @@ -5,7 +5,8 @@ from typing import Any import pytest -import yaml + +from ort.utils.yaml_loader import ort_yaml_load DATA_CONFIG_DIR = Path(__file__).parent.parent / "data" @@ -27,6 +28,6 @@ def load_yaml_config(filename: str, data_dir: Path | str | None = None) -> Any: try: with (data_dir_resolved / filename).open() as f: - return yaml.safe_load(f) + return ort_yaml_load(f) except OSError: pytest.fail("Fail to load test assets.") diff --git a/uv.lock b/uv.lock index d7fa2a7..e16dccd 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,10 @@ version = 1 revision = 3 requires-python = ">=3.10" +resolution-markers = [ + "python_full_version >= '3.14'", + "python_full_version < '3.14'", +] [[package]] name = "annotated-types" @@ -36,7 +40,7 @@ wheels = [ [[package]] name = "black" -version = "26.1.0" +version = "26.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -48,34 +52,34 @@ dependencies = [ { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/88/560b11e521c522440af991d46848a2bde64b5f7202ec14e1f46f9509d328/black-26.1.0.tar.gz", hash = "sha256:d294ac3340eef9c9eb5d29288e96dc719ff269a88e27b396340459dd85da4c58", size = 658785, upload-time = "2026-01-18T04:50:11.993Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/51/1b/523329e713f965ad0ea2b7a047eeb003007792a0353622ac7a8cb2ee6fef/black-26.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ca699710dece84e3ebf6e92ee15f5b8f72870ef984bf944a57a777a48357c168", size = 1849661, upload-time = "2026-01-18T04:59:12.425Z" }, - { url = "https://files.pythonhosted.org/packages/14/82/94c0640f7285fa71c2f32879f23e609dd2aa39ba2641f395487f24a578e7/black-26.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5e8e75dabb6eb83d064b0db46392b25cabb6e784ea624219736e8985a6b3675d", size = 1689065, upload-time = "2026-01-18T04:59:13.993Z" }, - { url = "https://files.pythonhosted.org/packages/f0/78/474373cbd798f9291ed8f7107056e343fd39fef42de4a51c7fd0d360840c/black-26.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eb07665d9a907a1a645ee41a0df8a25ffac8ad9c26cdb557b7b88eeeeec934e0", size = 1751502, upload-time = "2026-01-18T04:59:15.971Z" }, - { url = "https://files.pythonhosted.org/packages/29/89/59d0e350123f97bc32c27c4d79563432d7f3530dca2bff64d855c178af8b/black-26.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:7ed300200918147c963c87700ccf9966dceaefbbb7277450a8d646fc5646bf24", size = 1400102, upload-time = "2026-01-18T04:59:17.8Z" }, - { url = "https://files.pythonhosted.org/packages/e1/bc/5d866c7ae1c9d67d308f83af5462ca7046760158bbf142502bad8f22b3a1/black-26.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:c5b7713daea9bf943f79f8c3b46f361cc5229e0e604dcef6a8bb6d1c37d9df89", size = 1207038, upload-time = "2026-01-18T04:59:19.543Z" }, - { url = "https://files.pythonhosted.org/packages/30/83/f05f22ff13756e1a8ce7891db517dbc06200796a16326258268f4658a745/black-26.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3cee1487a9e4c640dc7467aaa543d6c0097c391dc8ac74eb313f2fbf9d7a7cb5", size = 1831956, upload-time = "2026-01-18T04:59:21.38Z" }, - { url = "https://files.pythonhosted.org/packages/7d/f2/b2c570550e39bedc157715e43927360312d6dd677eed2cc149a802577491/black-26.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d62d14ca31c92adf561ebb2e5f2741bf8dea28aef6deb400d49cca011d186c68", size = 1672499, upload-time = "2026-01-18T04:59:23.257Z" }, - { url = "https://files.pythonhosted.org/packages/7a/d7/990d6a94dc9e169f61374b1c3d4f4dd3037e93c2cc12b6f3b12bc663aa7b/black-26.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb1dafbbaa3b1ee8b4550a84425aac8874e5f390200f5502cf3aee4a2acb2f14", size = 1735431, upload-time = "2026-01-18T04:59:24.729Z" }, - { url = "https://files.pythonhosted.org/packages/36/1c/cbd7bae7dd3cb315dfe6eeca802bb56662cc92b89af272e014d98c1f2286/black-26.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:101540cb2a77c680f4f80e628ae98bd2bd8812fb9d72ade4f8995c5ff019e82c", size = 1400468, upload-time = "2026-01-18T04:59:27.381Z" }, - { url = "https://files.pythonhosted.org/packages/59/b1/9fe6132bb2d0d1f7094613320b56297a108ae19ecf3041d9678aec381b37/black-26.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:6f3977a16e347f1b115662be07daa93137259c711e526402aa444d7a88fdc9d4", size = 1207332, upload-time = "2026-01-18T04:59:28.711Z" }, - { url = "https://files.pythonhosted.org/packages/f5/13/710298938a61f0f54cdb4d1c0baeb672c01ff0358712eddaf29f76d32a0b/black-26.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6eeca41e70b5f5c84f2f913af857cf2ce17410847e1d54642e658e078da6544f", size = 1878189, upload-time = "2026-01-18T04:59:30.682Z" }, - { url = "https://files.pythonhosted.org/packages/79/a6/5179beaa57e5dbd2ec9f1c64016214057b4265647c62125aa6aeffb05392/black-26.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:dd39eef053e58e60204f2cdf059e2442e2eb08f15989eefe259870f89614c8b6", size = 1700178, upload-time = "2026-01-18T04:59:32.387Z" }, - { url = "https://files.pythonhosted.org/packages/8c/04/c96f79d7b93e8f09d9298b333ca0d31cd9b2ee6c46c274fd0f531de9dc61/black-26.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9459ad0d6cd483eacad4c6566b0f8e42af5e8b583cee917d90ffaa3778420a0a", size = 1777029, upload-time = "2026-01-18T04:59:33.767Z" }, - { url = "https://files.pythonhosted.org/packages/49/f9/71c161c4c7aa18bdda3776b66ac2dc07aed62053c7c0ff8bbda8c2624fe2/black-26.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a19915ec61f3a8746e8b10adbac4a577c6ba9851fa4a9e9fbfbcf319887a5791", size = 1406466, upload-time = "2026-01-18T04:59:35.177Z" }, - { url = "https://files.pythonhosted.org/packages/4a/8b/a7b0f974e473b159d0ac1b6bcefffeb6bec465898a516ee5cc989503cbc7/black-26.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:643d27fb5facc167c0b1b59d0315f2674a6e950341aed0fc05cf307d22bf4954", size = 1216393, upload-time = "2026-01-18T04:59:37.18Z" }, - { url = "https://files.pythonhosted.org/packages/79/04/fa2f4784f7237279332aa735cdfd5ae2e7730db0072fb2041dadda9ae551/black-26.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ba1d768fbfb6930fc93b0ecc32a43d8861ded16f47a40f14afa9bb04ab93d304", size = 1877781, upload-time = "2026-01-18T04:59:39.054Z" }, - { url = "https://files.pythonhosted.org/packages/cf/ad/5a131b01acc0e5336740a039628c0ab69d60cf09a2c87a4ec49f5826acda/black-26.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2b807c240b64609cb0e80d2200a35b23c7df82259f80bef1b2c96eb422b4aac9", size = 1699670, upload-time = "2026-01-18T04:59:41.005Z" }, - { url = "https://files.pythonhosted.org/packages/da/7c/b05f22964316a52ab6b4265bcd52c0ad2c30d7ca6bd3d0637e438fc32d6e/black-26.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1de0f7d01cc894066a1153b738145b194414cc6eeaad8ef4397ac9abacf40f6b", size = 1775212, upload-time = "2026-01-18T04:59:42.545Z" }, - { url = "https://files.pythonhosted.org/packages/a6/a3/e8d1526bea0446e040193185353920a9506eab60a7d8beb062029129c7d2/black-26.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:91a68ae46bf07868963671e4d05611b179c2313301bd756a89ad4e3b3db2325b", size = 1409953, upload-time = "2026-01-18T04:59:44.357Z" }, - { url = "https://files.pythonhosted.org/packages/c7/5a/d62ebf4d8f5e3a1daa54adaab94c107b57be1b1a2f115a0249b41931e188/black-26.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:be5e2fe860b9bd9edbf676d5b60a9282994c03fbbd40fe8f5e75d194f96064ca", size = 1217707, upload-time = "2026-01-18T04:59:45.719Z" }, - { url = "https://files.pythonhosted.org/packages/6a/83/be35a175aacfce4b05584ac415fd317dd6c24e93a0af2dcedce0f686f5d8/black-26.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9dc8c71656a79ca49b8d3e2ce8103210c9481c57798b48deeb3a8bb02db5f115", size = 1871864, upload-time = "2026-01-18T04:59:47.586Z" }, - { url = "https://files.pythonhosted.org/packages/a5/f5/d33696c099450b1274d925a42b7a030cd3ea1f56d72e5ca8bbed5f52759c/black-26.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b22b3810451abe359a964cc88121d57f7bce482b53a066de0f1584988ca36e79", size = 1701009, upload-time = "2026-01-18T04:59:49.443Z" }, - { url = "https://files.pythonhosted.org/packages/1b/87/670dd888c537acb53a863bc15abbd85b22b429237d9de1b77c0ed6b79c42/black-26.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:53c62883b3f999f14e5d30b5a79bd437236658ad45b2f853906c7cbe79de00af", size = 1767806, upload-time = "2026-01-18T04:59:50.769Z" }, - { url = "https://files.pythonhosted.org/packages/fe/9c/cd3deb79bfec5bcf30f9d2100ffeec63eecce826eb63e3961708b9431ff1/black-26.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:f016baaadc423dc960cdddf9acae679e71ee02c4c341f78f3179d7e4819c095f", size = 1433217, upload-time = "2026-01-18T04:59:52.218Z" }, - { url = "https://files.pythonhosted.org/packages/4e/29/f3be41a1cf502a283506f40f5d27203249d181f7a1a2abce1c6ce188035a/black-26.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:66912475200b67ef5a0ab665011964bf924745103f51977a78b4fb92a9fc1bf0", size = 1245773, upload-time = "2026-01-18T04:59:54.457Z" }, - { url = "https://files.pythonhosted.org/packages/e4/3d/51bdb3ecbfadfaf825ec0c75e1de6077422b4afa2091c6c9ba34fbfc0c2d/black-26.1.0-py3-none-any.whl", hash = "sha256:1054e8e47ebd686e078c0bb0eaf31e6ce69c966058d122f2c0c950311f9f3ede", size = 204010, upload-time = "2026-01-18T04:50:09.978Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/e1/c5/61175d618685d42b005847464b8fb4743a67b1b8fdb75e50e5a96c31a27a/black-26.3.1.tar.gz", hash = "sha256:2c50f5063a9641c7eed7795014ba37b0f5fa227f3d408b968936e24bc0566b07", size = 666155, upload-time = "2026-03-12T03:36:03.593Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/a8/11170031095655d36ebc6664fe0897866f6023892396900eec0e8fdc4299/black-26.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:86a8b5035fce64f5dcd1b794cf8ec4d31fe458cf6ce3986a30deb434df82a1d2", size = 1866562, upload-time = "2026-03-12T03:39:58.639Z" }, + { url = "https://files.pythonhosted.org/packages/69/ce/9e7548d719c3248c6c2abfd555d11169457cbd584d98d179111338423790/black-26.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5602bdb96d52d2d0672f24f6ffe5218795736dd34807fd0fd55ccd6bf206168b", size = 1703623, upload-time = "2026-03-12T03:40:00.347Z" }, + { url = "https://files.pythonhosted.org/packages/7f/0a/8d17d1a9c06f88d3d030d0b1d4373c1551146e252afe4547ed601c0e697f/black-26.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c54a4a82e291a1fee5137371ab488866b7c86a3305af4026bdd4dc78642e1ac", size = 1768388, upload-time = "2026-03-12T03:40:01.765Z" }, + { url = "https://files.pythonhosted.org/packages/52/79/c1ee726e221c863cde5164f925bacf183dfdf0397d4e3f94889439b947b4/black-26.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:6e131579c243c98f35bce64a7e08e87fb2d610544754675d4a0e73a070a5aa3a", size = 1412969, upload-time = "2026-03-12T03:40:03.252Z" }, + { url = "https://files.pythonhosted.org/packages/73/a5/15c01d613f5756f68ed8f6d4ec0a1e24b82b18889fa71affd3d1f7fad058/black-26.3.1-cp310-cp310-win_arm64.whl", hash = "sha256:5ed0ca58586c8d9a487352a96b15272b7fa55d139fc8496b519e78023a8dab0a", size = 1220345, upload-time = "2026-03-12T03:40:04.892Z" }, + { url = "https://files.pythonhosted.org/packages/17/57/5f11c92861f9c92eb9dddf515530bc2d06db843e44bdcf1c83c1427824bc/black-26.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:28ef38aee69e4b12fda8dba75e21f9b4f979b490c8ac0baa7cb505369ac9e1ff", size = 1851987, upload-time = "2026-03-12T03:40:06.248Z" }, + { url = "https://files.pythonhosted.org/packages/54/aa/340a1463660bf6831f9e39646bf774086dbd8ca7fc3cded9d59bbdf4ad0a/black-26.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bf162ed91a26f1adba8efda0b573bc6924ec1408a52cc6f82cb73ec2b142c", size = 1689499, upload-time = "2026-03-12T03:40:07.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/01/b726c93d717d72733da031d2de10b92c9fa4c8d0c67e8a8a372076579279/black-26.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:474c27574d6d7037c1bc875a81d9be0a9a4f9ee95e62800dab3cfaadbf75acd5", size = 1754369, upload-time = "2026-03-12T03:40:09.279Z" }, + { url = "https://files.pythonhosted.org/packages/e3/09/61e91881ca291f150cfc9eb7ba19473c2e59df28859a11a88248b5cbbc4d/black-26.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:5e9d0d86df21f2e1677cc4bd090cd0e446278bcbbe49bf3659c308c3e402843e", size = 1413613, upload-time = "2026-03-12T03:40:10.943Z" }, + { url = "https://files.pythonhosted.org/packages/16/73/544f23891b22e7efe4d8f812371ab85b57f6a01b2fc45e3ba2e52ba985b8/black-26.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9a5e9f45e5d5e1c5b5c29b3bd4265dcc90e8b92cf4534520896ed77f791f4da5", size = 1219719, upload-time = "2026-03-12T03:40:12.597Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f8/da5eae4fc75e78e6dceb60624e1b9662ab00d6b452996046dfa9b8a6025b/black-26.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e6f89631eb88a7302d416594a32faeee9fb8fb848290da9d0a5f2903519fc1", size = 1895920, upload-time = "2026-03-12T03:40:13.921Z" }, + { url = "https://files.pythonhosted.org/packages/2c/9f/04e6f26534da2e1629b2b48255c264cabf5eedc5141d04516d9d68a24111/black-26.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:41cd2012d35b47d589cb8a16faf8a32ef7a336f56356babd9fcf70939ad1897f", size = 1718499, upload-time = "2026-03-12T03:40:15.239Z" }, + { url = "https://files.pythonhosted.org/packages/04/91/a5935b2a63e31b331060c4a9fdb5a6c725840858c599032a6f3aac94055f/black-26.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f76ff19ec5297dd8e66eb64deda23631e642c9393ab592826fd4bdc97a4bce7", size = 1794994, upload-time = "2026-03-12T03:40:17.124Z" }, + { url = "https://files.pythonhosted.org/packages/e7/0a/86e462cdd311a3c2a8ece708d22aba17d0b2a0d5348ca34b40cdcbea512e/black-26.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:ddb113db38838eb9f043623ba274cfaf7d51d5b0c22ecb30afe58b1bb8322983", size = 1420867, upload-time = "2026-03-12T03:40:18.83Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e5/22515a19cb7eaee3440325a6b0d95d2c0e88dd180cb011b12ae488e031d1/black-26.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:dfdd51fc3e64ea4f35873d1b3fb25326773d55d2329ff8449139ebaad7357efb", size = 1230124, upload-time = "2026-03-12T03:40:20.425Z" }, + { url = "https://files.pythonhosted.org/packages/f5/77/5728052a3c0450c53d9bb3945c4c46b91baa62b2cafab6801411b6271e45/black-26.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:855822d90f884905362f602880ed8b5df1b7e3ee7d0db2502d4388a954cc8c54", size = 1895034, upload-time = "2026-03-12T03:40:21.813Z" }, + { url = "https://files.pythonhosted.org/packages/52/73/7cae55fdfdfbe9d19e9a8d25d145018965fe2079fa908101c3733b0c55a0/black-26.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8a33d657f3276328ce00e4d37fe70361e1ec7614da5d7b6e78de5426cb56332f", size = 1718503, upload-time = "2026-03-12T03:40:23.666Z" }, + { url = "https://files.pythonhosted.org/packages/e1/87/af89ad449e8254fdbc74654e6467e3c9381b61472cc532ee350d28cfdafb/black-26.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f1cd08e99d2f9317292a311dfe578fd2a24b15dbce97792f9c4d752275c1fa56", size = 1793557, upload-time = "2026-03-12T03:40:25.497Z" }, + { url = "https://files.pythonhosted.org/packages/43/10/d6c06a791d8124b843bf325ab4ac7d2f5b98731dff84d6064eafd687ded1/black-26.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:c7e72339f841b5a237ff14f7d3880ddd0fc7f98a1199e8c4327f9a4f478c1839", size = 1422766, upload-time = "2026-03-12T03:40:27.14Z" }, + { url = "https://files.pythonhosted.org/packages/59/4f/40a582c015f2d841ac24fed6390bd68f0fc896069ff3a886317959c9daf8/black-26.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:afc622538b430aa4c8c853f7f63bc582b3b8030fd8c80b70fb5fa5b834e575c2", size = 1232140, upload-time = "2026-03-12T03:40:28.882Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/e36e27c9cebc1311b7579210df6f1c86e50f2d7143ae4fcf8a5017dc8809/black-26.3.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2d6bfaf7fd0993b420bed691f20f9492d53ce9a2bcccea4b797d34e947318a78", size = 1889234, upload-time = "2026-03-12T03:40:30.964Z" }, + { url = "https://files.pythonhosted.org/packages/0e/7b/9871acf393f64a5fa33668c19350ca87177b181f44bb3d0c33b2d534f22c/black-26.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:f89f2ab047c76a9c03f78d0d66ca519e389519902fa27e7a91117ef7611c0568", size = 1720522, upload-time = "2026-03-12T03:40:32.346Z" }, + { url = "https://files.pythonhosted.org/packages/03/87/e766c7f2e90c07fb7586cc787c9ae6462b1eedab390191f2b7fc7f6170a9/black-26.3.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b07fc0dab849d24a80a29cfab8d8a19187d1c4685d8a5e6385a5ce323c1f015f", size = 1787824, upload-time = "2026-03-12T03:40:33.636Z" }, + { url = "https://files.pythonhosted.org/packages/ac/94/2424338fb2d1875e9e83eed4c8e9c67f6905ec25afd826a911aea2b02535/black-26.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:0126ae5b7c09957da2bdbd91a9ba1207453feada9e9fe51992848658c6c8e01c", size = 1445855, upload-time = "2026-03-12T03:40:35.442Z" }, + { url = "https://files.pythonhosted.org/packages/86/43/0c3338bd928afb8ee7471f1a4eec3bdbe2245ccb4a646092a222e8669840/black-26.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:92c0ec1f2cc149551a2b7b47efc32c866406b6891b0ee4625e95967c8f4acfb1", size = 1258109, upload-time = "2026-03-12T03:40:36.832Z" }, + { url = "https://files.pythonhosted.org/packages/8e/0d/52d98722666d6fc6c3dd4c76df339501d6efd40e0ff95e6186a7b7f0befd/black-26.3.1-py3-none-any.whl", hash = "sha256:2bd5aa94fc267d38bb21a70d7410a89f1a1d318841855f698746f8e7f51acd1b", size = 207542, upload-time = "2026-03-12T03:36:01.668Z" }, ] [[package]] @@ -110,7 +114,7 @@ wheels = [ [[package]] name = "datamodel-code-generator" -version = "0.54.0" +version = "0.55.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "argcomplete" }, @@ -119,14 +123,13 @@ dependencies = [ { name = "inflect" }, { name = "isort" }, { name = "jinja2" }, - { name = "packaging" }, { name = "pydantic" }, { name = "pyyaml" }, { name = "tomli", marker = "python_full_version < '3.12'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/be/43/2640cd5293fb5430528166908d6439cf3321bc1c54de5fe58ef100b143a1/datamodel_code_generator-0.54.0.tar.gz", hash = "sha256:2b183598d049e265146a8224c35d1bb96a80a641ea8ecd2a82e6a0e97b56da6b", size = 824327, upload-time = "2026-02-14T16:19:05.347Z" } +sdist = { url = "https://files.pythonhosted.org/packages/33/36/ec505ce62c143c0f045e82e2bb0360e2ede765c0cfe3a70bf32c5661b8a2/datamodel_code_generator-0.55.0.tar.gz", hash = "sha256:20ae7a4fbbb12be380f0bd02544db4abae96c5b644d4b3f2b9c3fc0bc9ee1184", size = 833828, upload-time = "2026-03-10T20:41:15.796Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/d9/fd646ea4ae48e374817b2750f5e678a5bf6e10d8924f09cf4cce86a81607/datamodel_code_generator-0.54.0-py3-none-any.whl", hash = "sha256:3156df7a7e8fa5a7c9a6d50836e5ba5abe0532f6b71eee6d73a0c8e1fb5b7e47", size = 261838, upload-time = "2026-02-14T16:19:03.298Z" }, + { url = "https://files.pythonhosted.org/packages/be/c6/2abc9d11adbbf689b6b4dfb7a136d57b9ccaa3b3f1ba83504462109e8dbb/datamodel_code_generator-0.55.0-py3-none-any.whl", hash = "sha256:efa5a925288ca2a135fdc3361c7d774ae5b24b4fd632868363e249d55ea2f137", size = 256860, upload-time = "2026-03-10T20:41:13.488Z" }, ] [package.optional-dependencies] @@ -225,11 +228,11 @@ wheels = [ [[package]] name = "isort" -version = "7.0.0" +version = "8.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/63/53/4f3c058e3bace40282876f9b553343376ee687f3c35a525dc79dbd450f88/isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187", size = 805049, upload-time = "2025-10-11T13:30:59.107Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ef/7c/ec4ab396d31b3b395e2e999c8f46dec78c5e29209fac49d1f4dace04041d/isort-8.0.1.tar.gz", hash = "sha256:171ac4ff559cdc060bcfff550bc8404a486fee0caab245679c2abe7cb253c78d", size = 769592, upload-time = "2026-02-28T10:08:20.685Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/ed/e3705d6d02b4f7aea715a353c8ce193efd0b5db13e204df895d38734c244/isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1", size = 94672, upload-time = "2025-10-11T13:30:57.665Z" }, + { url = "https://files.pythonhosted.org/packages/3e/95/c7c34aa53c16353c56d0b802fba48d5f5caa2cdee7958acbcb795c830416/isort-8.0.1-py3-none-any.whl", hash = "sha256:28b89bc70f751b559aeca209e6120393d43fbe2490de0559662be7a9787e3d75", size = 89733, upload-time = "2026-02-28T10:08:19.466Z" }, ] [[package]] @@ -397,11 +400,11 @@ wheels = [ [[package]] name = "platformdirs" -version = "4.9.2" +version = "4.9.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1b/04/fea538adf7dbbd6d186f551d595961e564a3b6715bdf276b477460858672/platformdirs-4.9.2.tar.gz", hash = "sha256:9a33809944b9db043ad67ca0db94b14bf452cc6aeaac46a88ea55b26e2e9d291", size = 28394, upload-time = "2026-02-16T03:56:10.574Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/56/8d4c30c8a1d07013911a8fdbd8f89440ef9f08d07a1b50ab8ca8be5a20f9/platformdirs-4.9.4.tar.gz", hash = "sha256:1ec356301b7dc906d83f371c8f487070e99d3ccf9e501686456394622a01a934", size = 28737, upload-time = "2026-03-05T18:34:13.271Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/31/05e764397056194206169869b50cf2fee4dbbbc71b344705b9c0d878d4d8/platformdirs-4.9.2-py3-none-any.whl", hash = "sha256:9170634f126f8efdae22fb58ae8a0eaa86f38365bc57897a6c4f781d1f5875bd", size = 21168, upload-time = "2026-02-16T03:56:08.891Z" }, + { url = "https://files.pythonhosted.org/packages/63/d7/97f7e3a6abb67d8080dd406fd4df842c2be0efaf712d1c899c32a075027c/platformdirs-4.9.4-py3-none-any.whl", hash = "sha256:68a9a4619a666ea6439f2ff250c12a853cd1cbd5158d258bd824a7df6be2f868", size = 21216, upload-time = "2026-03-05T18:34:12.172Z" }, ] [[package]] @@ -575,7 +578,7 @@ wheels = [ [[package]] name = "python-ort" -version = "0.6.6" +version = "0.7.0" source = { editable = "." } dependencies = [ { name = "packageurl-python" }, @@ -600,11 +603,11 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ - { name = "datamodel-code-generator", extras = ["http"], specifier = ">=0.54.0" }, + { name = "datamodel-code-generator", extras = ["http"], specifier = ">=0.55.0" }, { name = "pytest", specifier = ">=9.0.2" }, { name = "rich", specifier = ">=14.3.3" }, - { name = "ruff", specifier = ">=0.15.4" }, - { name = "ty", specifier = ">=0.0.20" }, + { name = "ruff", specifier = ">=0.15.5" }, + { name = "ty", specifier = ">=0.0.21" }, { name = "types-pyyaml", specifier = ">=6.0.12.20250915" }, ] @@ -726,27 +729,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.15.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/da/31/d6e536cdebb6568ae75a7f00e4b4819ae0ad2640c3604c305a0428680b0c/ruff-0.15.4.tar.gz", hash = "sha256:3412195319e42d634470cc97aa9803d07e9d5c9223b99bcb1518f0c725f26ae1", size = 4569550, upload-time = "2026-02-26T20:04:14.959Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/82/c11a03cfec3a4d26a0ea1e571f0f44be5993b923f905eeddfc397c13d360/ruff-0.15.4-py3-none-linux_armv6l.whl", hash = "sha256:a1810931c41606c686bae8b5b9a8072adac2f611bb433c0ba476acba17a332e0", size = 10453333, upload-time = "2026-02-26T20:04:20.093Z" }, - { url = "https://files.pythonhosted.org/packages/ce/5d/6a1f271f6e31dffb31855996493641edc3eef8077b883eaf007a2f1c2976/ruff-0.15.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:5a1632c66672b8b4d3e1d1782859e98d6e0b4e70829530666644286600a33992", size = 10853356, upload-time = "2026-02-26T20:04:05.808Z" }, - { url = "https://files.pythonhosted.org/packages/b1/d8/0fab9f8842b83b1a9c2bf81b85063f65e93fb512e60effa95b0be49bfc54/ruff-0.15.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:a4386ba2cd6c0f4ff75252845906acc7c7c8e1ac567b7bc3d373686ac8c222ba", size = 10187434, upload-time = "2026-02-26T20:03:54.656Z" }, - { url = "https://files.pythonhosted.org/packages/85/cc/cc220fd9394eff5db8d94dec199eec56dd6c9f3651d8869d024867a91030/ruff-0.15.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2496488bdfd3732747558b6f95ae427ff066d1fcd054daf75f5a50674411e75", size = 10535456, upload-time = "2026-02-26T20:03:52.738Z" }, - { url = "https://files.pythonhosted.org/packages/fa/0f/bced38fa5cf24373ec767713c8e4cadc90247f3863605fb030e597878661/ruff-0.15.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3f1c4893841ff2d54cbda1b2860fa3260173df5ddd7b95d370186f8a5e66a4ac", size = 10287772, upload-time = "2026-02-26T20:04:08.138Z" }, - { url = "https://files.pythonhosted.org/packages/2b/90/58a1802d84fed15f8f281925b21ab3cecd813bde52a8ca033a4de8ab0e7a/ruff-0.15.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:820b8766bd65503b6c30aaa6331e8ef3a6e564f7999c844e9a547c40179e440a", size = 11049051, upload-time = "2026-02-26T20:04:03.53Z" }, - { url = "https://files.pythonhosted.org/packages/d2/ac/b7ad36703c35f3866584564dc15f12f91cb1a26a897dc2fd13d7cb3ae1af/ruff-0.15.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9fb74bab47139c1751f900f857fa503987253c3ef89129b24ed375e72873e85", size = 11890494, upload-time = "2026-02-26T20:04:10.497Z" }, - { url = "https://files.pythonhosted.org/packages/93/3d/3eb2f47a39a8b0da99faf9c54d3eb24720add1e886a5309d4d1be73a6380/ruff-0.15.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f80c98765949c518142b3a50a5db89343aa90f2c2bf7799de9986498ae6176db", size = 11326221, upload-time = "2026-02-26T20:04:12.84Z" }, - { url = "https://files.pythonhosted.org/packages/ff/90/bf134f4c1e5243e62690e09d63c55df948a74084c8ac3e48a88468314da6/ruff-0.15.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:451a2e224151729b3b6c9ffb36aed9091b2996fe4bdbd11f47e27d8f2e8888ec", size = 11168459, upload-time = "2026-02-26T20:04:00.969Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e5/a64d27688789b06b5d55162aafc32059bb8c989c61a5139a36e1368285eb/ruff-0.15.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:a8f157f2e583c513c4f5f896163a93198297371f34c04220daf40d133fdd4f7f", size = 11104366, upload-time = "2026-02-26T20:03:48.099Z" }, - { url = "https://files.pythonhosted.org/packages/f1/f6/32d1dcb66a2559763fc3027bdd65836cad9eb09d90f2ed6a63d8e9252b02/ruff-0.15.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:917cc68503357021f541e69b35361c99387cdbbf99bd0ea4aa6f28ca99ff5338", size = 10510887, upload-time = "2026-02-26T20:03:45.771Z" }, - { url = "https://files.pythonhosted.org/packages/ff/92/22d1ced50971c5b6433aed166fcef8c9343f567a94cf2b9d9089f6aa80fe/ruff-0.15.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e9737c8161da79fd7cfec19f1e35620375bd8b2a50c3e77fa3d2c16f574105cc", size = 10285939, upload-time = "2026-02-26T20:04:22.42Z" }, - { url = "https://files.pythonhosted.org/packages/e6/f4/7c20aec3143837641a02509a4668fb146a642fd1211846634edc17eb5563/ruff-0.15.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:291258c917539e18f6ba40482fe31d6f5ac023994ee11d7bdafd716f2aab8a68", size = 10765471, upload-time = "2026-02-26T20:03:58.924Z" }, - { url = "https://files.pythonhosted.org/packages/d0/09/6d2f7586f09a16120aebdff8f64d962d7c4348313c77ebb29c566cefc357/ruff-0.15.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3f83c45911da6f2cd5936c436cf86b9f09f09165f033a99dcf7477e34041cbc3", size = 11263382, upload-time = "2026-02-26T20:04:24.424Z" }, - { url = "https://files.pythonhosted.org/packages/1b/fa/2ef715a1cd329ef47c1a050e10dee91a9054b7ce2fcfdd6a06d139afb7ec/ruff-0.15.4-py3-none-win32.whl", hash = "sha256:65594a2d557d4ee9f02834fcdf0a28daa8b3b9f6cb2cb93846025a36db47ef22", size = 10506664, upload-time = "2026-02-26T20:03:50.56Z" }, - { url = "https://files.pythonhosted.org/packages/d0/a8/c688ef7e29983976820d18710f955751d9f4d4eb69df658af3d006e2ba3e/ruff-0.15.4-py3-none-win_amd64.whl", hash = "sha256:04196ad44f0df220c2ece5b0e959c2f37c777375ec744397d21d15b50a75264f", size = 11651048, upload-time = "2026-02-26T20:04:17.191Z" }, - { url = "https://files.pythonhosted.org/packages/3e/0a/9e1be9035b37448ce2e68c978f0591da94389ade5a5abafa4cf99985d1b2/ruff-0.15.4-py3-none-win_arm64.whl", hash = "sha256:60d5177e8cfc70e51b9c5fad936c634872a74209f934c1e79107d11787ad5453", size = 10966776, upload-time = "2026-02-26T20:03:56.908Z" }, +version = "0.15.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/77/9b/840e0039e65fcf12758adf684d2289024d6140cde9268cc59887dc55189c/ruff-0.15.5.tar.gz", hash = "sha256:7c3601d3b6d76dce18c5c824fc8d06f4eef33d6df0c21ec7799510cde0f159a2", size = 4574214, upload-time = "2026-03-05T20:06:34.946Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/20/5369c3ce21588c708bcbe517a8fbe1a8dfdb5dfd5137e14790b1da71612c/ruff-0.15.5-py3-none-linux_armv6l.whl", hash = "sha256:4ae44c42281f42e3b06b988e442d344a5b9b72450ff3c892e30d11b29a96a57c", size = 10478185, upload-time = "2026-03-05T20:06:29.093Z" }, + { url = "https://files.pythonhosted.org/packages/44/ed/e81dd668547da281e5dce710cf0bc60193f8d3d43833e8241d006720e42b/ruff-0.15.5-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6edd3792d408ebcf61adabc01822da687579a1a023f297618ac27a5b51ef0080", size = 10859201, upload-time = "2026-03-05T20:06:32.632Z" }, + { url = "https://files.pythonhosted.org/packages/c4/8f/533075f00aaf19b07c5cd6aa6e5d89424b06b3b3f4583bfa9c640a079059/ruff-0.15.5-py3-none-macosx_11_0_arm64.whl", hash = "sha256:89f463f7c8205a9f8dea9d658d59eff49db05f88f89cc3047fb1a02d9f344010", size = 10184752, upload-time = "2026-03-05T20:06:40.312Z" }, + { url = "https://files.pythonhosted.org/packages/66/0e/ba49e2c3fa0395b3152bad634c7432f7edfc509c133b8f4529053ff024fb/ruff-0.15.5-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba786a8295c6574c1116704cf0b9e6563de3432ac888d8f83685654fe528fd65", size = 10534857, upload-time = "2026-03-05T20:06:19.581Z" }, + { url = "https://files.pythonhosted.org/packages/59/71/39234440f27a226475a0659561adb0d784b4d247dfe7f43ffc12dd02e288/ruff-0.15.5-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fd4b801e57955fe9f02b31d20375ab3a5c4415f2e5105b79fb94cf2642c91440", size = 10309120, upload-time = "2026-03-05T20:06:00.435Z" }, + { url = "https://files.pythonhosted.org/packages/f5/87/4140aa86a93df032156982b726f4952aaec4a883bb98cb6ef73c347da253/ruff-0.15.5-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391f7c73388f3d8c11b794dbbc2959a5b5afe66642c142a6effa90b45f6f5204", size = 11047428, upload-time = "2026-03-05T20:05:51.867Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f7/4953e7e3287676f78fbe85e3a0ca414c5ca81237b7575bdadc00229ac240/ruff-0.15.5-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dc18f30302e379fe1e998548b0f5e9f4dff907f52f73ad6da419ea9c19d66c8", size = 11914251, upload-time = "2026-03-05T20:06:22.887Z" }, + { url = "https://files.pythonhosted.org/packages/77/46/0f7c865c10cf896ccf5a939c3e84e1cfaeed608ff5249584799a74d33835/ruff-0.15.5-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc6e7f90087e2d27f98dc34ed1b3ab7c8f0d273cc5431415454e22c0bd2a681", size = 11333801, upload-time = "2026-03-05T20:05:57.168Z" }, + { url = "https://files.pythonhosted.org/packages/d3/01/a10fe54b653061585e655f5286c2662ebddb68831ed3eaebfb0eb08c0a16/ruff-0.15.5-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1cb7169f53c1ddb06e71a9aebd7e98fc0fea936b39afb36d8e86d36ecc2636a", size = 11206821, upload-time = "2026-03-05T20:06:03.441Z" }, + { url = "https://files.pythonhosted.org/packages/7a/0d/2132ceaf20c5e8699aa83da2706ecb5c5dcdf78b453f77edca7fb70f8a93/ruff-0.15.5-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:9b037924500a31ee17389b5c8c4d88874cc6ea8e42f12e9c61a3d754ff72f1ca", size = 11133326, upload-time = "2026-03-05T20:06:25.655Z" }, + { url = "https://files.pythonhosted.org/packages/72/cb/2e5259a7eb2a0f87c08c0fe5bf5825a1e4b90883a52685524596bfc93072/ruff-0.15.5-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:65bb414e5b4eadd95a8c1e4804f6772bbe8995889f203a01f77ddf2d790929dd", size = 10510820, upload-time = "2026-03-05T20:06:37.79Z" }, + { url = "https://files.pythonhosted.org/packages/ff/20/b67ce78f9e6c59ffbdb5b4503d0090e749b5f2d31b599b554698a80d861c/ruff-0.15.5-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d20aa469ae3b57033519c559e9bc9cd9e782842e39be05b50e852c7c981fa01d", size = 10302395, upload-time = "2026-03-05T20:05:54.504Z" }, + { url = "https://files.pythonhosted.org/packages/5f/e5/719f1acccd31b720d477751558ed74e9c88134adcc377e5e886af89d3072/ruff-0.15.5-py3-none-musllinux_1_2_i686.whl", hash = "sha256:15388dd28c9161cdb8eda68993533acc870aa4e646a0a277aa166de9ad5a8752", size = 10754069, upload-time = "2026-03-05T20:06:06.422Z" }, + { url = "https://files.pythonhosted.org/packages/c3/9c/d1db14469e32d98f3ca27079dbd30b7b44dbb5317d06ab36718dee3baf03/ruff-0.15.5-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b30da330cbd03bed0c21420b6b953158f60c74c54c5f4c1dabbdf3a57bf355d2", size = 11304315, upload-time = "2026-03-05T20:06:10.867Z" }, + { url = "https://files.pythonhosted.org/packages/28/3a/950367aee7c69027f4f422059227b290ed780366b6aecee5de5039d50fa8/ruff-0.15.5-py3-none-win32.whl", hash = "sha256:732e5ee1f98ba5b3679029989a06ca39a950cced52143a0ea82a2102cb592b74", size = 10551676, upload-time = "2026-03-05T20:06:13.705Z" }, + { url = "https://files.pythonhosted.org/packages/b8/00/bf077a505b4e649bdd3c47ff8ec967735ce2544c8e4a43aba42ee9bf935d/ruff-0.15.5-py3-none-win_amd64.whl", hash = "sha256:821d41c5fa9e19117616c35eaa3f4b75046ec76c65e7ae20a333e9a8696bc7fe", size = 11678972, upload-time = "2026-03-05T20:06:45.379Z" }, + { url = "https://files.pythonhosted.org/packages/fe/4e/cd76eca6db6115604b7626668e891c9dd03330384082e33662fb0f113614/ruff-0.15.5-py3-none-win_arm64.whl", hash = "sha256:b498d1c60d2fe5c10c45ec3f698901065772730b411f164ae270bb6bfcc4740b", size = 10965572, upload-time = "2026-03-05T20:06:16.984Z" }, ] [[package]] @@ -805,26 +808,26 @@ wheels = [ [[package]] name = "ty" -version = "0.0.20" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/56/95/8de69bb98417227b01f1b1d743c819d6456c9fd140255b6124b05b17dfd6/ty-0.0.20.tar.gz", hash = "sha256:ebba6be7974c14efbb2a9adda6ac59848f880d7259f089dfa72a093039f1dcc6", size = 5262529, upload-time = "2026-03-02T15:51:36.587Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/2c/718abe48393e521bf852cd6b0f984766869b09c258d6e38a118768a91731/ty-0.0.20-py3-none-linux_armv6l.whl", hash = "sha256:7cc12769c169c9709a829c2248ee2826b7aae82e92caeac813d856f07c021eae", size = 10333656, upload-time = "2026-03-02T15:51:56.461Z" }, - { url = "https://files.pythonhosted.org/packages/41/0e/eb1c4cc4a12862e2327b72657bcebb10b7d9f17046f1bdcd6457a0211615/ty-0.0.20-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3b777c1bf13bc0a95985ebb8a324b8668a4a9b2e514dde5ccf09e4d55d2ff232", size = 10168505, upload-time = "2026-03-02T15:51:51.895Z" }, - { url = "https://files.pythonhosted.org/packages/89/7f/10230798e673f0dd3094dfd16e43bfd90e9494e7af6e8e7db516fb431ddf/ty-0.0.20-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b2a4a7db48bf8cba30365001bc2cad7fd13c1a5aacdd704cc4b7925de8ca5eb3", size = 9678510, upload-time = "2026-03-02T15:51:48.451Z" }, - { url = "https://files.pythonhosted.org/packages/7a/3d/59d9159577494edd1728f7db77b51bb07884bd21384f517963114e3ab5f6/ty-0.0.20-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6846427b8b353a43483e9c19936dc6a25612573b44c8f7d983dfa317e7f00d4c", size = 10162926, upload-time = "2026-03-02T15:51:40.558Z" }, - { url = "https://files.pythonhosted.org/packages/9c/a8/b7273eec3e802f78eb913fbe0ce0c16ef263723173e06a5776a8359b2c66/ty-0.0.20-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:245ceef5bd88df366869385cf96411cb14696334f8daa75597cf7e41c3012eb8", size = 10171702, upload-time = "2026-03-02T15:51:44.069Z" }, - { url = "https://files.pythonhosted.org/packages/9f/32/5f1144f2f04a275109db06e3498450c4721554215b80ae73652ef412eeab/ty-0.0.20-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4d21d1cdf67a444d3c37583c17291ddba9382a9871021f3f5d5735e09e85efe", size = 10682552, upload-time = "2026-03-02T15:51:33.102Z" }, - { url = "https://files.pythonhosted.org/packages/6a/db/9f1f637310792f12bd6ed37d5fc8ab39ba1a9b0c6c55a33865e9f1cad840/ty-0.0.20-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd4ffd907d1bd70e46af9e9a2f88622f215e1bf44658ea43b32c2c0b357299e4", size = 11242605, upload-time = "2026-03-02T15:51:34.895Z" }, - { url = "https://files.pythonhosted.org/packages/1a/68/cc9cae2e732fcfd20ccdffc508407905a023fc8493b8771c392d915528dc/ty-0.0.20-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6594b58d8b0e9d16a22b3045fc1305db4b132c8d70c17784ab8c7a7cc986807", size = 10974655, upload-time = "2026-03-02T15:51:46.011Z" }, - { url = "https://files.pythonhosted.org/packages/1c/c1/b9e3e3f28fe63486331e653f6aeb4184af8b1fe80542fcf74d2dda40a93d/ty-0.0.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3662f890518ce6cf4d7568f57d03906912d2afbf948a01089a28e325b1ef198c", size = 10761325, upload-time = "2026-03-02T15:51:26.818Z" }, - { url = "https://files.pythonhosted.org/packages/39/9e/67db935bdedf219a00fb69ec5437ba24dab66e0f2e706dd54a4eca234b84/ty-0.0.20-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0e3ffbae58f9f0d17cdc4ac6d175ceae560b7ed7d54f9ddfb1c9f31054bcdc2c", size = 10145793, upload-time = "2026-03-02T15:51:38.562Z" }, - { url = "https://files.pythonhosted.org/packages/c7/de/b0eb815d4dc5a819c7e4faddc2a79058611169f7eef07ccc006531ce228c/ty-0.0.20-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:176e52bc8bb00b0e84efd34583962878a447a3a0e34ecc45fd7097a37554261b", size = 10189640, upload-time = "2026-03-02T15:51:50.202Z" }, - { url = "https://files.pythonhosted.org/packages/b8/71/63734923965cbb70df1da3e93e4b8875434e326b89e9f850611122f279bf/ty-0.0.20-py3-none-musllinux_1_2_i686.whl", hash = "sha256:b2bc73025418e976ca4143dde71fb9025a90754a08ac03e6aa9b80d4bed1294b", size = 10370568, upload-time = "2026-03-02T15:51:42.295Z" }, - { url = "https://files.pythonhosted.org/packages/32/a0/a532c2048533347dff48e9ca98bd86d2c224356e101688a8edaf8d6973fb/ty-0.0.20-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d52f7c9ec6e363e094b3c389c344d5a140401f14a77f0625e3f28c21918552f5", size = 10853999, upload-time = "2026-03-02T15:51:58.963Z" }, - { url = "https://files.pythonhosted.org/packages/48/88/36c652c658fe96658043e4abc8ea97801de6fb6e63ab50aaa82807bff1d8/ty-0.0.20-py3-none-win32.whl", hash = "sha256:c7d32bfe93f8fcaa52b6eef3f1b930fd7da410c2c94e96f7412c30cfbabf1d17", size = 9744206, upload-time = "2026-03-02T15:51:54.183Z" }, - { url = "https://files.pythonhosted.org/packages/ff/a7/a4a13bed1d7fd9d97aaa3c5bb5e6d3e9a689e6984806cbca2ab4c9233cac/ty-0.0.20-py3-none-win_amd64.whl", hash = "sha256:a5e10f40fc4a0a1cbcb740a4aad5c7ce35d79f030836ea3183b7a28f43170248", size = 10711999, upload-time = "2026-03-02T15:51:29.212Z" }, - { url = "https://files.pythonhosted.org/packages/8d/7e/6bfd748a9f4ff9267ed3329b86a0f02cdf6ab49f87bc36c8a164852f99fc/ty-0.0.20-py3-none-win_arm64.whl", hash = "sha256:53f7a5c12c960e71f160b734f328eff9a35d578af4b67a36b0bb5990ac5cdc27", size = 10150143, upload-time = "2026-03-02T15:51:31.283Z" }, +version = "0.0.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/20/2ba8fd9493c89c41dfe9dbb73bc70a28b28028463bc0d2897ba8be36230a/ty-0.0.21.tar.gz", hash = "sha256:a4c2ba5d67d64df8fcdefd8b280ac1149d24a73dbda82fa953a0dff9d21400ed", size = 5297967, upload-time = "2026-03-06T01:57:13.809Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/70/edf38bb37517531681d1c37f5df64744e5ad02673c02eb48447eae4bea08/ty-0.0.21-py3-none-linux_armv6l.whl", hash = "sha256:7bdf2f572378de78e1f388d24691c89db51b7caf07cf90f2bfcc1d6b18b70a76", size = 10299222, upload-time = "2026-03-06T01:57:16.64Z" }, + { url = "https://files.pythonhosted.org/packages/72/62/0047b0bd19afeefbc7286f20a5f78a2aa39f92b4d89853f0d7185ab89edc/ty-0.0.21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:7e9613994610431ab8625025bd2880dbcb77c5c9fabdd21134cda12d840a529d", size = 10130513, upload-time = "2026-03-06T01:57:29.93Z" }, + { url = "https://files.pythonhosted.org/packages/a2/20/0b93a9e91aaed23155780258cdfdb4726ef68b6985378ac069bc427291a0/ty-0.0.21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:56d3b198b64dd0a19b2b66e257deaed2ecea568e722ae5352f3c6fb62027f89d", size = 9605425, upload-time = "2026-03-06T01:57:27.115Z" }, + { url = "https://files.pythonhosted.org/packages/ea/fd/9945e2fa2996a1287b1e1d7ce050e97e1f420233b271e770934bfa0880a0/ty-0.0.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d23d2c34f7a77d974bb08f0860ef700addc8a683d81a0319f71c08f87506cfd0", size = 10108298, upload-time = "2026-03-06T01:57:35.429Z" }, + { url = "https://files.pythonhosted.org/packages/52/e7/4ec52fcb15f3200826c9f048472c062549a05b0d1ef0b51f32d527b513c4/ty-0.0.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:56b01fd2519637a4ca88344f61c96225f540c98ff18bca321d4eaa7bb0f7aa2f", size = 10121556, upload-time = "2026-03-06T01:57:03.242Z" }, + { url = "https://files.pythonhosted.org/packages/ee/c0/ad457be2a8abea0f25549598bd098554540ced66229488daa0d558dad3c8/ty-0.0.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9de7e11c63c6afc40f3e9ba716374add171aee7fabc70b5146a510705c6d41b", size = 10603264, upload-time = "2026-03-06T01:56:52.134Z" }, + { url = "https://files.pythonhosted.org/packages/f8/5b/2ecc7a2175243a4bcb72f5298ae41feabbb93b764bb0dc45722f3752c2c2/ty-0.0.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62f7f5b235c4f7876db305c36997aea07b7af29b1a068f373d0e2547e25f32ff", size = 11196428, upload-time = "2026-03-06T01:57:32.94Z" }, + { url = "https://files.pythonhosted.org/packages/37/f5/aff507d6a901f328ef96a298032b0c11aaaf950a146ed7dd3b5bf2cd3acf/ty-0.0.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ee8399f7c453a425291e6688efe430cfae7ab0ac4ffd50eba9f872bf878b54f6", size = 10866355, upload-time = "2026-03-06T01:56:57.831Z" }, + { url = "https://files.pythonhosted.org/packages/be/30/822bbcb92d55b65989aa7ed06d9585f28ade9c9447369194ed4b0fb3b5b9/ty-0.0.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210e7568c9f886c4d01308d751949ee714ad7ad9d7d928d2ba90d329dd880367", size = 10738177, upload-time = "2026-03-06T01:57:11.256Z" }, + { url = "https://files.pythonhosted.org/packages/57/cc/46e7991b6469e93ac2c7e533a028983e402485580150ac864c56352a3a82/ty-0.0.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:53508e345b11569f78b21ba8e2b4e61df38a9754947fb3cd9f2ef574367338fb", size = 10079158, upload-time = "2026-03-06T01:57:00.516Z" }, + { url = "https://files.pythonhosted.org/packages/15/c2/0bbdadfbd008240f8f1a87dc877433cb3884436097926107ccf06e618199/ty-0.0.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:553e43571f4a35604c36cfd07d8b61a5eb7a714e3c67f8c4ff2cf674fefbaef9", size = 10150535, upload-time = "2026-03-06T01:57:08.815Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b5/2dbdb7b57b5362200ef0a39738ebd31331726328336def0143ac097ee59d/ty-0.0.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:666f6822e3b9200abfa7e95eb0ddd576460adb8d66b550c0ad2c70abc84a2048", size = 10319803, upload-time = "2026-03-06T01:57:19.106Z" }, + { url = "https://files.pythonhosted.org/packages/72/84/70e52c0b7abc7c2086f9876ef454a73b161d3125315536d8d7e911c94ca4/ty-0.0.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a0854d008347ce4a5fb351af132f660a390ab2a1163444d075251d43e6f74b9b", size = 10826239, upload-time = "2026-03-06T01:57:21.727Z" }, + { url = "https://files.pythonhosted.org/packages/a1/8a/1f72480fd013bbc6cd1929002abbbcde9a0b08ead6a15154de9d7f7fa37e/ty-0.0.21-py3-none-win32.whl", hash = "sha256:bef3ab4c7b966bcc276a8ac6c11b63ba222d21355b48d471ea782c4104eee4e0", size = 9693196, upload-time = "2026-03-06T01:57:24.126Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f8/1104808b875c26c640e536945753a78562d606bef4e241d9dbf3d92477f6/ty-0.0.21-py3-none-win_amd64.whl", hash = "sha256:a709d576e5bea84b745d43058d8b9cd4f27f74a0b24acb4b0cbb7d3d41e0d050", size = 10668660, upload-time = "2026-03-06T01:56:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/1b/b8/25e0adc404bbf986977657b25318991f93097b49f8aea640d93c0b0db68e/ty-0.0.21-py3-none-win_arm64.whl", hash = "sha256:f72047996598ac20553fb7e21ba5741e3c82dee4e9eadf10d954551a5fe09391", size = 10104161, upload-time = "2026-03-06T01:57:06.072Z" }, ] [[package]]