Skip to content

Commit 5a50381

Browse files
authored
Bump pydantic to 2.10.0 and remove Base64 workaround (#73)
1 parent cfb3d4d commit 5a50381

File tree

3 files changed

+8
-36
lines changed

3 files changed

+8
-36
lines changed

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ dependencies = [
1313
"cryptography",
1414
"packaging",
1515
"pyasn1 ~= 0.6",
16-
"pydantic",
16+
"pydantic >= 2.10.0",
1717
"sigstore~=3.4",
1818
"sigstore-protobuf-specs",
1919
]

src/pypi_attestations/_impl.py

+1-25
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from packaging.utils import parse_sdist_filename, parse_wheel_filename
1818
from pyasn1.codec.der.decoder import decode as der_decode
1919
from pyasn1.type.char import UTF8String
20-
from pydantic import Base64Encoder, BaseModel, ConfigDict, EncodedBytes, Field, field_validator
20+
from pydantic import Base64Bytes, BaseModel, ConfigDict, Field, field_validator
2121
from pydantic.alias_generators import to_snake
2222
from pydantic_core import ValidationError
2323
from sigstore._utils import _sha256_streaming
@@ -38,30 +38,6 @@
3838
from sigstore.verify.policy import VerificationPolicy
3939

4040

41-
class Base64EncoderSansNewline(Base64Encoder):
42-
r"""A Base64Encoder that doesn't insert newlines when encoding.
43-
44-
Pydantic's Base64Bytes type inserts newlines b'\n' every 76 characters because they
45-
use `base64.encodebytes()` instead of `base64.b64encode()`. Pydantic maintainers
46-
have stated that they won't fix this, and that users should work around it by
47-
defining their own Base64 type with a custom encoder.
48-
See https://github.com/pydantic/pydantic/issues/9072 for more details.
49-
"""
50-
51-
@classmethod
52-
def encode(cls, value: bytes) -> bytes:
53-
"""Encode bytes to base64."""
54-
return base64.b64encode(value)
55-
56-
@classmethod
57-
def decode(cls, value: bytes) -> bytes:
58-
"""Decode base64 bytes."""
59-
return base64.b64decode(value, validate=True)
60-
61-
62-
Base64Bytes = Annotated[bytes, EncodedBytes(encoder=Base64EncoderSansNewline)]
63-
64-
6541
class Distribution(BaseModel):
6642
"""Represents a Python package distribution.
6743

test/test_impl.py

+6-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import pretend
1010
import pytest
1111
import sigstore
12-
from pydantic import BaseModel, TypeAdapter, ValidationError
12+
from pydantic import Base64Bytes, BaseModel, TypeAdapter, ValidationError
1313
from sigstore.dsse import DigestSet, StatementBuilder, Subject
1414
from sigstore.models import Bundle
1515
from sigstore.oidc import IdentityToken
@@ -614,18 +614,14 @@ def test_version(self) -> None:
614614

615615

616616
class DummyModel(BaseModel):
617-
base64_bytes: impl.Base64Bytes
617+
base64_bytes: Base64Bytes
618618

619619

620620
class TestBase64Bytes:
621-
# See the docstrings for `_impl.Base64Bytes` for more details
622-
def test_decoding(self) -> None:
623-
# This raises when using our custom type. When using Pydantic's Base64Bytes,
624-
# this succeeds
625-
# The exception message is different in Python 3.9 vs >=3.10
626-
with pytest.raises(ValueError, match="Non-base64 digit found|Only base64 data is allowed"):
627-
DummyModel(base64_bytes=b"a\n\naaa")
628-
621+
# Regression test for an issue with pydantic < 2.10.0
622+
# The Base64Bytes Pydantic type should not insert newlines
623+
# when encoding to base64.
624+
# See https://github.com/pydantic/pydantic/issues/9072
629625
def test_encoding(self) -> None:
630626
model = DummyModel(base64_bytes=b"aaaa" * 76)
631627
assert "\\n" not in model.model_dump_json()

0 commit comments

Comments
 (0)