You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Regression in Django with singledispatchmethod on models #127750
The following code works on Python 3.12 and I believe #85160 is the cause.
When traversing a relationship and then calling a singledispatchmethod method registered on a model, the reference to self seems to get cached and locked to the first created model.
Since dictionaries use __hash__/__eq__ for determining if a key is present, we can have collisions. Django hashs models based on the primary key. Here's a way to reproduce the same bug with just the stdlib:
fromfunctoolsimportsingledispatchmethodfromdataclassesimportdataclass@dataclass(frozen=True) # or (unsafe_hash=True)classTest:
pk: int@singledispatchmethoddefbroken(self, x):
raiseNotImplemenetedError@broken.registerdef_(self, x: int):
returnid(self)
t1=Test(1)
print(id(t1))
t2=Test(1)
print(id(t2))
assertid(t1) ==t1.broken(2) # both t1 and t2 will share the same dispatcherassertid(t2) ==t2.broken(2) # fails!
Activity
vodik commentedon Dec 9, 2024
I see what the issue is now: https://github.com/AlexWaygood/cpython/blob/3d8d4ba5f5367f2d87488b00afd55f75401c2b7d/Lib/functools.py#L950
Since dictionaries use
__hash__/__eq__for determining if a key is present, we can have collisions. Django hashs models based on the primary key. Here's a way to reproduce the same bug with just the stdlib:vodik commentedon Dec 9, 2024
I have a fix, I think. Working on a PR.
pythongh-127750: Improve singledispatchmethod caching
pythongh-127750: Improve singledispatchmethod caching
pythongh-127750: Improve singledispatchmethod caching
vodik commentedon Dec 9, 2024
I'm pretty sure the code in question is also leaking memory. See comment here.
eendebakpt commentedon Dec 9, 2024
@vodik There is indeed a behavior change between 3.12 and 3.13, so perhaps that needs to be fixed. Another example showing the issue is:
8 remaining items
gh-127750: Restore inspect and pydoc support of singledispatchmethod (G…
[3.13] pythongh-127750: Restore inspect and pydoc support of singledi…
[3.13] pythongh-127750: Backport some tests for singledispatchmethod (p…
[3.13] gh-127750: Backport some tests for singledispatchmethod (GH-13…
[3.13] pythongh-127750: Backport some tests for singledispatchmethod (p…
[3.12] gh-127750: Backport some tests for singledispatchmethod (GH-13…
gh-127750: Improve repr of functools.singledispatchmethod (GH-130220)
gh-127750: Fix annotations in singledispatchmethod signature tests (G…
pythongh-127750: Fix annotations in singledispatchmethod signature te…
pythongh-127750: Fix annotations in singledispatchmethod signature te…
[3.13] gh-127750: Fix annotations in singledispatchmethod signature t…
[3.14] gh-127750: Fix annotations in singledispatchmethod signature t…
pythongh-127750: Fix annotations in singledispatchmethod signature te…
pythongh-127750: Fix annotations in singledispatchmethod signature te…