python-ort 0.4.2__tar.gz → 0.5.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 (50) hide show
  1. {python_ort-0.4.2 → python_ort-0.5.0}/PKG-INFO +2 -2
  2. {python_ort-0.4.2 → python_ort-0.5.0}/pyproject.toml +7 -7
  3. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/__init__.py +4 -0
  4. python_ort-0.5.0/src/ort/models/__init__.py +10 -0
  5. python_ort-0.5.0/src/ort/models/analyzer_result.py +43 -0
  6. python_ort-0.5.0/src/ort/models/analyzer_run.py +37 -0
  7. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/analyzer_configuration.py +3 -5
  8. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/package_manager_configuration.py +3 -2
  9. python_ort-0.5.0/src/ort/models/dependency_graph.py +98 -0
  10. python_ort-0.5.0/src/ort/models/dependency_graph_edge.py +30 -0
  11. python_ort-0.5.0/src/ort/models/dependency_graph_node.py +44 -0
  12. python_ort-0.5.0/src/ort/models/dependency_reference.py +51 -0
  13. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/identifier.py +4 -0
  14. python_ort-0.5.0/src/ort/models/issue.py +36 -0
  15. python_ort-0.5.0/src/ort/models/ort_result.py +32 -0
  16. python_ort-0.5.0/src/ort/models/package.py +130 -0
  17. python_ort-0.5.0/src/ort/models/package_linkage.py +33 -0
  18. python_ort-0.5.0/src/ort/models/package_reference.py +33 -0
  19. python_ort-0.5.0/src/ort/models/project.py +80 -0
  20. python_ort-0.5.0/src/ort/models/remote_artifact.py +20 -0
  21. python_ort-0.5.0/src/ort/models/repository.py +42 -0
  22. python_ort-0.5.0/src/ort/models/root_dependency_index.py +27 -0
  23. python_ort-0.5.0/src/ort/models/scope.py +30 -0
  24. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/source_code_origin.py +4 -0
  25. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/vcsinfo.py +4 -1
  26. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/vcstype.py +6 -1
  27. python_ort-0.5.0/src/ort/severity.py +19 -0
  28. python_ort-0.5.0/src/ort/utils/__init__.py +10 -0
  29. python_ort-0.5.0/src/ort/utils/environment.py +38 -0
  30. python_ort-0.5.0/src/ort/utils/processed_declared_license.py +30 -0
  31. python_ort-0.4.2/src/ort/models/__init__.py +0 -0
  32. python_ort-0.4.2/src/ort/models/ort_configuration.py +0 -322
  33. {python_ort-0.4.2 → python_ort-0.5.0}/LICENSE +0 -0
  34. {python_ort-0.4.2 → python_ort-0.5.0}/README.md +0 -0
  35. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/curations.py +0 -0
  36. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/license_finding_curation.py +0 -0
  37. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/license_finding_curation_reason.py +0 -0
  38. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/package_configuration.py +0 -0
  39. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/path_exclude.py +0 -0
  40. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/path_exclude_reason.py +0 -0
  41. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/path_include_reason.py +0 -0
  42. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/repository_analyzer_configuration.py +0 -0
  43. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/config/vcsmatcher.py +0 -0
  44. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/hash.py +0 -0
  45. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/hash_algorithm.py +0 -0
  46. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/package_curation.py +0 -0
  47. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/package_curation_data.py +0 -0
  48. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/repository_configuration.py +0 -0
  49. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/resolutions.py +0 -0
  50. {python_ort-0.4.2 → python_ort-0.5.0}/src/ort/models/vcsinfo_curation_data.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-ort
3
- Version: 0.4.2
3
+ Version: 0.5.0
4
4
  Summary: A Python Ort model serialization library
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.12
13
13
  Classifier: Programming Language :: Python :: 3.13
14
14
  Classifier: Programming Language :: Python :: 3.14
15
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
- Requires-Dist: pydantic>=2.12.4
16
+ Requires-Dist: pydantic>=2.12.5
17
17
  Requires-Python: >=3.10
18
18
  Description-Content-Type: text/markdown
19
19
 
@@ -4,14 +4,14 @@ build-backend = "uv_build"
4
4
 
5
5
  [project]
6
6
  name = "python-ort"
7
- version = "0.4.2"
7
+ version = "0.5.0"
8
8
  description = "A Python Ort model serialization library"
9
9
  readme = "README.md"
10
10
  license = "MIT"
11
11
  license-files = ["LICENSE"]
12
12
  requires-python = ">=3.10"
13
13
  dependencies = [
14
- "pydantic>=2.12.4",
14
+ "pydantic>=2.12.5",
15
15
  ]
16
16
  classifiers = [
17
17
  "Development Status :: 3 - Alpha",
@@ -31,13 +31,13 @@ module-root = "src"
31
31
 
32
32
  [dependency-groups]
33
33
  dev = [
34
- "datamodel-code-generator[http]>=0.35.0",
35
- "pre-commit>=4.3.0",
34
+ "datamodel-code-generator[http]>=0.53.0",
35
+ "pre-commit>=4.5.1",
36
36
  "pycodestyle>=2.14.0",
37
- "pyrefly>=0.40.0",
38
- "pytest>=8.4.2",
37
+ "pyrefly>=0.49.0",
38
+ "pytest>=9.0.2",
39
39
  "rich>=14.2.0",
40
- "ruff>=0.14.4",
40
+ "ruff>=0.14.14",
41
41
  "types-pyyaml>=6.0.12.20250915",
42
42
  ]
43
43
 
@@ -2,8 +2,12 @@
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
4
 
5
+ from ort.models.analyzer_result import AnalyzerResult
6
+ from ort.models.ort_result import OrtResult
5
7
  from ort.models.repository_configuration import OrtRepositoryConfiguration
6
8
 
7
9
  __all__ = [
10
+ "AnalyzerResult",
8
11
  "OrtRepositoryConfiguration",
12
+ "OrtResult",
9
13
  ]
@@ -0,0 +1,10 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from .identifier import Identifier
5
+ from .vcstype import VcsType
6
+
7
+ __all__ = [
8
+ "Identifier",
9
+ "VcsType",
10
+ ]
@@ -0,0 +1,43 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+ from ort.models.dependency_graph import DependencyGraph
8
+ from ort.models.identifier import Identifier
9
+ from ort.models.issue import Issue
10
+ from ort.models.package import Package
11
+ from ort.models.project import Project
12
+
13
+
14
+ class AnalyzerResult(BaseModel):
15
+ """
16
+ A class that merges all information from individual [ProjectAnalyzerResult]s created for each found definition file.
17
+ """
18
+
19
+ model_config = ConfigDict(
20
+ extra="forbid",
21
+ )
22
+
23
+ projects: set[Project] = Field(
24
+ description="Sorted set of the projects, as they appear in the individual analyzer results.",
25
+ )
26
+
27
+ packages: set[Package] = Field(
28
+ description="The set of identified packages for all projects.",
29
+ )
30
+
31
+ issues: dict[Identifier, list[Issue]] = Field(
32
+ default_factory=dict,
33
+ description="The lists of Issue objects that occurred within the analyzed projects themselves. Issues related"
34
+ "to project dependencies are contained in the dependencies of the project's scopes. This property is not"
35
+ "serialized if the map is empty to reduce the size of the result file.",
36
+ )
37
+
38
+ dependency_graphs: dict[str, DependencyGraph] = Field(
39
+ default_factory=dict,
40
+ description="A map with DependencyGraph objects keyed by the name of the package manager that created this"
41
+ "graph. Package managers supporting this feature can construct a shared DependencyGraph over all projects and"
42
+ "store it in this map.",
43
+ )
@@ -0,0 +1,37 @@
1
+ # SPDX-FileCopyrightText: 2025 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.analyzer_result import AnalyzerResult
9
+ from ort.models.config.analyzer_configuration import AnalyzerConfiguration
10
+ from ort.utils.environment import Environment
11
+
12
+
13
+ class AnalyzerRun(BaseModel):
14
+ """
15
+ The summary of a single run of the analyzer.
16
+
17
+ """
18
+
19
+ model_config = ConfigDict(
20
+ extra="forbid",
21
+ )
22
+ start_time: datetime = Field(
23
+ description="The time the analyzer was started.",
24
+ )
25
+ end_time: datetime = Field(
26
+ description="The time the analyzer has finished.",
27
+ )
28
+ environment: Environment = Field(
29
+ description="The [Environment] in which the analyzer was executed.",
30
+ )
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
+ )
@@ -38,11 +38,9 @@ _package_managers: list[str] = [
38
38
 
39
39
  class AnalyzerConfiguration(BaseModel):
40
40
  """
41
- Enable the analysis of projects that use version ranges to declare their dependencies. If set to true,
42
- dependencies of exactly the same project might change with another scan done at a later time if any of the
43
- (transitive) dependencies are declared using version ranges and a new version of such a dependency was
44
- published in the meantime. If set to false, analysis of projects that use version ranges will fail. Defaults to
45
- false.
41
+ The configuration model of the analyzer. This class is (de-)serialized in the following places:
42
+ - Deserialized from "config.yml" as part of [OrtConfiguration] (via Hoplite).
43
+ - (De-)Serialized as part of [org.ossreviewtoolkit.model.OrtResult] (via Jackson).
46
44
  """
47
45
 
48
46
  model_config = ConfigDict(
@@ -29,7 +29,8 @@ class PackageManagerConfiguration(BaseModel):
29
29
 
30
30
  @field_validator("options", mode="before")
31
31
  @classmethod
32
- def convert_bools_to_str(cls, value: Any) -> Any:
32
+ def convert_to_str(cls, value: Any) -> Any:
33
33
  if not isinstance(value, dict):
34
34
  return value
35
- return {k: str(v).lower() if isinstance(v, bool) else v for k, v in value.items()}
35
+ for key, item in value.items():
36
+ return {k: str(v).lower() if not isinstance(v, str) else v for k, v in value.items()}
@@ -0,0 +1,98 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
6
+
7
+ from ort.models.dependency_graph_edge import DependencyGraphEdge
8
+ from ort.models.dependency_graph_node import DependencyGraphNode
9
+ from ort.models.dependency_reference import DependencyReference
10
+ from ort.models.identifier import Identifier
11
+ from ort.models.root_dependency_index import RootDependencyIndex
12
+
13
+
14
+ class DependencyGraph(BaseModel):
15
+ """
16
+ Represents the graph of dependencies of a project.
17
+
18
+ This class holds information about a project's scopes and their dependencies in a format that minimizes the
19
+ consumption of memory. In projects with many scopes there is often a high degree of duplication in the dependencies
20
+ of the scopes. To avoid this, this class aims to share as many parts of the dependency graph as possible between
21
+ the different scopes. Ideally, there is only a single dependency graph containing the dependencies used by all
22
+ scopes. This is not always possible due to inconsistencies in dependency relations, like a package using different
23
+ dependencies in different scopes. Then the dependency graph is split into multiple fragments, and each fragment has
24
+ a consistent view on the dependencies it contains.
25
+
26
+ When constructing a dependency graph the dependencies are organized as a connected structure of DependencyReference
27
+ objects in memory. Originally, the serialization format of a graph was based on this structure, but that turned out
28
+ to be not ideal: During serialization, sub graphs referenced from multiple nodes (e.g. libraries with transitive
29
+ dependencies referenced from multiple projects) get duplicated, which can cause a significant amount of redundancy.
30
+ Therefore, the data representation has been changed again to a form, which can be serialized without introducing
31
+ redundancy. It consists of the following elements:
32
+
33
+ - packages: A list with the coordinates of all the packages (free of duplication) that are referenced by the graph.
34
+ This allows extracting the packages directly, but also has the advantage that the package coordinates do not have
35
+ to be repeated over and over: All the references to packages are expressed by indices into this list.
36
+ - nodes: An ordered list with the nodes of the dependency graph. A single node represents a package, and therefore
37
+ has a reference into the list with package coordinates. It can, however, happen that packages occur multiple
38
+ times in the graph if they are in different subtrees with different sets of transitive dependencies. Then there
39
+ are multiple nodes for the packages affected, and a fragment_index is used to identify them uniquely. Nodes also
40
+ store information about issues of a package and their linkage.
41
+ - edges: Here the structure of the graph comes in. Each edge connects two nodes and represents a directed
42
+ depends-on relationship. The nodes are referenced by numeric indices into the list of nodes.
43
+ - scopes: This is a map that associates the scopes used by projects with their direct dependencies. A single
44
+ dependency graph contains the dependencies of all the projects processed by a specific package manager.
45
+ Therefore, the keys of this map are scope names qualified by the coordinates of a project; which makes them
46
+ unique. The values are references to the nodes in the graph that correspond to the packages the scopes depend on
47
+ directly.
48
+
49
+ To navigate this structure, start with a scope and gather the references to its direct dependency nodes. Then, by
50
+ following the edges starting from these nodes, the set of transitive dependencies can be determined. The numeric
51
+ indices can be resolved via the packages list.
52
+ """
53
+
54
+ model_config = ConfigDict(
55
+ extra="forbid",
56
+ )
57
+
58
+ packages: list[Identifier] = Field(
59
+ default_factory=list,
60
+ description="A list with the identifiers of the packages that appear in the dependency graph. This list is "
61
+ "used to resolve the numeric indices contained in the dependency_graph_node objects.",
62
+ )
63
+
64
+ scope_roots: set[DependencyReference] = Field(
65
+ default_factory=set,
66
+ description="Stores the dependency graph as a list of root nodes for the direct dependencies referenced by "
67
+ "scopes. Starting with these nodes, the whole graph can be traversed. The nodes are constructed "
68
+ "from the direct dependencies declared by scopes that cannot be reached via other paths in the "
69
+ "dependency graph. Note that this property exists for backwards compatibility only; it is replaced "
70
+ "by the lists of nodes and edges.",
71
+ )
72
+
73
+ scopes: dict[str, list[RootDependencyIndex]] = Field(
74
+ default_factory=dict,
75
+ description="A mapping from scope names to the direct dependencies of the scopes. Based on this information, "
76
+ "the set of scopes of a project can be constructed from the serialized form.",
77
+ )
78
+
79
+ nodes: list[DependencyGraphNode] = Field(
80
+ default_factory=list,
81
+ description="A list with the nodes of this dependency graph. Nodes correspond to packages, but in contrast to "
82
+ "the packages list, there can be multiple nodes for a single package. The order of nodes in this "
83
+ "list is relevant; the edges of the graph reference their nodes by numeric indices.",
84
+ )
85
+
86
+ edges: set[DependencyGraphEdge] = Field(
87
+ default_factory=set,
88
+ description="A set with the edges of this dependency graph. By traversing the edges, the dependencies of "
89
+ "packages can be determined.",
90
+ )
91
+
92
+ @field_validator("edges", mode="before")
93
+ @classmethod
94
+ def sort_and_set_edges(cls, v):
95
+ if v is None:
96
+ return set()
97
+
98
+ return {DependencyGraphEdge.model_validate(e) for e in v}
@@ -0,0 +1,30 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+
8
+ class DependencyGraphEdge(BaseModel):
9
+ """
10
+ A data class representing an edge in the dependency graph.
11
+
12
+ An edge corresponds to a directed depends-on relationship between two packages. The packages are identified by the
13
+ numeric indices into the list of nodes.
14
+ """
15
+
16
+ model_config = ConfigDict(
17
+ extra="forbid",
18
+ frozen=True,
19
+ )
20
+
21
+ from_: int = Field(
22
+ ...,
23
+ alias="from",
24
+ description="The index of the source node of this edge.",
25
+ )
26
+ to_: int = Field(
27
+ ...,
28
+ alias="to",
29
+ description="The index of the destination node of this edge.",
30
+ )
@@ -0,0 +1,44 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+ from ort.models.issue import Issue
8
+ from ort.models.package_linkage import PackageLinkage
9
+
10
+
11
+ class DependencyGraphNode(BaseModel):
12
+ """
13
+ A data class representing a node in the dependency graph.
14
+
15
+ A node corresponds to a package, which is referenced by a numeric index. A package may, however, occur multiple
16
+ times in the dependency graph with different transitive dependencies. In this case, different fragment indices are
17
+ used to distinguish between these occurrences.
18
+ """
19
+
20
+ model_config = ConfigDict(
21
+ extra="forbid",
22
+ )
23
+
24
+ pkg: int | None = Field(
25
+ default=None,
26
+ description="Stores the numeric index of the package dependency referenced by this object. The package behind "
27
+ "this index can be resolved by evaluating the list of identifiers stored in DependencyGraph at "
28
+ "this index.",
29
+ )
30
+ fragment: int = Field(
31
+ 0,
32
+ description="Stores the index of the fragment in the dependency graph where the referenced dependency is "
33
+ "contained. This is needed to uniquely identify the target if the dependency occurs multiple times "
34
+ "in the graph.",
35
+ )
36
+ linkage: PackageLinkage = Field(
37
+ default=PackageLinkage.DYNAMIC,
38
+ description="The type of linkage used for the referred package from its dependent package. As most of ORT's "
39
+ "supported package managers / languages only support dynamic linking or at least default to it, "
40
+ "also use that as the default value here to not blow up ORT result files.",
41
+ )
42
+ issues: list[Issue] = Field(
43
+ default_factory=list, description="A list of Issue objects that occurred handling this dependency."
44
+ )
@@ -0,0 +1,51 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+ from ort.models.issue import Issue
8
+ from ort.models.package_linkage import PackageLinkage
9
+
10
+
11
+ class DependencyReference(BaseModel):
12
+ """
13
+ A class to model a tree-like structure to represent the dependencies of a project.
14
+
15
+ Instances of this class are used to store the relations between dependencies in fragments of dependency trees in an
16
+ Analyzer result. The main purpose of this class is to define an efficient serialization format, which avoids
17
+ redundancy as far as possible. Therefore, dependencies are represented by numeric indices into an external table.
18
+ As a dependency can occur multiple times in the dependency graph with different transitive dependencies, the class
19
+ defines another index to distinguish these cases.
20
+
21
+ Note: This is by intention no data class. Equality is tested via references and not via the values contained.
22
+ """
23
+
24
+ model_config = ConfigDict(
25
+ extra="forbid",
26
+ )
27
+
28
+ pkg: int = Field(
29
+ ...,
30
+ description="Stores the numeric index of the package dependency referenced by this object. The package behind "
31
+ "this index can be resolved by evaluating the list of identifiers stored in DependencyGraph at "
32
+ "this index.",
33
+ )
34
+ fragment: int = Field(
35
+ default=0,
36
+ description="Stores the index of the fragment in the dependency graph where the referenced dependency is "
37
+ "contained. This is needed to uniquely identify the target if the dependency occurs multiple times "
38
+ "in the graph.",
39
+ )
40
+ dependencies: set["DependencyReference"] = Field(
41
+ default_factory=set,
42
+ description="A set with the references to the dependencies of this dependency. That way a tree-like structure "
43
+ "is established.",
44
+ )
45
+ linkage: PackageLinkage = Field(
46
+ default=PackageLinkage.DYNAMIC,
47
+ description="The type of linkage used for the referred package from its dependent package. As most of ORT's "
48
+ "supported package managers / languages only support dynamic linking or at least default to it, "
49
+ "also use that as the default value here to not blow up ORT result files.",
50
+ )
51
+ issues: list[Issue] = Field(..., description="A list of Issue objects that occurred handling this dependency.")
@@ -23,6 +23,7 @@ class Identifier(BaseModel):
23
23
 
24
24
  model_config = ConfigDict(
25
25
  extra="forbid",
26
+ frozen=True,
26
27
  )
27
28
 
28
29
  orttype: str = Field(
@@ -61,3 +62,6 @@ class Identifier(BaseModel):
61
62
  "version": parts[3],
62
63
  }
63
64
  raise TypeError("Identifier must be a dict or a string in the correct format")
65
+
66
+ def __str__(self) -> str:
67
+ return ":".join([self.orttype, self.namespace, self.name, self.version])
@@ -0,0 +1,36 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from datetime import datetime
6
+
7
+ from pydantic import BaseModel, ConfigDict, Field
8
+
9
+ from ort.severity import Severity
10
+
11
+
12
+ class Issue(BaseModel):
13
+ """
14
+ An issue that occurred while executing ORT.
15
+ """
16
+
17
+ model_config = ConfigDict(
18
+ extra="forbid",
19
+ )
20
+
21
+ timestamp: datetime = Field(
22
+ description="The timestamp of the issue.",
23
+ )
24
+ source: str = Field(
25
+ description="A description of the issue source, e.g. the tool that caused the issue.",
26
+ )
27
+ message: str = Field(
28
+ description="The issue's message.",
29
+ )
30
+ severity: Severity = Field(
31
+ description="The issue's severity.",
32
+ )
33
+ affected_path: str | None = Field(
34
+ default=None,
35
+ description="The affected file or directory the issue is limited to, if any.",
36
+ )
@@ -0,0 +1,32 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+ from ort.models.analyzer_run import AnalyzerRun
8
+ from ort.models.repository import Repository
9
+
10
+
11
+ class OrtResult(BaseModel):
12
+ """
13
+ The common output format for the analyzer and scanner. It contains information about the scanned repository,
14
+ and the analyzer and scanner will add their result to it.
15
+
16
+ Attributes:
17
+ repository(Repository): Information about the repository that was used as input.
18
+ analyzer(AnalyzerRun): An [AnalyzerRun] containing details about the analyzer that was run using [repository]
19
+ as input. Can be null if the [repository] was not yet analyzed.
20
+
21
+ """
22
+
23
+ model_config = ConfigDict(
24
+ extra="ignore",
25
+ )
26
+ repository: Repository = Field(
27
+ description="Information about the repository that was used as input.",
28
+ )
29
+ analyzer: AnalyzerRun = Field(
30
+ description="An [AnalyzerRun] containing details about the analyzer that was run using [repository]"
31
+ "as input. Can be null if the [repository] was not yet analyzed."
32
+ )
@@ -0,0 +1,130 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+ from ort.models.identifier import Identifier
8
+ from ort.models.remote_artifact import RemoteArtifact
9
+ from ort.models.source_code_origin import SourceCodeOrigin
10
+ from ort.models.vcsinfo import VcsInfo
11
+ from ort.utils.processed_declared_license import ProcessedDeclaredLicense
12
+
13
+
14
+ class Package(BaseModel):
15
+ """
16
+ A generic descriptor for a software package. It contains all relevant metadata about a package like the name,
17
+ version, and how to retrieve the package and its source code. It does not contain information about the package's
18
+ dependencies, however. This is because at this stage ORT would only be able to get the declared dependencies,
19
+ whereas the resolved dependencies are of interest. Resolved dependencies might differ from declared dependencies
20
+ due to specified version ranges, or change depending on how the package is used in a project due to the build
21
+ system's dependency resolution process. For example, if multiple versions of the same package are used in a
22
+ project, the build system might decide to align on a single version of that package.
23
+ """
24
+
25
+ model_config = ConfigDict(
26
+ extra="forbid",
27
+ )
28
+
29
+ id: Identifier = Field(
30
+ description="The unique identifier of this package. The id's type is the name of the package type or protocol "
31
+ "(e.g. 'Maven' for a file from a Maven repository).",
32
+ )
33
+
34
+ purl: str = Field(
35
+ ...,
36
+ description="An additional identifier in package URL syntax (https://github.com/package-url/purl-spec).",
37
+ )
38
+
39
+ cpe: str | None = Field(
40
+ default=None,
41
+ description="An optional additional identifier in CPE syntax (https://cpe.mitre.org/specification/).",
42
+ )
43
+
44
+ authors: set[str] = Field(
45
+ default_factory=set,
46
+ description="The set of authors declared for this package.",
47
+ )
48
+
49
+ declared_licenses: set[str] = Field(
50
+ ...,
51
+ description="The set of licenses declared for this package. This does not necessarily correspond to"
52
+ "the licenses as detected by a scanner. Both need to be taken into account for any conclusions.",
53
+ )
54
+
55
+ declared_licenses_processed: ProcessedDeclaredLicense = Field(
56
+ ...,
57
+ description="The declared licenses as SpdxExpression. If declared_licenses contains multiple licenses they are "
58
+ "concatenated with SpdxOperator.AND.",
59
+ )
60
+
61
+ concluded_license: str | None = Field(
62
+ default=None,
63
+ description="The concluded license as an SpdxExpression. It can be used to override the declared/detected "
64
+ "licenses of a package. ORT itself does not set this field, it needs to be set by the user using a "
65
+ "PackageCuration.",
66
+ )
67
+
68
+ description: str = Field(
69
+ ...,
70
+ description="The description of the package, as provided by the package manager.",
71
+ )
72
+
73
+ homepage_url: str = Field(
74
+ ...,
75
+ description="The homepage of the package.",
76
+ )
77
+
78
+ binary_artifact: RemoteArtifact = Field(
79
+ ...,
80
+ description="The remote artifact where the binary package can be downloaded.",
81
+ )
82
+
83
+ source_artifact: RemoteArtifact = Field(
84
+ ...,
85
+ description="The remote artifact where the source package can be downloaded.",
86
+ )
87
+
88
+ vcs: VcsInfo = Field(
89
+ ...,
90
+ description="Original VCS-related information as defined in the package's metadata.",
91
+ )
92
+
93
+ vcs_processed: VcsInfo = Field(
94
+ ...,
95
+ description="Processed VCS-related information about the package in normalized form. The information is either "
96
+ "derived from vcs, guessed from additional data as a fallback, or empty. On top of that PackageCurations may "
97
+ "have been applied.",
98
+ )
99
+
100
+ is_metadata_only: bool = Field(
101
+ default=False,
102
+ description="Indicates whether the package is just metadata, like e.g. Maven BOM artifacts which only define "
103
+ "constraints for dependency versions.",
104
+ )
105
+
106
+ is_modified: bool = Field(
107
+ default=False,
108
+ description="Indicates whether the source code of the package has been modified compared to the original source"
109
+ "code, e.g., in case of a fork of an upstream Open Source project.",
110
+ )
111
+
112
+ source_code_origins: list[SourceCodeOrigin] | None = Field(
113
+ default=None,
114
+ description="The considered source code origins and their priority order to use for this package. If null, the "
115
+ "configured default is used. If not null, this must not be empty and not contain any duplicates.",
116
+ )
117
+
118
+ labels: dict[str, str] = Field(
119
+ default_factory=dict,
120
+ description="User defined labels associated with this package. The labels are not interpreted by the core of"
121
+ "ORT itself, but can be used in parts of ORT such as plugins, in evaluator rules, or in reporter templates.",
122
+ )
123
+
124
+ def __hash__(self) -> int:
125
+ return hash(self.id)
126
+
127
+ def __eq__(self, other) -> bool:
128
+ if not isinstance(other, Package):
129
+ return NotImplemented
130
+ return self.id == other.id
@@ -0,0 +1,33 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from enum import Enum, auto
6
+
7
+
8
+ class PackageLinkage(Enum):
9
+ """
10
+ A class to denote the linkage type between two packages.
11
+
12
+ Members:
13
+ DYNAMIC:
14
+ A dynamically linked package whose source code is not directly defined in the project itself,
15
+ but which is retrieved as an external artifact.
16
+
17
+ STATIC:
18
+ A statically linked package whose source code is not directly defined in the project itself,
19
+ but which is retrieved as an external artifact.
20
+
21
+ PROJECT_DYNAMIC:
22
+ A dynamically linked package whose source code is part of the project itself,
23
+ e.g. a subproject of a multi-project.
24
+
25
+ PROJECT_STATIC:
26
+ A statically linked package whose source code is part of the project itself,
27
+ e.g. a subproject of a multi-project.
28
+ """
29
+
30
+ DYNAMIC = auto()
31
+ STATIC = auto()
32
+ PROJECT_DYNAMIC = auto()
33
+ PROJECT_STATIC = auto()