Skip to content

Commit dc9156f

Browse files
committed
Make minimum Python version 3.9 again
1 parent a68278c commit dc9156f

File tree

5 files changed

+21
-9
lines changed

5 files changed

+21
-9
lines changed

.github/workflows/tests.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ jobs:
1111
strategy:
1212
matrix:
1313
python:
14+
- "3.9"
15+
- "3.10"
1416
- "3.11"
1517
- "3.12"
1618
- "3.13"

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- The minimum Python version required has been brought back to `3.9`
13+
([#64](https://github.com/trailofbits/pypi-attestations/pull/64)).
14+
1015
### Fixed
1116

1217
- `python -m pypi_attestations verify` now handles inputs like `dist/*`

pyproject.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ dependencies = [
1616
"sigstore~=3.3",
1717
"sigstore-protobuf-specs",
1818
]
19-
requires-python = ">=3.11"
19+
requires-python = ">=3.9"
2020

2121
[tool.setuptools.dynamic]
2222
version = { attr = "pypi_attestations.__version__" }
@@ -56,6 +56,7 @@ omit = ["src/pypi_attestations/_cli.py", "src/pypi_attestations/__main__.py"]
5656
mypy_path = "src"
5757
packages = "pypi_attestations"
5858
plugins = ["pydantic.mypy"]
59+
python_version = "3.9"
5960
allow_redefinition = true
6061
check_untyped_defs = true
6162
disallow_incomplete_defs = true
@@ -74,7 +75,7 @@ warn_unused_ignores = true
7475

7576
[tool.ruff]
7677
line-length = 100
77-
target-version = "py311"
78+
target-version = "py39"
7879

7980
[tool.ruff.lint]
8081
select = ["E", "F", "I", "W", "UP", "ANN", "D", "COM", "ISC", "TCH", "SLF"]
@@ -83,6 +84,9 @@ select = ["E", "F", "I", "W", "UP", "ANN", "D", "COM", "ISC", "TCH", "SLF"]
8384
# COM812 and ISC001 can cause conflicts when using ruff as a formatter.
8485
# See https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules.
8586
ignore = ["ANN101", "ANN102", "D203", "D213", "COM812", "ISC001"]
87+
# Needed since Pydantic relies on runtime type annotations, and we target Python versions
88+
# < 3.10. See https://docs.astral.sh/ruff/rules/non-pep604-annotation/#why-is-this-bad
89+
pyupgrade.keep-runtime-typing = true
8690

8791
[tool.ruff.lint.per-file-ignores]
8892

src/pypi_attestations/_impl.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import base64
99
from enum import Enum
10-
from typing import TYPE_CHECKING, Annotated, Any, Literal, NewType
10+
from typing import TYPE_CHECKING, Annotated, Any, Literal, NewType, Optional, Union
1111

1212
import sigstore.errors
1313
from annotated_types import MinLen # noqa: TCH002
@@ -183,7 +183,7 @@ def verify(
183183
verifier: Verifier,
184184
policy: VerificationPolicy,
185185
dist: Distribution,
186-
) -> tuple[str, dict[str, Any] | None]:
186+
) -> tuple[str, Optional[dict[str, Any]]]:
187187
"""Verify against an existing Python distribution.
188188
189189
On failure, raises an appropriate subclass of `AttestationError`.
@@ -362,7 +362,7 @@ class _PublisherBase(BaseModel):
362362
model_config = ConfigDict(alias_generator=to_snake)
363363

364364
kind: str
365-
claims: dict[str, Any] | None = None
365+
claims: Optional[dict[str, Any]] = None
366366

367367

368368
class GitHubPublisher(_PublisherBase):
@@ -382,7 +382,7 @@ class GitHubPublisher(_PublisherBase):
382382
action.
383383
"""
384384

385-
environment: str | None = None
385+
environment: Optional[str] = None
386386
"""
387387
The optional name GitHub Actions environment that the publishing
388388
action was performed from.
@@ -401,13 +401,13 @@ class GitLabPublisher(_PublisherBase):
401401
`bar` owned by group `foo` and subgroup `baz`.
402402
"""
403403

404-
environment: str | None = None
404+
environment: Optional[str] = None
405405
"""
406406
The optional environment that the publishing action was performed from.
407407
"""
408408

409409

410-
Publisher = Annotated[GitHubPublisher | GitLabPublisher, Field(discriminator="kind")]
410+
Publisher = Annotated[Union[GitHubPublisher, GitLabPublisher], Field(discriminator="kind")]
411411

412412

413413
class AttestationBundle(BaseModel):

test/test_impl.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,8 @@ class TestBase64Bytes:
546546
def test_decoding(self) -> None:
547547
# This raises when using our custom type. When using Pydantic's Base64Bytes,
548548
# this succeeds
549-
with pytest.raises(ValueError, match="Only base64 data is allowed"):
549+
# The exception message is different in Python 3.9 vs >=3.10
550+
with pytest.raises(ValueError, match="Non-base64 digit found|Only base64 data is allowed"):
550551
DummyModel(base64_bytes=b"a\n\naaa")
551552

552553
def test_encoding(self) -> None:

0 commit comments

Comments
 (0)