Skip to content

Avoid numeric hash-cache collisions with user tuples - #639

Open
FanWu-ai wants to merge 1 commit into
qlustered:devfrom
FanWu-ai:fix/numeric-hash-cache-collision
Open

FanWu-ai wants to merge 1 commit into
qlustered:devfrom
FanWu-ai:fix/numeric-hash-cache-collision

Conversation

@FanWu-ai

@FanWu-ai FanWu-ai commented Oct 4, 2026

Copy link
Copy Markdown

Problem

The typed numeric cache key for 1 is currently the ordinary tuple (int, 1). A user-provided tuple with that value therefore aliases the cached number:

DeepDiff([1], [(int, 1)], ignore_order=True)
# Before: {}
# After: {'type_changes': {'root[0]': {
#     'old_type': int, 'new_type': tuple,
#     'old_value': 1, 'new_value': (int, 1)}}}

The reverse comparison is also missed. DeepHash lookups and public key iteration can conflate the same distinct objects.

Fix

  • Prefix numeric cache keys with a private class marker, keeping the numeric type/value distinction while separating ordinary user tuples.
  • Unwrap only marked keys in the public accessors.
  • Use a class marker so cache keys retain their identity through pickle and deepcopy.

The change is limited to deephash.py, one safe-import entry for its inert marker in serialization.py, and regression tests. It does not change the serialized hash content of ordinary numeric inputs or numeric-equivalence behavior with ignore_numeric_type_changes=True. Ordinary tuple keys now remain intact in public key iteration with either flag value.

Validation

  • All 20 new regression cases fail on unchanged dev and pass after the fix.
  • Covers int, float, complex, Decimal and NumPy numbers; both insertion/comparison directions; public accessors; shared cache reuse; standard and restricted pickle/deepcopy.
  • Linux CPython 3.12.14: pytest --cov=deepdiff --cov-report=term-missing --runslow --benchmark-disable: 1,329 passed, 8 skipped, 95% overall coverage (98% for deephash.py).
  • Pyright for both changed production files: no errors or warnings.
  • CI-blocking Flake8 rules and git diff --check: passed. Full touched-file lint introduces no new diagnostics.

Compatibility note

Numeric entries in raw .hashes dictionaries use a new key shape. Such dictionaries retained from older versions should be rebuilt. Public object-based lookup remains unchanged.

@FanWu-ai
FanWu-ai marked this pull request as ready for review October 4, 2026 08:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant