python-ort 0.6.5__tar.gz → 0.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. {python_ort-0.6.5 → python_ort-0.7.0}/PKG-INFO +1 -1
  2. {python_ort-0.6.5 → python_ort-0.7.0}/pyproject.toml +4 -10
  3. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/__init__.py +3 -0
  4. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/advisor_capability.py +2 -2
  5. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/advisor_details.py +1 -18
  6. python_ort-0.7.0/src/ort/models/advisor_run.py +25 -0
  7. python_ort-0.7.0/src/ort/models/analyzer_run.py +24 -0
  8. python_ort-0.6.5/src/ort/models/analyzer_run.py → python_ort-0.7.0/src/ort/models/base_run.py +1 -10
  9. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/issue_resolution.py +1 -8
  10. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/issue_resolution_reason.py +2 -2
  11. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/path_exclude.py +1 -8
  12. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/path_exclude_reason.py +2 -2
  13. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/path_include.py +1 -8
  14. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/path_include_reason.py +2 -2
  15. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/repository_configuration.py +2 -2
  16. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/rule_violation_reason.py +2 -2
  17. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/rule_violation_resolution.py +1 -8
  18. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/scope_exclude.py +1 -7
  19. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/scope_exclude_reason.py +2 -2
  20. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/snippet/snippet_choice_reason.py +2 -2
  21. python_ort-0.7.0/src/ort/models/config/snippet/snippet_choices.py +25 -0
  22. python_ort-0.6.5/src/ort/models/config/snippet/Provenance.py → python_ort-0.7.0/src/ort/models/config/snippet/snippet_provenance.py +2 -1
  23. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/vulnerability_resolution.py +1 -8
  24. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/vulnerability_resolution_reason.py +2 -2
  25. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/dependency_graph_node.py +1 -11
  26. python_ort-0.7.0/src/ort/models/evaluator_run.py +19 -0
  27. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/issue.py +1 -7
  28. python_ort-0.7.0/src/ort/models/license_source.py +23 -0
  29. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/ort_result.py +7 -1
  30. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/package_linkage.py +2 -2
  31. python_ort-0.7.0/src/ort/models/provenance.py +85 -0
  32. python_ort-0.7.0/src/ort/models/rule_violation.py +50 -0
  33. python_ort-0.7.0/src/ort/models/severity.py +23 -0
  34. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/severity.py +2 -2
  35. python_ort-0.7.0/src/ort/types/__init__.py +0 -0
  36. python_ort-0.7.0/src/ort/utils/__init__.py +15 -0
  37. python_ort-0.7.0/src/ort/utils/spdx/__init__.py +0 -0
  38. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/utils/spdx/spdx_expression.py +2 -2
  39. python_ort-0.7.0/src/ort/utils/validated_enum.py +34 -0
  40. python_ort-0.7.0/src/ort/utils/yaml_loader.py +43 -0
  41. python_ort-0.6.5/src/ort/models/advisor_run.py +0 -39
  42. python_ort-0.6.5/src/ort/utils/__init__.py +0 -12
  43. python_ort-0.6.5/src/ort/utils/convert_enum.py +0 -18
  44. {python_ort-0.6.5 → python_ort-0.7.0}/LICENSE +0 -0
  45. {python_ort-0.6.5 → python_ort-0.7.0}/README.md +0 -0
  46. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/__init__.py +0 -0
  47. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/advisor_result.py +0 -0
  48. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/advisor_summary.py +0 -0
  49. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/analyzer_result.py +0 -0
  50. {python_ort-0.6.5/src/ort/types → python_ort-0.7.0/src/ort/models/config}/__init__.py +0 -0
  51. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/advisor_configuration.py +0 -0
  52. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/analyzer_configuration.py +0 -0
  53. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/curations.py +0 -0
  54. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/excludes.py +0 -0
  55. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/includes.py +0 -0
  56. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/license_choice.py +0 -0
  57. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/license_finding_curation.py +0 -0
  58. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/license_finding_curation_reason.py +0 -0
  59. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/package_configuration.py +0 -0
  60. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/package_manager_configuration.py +0 -0
  61. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/repository_analyzer_configuration.py +0 -0
  62. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/resolutions.py +0 -0
  63. {python_ort-0.6.5/src/ort/utils/spdx → python_ort-0.7.0/src/ort/models/config/snippet}/__init__.py +0 -0
  64. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/snippet/snippet_choice.py +0 -0
  65. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/config/vcsmatcher.py +0 -0
  66. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/defect.py +0 -0
  67. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/dependency_graph.py +0 -0
  68. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/dependency_graph_edge.py +0 -0
  69. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/dependency_reference.py +0 -0
  70. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/hash.py +0 -0
  71. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/hash_algorithm.py +0 -0
  72. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/identifier.py +0 -0
  73. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/package.py +0 -0
  74. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/package_curation.py +0 -0
  75. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/package_curation_data.py +0 -0
  76. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/package_reference.py +0 -0
  77. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/project.py +0 -0
  78. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/remote_artifact.py +0 -0
  79. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/repository.py +0 -0
  80. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/resolutions.py +0 -0
  81. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/root_dependency_index.py +0 -0
  82. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/scope.py +0 -0
  83. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/source_code_origin.py +0 -0
  84. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/text_location.py +0 -0
  85. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/vcsinfo.py +0 -0
  86. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/vcsinfo_curation_data.py +0 -0
  87. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/vcstype.py +0 -0
  88. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/vulnerabilities/__init__.py +0 -0
  89. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/vulnerabilities/cvss2_rating.py +0 -0
  90. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/vulnerabilities/cvss3_rating.py +0 -0
  91. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/vulnerabilities/cvss4_rating.py +0 -0
  92. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/vulnerabilities/vulnerability.py +0 -0
  93. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/models/vulnerabilities/vulnerability_reference.py +0 -0
  94. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/types/purl_type.py +0 -0
  95. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/utils/environment.py +0 -0
  96. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/utils/processed_declared_license.py +0 -0
  97. {python_ort-0.6.5 → python_ort-0.7.0}/src/ort/utils/spdx/spdx_license_choice.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-ort
3
- Version: 0.6.5
3
+ Version: 0.7.0
4
4
  Summary: A Python Ort model serialization library
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -4,7 +4,7 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "python-ort"
7
- version = "0.6.5"
7
+ version = "0.7.0"
8
8
  description = "A Python Ort model serialization library"
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -35,11 +35,11 @@ module-root = "src"
35
35
 
36
36
  [dependency-groups]
37
37
  dev = [
38
- "datamodel-code-generator[http]>=0.54.0",
38
+ "datamodel-code-generator[http]>=0.55.0",
39
39
  "pytest>=9.0.2",
40
40
  "rich>=14.3.3",
41
- "ruff>=0.15.4",
42
- "ty>=0.0.20",
41
+ "ruff>=0.15.5",
42
+ "ty>=0.0.21",
43
43
  "types-pyyaml>=6.0.12.20250915",
44
44
  ]
45
45
 
@@ -159,9 +159,3 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
159
159
  quote-style = "double"
160
160
  indent-style = "space"
161
161
  skip-magic-trailing-comma = false
162
-
163
- [tool.pyrefly]
164
- project_includes = [
165
- "src/ort/**",
166
- "tests/**",
167
- ]
@@ -5,9 +5,12 @@
5
5
  from .models.analyzer_result import AnalyzerResult
6
6
  from .models.config.repository_configuration import RepositoryConfiguration
7
7
  from .models.ort_result import OrtResult
8
+ from .utils.yaml_loader import OrtYamlLoader, ort_yaml_load
8
9
 
9
10
  __all__ = [
10
11
  "AnalyzerResult",
12
+ "OrtYamlLoader",
11
13
  "RepositoryConfiguration",
12
14
  "OrtResult",
15
+ "ort_yaml_load",
13
16
  ]
@@ -2,10 +2,10 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from enum import IntEnum
5
+ from ort.utils.validated_enum import ValidatedIntEnum
6
6
 
7
7
 
8
- class AdvisorCapability(IntEnum):
8
+ class AdvisorCapability(ValidatedIntEnum):
9
9
  """
10
10
  An enum class that defines the capabilities of a specific advisor implementation.
11
11
 
@@ -2,7 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from pydantic import BaseModel, ConfigDict, Field, field_validator
5
+ from pydantic import BaseModel, ConfigDict, Field
6
6
 
7
7
  from ort.models import AdvisorCapability
8
8
 
@@ -22,20 +22,3 @@ class AdvisorDetails(BaseModel):
22
22
  description="The capabilities of the used advisor. This property indicates, which kind of findings"
23
23
  "are retrieved by the advisor."
24
24
  )
25
-
26
- @field_validator("capabilities", mode="before")
27
- @classmethod
28
- def convert_capability(cls, v):
29
- def _convert(item):
30
- if isinstance(item, str):
31
- try:
32
- return AdvisorCapability[item]
33
- except KeyError:
34
- raise ValueError(f"Invalid capability: {item}")
35
- return item
36
-
37
- if isinstance(v, (list, set)):
38
- return {_convert(item) for item in v}
39
- if isinstance(v, str):
40
- return _convert(v)
41
- return v
@@ -0,0 +1,25 @@
1
+ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import Field
6
+
7
+ from .advisor_result import AdvisorResult
8
+ from .base_run import BaseRun
9
+ from .config.advisor_configuration import AdvisorConfiguration
10
+ from .identifier import Identifier
11
+
12
+
13
+ class AdvisorRun(BaseRun):
14
+ """
15
+ Type alias for a function that allows filtering of [AdvisorResult]s.
16
+
17
+ """
18
+
19
+ config: AdvisorConfiguration = Field(
20
+ description="The [AdvisorConfiguration] used for this run.",
21
+ )
22
+ results: dict[Identifier, list[AdvisorResult]] = Field(
23
+ default_factory=dict,
24
+ description="The result of this run.",
25
+ )
@@ -0,0 +1,24 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import Field
6
+
7
+ from .analyzer_result import AnalyzerResult
8
+ from .base_run import BaseRun
9
+ from .config.analyzer_configuration import AnalyzerConfiguration
10
+
11
+
12
+ class AnalyzerRun(BaseRun):
13
+ """
14
+ The summary of a single run of the analyzer.
15
+
16
+ """
17
+
18
+ config: AnalyzerConfiguration = Field(
19
+ description="The [AnalyzerConfiguration] used for this run.",
20
+ )
21
+ result: AnalyzerResult | None = Field(
22
+ default=None,
23
+ description="The result of this run.",
24
+ )
@@ -5,12 +5,10 @@ from datetime import datetime
5
5
 
6
6
  from pydantic import BaseModel, ConfigDict, Field
7
7
 
8
- from ort.models import AnalyzerResult
9
- from ort.models.config.analyzer_configuration import AnalyzerConfiguration
10
8
  from ort.utils.environment import Environment
11
9
 
12
10
 
13
- class AnalyzerRun(BaseModel):
11
+ class BaseRun(BaseModel):
14
12
  """
15
13
  The summary of a single run of the analyzer.
16
14
 
@@ -28,10 +26,3 @@ class AnalyzerRun(BaseModel):
28
26
  environment: Environment = Field(
29
27
  description="The [Environment] in which the analyzer was executed.",
30
28
  )
31
- config: AnalyzerConfiguration = Field(
32
- description="The [AnalyzerConfiguration] used for this run.",
33
- )
34
- result: AnalyzerResult | None = Field(
35
- default=None,
36
- description="The result of this run.",
37
- )
@@ -2,9 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from pydantic import BaseModel, ConfigDict, Field, field_validator
6
-
7
- from ort.utils import convert_enum
5
+ from pydantic import BaseModel, ConfigDict, Field
8
6
 
9
7
  from .issue_resolution_reason import IssueResolutionReason
10
8
 
@@ -32,8 +30,3 @@ class IssueResolution(BaseModel):
32
30
  comment: str = Field(
33
31
  description="A comment to further explain why the [reason] is applicable here.",
34
32
  )
35
-
36
- @field_validator("reason", mode="before")
37
- @classmethod
38
- def validate_reason(cls, value):
39
- return convert_enum(IssueResolutionReason, value)
@@ -1,10 +1,10 @@
1
1
  # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
- from enum import IntEnum
4
+ from ort.utils.validated_enum import ValidatedIntEnum
5
5
 
6
6
 
7
- class IssueResolutionReason(IntEnum):
7
+ class IssueResolutionReason(ValidatedIntEnum):
8
8
  """
9
9
  Possible reasons for resolving an Issue using an IssueResolution.
10
10
 
@@ -2,9 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from pydantic import BaseModel, ConfigDict, Field, field_validator
6
-
7
- from ort.utils import convert_enum
5
+ from pydantic import BaseModel, ConfigDict, Field
8
6
 
9
7
  from .path_exclude_reason import PathExcludeReason
10
8
 
@@ -32,8 +30,3 @@ class PathExclude(BaseModel):
32
30
  default_factory=str,
33
31
  description="A comment to further explain why the [reason] is applicable here.",
34
32
  )
35
-
36
- @field_validator("reason", mode="before")
37
- @classmethod
38
- def validate_reason(cls, value):
39
- return convert_enum(PathExcludeReason, value)
@@ -1,10 +1,10 @@
1
1
  # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
- from enum import IntEnum
4
+ from ort.utils.validated_enum import ValidatedIntEnum
5
5
 
6
6
 
7
- class PathExcludeReason(IntEnum):
7
+ class PathExcludeReason(ValidatedIntEnum):
8
8
  """
9
9
  Possible reasons for excluding a path.
10
10
 
@@ -2,9 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from pydantic import BaseModel, ConfigDict, Field, field_validator
6
-
7
- from ort.utils import convert_enum
5
+ from pydantic import BaseModel, ConfigDict, Field
8
6
 
9
7
  from .path_include_reason import PathIncludeReason
10
8
 
@@ -32,8 +30,3 @@ class PathInclude(BaseModel):
32
30
  default_factory=str,
33
31
  description="A comment to further explain why the [reason] is applicable here.",
34
32
  )
35
-
36
- @field_validator("reason", mode="before")
37
- @classmethod
38
- def validate_reason(cls, value):
39
- return convert_enum(PathIncludeReason, value)
@@ -1,10 +1,10 @@
1
1
  # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
- from enum import IntEnum
4
+ from ort.utils.validated_enum import ValidatedIntEnum
5
5
 
6
6
 
7
- class PathIncludeReason(IntEnum):
7
+ class PathIncludeReason(ValidatedIntEnum):
8
8
  """
9
9
  Possible reasons for including a path.
10
10
 
@@ -11,7 +11,7 @@ from .license_choice import LicenseChoice
11
11
  from .package_configuration import PackageConfiguration
12
12
  from .repository_analyzer_configuration import RepositoryAnalyzerConfiguration
13
13
  from .resolutions import Resolutions
14
- from .snippet.snippet_choice import SnippetChoice
14
+ from .snippet.snippet_choices import SnippetChoices
15
15
 
16
16
 
17
17
  class RepositoryConfiguration(BaseModel):
@@ -60,7 +60,7 @@ class RepositoryConfiguration(BaseModel):
60
60
  None,
61
61
  description="A configuration to select a license from a multi-licensed package.",
62
62
  )
63
- snippet_choices: list[SnippetChoice] = Field(
63
+ snippet_choices: list[SnippetChoices] = Field(
64
64
  default_factory=list,
65
65
  description="A configuration to select a snippet from a package with multiple snippet findings.",
66
66
  )
@@ -1,10 +1,10 @@
1
1
  # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
- from enum import IntEnum
4
+ from ort.utils.validated_enum import ValidatedIntEnum
5
5
 
6
6
 
7
- class RuleViolationResolutionReason(IntEnum):
7
+ class RuleViolationResolutionReason(ValidatedIntEnum):
8
8
  """
9
9
  Properties:
10
10
  CANT_FIX_EXCEPTION:
@@ -2,9 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from pydantic import BaseModel, ConfigDict, Field, field_validator
6
-
7
- from ort.utils import convert_enum
5
+ from pydantic import BaseModel, ConfigDict, Field
8
6
 
9
7
  from .rule_violation_reason import RuleViolationResolutionReason
10
8
 
@@ -32,8 +30,3 @@ class RuleViolationResolution(BaseModel):
32
30
  comment: str = Field(
33
31
  description="A comment to further explain why the [reason] is applicable here.",
34
32
  )
35
-
36
- @field_validator("reason", mode="before")
37
- @classmethod
38
- def validate_reason(cls, value):
39
- return convert_enum(RuleViolationResolutionReason, value)
@@ -2,10 +2,9 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from pydantic import BaseModel, ConfigDict, Field, field_validator
5
+ from pydantic import BaseModel, ConfigDict, Field
6
6
 
7
7
  from ort.models.config.scope_exclude_reason import ScopeExcludeReason
8
- from ort.utils import convert_enum
9
8
 
10
9
 
11
10
  class ScopeExclude(BaseModel):
@@ -29,8 +28,3 @@ class ScopeExclude(BaseModel):
29
28
  default_factory=str,
30
29
  description="A comment to further explain why the [reason] is applicable here.",
31
30
  )
32
-
33
- @field_validator("reason", mode="before")
34
- @classmethod
35
- def validate_reason(cls, value):
36
- return convert_enum(ScopeExcludeReason, value)
@@ -2,10 +2,10 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from enum import IntEnum
5
+ from ort.utils.validated_enum import ValidatedIntEnum
6
6
 
7
7
 
8
- class ScopeExcludeReason(IntEnum):
8
+ class ScopeExcludeReason(ValidatedIntEnum):
9
9
  """
10
10
  Possible reasons for excluding a scope.
11
11
 
@@ -1,10 +1,10 @@
1
1
  # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
- from enum import IntEnum
4
+ from ort.utils.validated_enum import ValidatedIntEnum
5
5
 
6
6
 
7
- class SnippetChoiceReason(IntEnum):
7
+ class SnippetChoiceReason(ValidatedIntEnum):
8
8
  """
9
9
  The reason for which the snippet choice has been made.
10
10
 
@@ -0,0 +1,25 @@
1
+ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field
5
+
6
+ from .snippet_choice import SnippetChoice
7
+ from .snippet_provenance import SnippetProvenance
8
+
9
+
10
+ class SnippetChoices(BaseModel):
11
+ """
12
+ A collection of snippet choices for a given provenance.
13
+ """
14
+
15
+ model_config = ConfigDict(
16
+ extra="forbid",
17
+ )
18
+ provenance: SnippetProvenance = Field(
19
+ ...,
20
+ description="The source file for which the snippet choice is made.",
21
+ )
22
+ choices: list[SnippetChoice] = Field(
23
+ ...,
24
+ description="The snippet choice for the given source file.",
25
+ )
@@ -1,9 +1,10 @@
1
1
  # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
2
  # SPDX-License-Identifier: MIT
3
+ #
3
4
  from pydantic import AnyUrl, BaseModel, ConfigDict, Field
4
5
 
5
6
 
6
- class Provenance(BaseModel):
7
+ class SnippetProvenance(BaseModel):
7
8
  """
8
9
  The URL of the [RepositoryProvenance] the snippet choice applies to.
9
10
  """
@@ -2,9 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from pydantic import BaseModel, ConfigDict, Field, field_validator
6
-
7
- from ort.utils import convert_enum
5
+ from pydantic import BaseModel, ConfigDict, Field
8
6
 
9
7
  from .vulnerability_resolution_reason import VulnerabilityResolutionReason
10
8
 
@@ -31,8 +29,3 @@ class VulnerabilityResolution(BaseModel):
31
29
  comment: str = Field(
32
30
  description="A comment to further explain why the [reason] is applicable here.",
33
31
  )
34
-
35
- @field_validator("reason", mode="before")
36
- @classmethod
37
- def validate_reason(cls, value):
38
- return convert_enum(VulnerabilityResolutionReason, value)
@@ -1,10 +1,10 @@
1
1
  # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
- from enum import IntEnum
4
+ from ort.utils.validated_enum import ValidatedIntEnum
5
5
 
6
6
 
7
- class VulnerabilityResolutionReason(IntEnum):
7
+ class VulnerabilityResolutionReason(ValidatedIntEnum):
8
8
  """
9
9
  Possible reasons for resolving a Vulnerability using a VulnerabilityResolution.
10
10
 
@@ -2,7 +2,7 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from pydantic import BaseModel, ConfigDict, Field, field_validator
5
+ from pydantic import BaseModel, ConfigDict, Field
6
6
 
7
7
  from .issue import Issue
8
8
  from .package_linkage import PackageLinkage
@@ -42,13 +42,3 @@ class DependencyGraphNode(BaseModel):
42
42
  issues: list[Issue] = Field(
43
43
  default_factory=list, description="A list of Issue objects that occurred handling this dependency."
44
44
  )
45
-
46
- @field_validator("linkage", mode="before")
47
- @classmethod
48
- def convert_linkage(cls, v):
49
- if isinstance(v, str):
50
- try:
51
- return PackageLinkage[v]
52
- except KeyError:
53
- raise ValueError(f"Invalid linkage: {v}")
54
- return v
@@ -0,0 +1,19 @@
1
+ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import Field
6
+
7
+ from .base_run import BaseRun
8
+ from .rule_violation import RuleViolation
9
+
10
+
11
+ class EvaluatorRun(BaseRun):
12
+ """
13
+ The summary of a single run of the evaluator.
14
+ """
15
+
16
+ violations: list[RuleViolation] = Field(
17
+ default_factory=list,
18
+ description="The list of rule violations found by the evaluator.",
19
+ )
@@ -4,10 +4,9 @@
4
4
 
5
5
  from datetime import datetime
6
6
 
7
- from pydantic import BaseModel, ConfigDict, Field, field_validator
7
+ from pydantic import BaseModel, ConfigDict, Field
8
8
 
9
9
  from ort.severity import Severity
10
- from ort.utils import convert_enum
11
10
 
12
11
 
13
12
  class Issue(BaseModel):
@@ -35,8 +34,3 @@ class Issue(BaseModel):
35
34
  default=None,
36
35
  description="The affected file or directory the issue is limited to, if any.",
37
36
  )
38
-
39
- @field_validator("severity", mode="before")
40
- @classmethod
41
- def convert_severity(cls, v):
42
- return convert_enum(Severity, v)
@@ -0,0 +1,23 @@
1
+ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <dev@heliocastro.info>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from ..utils.validated_enum import ValidatedIntEnum
5
+
6
+
7
+ class LicenseSource(ValidatedIntEnum):
8
+ """
9
+ The source where a license originates from.
10
+
11
+ properties:
12
+ CONCLUDED:
13
+ Licenses which are part of the [concluded license][Package.concludedLicense] of a [Package].
14
+ DECLARED:
15
+ Licenses which are part of the [(processed)][Package.declaredLicensesProcessed]
16
+ [declared licenses][Package.declaredLicenses] of a [Package].
17
+ DETECTED:
18
+ Licenses which were detected by a license scanner.
19
+ """
20
+
21
+ CONCLUDED = 1
22
+ DECLARED = 2
23
+ DETECTED = 3
@@ -1,4 +1,4 @@
1
- # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <dev@heliocastro.info
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
@@ -6,6 +6,7 @@ from pydantic import BaseModel, ConfigDict, Field
6
6
 
7
7
  from .advisor_run import AdvisorRun
8
8
  from .analyzer_run import AnalyzerRun
9
+ from .evaluator_run import EvaluatorRun
9
10
  from .repository import Repository
10
11
 
11
12
 
@@ -36,6 +37,11 @@ class OrtResult(BaseModel):
36
37
  description="An [AdvisorRun] containing details about the advisor that was run using the result from"
37
38
  "[analyzer] as input. Can be null if no advisor was run.",
38
39
  )
40
+ evaluator: EvaluatorRun | None = Field(
41
+ default=None,
42
+ description="A [ResolvedConfiguration] containing data resolved during the analysis which augments the"
43
+ "automatically determined data.",
44
+ )
39
45
  labels: dict[str, str] = Field(
40
46
  default_factory=dict,
41
47
  description="User defined labels associated to this result. Labels are not used by ORT itself, "
@@ -2,10 +2,10 @@
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
4
 
5
- from enum import IntEnum
5
+ from ort.utils.validated_enum import ValidatedIntEnum
6
6
 
7
7
 
8
- class PackageLinkage(IntEnum):
8
+ class PackageLinkage(ValidatedIntEnum):
9
9
  """
10
10
  A class to denote the linkage type between two packages.
11
11
 
@@ -0,0 +1,85 @@
1
+ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from pydantic import BaseModel, ConfigDict, Field, model_validator
5
+
6
+ from .remote_artifact import RemoteArtifact
7
+ from .vcsinfo import VcsInfo
8
+
9
+
10
+ class SnippetProvenance(BaseModel):
11
+ """
12
+ Provenance information about the origin of source code.
13
+
14
+ This is a union type that can be one of the following:
15
+ - UnknownProvenance: No provenance information is available.
16
+ - ArtifactProvenance: Provenance information for a source artifact.
17
+ - RepositoryProvenance: Provenance information for a Version Control System location.
18
+ """
19
+
20
+ model_config = ConfigDict(extra="allow")
21
+
22
+ @model_validator(mode="before")
23
+ @classmethod
24
+ def validate_provenance(cls, v):
25
+ print(v)
26
+ breakpoint()
27
+ if not isinstance(v, dict):
28
+ raise ValueError("Provenance must be a dictionary.")
29
+ if "source_artifact" in v:
30
+ return ArtifactProvenance(**v)
31
+ elif "vcs_info" in v and "resolved_revision" in v:
32
+ return RepositoryProvenance(**v)
33
+ else:
34
+ return UnknownProvenance()
35
+
36
+
37
+ class UnknownProvenance(BaseModel):
38
+ """
39
+ Provenance information about the origin of source code.
40
+ """
41
+
42
+ model_config = ConfigDict(extra="forbid")
43
+
44
+
45
+ class KnownProvenance(BaseModel):
46
+ """
47
+ Provenance information about the origin of source code.
48
+ """
49
+
50
+ model_config = ConfigDict(extra="forbid")
51
+
52
+
53
+ class RemoteProvenance(KnownProvenance):
54
+ """
55
+ Provenance information about the origin of source code.
56
+ """
57
+
58
+ model_config = ConfigDict(extra="forbid")
59
+
60
+
61
+ class ArtifactProvenance(RemoteProvenance):
62
+ """
63
+ Provenance information for a source artifact.
64
+ """
65
+
66
+ model_config = ConfigDict(extra="forbid")
67
+
68
+ source_artifact: RemoteArtifact = Field(
69
+ description="The source artifact that was downloaded.",
70
+ )
71
+
72
+
73
+ class RepositoryProvenance(BaseModel):
74
+ """
75
+ Provenance information for a Version Control System location.
76
+ """
77
+
78
+ model_config = ConfigDict(extra="forbid")
79
+
80
+ vcs_info: VcsInfo = Field(
81
+ description="VCS info used to resolve the revision. May still contain a moving revision like a branch.",
82
+ )
83
+ resolved_revision: str = Field(
84
+ description="Resolved fixed VCS revision, not blank and not moving (e.g. Git commit SHA1)."
85
+ )
@@ -0,0 +1,50 @@
1
+ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <dev@heliocastro.info>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import BaseModel, Field
6
+
7
+ from .identifier import Identifier
8
+ from .license_source import LicenseSource
9
+ from .severity import Severity
10
+
11
+
12
+ class RuleViolation(BaseModel):
13
+ """
14
+ A violation of a rule found during evaluation.
15
+ """
16
+
17
+ model_config = {
18
+ "extra": "forbid",
19
+ }
20
+
21
+ rule: str = Field(description=("The identifier of the rule that found this violation."))
22
+
23
+ pkg: Identifier | None = Field(
24
+ default=None,
25
+ description=("The identifier of the package that caused this rule violation."),
26
+ )
27
+
28
+ license: str | None = Field(
29
+ default=None,
30
+ description=(
31
+ "The name of the license that caused this rule "
32
+ "violation. Can be null if the rule does not work on "
33
+ "licenses."
34
+ ),
35
+ )
36
+
37
+ license_sources: set[LicenseSource] = Field(
38
+ default_factory=set,
39
+ description=("The sources of the license. Can be empty if the rule does not work on licenses."),
40
+ )
41
+
42
+ severity: Severity = Field(description="The severity of the rule violation.")
43
+
44
+ message: str = Field(description="A message explaining the rule violation.")
45
+
46
+ how_to_fix: str = Field(
47
+ description=(
48
+ "A text explaining how the rule violation can be fixed. Renderers should support Markdown syntax."
49
+ ),
50
+ )
@@ -0,0 +1,23 @@
1
+ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <dev@heliocastro.info>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from ..utils.validated_enum import ValidatedIntEnum
6
+
7
+
8
+ class Severity(ValidatedIntEnum):
9
+ """
10
+ A generic class describing a severity, e.g. of issues, sorted from least severe to most severe.
11
+
12
+ properties:
13
+ HINT:
14
+ A hint is something that is provided for information only.
15
+ WARNING:
16
+ A warning is something that should be addressed.
17
+ ERROR:
18
+ An error is something that has to be addressed.
19
+ """
20
+
21
+ HINT = 1
22
+ WARNING = 2
23
+ ERROR = 3
@@ -1,10 +1,10 @@
1
1
  # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
- from enum import IntEnum
4
+ from ort.utils.validated_enum import ValidatedIntEnum
5
5
 
6
6
 
7
- class Severity(IntEnum):
7
+ class Severity(ValidatedIntEnum):
8
8
  """
9
9
  A generic class describing a severity, e.g. of issues, sorted from least severe to most severe.
10
10
 
File without changes
@@ -0,0 +1,15 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from .environment import Environment
5
+ from .processed_declared_license import ProcessedDeclaredLicense
6
+ from .validated_enum import ValidatedIntEnum
7
+ from .yaml_loader import OrtYamlLoader, ort_yaml_load
8
+
9
+ __all__ = [
10
+ "Environment",
11
+ "OrtYamlLoader",
12
+ "ProcessedDeclaredLicense",
13
+ "ValidatedIntEnum",
14
+ "ort_yaml_load",
15
+ ]
File without changes
@@ -1,10 +1,10 @@
1
1
  # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
2
  # SPDX-License-Identifier: MIT
3
3
 
4
- from enum import IntEnum
4
+ from ort.utils.validated_enum import ValidatedIntEnum
5
5
 
6
6
 
7
- class SpdxExpression(IntEnum):
7
+ class SpdxExpression(ValidatedIntEnum):
8
8
  """
9
9
  The level of strictness to apply when validating an SpdxExpression.
10
10
 
@@ -0,0 +1,34 @@
1
+ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <dev@heliocastro.info>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from enum import IntEnum
5
+ from typing import Any
6
+
7
+ from pydantic import GetCoreSchemaHandler
8
+ from pydantic_core import CoreSchema, core_schema
9
+
10
+
11
+ class ValidatedIntEnum(IntEnum):
12
+ """
13
+ IntEnum base class with built-in Pydantic validation for string names.
14
+ """
15
+
16
+ @classmethod
17
+ def __get_pydantic_core_schema__(
18
+ cls,
19
+ source_type: Any,
20
+ handler: GetCoreSchemaHandler,
21
+ ) -> CoreSchema:
22
+ def validate(value: Any) -> ValidatedIntEnum:
23
+ if isinstance(value, cls):
24
+ return value
25
+ if isinstance(value, str):
26
+ try:
27
+ return cls[value]
28
+ except KeyError:
29
+ raise ValueError(f"Invalid value for {cls.__name__}: {value}")
30
+ if isinstance(value, int):
31
+ return cls(value)
32
+ raise ValueError(f"Invalid value for {cls.__name__}: {value}")
33
+
34
+ return core_schema.no_info_plain_validator_function(validate)
@@ -0,0 +1,43 @@
1
+ # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <dev@heliocastro.info>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from typing import Any
5
+
6
+ import yaml
7
+
8
+ # Prefer the C-accelerated SafeLoader when available (5-10x faster).
9
+ try:
10
+ _BaseLoader = yaml.CSafeLoader
11
+ except AttributeError:
12
+ _BaseLoader = yaml.SafeLoader
13
+
14
+
15
+ class OrtYamlLoader(_BaseLoader): # type: ignore[misc]
16
+ """A YAML loader that handles ORT-specific custom tags.
17
+
18
+ ORT result files may contain custom YAML tags like
19
+ ``!<.PostgresStorageConfiguration>`` which are not supported by the
20
+ standard safe loader. This loader silently treats any unknown tag as
21
+ a plain mapping/sequence/scalar so the data can still be parsed.
22
+
23
+ Uses the C-accelerated SafeLoader when available for better performance.
24
+ """
25
+
26
+
27
+ # Register a multi-constructor that matches every unknown tag and
28
+ # delegates to the default safe constructors based on node type.
29
+ OrtYamlLoader.add_multi_constructor(
30
+ "",
31
+ lambda loader, suffix, node: (
32
+ loader.construct_mapping(node, deep=True)
33
+ if isinstance(node, yaml.MappingNode)
34
+ else loader.construct_sequence(node, deep=True)
35
+ if isinstance(node, yaml.SequenceNode)
36
+ else loader.construct_scalar(node)
37
+ ),
38
+ )
39
+
40
+
41
+ def ort_yaml_load(stream: Any) -> Any:
42
+ """Load a YAML document using the ORT-aware loader."""
43
+ return yaml.load(stream, Loader=OrtYamlLoader) # noqa: S506
@@ -1,39 +0,0 @@
1
- # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
- # SPDX-License-Identifier: MIT
3
-
4
- from datetime import datetime
5
-
6
- from pydantic import BaseModel, ConfigDict, Field
7
-
8
- from ort.models import AdvisorResult
9
- from ort.models.config.advisor_configuration import AdvisorConfiguration
10
- from ort.utils.environment import Environment
11
-
12
- from .identifier import Identifier
13
-
14
-
15
- class AdvisorRun(BaseModel):
16
- """
17
- Type alias for a function that allows filtering of [AdvisorResult]s.
18
-
19
- """
20
-
21
- model_config = ConfigDict(
22
- extra="forbid",
23
- )
24
- start_time: datetime = Field(
25
- description="The time the advisor was started.",
26
- )
27
- end_time: datetime = Field(
28
- description="The time the advisor has finished.",
29
- )
30
- environment: Environment = Field(
31
- description="The [Environment] in which the advisor was executed.",
32
- )
33
- config: AdvisorConfiguration = Field(
34
- description="The [AdvisorConfiguration] used for this run.",
35
- )
36
- results: dict[Identifier, list[AdvisorResult]] = Field(
37
- default_factory=dict,
38
- description="The result of this run.",
39
- )
@@ -1,12 +0,0 @@
1
- # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
- # SPDX-License-Identifier: MIT
3
-
4
- from ort.utils.convert_enum import convert_enum
5
- from ort.utils.environment import Environment
6
- from ort.utils.processed_declared_license import ProcessedDeclaredLicense
7
-
8
- __all__ = [
9
- "convert_enum",
10
- "Environment",
11
- "ProcessedDeclaredLicense",
12
- ]
@@ -1,18 +0,0 @@
1
- # SPDX-FileCopyrightText: 2026 Helio Chissini de Castro <heliocastro@gmail.com>
2
- # SPDX-License-Identifier: MIT
3
-
4
-
5
- def convert_enum(enum_cls, v):
6
- def _convert(item):
7
- if isinstance(item, str):
8
- try:
9
- return enum_cls[item]
10
- except KeyError:
11
- raise ValueError(f"Invalid value for {enum_cls.__name__}: {item}")
12
- return item
13
-
14
- if isinstance(v, (list, set)):
15
- return {_convert(item) for item in v}
16
- if isinstance(v, str):
17
- return _convert(v)
18
- return v
File without changes
File without changes