Exemple
pillow 12.3.0: Normalize EXIF orientation with Pillow 12.3.0 without mistaking the in-place API's None return for the transformed image.
Échantillon vérifié pour pypi pillow 12.3.0: Normalize EXIF orientation with Pillow 12.3.0 without mistaking the in-place API's None return for the…
sha256:1a0c77d1acd1df6aa566ef5dd18ab1b8a9b9245b1e7c6e853fd1c0d339f895e6
Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré.
Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes.
MIT-0
Preuves d'exécution
L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.
- Base de preuve
- Contrat signé réussi
- Reçus de vérification
- 2
- Clés de signature qui l’ont compilé
- 2
Environnement déclaré
python linux x64 python python pip
Environnements des exécutions de vérification
| Environnement | Contrat | Étapes | Exécution |
|---|---|---|---|
| python 3.12 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-17 |
| python 3.12 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · python@1 |
2026-08-18 |
Cas
HOW- Objectif
- Normalize EXIF orientation with Pillow 12.3.0 without mistaking the in-place API's None return for the transformed image.
- Paquets
- Symboles
-
- PIL.Image.new
- PIL.Image.Exif
- PIL.ImageOps.exif_transpose
- PIL.ExifTags.Base.Orientation
- PIL.Image.Transpose.ROTATE_270
- Environnement
- python
- Créé
- 2026-08-17T02:14:46Z
Contrat
- The default ImageOps.exif_transpose call returns a distinct transformed copy, removes EXIF Orientation from the copy, and leaves the source image unchanged.
- ImageOps.exif_transpose(..., in_place=True) mutates the source pixels and dimensions, removes EXIF Orientation, and returns None rather than the image.
- The in_place parameter is keyword-only; passing it positionally raises TypeError.
- EXIF Orientation 6 maps a 3-by-2 image to a 2-by-3 clockwise rotation with deterministic pixel order.
Fichiers
- NOTES.md
- csx.json
- requirements.lock
- requirements.txt
- test/contract.py
Code source
# Pillow EXIF transpose contract
`ImageOps.exif_transpose` has two deliberately different ownership modes. The
default call returns a new image, while `in_place=True` mutates the input and
returns `None`. In both modes, a handled EXIF Orientation value is removed so
that downstream software does not rotate the pixels a second time.
This contract builds an RGB image and its EXIF bytes entirely in memory. Using
Orientation 6 makes both the dimension swap and the exact clockwise pixel
mapping observable without filesystem fixtures or lossy JPEG encoding.
{"case":{"believed":"ImageOps.exif_transpose always returns the transformed image and accepts in_place as a positional argument.","caseId":"case:sha256:f1f2db3e57984b0c6f1fbaf071d1e0f3df0f53aec6de21c1c4147004426161eb","contract":["The default ImageOps.exif_transpose call returns a distinct transformed copy, removes EXIF Orientation from the copy, and leaves the source image unchanged.","ImageOps.exif_transpose(..., in_place=True) mutates the source pixels and dimensions, removes EXIF Orientation, and returns None rather than the image.","The in_place parameter is keyword-only; passing it positionally raises TypeError.","EXIF Orientation 6 maps a 3-by-2 image to a 2-by-3 clockwise rotation with deterministic pixel order."],"goal":"Normalize EXIF orientation with Pillow 12.3.0 without mistaking the in-place API's None return for the transformed image.","kind":"HOW","packages":["pkg:pypi/pillow@12.3.0"],"schemaVersion":1,"symbols":["PIL.Image.new","PIL.Image.Exif","PIL.ImageOps.exif_transpose","PIL.ExifTags.Base.Orientation","PIL.Image.Transpose.ROTATE_270"]},"contractCommand":["python","test/contract.py"],"environment":{"arch":"x64","ecosystem":"pypi","executionContext":"python","language":"python","os":"linux","packageManager":"pip","runtime":"python","schemaVersion":1},"license":"MIT-0","packages":["pkg:pypi/pillow@12.3.0"],"schemaVersion":1,"symbols":["PIL.Image.new","PIL.Image.Exif","PIL.ImageOps.exif_transpose","PIL.ExifTags.Base.Orientation","PIL.Image.Transpose.ROTATE_270"],"verifierAdapter":"python@1"}
Pillow==12.3.0
Pillow==12.3.0
import unittest
import PIL
from PIL import ExifTags, Image, ImageOps
ORIENTATION = ExifTags.Base.Orientation
SOURCE_PIXELS = [
(1, 0, 0),
(2, 0, 0),
(3, 0, 0),
(4, 0, 0),
(5, 0, 0),
(6, 0, 0),
]
ROTATED_PIXELS = [
(4, 0, 0),
(1, 0, 0),
(5, 0, 0),
(2, 0, 0),
(6, 0, 0),
(3, 0, 0),
]
def oriented_image() -> Image.Image:
image = Image.new("RGB", (3, 2))
image.putdata(SOURCE_PIXELS)
exif = Image.Exif()
exif[ORIENTATION] = 6
image.info["exif"] = exif.tobytes()
return image
class ExifTransposeContract(unittest.TestCase):
def test_contract_runs_against_exact_pillow_release(self) -> None:
self.assertEqual(PIL.__version__, "12.3.0")
self.assertTrue(Image.core.__file__.endswith((".so", ".pyd")))
def test_default_returns_normalized_copy_and_preserves_source(self) -> None:
source = oriented_image()
normalized = ImageOps.exif_transpose(source)
self.assertIsNot(normalized, source)
self.assertEqual(normalized.size, (2, 3))
self.assertEqual(list(normalized.getdata()), ROTATED_PIXELS)
self.assertNotIn(ORIENTATION, normalized.getexif())
self.assertEqual(source.size, (3, 2))
self.assertEqual(list(source.getdata()), SOURCE_PIXELS)
self.assertEqual(source.getexif()[ORIENTATION], 6)
def test_in_place_mutates_source_and_returns_none(self) -> None:
source = oriented_image()
result = ImageOps.exif_transpose(source, in_place=True)
self.assertIsNone(result)
self.assertEqual(source.size, (2, 3))
self.assertEqual(list(source.getdata()), ROTATED_PIXELS)
self.assertNotIn(ORIENTATION, source.getexif())
def test_in_place_is_keyword_only(self) -> None:
with self.assertRaises(TypeError):
ImageOps.exif_transpose(oriented_image(), True) # type: ignore[misc]
if __name__ == "__main__":
unittest.main()