Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ jobs:
strategy:
matrix:
conf:
- { py: "3.9", os: "ubuntu-latest" }
- { py: "3.10", os: "ubuntu-latest" }
- { py: "3.11", os: "ubuntu-latest" }
- { py: "3.12", os: "ubuntu-latest" }
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@ jobs:
with:
persist-credentials: false

# NOTE: We intentionally check `--help` rendering against our minimum Python,
# NOTE: We intentionally check --help rendering against our minimum Python,
# since it changes slightly between Python versions.
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.9"
python-version: "3.10"
cache: "pip"
cache-dependency-path: pyproject.toml

Expand Down Expand Up @@ -76,7 +76,7 @@ jobs:
# NOTE: We intentionally check test certificates against our minimum supported Python.
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
with:
python-version: "3.9"
python-version: "3.10"
cache: "pip"
cache-dependency-path: pyproject.toml

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/requirements.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
SIGSTORE_REF: ${{ inputs.ref }}
strategy:
matrix:
python_version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
python_version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- name: Populate reference from context
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ All versions prior to 0.9.0 are untracked.

## [Unreleased]

### Removed

* Removed support for Python 3.9 as it is end-of-life
([#1645](https://github.com/sigstore/sigstore-python/pull/1645))


## [4.1.0]

### Added
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ as well as performing common development tasks.

## Requirements

`sigstore`'s only development environment requirement *should* be Python 3.9
`sigstore`'s only development environment requirement *should* be Python 3.10
or newer. Development and testing is actively performed on macOS and Linux,
but Windows and other supported platforms that are supported by Python
should also work.
Expand Down Expand Up @@ -105,7 +105,7 @@ make gen-x509-testcases

### Documentation

If you're running Python 3.9 or newer, you can run the documentation build locally:
If you're running Python 3.10 or newer, you can run the documentation build locally:

```bash
make doc
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ else!

## Installation

`sigstore` requires Python 3.9 or newer, and can be installed directly via `pip`:
`sigstore` requires Python 3.10 or newer, and can be installed directly via `pip`:

```console
python -m pip install sigstore
Expand Down Expand Up @@ -81,7 +81,7 @@ positional arguments:
trust-instance Initialize trust for a Sigstore instance
plumbing developer-only plumbing operations

optional arguments:
options:
-h, --help show this help message and exit
-v, --verbose run with additional debug logging; supply multiple
times to increase verbosity (default: 0)
Expand Down Expand Up @@ -116,7 +116,7 @@ usage: sigstore sign [-h] [-v] [--rekor-version VERSION]
positional arguments:
FILE The file to sign

optional arguments:
options:
-h, --help show this help message and exit
-v, --verbose run with additional debug logging; supply multiple
times to increase verbosity (default: 0)
Expand Down Expand Up @@ -176,7 +176,7 @@ usage: sigstore attest [-h] [-v] [--rekor-version VERSION] --predicate FILE
positional arguments:
FILE The file to sign

optional arguments:
options:
-h, --help show this help message and exit
-v, --verbose run with additional debug logging; supply multiple
times to increase verbosity (default: 0)
Expand Down Expand Up @@ -228,7 +228,7 @@ usage: sigstore verify identity [-h] [-v] [--certificate FILE]
URL
FILE_OR_DIGEST [FILE_OR_DIGEST ...]

optional arguments:
options:
-h, --help show this help message and exit
-v, --verbose run with additional debug logging; supply multiple
times to increase verbosity (default: 0)
Expand Down Expand Up @@ -267,7 +267,7 @@ usage: sigstore verify github [-h] [-v] [--certificate FILE]
[--ref REF]
FILE_OR_DIGEST [FILE_OR_DIGEST ...]

optional arguments:
options:
-h, --help show this help message and exit
-v, --verbose run with additional debug logging; supply multiple
times to increase verbosity (default: 0)
Expand Down
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ classifiers = [
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand Down Expand Up @@ -45,7 +44,7 @@ dependencies = [
"tuf ~= 6.0",
"platformdirs ~= 4.2",
]
requires-python = ">=3.9"
requires-python = ">=3.10"

[project.scripts]
sigstore = "sigstore._cli:main"
Expand Down
3 changes: 1 addition & 2 deletions sigstore/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from concurrent import futures
from dataclasses import dataclass
from pathlib import Path
from typing import Any, NoReturn, Union
from typing import Any, NoReturn, TypeAlias, Union

from cryptography.hazmat.primitives.serialization import Encoding
from cryptography.x509 import load_pem_x509_certificate
Expand All @@ -32,7 +32,6 @@
from rich.logging import RichHandler
from sigstore_models.bundle.v1 import Bundle as RawBundle
from sigstore_models.common.v1 import HashAlgorithm
from typing_extensions import TypeAlias

from sigstore import __version__, dsse
from sigstore._internal.fulcio.client import ExpiredCertificate
Expand Down
5 changes: 2 additions & 3 deletions sigstore/_internal/sct.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import logging
import struct
from datetime import timezone
from typing import Optional

from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec, rsa
Expand Down Expand Up @@ -47,7 +46,7 @@


def _pack_signed_entry(
sct: SignedCertificateTimestamp, cert: Certificate, issuer_key_id: Optional[bytes]
sct: SignedCertificateTimestamp, cert: Certificate, issuer_key_id: bytes | None
) -> bytes:
fields = []
if sct.entry_type == LogEntryType.X509_CERTIFICATE:
Expand Down Expand Up @@ -92,7 +91,7 @@ def _pack_signed_entry(
def _pack_digitally_signed(
sct: SignedCertificateTimestamp,
cert: Certificate,
issuer_key_id: Optional[KeyID],
issuer_key_id: KeyID | None,
) -> bytes:
"""
Packs the contents of `cert` (and some pieces of `sct`) into a structured
Expand Down
74 changes: 37 additions & 37 deletions sigstore/dsse/_predicate.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""

import enum
from typing import Any, Literal, Optional, Union
from typing import Any, Literal, Union

from pydantic import (
BaseModel,
Expand Down Expand Up @@ -86,50 +86,50 @@ class ConfigSource(_SLSAConfigBase):
The ConfigSource object used by Invocation in v0.2
"""

uri: Optional[StrictStr] = None
digest: Optional[DigestSetSource] = None
entry_point: Optional[StrictStr] = None
uri: StrictStr | None = None
digest: DigestSetSource | None = None
entry_point: StrictStr | None = None


class Invocation(_SLSAConfigBase):
"""
The Invocation object used by SLSAPredicateV0_2
"""

config_source: Optional[ConfigSource] = None
parameters: Optional[dict[str, Any]] = None
environment: Optional[dict[str, Any]] = None
config_source: ConfigSource | None = None
parameters: dict[str, Any] | None = None
environment: dict[str, Any] | None = None


class Completeness(_SLSAConfigBase):
"""
The Completeness object used by Metadata in v0.2
"""

parameters: Optional[bool] = None
environment: Optional[bool] = None
materials: Optional[bool] = None
parameters: bool | None = None
environment: bool | None = None
materials: bool | None = None


class Material(_SLSAConfigBase):
"""
The Material object used by Metadata in v0.2
"""

uri: Optional[StrictStr] = None
digest: Optional[DigestSetSource] = None
uri: StrictStr | None = None
digest: DigestSetSource | None = None


class Metadata(_SLSAConfigBase):
"""
The Metadata object used by SLSAPredicateV0_2
"""

build_invocation_id: Optional[StrictStr] = None
build_started_on: Optional[StrictStr] = None
build_finished_on: Optional[StrictStr] = None
completeness: Optional[Completeness] = None
reproducible: Optional[bool] = None
build_invocation_id: StrictStr | None = None
build_started_on: StrictStr | None = None
build_finished_on: StrictStr | None = None
completeness: Completeness | None = None
reproducible: bool | None = None


class SLSAPredicateV0_2(Predicate, _SLSAConfigBase):
Expand All @@ -139,10 +139,10 @@ class SLSAPredicateV0_2(Predicate, _SLSAConfigBase):

builder: BuilderV0_1
build_type: StrictStr
invocation: Optional[Invocation] = None
metadata: Optional[Metadata] = None
build_config: Optional[dict[str, Any]] = None
materials: Optional[list[Material]] = None
invocation: Invocation | None = None
metadata: Metadata | None = None
build_config: dict[str, Any] | None = None
materials: list[Material] | None = None


# Models for SLSA Provenance v1.0
Expand All @@ -153,13 +153,13 @@ class ResourceDescriptor(_SLSAConfigBase):
The ResourceDescriptor object defined defined by the in-toto attestations spec
"""

name: Optional[StrictStr] = None
uri: Optional[StrictStr] = None
digest: Optional[DigestSetSource] = None
content: Optional[StrictBytes] = None
download_location: Optional[StrictStr] = None
media_type: Optional[StrictStr] = None
annotations: Optional[dict[StrictStr, Any]] = None
name: StrictStr | None = None
uri: StrictStr | None = None
digest: DigestSetSource | None = None
content: StrictBytes | None = None
download_location: StrictStr | None = None
media_type: StrictStr | None = None
annotations: dict[StrictStr, Any] | None = None

@model_validator(mode="after")
def check_required_fields(self: Self) -> Self:
Expand All @@ -180,18 +180,18 @@ class BuilderV1_0(_SLSAConfigBase):
"""

id: StrictStr
builder_dependencies: Optional[list[ResourceDescriptor]] = None
version: Optional[dict[StrictStr, StrictStr]] = None
builder_dependencies: list[ResourceDescriptor] | None = None
version: dict[StrictStr, StrictStr] | None = None


class BuildMetadata(_SLSAConfigBase):
"""
The BuildMetadata object used by RunDetails
"""

invocation_id: Optional[StrictStr] = None
started_on: Optional[StrictStr] = None
finished_on: Optional[StrictStr] = None
invocation_id: StrictStr | None = None
started_on: StrictStr | None = None
finished_on: StrictStr | None = None


class RunDetails(_SLSAConfigBase):
Expand All @@ -200,8 +200,8 @@ class RunDetails(_SLSAConfigBase):
"""

builder: BuilderV1_0
metadata: Optional[BuildMetadata] = None
byproducts: Optional[list[ResourceDescriptor]] = None
metadata: BuildMetadata | None = None
byproducts: list[ResourceDescriptor] | None = None


class BuildDefinition(_SLSAConfigBase):
Expand All @@ -211,8 +211,8 @@ class BuildDefinition(_SLSAConfigBase):

build_type: StrictStr
external_parameters: dict[StrictStr, Any]
internal_parameters: Optional[dict[str, Any]] = None
resolved_dependencies: Optional[list[ResourceDescriptor]] = None
internal_parameters: dict[str, Any] | None = None
resolved_dependencies: list[ResourceDescriptor] | None = None


class SLSAPredicateV1_0(Predicate, _SLSAConfigBase):
Expand Down
4 changes: 2 additions & 2 deletions sigstore/oidc.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
import urllib.parse
import webbrowser
from datetime import datetime, timezone
from typing import NoReturn, Optional, cast
from typing import NoReturn, cast

import id
import jwt
Expand Down Expand Up @@ -407,6 +407,6 @@ def detect_credential(client_id: str = _DEFAULT_CLIENT_ID) -> str | None:
"""Calls `id.detect_credential`, but wraps exceptions with our own exception type."""

try:
return cast(Optional[str], id.detect_credential(client_id))
return cast(str | None, id.detect_credential(client_id))
except id.IdentityError as exc:
IdentityError.raise_from_id(exc)
2 changes: 1 addition & 1 deletion test/integration/cli/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from collections.abc import Callable
from pathlib import Path
from typing import Callable

import pytest

Expand Down
3 changes: 1 addition & 2 deletions test/integration/cli/test_attest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from pathlib import Path
from typing import Optional

import pytest

Expand All @@ -27,7 +26,7 @@ def get_cli_params(
pred_path: Path,
artifact_path: Path,
overwrite: bool = False,
bundle_path: Optional[Path] = None,
bundle_path: Path | None = None,
) -> list[str]:
cli_params = [
"--staging",
Expand Down
Loading