python-ort 0.1.4__tar.gz → 0.3.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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-ort
3
- Version: 0.1.4
3
+ Version: 0.3.0
4
4
  Summary: A Python Ort model serialization library
5
5
  License-Expression: MIT
6
6
  License-File: LICENSE
@@ -11,9 +11,9 @@ Classifier: Programming Language :: Python :: 3.10
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
13
  Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
14
15
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
- Requires-Dist: pydantic>=2.11.10
16
- Requires-Dist: pyyaml>=6.0.3
16
+ Requires-Dist: pydantic>=2.12.4
17
17
  Requires-Python: >=3.10
18
18
  Description-Content-Type: text/markdown
19
19
 
@@ -1,5 +1,5 @@
1
1
  [build-system]
2
- requires = ["uv_build>=0.8.12,<0.9.0"]
2
+ requires = ["uv_build>=0.8.12,<0.10.0"]
3
3
  build-backend = "uv_build"
4
4
 
5
5
  [tool.hatch.build.targets.wheel]
@@ -7,15 +7,14 @@ packages = ["src/ort"]
7
7
 
8
8
  [project]
9
9
  name = "python-ort"
10
- version = "0.1.4"
10
+ version = "0.3.0"
11
11
  description = "A Python Ort model serialization library"
12
12
  readme = "README.md"
13
13
  license = "MIT"
14
14
  license-files = ["LICENSE"]
15
15
  requires-python = ">=3.10"
16
16
  dependencies = [
17
- "pydantic>=2.11.10",
18
- "pyyaml>=6.0.3",
17
+ "pydantic>=2.12.4",
19
18
  ]
20
19
  classifiers = [
21
20
  "Development Status :: 3 - Alpha",
@@ -25,6 +24,7 @@ classifiers = [
25
24
  "Programming Language :: Python :: 3.11",
26
25
  "Programming Language :: Python :: 3.12",
27
26
  "Programming Language :: Python :: 3.13",
27
+ "Programming Language :: Python :: 3.14",
28
28
  "Topic :: Software Development :: Libraries :: Python Modules",
29
29
  ]
30
30
 
@@ -34,12 +34,12 @@ module-root = "src"
34
34
 
35
35
  [dependency-groups]
36
36
  dev = [
37
- "datamodel-code-generator[http]>=0.34.0",
37
+ "datamodel-code-generator[http]>=0.35.0",
38
38
  "pre-commit>=4.3.0",
39
39
  "pycodestyle>=2.14.0",
40
- "pyrefly>=0.35.0",
40
+ "pyrefly>=0.40.0",
41
41
  "pytest>=8.4.2",
42
- "ruff>=0.13.3",
42
+ "ruff>=0.14.4",
43
43
  "types-pyyaml>=6.0.12.20250915",
44
44
  ]
45
45
 
@@ -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
+ from ort.models.config.license_finding_curation import LicenseFindingCuration
8
+ from ort.models.package_curation import PackageCuration
9
+
10
+
11
+ class Curations(BaseModel):
12
+ """
13
+ Curations for artifacts in a repository.
14
+
15
+ Attributes:
16
+ packages(list[PackageCuration]): Curations for third-party packages.
17
+ license_findings(list[LicenseFindingCuration]): Curations for license findings.
18
+ """
19
+
20
+ model_config = ConfigDict(
21
+ extra="forbid",
22
+ )
23
+ packages: list[PackageCuration] = Field(
24
+ default_factory=list,
25
+ description="Curations for third-party packages.",
26
+ )
27
+ license_findings: list[LicenseFindingCuration] = Field(
28
+ default_factory=list,
29
+ description="Curations for license findings.",
30
+ )
@@ -0,0 +1,61 @@
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.config.license_finding_curation_reason import LicenseFindingCurationReason
8
+
9
+
10
+ class LicenseFindingCuration(BaseModel):
11
+ """
12
+ A curation for a license finding. Use it to correct a license finding or to add a license
13
+ that was not previously detected.
14
+
15
+ Attributes:
16
+ path (str): A glob to match the file path of a license finding.
17
+ start_lines (list[int] | None): A matcher for the start line of a license finding, matches if the start line
18
+ matches any of [startLines] or if [startLines] is empty.
19
+ line_count (int | None): A matcher for the line count of a license finding
20
+ matches if the line count equals [lineCount] or if [lineCount] is None
21
+ detected_license (str | None): The concluded license as SPDX expression or None
22
+ for no license, see https://spdx.dev/spdx-specification-21-web-version#h.jxpfx0ykyb60.
23
+ concluded_license (str): The concluded license as SPDX expression or None for no license,
24
+ see https://spdx.dev/spdx-specification-21-web-version#h.jxpfx0ykyb60.
25
+ reason (LicenseFindingCurationReason): The reason why the curation was made, out of a predefined choice.
26
+ comment (str | None): A comment explaining this [LicenseFindingCuration].
27
+ """
28
+
29
+ model_config = ConfigDict(
30
+ extra="forbid",
31
+ )
32
+ path: str = Field(
33
+ description="A glob to match the file path of a license finding.",
34
+ )
35
+ start_lines: list[int] | None = Field(
36
+ default=None,
37
+ description="A matcher for the start line of a license finding, matches if the start line matches any of"
38
+ "[startLines] or if [startLines] is empty.",
39
+ )
40
+ line_count: int | None = Field(
41
+ default=None,
42
+ description="A matcher for the line count of a license finding"
43
+ "matches if the line count equals [lineCount] or if [lineCount] is None",
44
+ )
45
+
46
+ detected_license: str | None = Field(
47
+ default=None,
48
+ description="The concluded license as SPDX expression or None"
49
+ "for no license, see https://spdx.dev/spdx-specification-21-web-version#h.jxpfx0ykyb60.",
50
+ )
51
+ concluded_license: str = Field(
52
+ description="The concluded license as SPDX expression or None for no license,"
53
+ " see https://spdx.dev/spdx-specification-21-web-version#h.jxpfx0ykyb60.",
54
+ )
55
+ reason: LicenseFindingCurationReason = Field(
56
+ description="The reason why the curation was made, out of a predefined choice.",
57
+ )
58
+ comment: str | None = Field(
59
+ default=None,
60
+ description="A comment explaining this [LicenseFindingCuration].",
61
+ )
@@ -0,0 +1,28 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+
6
+ from enum import Enum
7
+
8
+
9
+ class LicenseFindingCurationReason(Enum):
10
+ """
11
+ A curation for a license finding. Use it to correct a license finding or to add a license that was not
12
+ previously detected.
13
+
14
+ Attributes:
15
+ CODE: The findings occur in source code, for example the name of a variable.
16
+ DATA_OF: The findings occur in a data, for example a JSON object defining all SPDX licenses.
17
+ DOCUMENTATION_OF: The findings occur in documentation, for example in code comments or in the README.md.
18
+ INCORRECT: The detected licenses are not correct. Use only if none of the other reasons apply.
19
+ NOT_DETECTED: Add applicable license as the scanner did not detect it.
20
+ REFERENCE: The findings reference a file or URL, e.g. SEE LICENSE IN LICENSE or https://jquery.org/license/.
21
+ """
22
+
23
+ CODE = "CODE"
24
+ DATA_OF = "DATA_OF"
25
+ DOCUMENTATION_OF = "DOCUMENTATION_OF"
26
+ INCORRECT = "INCORRECT"
27
+ NOT_DETECTED = "NOT_DETECTED"
28
+ REFERENCE = "REFERENCE"
@@ -0,0 +1,19 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+ from ort.models.hash_algorithm import HashAlgorithm
7
+
8
+
9
+ class Hash(BaseModel):
10
+ """
11
+ A class that bundles a hash algorithm with its hash value.
12
+
13
+ Attributes:
14
+ value (str): The value calculated using the hash algorithm.
15
+ algorithm (HashAlgorithm): The algorithm used to calculate the hash value.
16
+ """
17
+
18
+ value: str = Field(description="The value calculated using the hash algorithm.")
19
+ algorithm: HashAlgorithm = Field(description="The algorithm used to calculate the hash value.")
@@ -0,0 +1,37 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+
6
+ from enum import Enum
7
+
8
+
9
+ class HashAlgorithm(Enum):
10
+ """
11
+ An enum of supported hash algorithms. Each algorithm has one or more [aliases] associated to it,
12
+ where the first alias is the definite name.
13
+
14
+ Attributes:
15
+ NONE: No hash algorithm.
16
+ UNKNOWN: An unknown hash algorithm.
17
+ MD5: The Message-Digest 5 hash algorithm, see [MD5](http://en.wikipedia.org/wiki/MD5).
18
+ SHA1: The Secure Hash Algorithm 1, see [SHA-1](https://en.wikipedia.org/wiki/SHA-1).
19
+ SHA256: The Secure Hash Algorithm 2 with 256 bits, see [SHA-256](https://en.wikipedia.org/wiki/SHA-256).
20
+ SHA384: The Secure Hash Algorithm 2 with 384 bits, see [SHA-384](https://en.wikipedia.org/wiki/SHA-384).
21
+ SHA512: The Secure Hash Algorithm 2 with 512 bits, see [SHA-512](https://en.wikipedia.org/wiki/SHA-512).
22
+ SHA1GIT: The Secure Hash Algorithm 1, but calculated on a Git "blob" object, see
23
+ - https://git-scm.com/book/en/v2/Git-Internals-Git-Objects#_object_storage
24
+ - https://docs.softwareheritage.org/devel/swh-model/persistent-identifiers.html#git-compatibility
25
+ """
26
+
27
+ NONE = "NONE"
28
+ UNKNOWN = "UNKNOWN"
29
+ MD5 = "MD5"
30
+ SHA1 = "SHA1"
31
+ SHA256 = "SHA256"
32
+ SHA384 = "SHA384"
33
+ SHA512 = "SHA512"
34
+ SHA1GIT = (
35
+ ["SHA-1-GIT", "SHA1-GIT", "SHA1GIT", "SWHID"],
36
+ "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
37
+ )
@@ -0,0 +1,15 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+
5
+ from pydantic import BaseModel, ConfigDict
6
+
7
+ from .package_curation_data import PackageCurationData
8
+
9
+
10
+ class PackageCuration(BaseModel):
11
+ model_config = ConfigDict(
12
+ extra="forbid",
13
+ )
14
+ id: str
15
+ curations: PackageCurationData
@@ -0,0 +1,36 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from typing import Any
5
+
6
+ from pydantic import AnyUrl, BaseModel, ConfigDict, Field
7
+
8
+ from .hash import Hash
9
+ from .source_code_origin import SourceCodeOrigin
10
+ from .vcsinfo import VcsInfo
11
+
12
+
13
+ class CurationArtifact(BaseModel):
14
+ url: AnyUrl
15
+ hash: Hash
16
+
17
+
18
+ class PackageCurationData(BaseModel):
19
+ model_config = ConfigDict(
20
+ extra="forbid",
21
+ )
22
+ comment: str | None = None
23
+ purl: str | None = None
24
+ cpe: str | None = None
25
+ authors: list[str] | None = None
26
+ concluded_license: str | None = None
27
+ description: str | None = None
28
+ homepage_url: str | None = None
29
+ binary_artifact: CurationArtifact | None = None
30
+ source_artifact: CurationArtifact | None = None
31
+ vcs: VcsInfo | None = None
32
+ is_metadata_only: bool | None = None
33
+ is_modified: bool | None = None
34
+ declared_license_mapping: dict[str, Any] = Field(default_factory=dict)
35
+ source_code_origins: list[SourceCodeOrigin] | None = None
36
+ labels: dict[str, str] = Field(default_factory=dict)
@@ -7,8 +7,9 @@ from typing import Any
7
7
 
8
8
  from pydantic import BaseModel, Field, RootModel
9
9
 
10
- from .analyzer_configurations import OrtAnalyzerConfigurations
11
- from .package_managers import OrtPackageManagerConfigurations, PackageManagerConfigs
10
+ from ort.models.analyzer_configurations import OrtAnalyzerConfigurations
11
+ from ort.models.config.curations import Curations
12
+ from ort.models.package_managers import OrtPackageManagerConfigurations, PackageManagerConfigs
12
13
 
13
14
 
14
15
  class OrtRepositoryConfigurationLicenseChoicesPackageLicenseChoiceLicenseChoice(BaseModel):
@@ -65,45 +66,6 @@ class VulnerabilityResolutionReason(Enum):
65
66
  workaround_for_vulnerability = "WORKAROUND_FOR_VULNERABILITY"
66
67
 
67
68
 
68
- class VcsMatcherVcsMatcher(BaseModel):
69
- path: str | None = None
70
- revision: str | None = None
71
- type: str
72
- url: str | None = None
73
-
74
-
75
- class VcsMatcherVcsMatcher1(BaseModel):
76
- path: str | None = None
77
- revision: str | None = None
78
- type: str | None = None
79
- url: str
80
-
81
-
82
- class VcsMatcherVcsMatcher2(BaseModel):
83
- path: str | None = None
84
- revision: str
85
- type: str | None = None
86
- url: str | None = None
87
-
88
-
89
- class VcsMatcherVcsMatcher3(BaseModel):
90
- path: str
91
- revision: str | None = None
92
- type: str | None = None
93
- url: str | None = None
94
-
95
-
96
- class VcsMatcher(
97
- RootModel[VcsMatcherVcsMatcher | VcsMatcherVcsMatcher1 | VcsMatcherVcsMatcher2 | VcsMatcherVcsMatcher3]
98
- ):
99
- root: VcsMatcherVcsMatcher | VcsMatcherVcsMatcher1 | VcsMatcherVcsMatcher2 | VcsMatcherVcsMatcher3
100
-
101
-
102
- class Hash(BaseModel):
103
- value: str
104
- algorithm: str
105
-
106
-
107
69
  class PackageConfigurationSchemaSourceCodeOrigin(Enum):
108
70
  vcs = "VCS"
109
71
  artifact = "ARTIFACT"
@@ -140,24 +102,6 @@ class PathExcludeReason(Enum):
140
102
  test_tool_of = "TEST_TOOL_OF"
141
103
 
142
104
 
143
- VcsMatcherVcsMatcher4 = VcsMatcherVcsMatcher
144
-
145
-
146
- VcsMatcherVcsMatcher5 = VcsMatcherVcsMatcher1
147
-
148
-
149
- VcsMatcherVcsMatcher6 = VcsMatcherVcsMatcher2
150
-
151
-
152
- VcsMatcherVcsMatcher7 = VcsMatcherVcsMatcher3
153
-
154
-
155
- class VcsMatcherModel(
156
- RootModel[VcsMatcherVcsMatcher4 | VcsMatcherVcsMatcher5 | VcsMatcherVcsMatcher6 | VcsMatcherVcsMatcher7]
157
- ):
158
- root: VcsMatcherVcsMatcher4 | VcsMatcherVcsMatcher5 | VcsMatcherVcsMatcher6 | VcsMatcherVcsMatcher7
159
-
160
-
161
105
  class PathIncludeReason(Enum):
162
106
  source_of = "SOURCE_OF"
163
107
 
@@ -300,45 +244,6 @@ class ResolutionsSchema(
300
244
  )
301
245
 
302
246
 
303
- class CurationsSchemaCurationsSchemaItemCurationsBinaryArtifact(BaseModel):
304
- url: str
305
- hash: Hash
306
-
307
-
308
- CurationsSchemaCurationsSchemaItemCurationsSourceArtifact = CurationsSchemaCurationsSchemaItemCurationsBinaryArtifact
309
-
310
-
311
- class CurationsSchemaCurationsSchemaItemCurations(BaseModel):
312
- comment: str | None = None
313
- authors: list[str] | None = None
314
- concluded_license: str | None = None
315
- cpe: str | None = None
316
- declared_license_mapping: dict[str, Any] | None = None
317
- description: str | None = None
318
- homepage_url: str | None = None
319
- purl: str | None = None
320
- binary_artifact: CurationsSchemaCurationsSchemaItemCurationsBinaryArtifact | None = None
321
- source_artifact: CurationsSchemaCurationsSchemaItemCurationsSourceArtifact | None = None
322
- vcs: VcsMatcher | None = None
323
- is_metadata_only: bool | None = None
324
- is_modified: bool | None = None
325
-
326
-
327
- class CurationsSchemaCurationsSchemaItem(BaseModel):
328
- id: str
329
- curations: CurationsSchemaCurationsSchemaItemCurations
330
-
331
-
332
- class CurationsSchema(RootModel[list[CurationsSchemaCurationsSchemaItem]]):
333
- root: list[CurationsSchemaCurationsSchemaItem] = Field(
334
- ...,
335
- description="The OSS-Review-Toolkit (ORT) provides a possibility to correct metadata and set "
336
- "the concluded license for specific packages (dependencies) in curation files. A full list of all available "
337
- "options can be found at https://oss-review-toolkit.org/ort/docs/configuration/package-curations.",
338
- title="ORT curations",
339
- )
340
-
341
-
342
247
  class LicenseFindingCurationsModel(BaseModel):
343
248
  path: str
344
249
  start_lines: int | str | None = None
@@ -349,14 +254,14 @@ class LicenseFindingCurationsModel(BaseModel):
349
254
  comment: str | None = None
350
255
 
351
256
 
352
- class OrtRepositoryConfigurationCurations(BaseModel):
257
+ class OrtRepositoryConfigurationH(BaseModel):
353
258
  license_findings: list[LicenseFindingCurationsModel]
354
- packages: CurationsSchema | None = None
259
+ packages: Curations | None = None
355
260
 
356
261
 
357
262
  class OrtRepositoryConfigurationCurations1(BaseModel):
358
263
  license_findings: list[LicenseFindingCurationsModel] | None = None
359
- packages: CurationsSchema
264
+ packages: Curations
360
265
 
361
266
 
362
267
  class OrtRepositoryConfiguration(BaseModel):
@@ -385,9 +290,10 @@ class OrtRepositoryConfiguration(BaseModel):
385
290
  description="Defines which parts of a repository should be excluded.",
386
291
  )
387
292
  resolutions: ResolutionsSchema | None = None
388
- curations: OrtRepositoryConfigurationCurations | OrtRepositoryConfigurationCurations1 | None = Field(
293
+ curations: Curations | None = Field(
389
294
  None,
390
- description="Curations for artifacts in a repository.",
295
+ description="Defines curations for packages used as dependencies by projects in this repository,"
296
+ " or curations for license findings in the source code of a project in this repository.",
391
297
  )
392
298
  package_configurations: list[OrtPackageManagerConfigurations] | None = Field(
393
299
  None,
@@ -0,0 +1,9 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from enum import Enum
5
+
6
+
7
+ class SourceCodeOrigin(Enum):
8
+ vcs = "VCS"
9
+ artifact = "ARTIFACT"
@@ -0,0 +1,33 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from pydantic import AnyUrl, BaseModel, Field
5
+
6
+ from .vcstype import VcsType
7
+
8
+
9
+ class VcsInfo(BaseModel):
10
+ """
11
+ Bundles general Version Control System information.
12
+
13
+ Attributes:
14
+ type(VcsType): The type of the VCS, for example Git, GitRepo, Mercurial, etc.
15
+ url(AnyUrl): The URL to the VCS repository.
16
+ revision(str): The VCS-specific revision (tag, branch, SHA1) that the version of the package maps to.
17
+ path(str): The path inside the VCS to take into account.
18
+ If the VCS supports checking out only a subdirectory, only this path is checked out.
19
+ """
20
+
21
+ type: VcsType = Field(
22
+ default_factory=VcsType,
23
+ description="The type of the VCS, for example Git, GitRepo, Mercurial, etc.",
24
+ )
25
+ url: AnyUrl = Field(description="The URL to the VCS repository.")
26
+ revision: str = Field(
27
+ description="The VCS-specific revision (tag, branch, SHA1) that the version of the package maps to."
28
+ )
29
+ path: str = Field(
30
+ default="",
31
+ description="The path inside the VCS to take into account."
32
+ "If the VCS supports checking out only a subdirectory, only this path is checked out.",
33
+ )
@@ -0,0 +1,46 @@
1
+ # SPDX-FileCopyrightText: 2025 Helio Chissini de Castro <heliocastro@gmail.com>
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ from pydantic import BaseModel, Field, model_validator
5
+
6
+
7
+ class VcsType(BaseModel):
8
+ """
9
+ A class for Version Control System types. Each type has one or more [aliases] associated to it,
10
+ where the first alias is the definite name. This class is not implemented as an enum as
11
+ constructing from an unknown type should be supported while maintaining that type as the primary
12
+ alias for the string representation.
13
+
14
+ Attributes:
15
+ aliases(list[str]): Primary name and aliases
16
+ """
17
+
18
+ aliases: list[str] = Field(default_factory=list, description="Primary name and aliases")
19
+
20
+ @model_validator(mode="after")
21
+ def ensure_non_empty(self):
22
+ """Ensure the aliases list is never empty."""
23
+ if not self.aliases:
24
+ self.aliases = [""]
25
+ return self
26
+
27
+ def __str__(self):
28
+ return self.aliases[0] if self.aliases else ""
29
+
30
+ @classmethod
31
+ def for_name(cls, name: str) -> "VcsType":
32
+ """Lookup known type by name, or create a new instance."""
33
+ for t in KNOWN_TYPES:
34
+ if any(alias.lower() == name.lower() for alias in t.aliases):
35
+ return t
36
+ return cls(aliases=[name])
37
+
38
+
39
+ # Define known VCS types as constants
40
+ GIT = VcsType(aliases=["Git", "GitHub", "GitLab"])
41
+ GIT_REPO = VcsType(aliases=["GitRepo", "git-repo", "repo"])
42
+ MERCURIAL = VcsType(aliases=["Mercurial", "hg"])
43
+ SUBVERSION = VcsType(aliases=["Subversion", "svn"])
44
+ UNKNOWN = VcsType(aliases=[""])
45
+
46
+ KNOWN_TYPES = [GIT, GIT_REPO, MERCURIAL, SUBVERSION]
File without changes
File without changes