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¶
-
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.
-
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¶
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",
+]