#37310: MediaAsset instances with attributes violate equality/hash contract with
strings
-------------------------------------+-------------------------------------
Reporter: | Owner: miladkhoshdel
miladkhoshdel |
Type: Bug | Status: assigned
Component: Forms | Version: 6.1
Severity: Normal | Keywords: MediaAsset hash
Triage Stage: | equality
Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
After the fix for #37088, `MediaAsset.__eq__()` still considers an asset
equal to a string containing the same path, while `MediaAsset.__hash__()`
includes the asset's attributes.
This violates Python's requirement that equal objects have equal hashes.
Reproduction on Django 6.2.dev20260831204047:
{{{#!python
from django.forms import Script
asset = Script("/static/app.js", defer=True)
path = "/static/app.js"
print(asset == path)
print(hash(asset) == hash(path))
print(path in {asset})
}}}
Output:
{{{
True
False
False
}}}
Although `asset == path`, a set cannot find `path` because the two objects
are placed in different hash buckets. Dictionary lookups can be affected
in the same way. `Stylesheet` instances with attributes have the same
issue.
Expected behavior: Whenever `asset == path`, `hash(asset) == hash(path)`.
This appears to be a regression introduced by
bc9bed573ce39c3b739a4a3b7848816d464b6bdc for #37088 in Django 6.1.
A possible fix is to hash only `self._path`. Assets with the same path but
different attributes may then share a hash while remaining unequal, which
is valid Python behavior.
--
Ticket URL: <
https://code.djangoproject.com/ticket/37310>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.