Skip to content

to_dict and from_dict silently drop the reco count fields #3374

Description

@adamtheturtle

What happens

CloudDatabase.to_dict in src/mock_vws/database.py omits four fields which CloudDatabase carries:

  • total_recos
  • current_month_recos
  • previous_month_recos
  • reco_threshold

from_dict therefore restores them to their class defaults rather than to the values the original object had. ImageTarget.to_dict in src/mock_vws/target.py drops the same three reco fields plus reco_rating.

So from_dict(to_dict(database)) != database whenever any of those fields is non-default.

Why it matters

Nothing breaks today, because every one of those fields is 0 or "" for every database the mock creates, so the lossy round trip is invisible.

It stops being invisible with #3356, which is about making recognition counts seedable so that reco reports can be non-empty. The Docker backend round-trips every database through to_dict and from_dict on every request, in get_all_cloud_databases at src/mock_vws/_flask_server/vws.py:110. A seeded reco count would survive in the in-process backend and be silently reset to zero in Docker, which is exactly the kind of backend-specific difference that is expensive to debug.

reco_threshold has the same problem and is already configurable on the dataclass, so it is reachable today by anyone constructing a CloudDatabase directly.

Suggested resolution

Add the missing fields to CloudDatabaseDict, ImageTargetDict and the two to_dict / from_dict pairs.

More usefully, add a round-trip test asserting from_dict(to_dict(x)) == x for both classes with every field set to a non-default value. That pins the property rather than the current field list, so the next field added to either dataclass cannot quietly fall out of the serialisation. Doing this before #3356 means that work does not have to discover the problem first.

Note that ImageTarget round trips are lossy in one further respect by design: to_dict writes the computed tracking_rating and from_dict rebuilds the target with a HardcodedTargetTrackingRater, so the rater identity is not preserved. That is deliberate and should stay, but the test will need to account for it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions