python / python/cpython

PyRefTracer_DESTROY is not called for objects deferred by the trashcan mechanism

Đang mở
#156,371 2 bình luận 0 reaction 1 người được giao Xem trên GitHub

@corona10 đang làm issue này rồi.

Từ ngày 25/8/2026.

3.14 3.15 3.16 type-bug
Ngôn ngữ chính
Python
Star
77.2k
Fork
35.9k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

Bug report

This works correctly until Python 3.13, but https://github.com/python/cpython/pull/132280 introduces a regression.
A simple PR will fix this issue, and I have already prepared a fix for this issue.

import os
import subprocess
import sys
import sysconfig
import tempfile

CSRC = r"""
#include <Python.h>

static Py_ssize_t list_destroys = 0;

static int
tracer(PyObject *obj, PyRefTracerEvent event, void *data)
{
    if (event == PyRefTracer_DESTROY && PyList_CheckExact(obj)) {
        list_destroys++;
    }
    return 0;
}

static PyObject *
start(PyObject *self, PyObject *args)
{
    list_destroys = 0;
    if (PyRefTracer_SetTracer(tracer, NULL) < 0) {
        return NULL;
    }
    Py_RETURN_NONE;
}

static PyObject *
stop(PyObject *self, PyObject *args)
{
    if (PyRefTracer_SetTracer(NULL, NULL) < 0) {
        return NULL;
    }
    return PyLong_FromSsize_t(list_destroys);
}

static PyMethodDef methods[] = {
    {"start", start, METH_NOARGS, NULL},
    {"stop", stop, METH_NOARGS, NULL},
    {NULL, NULL, 0, NULL},
};

static PyModuleDef_Slot slots[] = {
#ifdef Py_GIL_DISABLED
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
#endif
    {0, NULL},
};

static struct PyModuleDef module = {
    PyModuleDef_HEAD_INIT,
    .m_name = "reftrace_repro",
    .m_size = 0,
    .m_methods = methods,
    .m_slots = slots,
};

PyMODINIT_FUNC
PyInit_reftrace_repro(void)
{
    return PyModuleDef_Init(&module);
}
"""


def build_module():
    tmpdir = tempfile.mkdtemp(prefix="reftrace_repro_")
    src = os.path.join(tmpdir, "reftrace_repro.c")
    with open(src, "w") as f:
        f.write(CSRC)
    ext = os.path.join(tmpdir, "reftrace_repro.so")
    cmd = ["cc", "-O2", "-shared", "-fPIC",
           "-I", sysconfig.get_path("include"),
           "-I", sysconfig.get_path("platinclude"),
           "-o", ext, src]
    if sys.platform == "darwin":
        cmd.insert(3, "-undefined")
        cmd.insert(4, "dynamic_lookup")
    subprocess.run(cmd, check=True)
    sys.path.insert(0, tmpdir)


def run(depth):
    import reftrace_repro

    chain = None
    for _ in range(depth):
        chain = [chain]
    reftrace_repro.start()
    del chain
    destroys = reftrace_repro.stop()
    missing = depth - destroys
    print(f"depth={depth:>7}  DESTROY events={destroys:>7}  "
          f"missing={missing:>5}  [{'BUG' if missing else 'OK'}]")


if __name__ == "__main__":
    print(sys.version)
    build_module()
    run(100)        
    run(200_000)

Status

$ python3.13 repro.py
3.13.11 (main, Dec 17 2025, 20:55:16) [Clang 21.1.4 ]
depth=    100  DESTROY events=    100  missing=    0  [OK]
depth= 200000  DESTROY events= 200000  missing=    0  [OK]

$ python3.14 repro.py
3.14.3 (main, Feb  3 2026, 15:32:20) [Clang 17.0.0 (clang-1700.6.3.2)]
depth=    100  DESTROY events=    100  missing=    0  [OK]
depth= 200000  DESTROY events= 199923  missing=   77  [BUG]

$ python3.15 repro.py
3.15.0a3 (main, Dec 17 2025, 21:18:28) [Clang 21.1.4 ]
depth=    100  DESTROY events=    100  missing=    0  [OK]
depth= 200000  DESTROY events= 199570  missing=  430  [BUG]

$ ./python.exe repro.py   # main (unpatched)
3.16.0a0 (heads/main:e4b22adf249, Aug 26 2026, 01:02:19) [Clang 21.0.0]
depth=    100  DESTROY events=    100  missing=    0  [OK]
depth= 200000  DESTROY events= 199923  missing=   77  [BUG]
Linked PRs
  • gh-156372
  • gh-156789
  • gh-156802

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.