Skip to content

Make S3Object a dict subclass and return copies of cached entries #1382

Open

Description

@laughingman7743

Part of #1341 (decisions 1 and 2 of the audit). Defect 22 of #1327.

Current state (29cc1d3)

  1. S3Object is a MutableMapping over __dict__: after entry["keys"] = 1, dict(entry) raises TypeError: 'int' object is not callable; after entry["get"] = 1, entry.get("size") raises the same.
  2. isinstance(entry, dict) is False, repr() is the default <S3Object object at ...>, and update({"ContentType": ...}) stores the API name while __init__ maps it.
  3. S3Object.from_summary takes 2.36 µs per listed key and copy() 1.20 µs; a dict subclass prototype takes 0.23 µs.
  4. info() and ls(detail=True) return the cached entries by reference: after fs.info("bucket/a")["size"] = 999, the next info() returns 999.

Decision

  1. S3Object becomes a dict subclass, built directly from the page models, with attribute access for known fields (None for an absent known field, AttributeError otherwise) and attribute set/delete mapped to the entries. copy() returns an S3Object; to_dict(), to_api_repr() and the S3Object(init, **kwargs) constructor keep their behavior. Entries keep their current key sets.
  2. Every boundary that returns entries (info, the detail=True results of ls, find, glob and walk, file details, and the aio counterparts, including aio _find) returns copies, with the nested metadata mapping copied too. The cost of the type-preserving copy is measured.

Compatibility

isinstance(entry, dict) becomes True and the pickled form changes (release note). A file entry is still not JSON-serializable as is, since last_modified is a datetime.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions