Skip to content

Translate delete-marker versions to FileNotFoundError and fix two S3Core edge cases #1338

Closed

Description

@laughingman7743

Part of #1327 (defects 19 to 21 of the audit report).

Summary

Three S3Core and error-translation defects, reproduced offline with botocore's Stubber at 766d79d.

Defects

  1. A delete-marker version raises PermissionError, and exists() raises on it. HeadObject or GetObject of a version that is a delete marker answers 405 (MethodNotAllowed, with x-amz-delete-marker: true). Neither code is in the translation tables, so 405 maps to EPERM (s3_errors.py:90-99, :122-128) and becomes PermissionError; exists() catches only FileNotFoundError (s3.py:1000-1006). The S3Core docstring and docs/filesystem.md say that a missing object or version raises FileNotFoundError. fs.exists("s3://b/k?versionId=<delete marker>") should return False. test_s3_errors.py pins the generic 405 to EPERM, so the fix has to recognize the delete-marker header.
  2. S3Core.part_ranges(0, block_size) raises ValueError: zip() argument 2 is longer than argument 1 (s3_core.py:1120-1126) instead of returning []; the method is public and documented. Current callers guard against size 0.
  3. S3Core.call() with request_kwargs fails for a callable without __name__: S3Core(client, request_kwargs={"RequestPayer": "requester"}).call(functools.partial(client.head_object, Bucket="b"), Key="k") raises AttributeError (s3_core.py:642-644); the docstring accepts the client method itself without that restriction.

Fix direction

Translate a 405 with the delete-marker header to FileNotFoundError; return [] from part_ranges(0, ...); resolve the operation name of a callable through the client's method mapping or require a method name, and document the choice.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions