GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Regression in Django with singledispatchmethod on models · Issue #127750 · python/cpython

Regression in Django with singledispatchmethod on models #127750

New issue
Copy link
New issue
Copy link
Closed
Closed
Regression in Django with singledispatchmethod on models#127750
Copy link
Labels
3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@vodik
vodik
opened on Dec 8, 2024
Issue body actions

Bug report

Bug description:

Also reported upstream to Django here.

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.

class Test(models.Model):
    ...

class Test2(models.Model):
    relationship = models.ForeignKey("Test", on_delete=models.CASCADE)

    @singledispatchmethod
    def bug(self, x):
        print(">", id(self))

    @bug.register
    def _(self, x: int):
        print(">", id(self))

and then it's pretty easy to trigger:

for t in test.test2_set.all():
    print("id:", id(t))  # always changes
    t.bug(4)             # only ever prints a single id

CPython versions tested on:

3.13

Operating systems tested on:

macOS

Linked PRs

  • gh-127750: Improve caching in singledispatchmethod #127751
  • gh-127750: Fix singledispatchmethod caching #127839
  • gh-127750: Fix singledispatchmethod caching (v2) #128648
  • gh-127750: Fix and optimize functools.singledispatchmethod() #130008
  • [3.13] gh-127750: Fix functools.singledispatchmethod()  #130029
  • gh-127750: Improve repr of functools.singledispatchmethod #130220
  • gh-127750: Restore inspect and pydoc support of singledispatchmethod #130309
  • [3.13] gh-127750: Backport some tests for singledispatchmethod (GH-130309) #130340
  • [3.12] gh-127750: Backport some tests for singledispatchmethod (GH-130309) (GH-130340) #130341
  • gh-127750: Fix annotations in singledispatchmethod signature tests #143571
  • [3.14] gh-127750: Fix annotations in singledispatchmethod signature tests (GH-143571) #143707
  • [3.13] gh-127750: Fix annotations in singledispatchmethod signature tests (GH-143571) #143708

Activity

Next
  1. vodik
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Dec 8, 2024
  2. picnixz
    added
    extension-modulesC modules in the Modules dirC modules in the Modules dir
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    3.12only security fixesonly security fixes
    3.13only security fixesonly security fixes
    3.14bugs and security fixesbugs and security fixes
    and removed
    extension-modulesC modules in the Modules dirC modules in the Modules dir
    3.12only security fixesonly security fixes
    on Dec 8, 2024
  3. vodik commented on Dec 9, 2024

    @vodik
    vodik
    on Dec 9, 2024
    Author
    More actions

    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:

    from functools import singledispatchmethod
    from dataclasses import dataclass
    
    @dataclass(frozen=True)  # or (unsafe_hash=True)
    class Test:
        pk: int
    
        @singledispatchmethod
        def broken(self, x):
            raise NotImplemenetedError
    
        @broken.register
        def _(self, x: int):
            return id(self)
    
    
    t1 = Test(1)
    print(id(t1))
    
    t2 = Test(1)
    print(id(t2))
    
    assert id(t1) == t1.broken(2)  # both t1 and t2 will share the same dispatcher
    assert id(t2) == t2.broken(2)  # fails! 
  4. vodik commented on Dec 9, 2024

    @vodik
    vodik
    on Dec 9, 2024
    Author
    More actions

    I have a fix, I think. Working on a PR.

    Reacted by Peter Bierma
  5. vodik
    added 3 commits that reference this issue on Dec 9, 2024

    pythongh-127750: Improve singledispatchmethod caching

    2e08bd9

    pythongh-127750: Improve singledispatchmethod caching

    a81b83e

    pythongh-127750: Improve singledispatchmethod caching

    fe804ef
  6. vodik commented on Dec 9, 2024

    @vodik
    vodik
    on Dec 9, 2024
    Author
    More actions

    I'm pretty sure the code in question is also leaking memory. See comment here.

  7. eendebakpt commented on Dec 9, 2024

    @eendebakpt
    eendebakpt
    on Dec 9, 2024
    Contributor
    More actions

    @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:

    from functools import lru_cache
    from dataclasses import dataclass
    
    @dataclass(frozen=True)  # or (unsafe_hash=True)
    class Test:
        pk: int
    
    t1 = Test(1)
    t2 = Test(1)  
    
    @lru_cache
    def return_id(obj):
        return id(obj)
    
    print(return_id(t1))
    print(return_id(t2))
  8. 9 remaining items

  9. serhiy-storchaka
    added 3 commits that reference this issue on Feb 20, 2025

    [3.13] pythongh-127750: Restore inspect and pydoc support of singledi…

    e79ded4

    [3.13] pythongh-127750: Backport some tests for singledispatchmethod (p…

    c6c2d33

    [3.13] gh-127750: Backport some tests for singledispatchmethod (GH-13…

    68c57d6
  10. miss-islington
    added a commit that references this issue on Feb 20, 2025

    [3.13] pythongh-127750: Backport some tests for singledispatchmethod (p…

    c160ee6
  11. serhiy-storchaka
    added a commit that references this issue on Feb 20, 2025

    [3.12] gh-127750: Backport some tests for singledispatchmethod (GH-13…

    e63ca56
  12. serhiy-storchaka
    added a commit that references this issue on Mar 5, 2025

    gh-127750: Improve repr of functools.singledispatchmethod (GH-130220)

    f33d21e
  13. serhiy-storchaka
    closed this as completedon Mar 5, 2025
  14. serhiy-storchaka
    added a commit that references this issue on Jan 11, 2026

    gh-127750: Fix annotations in singledispatchmethod signature tests (G…

    620a5b9
  15. miss-islington
    added 2 commits that reference this issue on Jan 11, 2026

    pythongh-127750: Fix annotations in singledispatchmethod signature te…

    9c7f1fc

    pythongh-127750: Fix annotations in singledispatchmethod signature te…

    c9eccc7
  16. serhiy-storchaka
    added 2 commits that reference this issue on Jan 11, 2026

    [3.13] gh-127750: Fix annotations in singledispatchmethod signature t…

    ea1ecf6

    [3.14] gh-127750: Fix annotations in singledispatchmethod signature t…

    ea26c88
  17. reidenong
    added a commit that references this issue on Jan 12, 2026

    pythongh-127750: Fix annotations in singledispatchmethod signature te…

    13c9f56
  18. thunder-coding
    added a commit that references this issue on Feb 15, 2026

    pythongh-127750: Fix annotations in singledispatchmethod signature te…

    5b0a063
  19. rjpower
    added a commit that references this issue on Oct 26, 2026

    boil: test_functools drops the singledispatchmethod reference-loop test

    9eea555
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.13only security fixesonly security fixes3.14bugs and security fixesbugs and security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.