python / python/cpython

Comment for bounded_lru_cache_wrapper seems incorrect

Aberta
#94,879 8 comentários 0 reações 3 responsáveis Ver no GitHub

@tim-one já está trabalhando nisso.

Desde 17/7/2022.

extension-modules type-bug
Linguagem predominante
Python
Estrelas
77.2k
Forks
36k
Métricas de merge de PRs
Métricas de PR pendentes

Descrição

https://github.com/python/cpython/blob/c22f134211743cd5ad14cec1dd4f527bee542b4c/Modules/_functoolsmodule.c#L975-L976
However the __eq__ method call actually could be made for the deletion of the oldest entry.

from functools import lru_cache

class A:
    def __init__(self, name):
        self.name = name
        self.counter = []

    def __hash__(self):
        return 0 # mock hash collision
    
    def __eq__(self, __o: 'A'):
        self.counter.append(__o.name)
        return self is __o

@lru_cache(maxsize=2)
def foo(_):
    return 0

a, b, c = A('a'), A('b'), A('c')

foo(a)
foo(b)

# make 'b' be the oldest-used entry
# but not the oldest-inserted entry
foo(a)
a.counter.clear()

foo(c) # will evict 'b'

# The assertion shows that
# 'a' was compared with 'b' for the deletion of 'b'
assert 'b' in a.counter
print(a.counter) # ['c', 'c', 'b', 'c']

It seems that reentrant here might cause the assertion in L1092 failed:
https://github.com/python/cpython/blob/c22f134211743cd5ad14cec1dd4f527bee542b4c/Modules/_functoolsmodule.c#L1092-L1099
Since link has been extracted but hasn't been popped from cache dict, link list could be empty while cache dict is full.

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.