You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Complete the remaining S3 API extraction in #1053.
Steps 1–4 are merged: paths (#1052), typed listing/HEAD operations (#1060), delete/multipart/copy/pairing (#1064, #1069, #1072, #1074, #1081), and the multipart writer (#1085).
The native sub-issues #1049, #1059, #1063 and #1077 are closed.
On master 855d4a7b652d6dad106c27ee7112264ca45b923e, several operations still build S3 requests and apply S3 rules inside S3FileSystem.
They use S3Core.call() for transport, retries and error translation, but a direct core caller has no typed operation taking S3Path for these requests.
Moving only GET/PUT, tags and ACLs would leave other request construction in the adapter and would not finish the separation proposed in #1053.
The remaining inventory in pyathena/filesystem/s3.py is:
Area
Current owner on the recorded master
Object GET/PUT
_get_object() (2843), _put_object() (2892): request construction, ranges, body handling and PUT result conversion
Tags and ACLs
get_tags() (2313), put_tags() (2336), chmod() (2377): request construction, version selection, tag merge and ACL validation
Metadata updates
setxattr() (2227): metadata changes, retained system/storage/encryption fields, and the self-copy request; reads already use core.head_object()
Multipart upload listing
list_multipart_uploads() (2429): requests, pagination and conversion to upload objects
Presigned URLs
sign() (2147): S3 request parameters and SDK signing
Bucket lifecycle
mkdir() (1240), rmdir() (1336): create/delete requests and region/ACL rules
Multipart size planning
_check_multipart_upload_size() (1744): S3 part-count validation also reached by the aio transaction helpers
Proposed change
Add the remaining public, synchronous operations and pure S3 planning rules to S3Core, S3MultipartWriter, or an appropriate fsspec-independent type.
Object operations accept S3Path; bucket operations use a clearly documented bucket-only argument.
Results expose documented types, including the existing S3PutObject, S3Metadata and S3MultipartUpload where appropriate.
Settle the GET result and ownership contract before implementation: whether a result exposes a response body or bytes determines who reads and closes it, and how read failures are handled.
Move request construction, operation-specific parameter rules, version handling, response conversion, and S3 validation out of the adapters for the inventory above.
Extract page-level multipart upload listing separately from iteration, following the existing core listing API.
The core uses S3 prefix semantics; the adapter retains its documented key-or-descendant filter, which excludes sibling keys sharing a prefix.
Make metadata replacement and tag merging use core operations or pure planners while preserving their existing requests and results.
Centralize the multipart size rule for sync and aio callers without changing the existing error conditions.
The adapters keep path parsing and fsspec behavior: directory synthesis/expansion, recursive traversal, chmod(recursive=True), callbacks, cache invalidation, buffering, transactions, executor scheduling and async bridging.
Bucket lifecycle opt-ins (allow_bucket_creation and allow_bucket_deletion) remain enforced by the filesystem before it invokes a core primitive.
The public core bucket methods document that a direct call creates or deletes a bucket; an adapter option is not a core permission mechanism.
Preserve the existing public filesystem signatures, return shapes, errors, request order/count, per-call parameter precedence, checksum behavior and cleanup.
Preserve open-ended and suffix reads, empty-range handling, empty PUT bodies, tag overwrite/merge modes, version-qualified paths, metadata retention/override rules, ACL validation before recursive mutation, bucket region handling and multipart listing markers.
The core stays synchronous and imports no fsspec or aiobotocore; scheduling stays with the adapters as decided on #1053.
New public names and result contracts should be agreed in this issue before implementation.
The implementation can use several independently reviewable PRs, each keeping the adapters functional.
Completion criteria
Cover every inventory item with a public core operation or pure S3 planner, document its arguments/results/errors, and make the sync/aio adapters delegate to it.
Audit the remaining SDK calls and S3 request builders in both adapters and S3File. Record each remaining site's reason; SDK client compatibility, raw-call compatibility shims, fsspec translation and orchestration remain adapter responsibilities.
Keep the existing DirCache storage, options, invalidation and sync/aio sharing. Record the disposition of step 5: centralize cache keys from S3Path only if this extraction needs it; otherwise explicitly record that the conditional step was not needed, as decided in Separate an S3 core from the fsspec adapter in pyathena.filesystem #1053.
Preserve the public adapter API and the internal users in pyathena/s3fs/, pyathena/pandas/, pyathena/aio/s3fs/ and Polars/fsspec registration.
Complete core regression tests, affected adapter/runtime validation, public API documentation, both self-review rounds, independent review and applicable current CI for each implementation PR.
The separate mv() behavior defect #1083 keeps its own issue and implementation.
This extraction preserves existing behavior; new S3 features and behavior changes require separate agreement, as specified by #1053.
Validation plan (if implementing)
Use botocore Stubber and self-contained tests for the new operations, typed results and planners.
Cover inherited/per-call parameter precedence, version IDs including null, request bodies/ranges, body ownership and read failures, metadata/encryption retention, tag modes, ACL validation, bucket regions, multipart pagination and size limits, plus translated failures.
Pin expected requests independently of the moved implementation.
Run just format and just lint, then the affected tests in tests/pyathena/filesystem/test_s3_core.py, test_s3_writer.py, test_s3.py and test_s3_async.py.
Check the existing filesystem request sequences, cache invalidation, transactions, conditional creation, multipart checksums and interruption/cancellation cleanup.
Exercise internal consumers that use these read/write operations and fsspec registration.
Run documentation lint/build for API changes and the applicable full PyAthena AWS CI before declaring an implementation PR ready.
Use the repository's existing AWS test environment and fixtures for live S3 validation.
Serialize live runs with other Test workflows/local tests; do not provision new persistent infrastructure for this extraction.
Bucket creation/deletion coverage must use the explicit opt-ins and disposable test resources.
Record exact tested commits, commands, results and skipped coverage, separating static, offline and live AWS evidence.
This proposal is based on source and GitHub-state inspection; no new tests or AWS operations were run to prepare it.
Use case
Complete the remaining S3 API extraction in #1053.
Steps 1–4 are merged: paths (#1052), typed listing/HEAD operations (#1060), delete/multipart/copy/pairing (#1064, #1069, #1072, #1074, #1081), and the multipart writer (#1085).
The native sub-issues #1049, #1059, #1063 and #1077 are closed.
On master
855d4a7b652d6dad106c27ee7112264ca45b923e, several operations still build S3 requests and apply S3 rules insideS3FileSystem.They use
S3Core.call()for transport, retries and error translation, but a direct core caller has no typed operation takingS3Pathfor these requests.Moving only GET/PUT, tags and ACLs would leave other request construction in the adapter and would not finish the separation proposed in #1053.
The remaining inventory in
pyathena/filesystem/s3.pyis:_get_object()(2843),_put_object()(2892): request construction, ranges, body handling and PUT result conversionget_tags()(2313),put_tags()(2336),chmod()(2377): request construction, version selection, tag merge and ACL validationsetxattr()(2227): metadata changes, retained system/storage/encryption fields, and the self-copy request; reads already usecore.head_object()list_multipart_uploads()(2429): requests, pagination and conversion to upload objectssign()(2147): S3 request parameters and SDK signingmkdir()(1240),rmdir()(1336): create/delete requests and region/ACL rules_check_multipart_upload_size()(1744): S3 part-count validation also reached by the aio transaction helpersProposed change
Add the remaining public, synchronous operations and pure S3 planning rules to
S3Core,S3MultipartWriter, or an appropriate fsspec-independent type.Object operations accept
S3Path; bucket operations use a clearly documented bucket-only argument.Results expose documented types, including the existing
S3PutObject,S3MetadataandS3MultipartUploadwhere appropriate.Settle the GET result and ownership contract before implementation: whether a result exposes a response body or bytes determines who reads and closes it, and how read failures are handled.
Move request construction, operation-specific parameter rules, version handling, response conversion, and S3 validation out of the adapters for the inventory above.
Extract page-level multipart upload listing separately from iteration, following the existing core listing API.
The core uses S3 prefix semantics; the adapter retains its documented key-or-descendant filter, which excludes sibling keys sharing a prefix.
Make metadata replacement and tag merging use core operations or pure planners while preserving their existing requests and results.
Centralize the multipart size rule for sync and aio callers without changing the existing error conditions.
The adapters keep path parsing and fsspec behavior: directory synthesis/expansion, recursive traversal,
chmod(recursive=True), callbacks, cache invalidation, buffering, transactions, executor scheduling and async bridging.Bucket lifecycle opt-ins (
allow_bucket_creationandallow_bucket_deletion) remain enforced by the filesystem before it invokes a core primitive.The public core bucket methods document that a direct call creates or deletes a bucket; an adapter option is not a core permission mechanism.
Preserve the existing public filesystem signatures, return shapes, errors, request order/count, per-call parameter precedence, checksum behavior and cleanup.
Preserve open-ended and suffix reads, empty-range handling, empty PUT bodies, tag overwrite/merge modes, version-qualified paths, metadata retention/override rules, ACL validation before recursive mutation, bucket region handling and multipart listing markers.
The core stays synchronous and imports no fsspec or aiobotocore; scheduling stays with the adapters as decided on #1053.
New public names and result contracts should be agreed in this issue before implementation.
The implementation can use several independently reviewable PRs, each keeping the adapters functional.
Completion criteria
S3File. Record each remaining site's reason; SDK client compatibility, raw-call compatibility shims, fsspec translation and orchestration remain adapter responsibilities.DirCachestorage, options, invalidation and sync/aio sharing. Record the disposition of step 5: centralize cache keys fromS3Pathonly if this extraction needs it; otherwise explicitly record that the conditional step was not needed, as decided in Separate an S3 core from the fsspec adapter in pyathena.filesystem #1053.pyathena/s3fs/,pyathena/pandas/,pyathena/aio/s3fs/and Polars/fsspec registration.The separate
mv()behavior defect #1083 keeps its own issue and implementation.This extraction preserves existing behavior; new S3 features and behavior changes require separate agreement, as specified by #1053.
Validation plan (if implementing)
Use botocore
Stubberand self-contained tests for the new operations, typed results and planners.Cover inherited/per-call parameter precedence, version IDs including
null, request bodies/ranges, body ownership and read failures, metadata/encryption retention, tag modes, ACL validation, bucket regions, multipart pagination and size limits, plus translated failures.Pin expected requests independently of the moved implementation.
Run
just formatandjust lint, then the affected tests intests/pyathena/filesystem/test_s3_core.py,test_s3_writer.py,test_s3.pyandtest_s3_async.py.Check the existing filesystem request sequences, cache invalidation, transactions, conditional creation, multipart checksums and interruption/cancellation cleanup.
Exercise internal consumers that use these read/write operations and fsspec registration.
Run documentation lint/build for API changes and the applicable full PyAthena AWS CI before declaring an implementation PR ready.
Use the repository's existing AWS test environment and fixtures for live S3 validation.
Serialize live runs with other Test workflows/local tests; do not provision new persistent infrastructure for this extraction.
Bucket creation/deletion coverage must use the explicit opt-ins and disposable test resources.
Record exact tested commits, commands, results and skipped coverage, separating static, offline and live AWS evidence.
This proposal is based on source and GitHub-state inspection; no new tests or AWS operations were run to prepare it.