Skip to content

Stage 15 · Public API and parity closeout

Goal

Expose the complete teaching API and prove the reconstructed source and tests equal main byte for byte.

Hands-on task

Starting from stage-14, Finalize minis3.__init__ exports and run the complete 49-test contract. Keep all behavior inside the listed source-like boundaries; do not copy the patch first.

Deliverable files / 交付文件

  • src/minis3/__init__.py

Self-check

  1. Where is this stage's visibility or state transition owned?

    Answer

    A rebuild journey stays trustworthy only when CI guards both behavior and final-source parity.

  2. Which test would fail first if the new boundary were bypassed?

    Answer

    Read tests.txt, identify the narrowest new node, and name the public call it exercises.

Pass command

uv run pytest -q $(cat journey/stages/15-public-api-parity/tests.txt)

The real S3 lesson

A rebuild journey stays trustworthy only when CI guards both behavior and final-source parity.

Textbook

Chapter 9

Compare this stage on GitHub

After finishing, use git checkout stage-15 to compare your result.

Try first, then peek: stage.patch
diff --git a/src/minis3/__init__.py b/src/minis3/__init__.py
index 36bc1f3..86d6755 100644
--- a/src/minis3/__init__.py
+++ b/src/minis3/__init__.py
@@ -32,3 +32,38 @@ from .lifecycle import (
 from .multipart import MIN_PART_SIZE, MultipartPart, MultipartUpload
 from .store import MiniS3
 from .storage import InjectedCrash
+
+__all__ = [
+    "BucketAlreadyExists",
+    "BucketNotEmpty",
+    "DeleteMarker",
+    "EntityTooSmall",
+    "ExpirationRule",
+    "InvalidPart",
+    "InvalidPartOrder",
+    "ListedObject",
+    "ListedVersion",
+    "ListObjectsResult",
+    "ListObjectVersionsResult",
+    "MiniS3",
+    "InvalidContinuationToken",
+    "InjectedCrash",
+    "LifecycleAction",
+    "LifecycleActionKind",
+    "MIN_PART_SIZE",
+    "MiniS3Error",
+    "NoSuchBucket",
+    "NoSuchKey",
+    "NoSuchUpload",
+    "NoSuchVersion",
+    "NotModified",
+    "ObjectRecord",
+    "MultipartPart",
+    "MultipartUpload",
+    "PreconditionFailed",
+    "SequenceCounter",
+    "Version",
+    "VersioningState",
+    "content_etag",
+    "evaluate_expiration",
+]