From c5cdaa7976748b015955e5c9b85fdc3a86feb51d Mon Sep 17 00:00:00 2001 From: "Jorj X. McKie" Date: Sat, 11 Jul 2026 03:57:34 -0400 Subject: [PATCH] Prevent Death of None Prevent dropping refcount of Py_None to 0. --- src/extra.i | 9 ++++++++- tests/test_pynone.py | 13 +++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/test_pynone.py diff --git a/src/extra.i b/src/extra.i index 6ce80c481..e2f815107 100644 --- a/src/extra.i +++ b/src/extra.i @@ -1915,7 +1915,10 @@ static void jm_trace_text_span( if (stroke) dict_setitemstr_drop(span_dict, "linewidth", PyFloat_FromDouble((double) stroke->linewidth)); else + { + Py_INCREF(Py_None); dict_setitemstr_drop(span_dict, "linewidth", Py_None); + } dict_setitemstr_drop(span_dict, "spacewidth", PyFloat_FromDouble(space_adv)); dict_setitem_drop(span_dict, dictkey_type, PyLong_FromLong((long) type)); dict_setitem_drop(span_dict, dictkey_bbox, JM_py_from_rect(span_bbox)); @@ -2136,8 +2139,12 @@ mupdf::FzDevice JM_new_texttrace_device(PyObject* out) dev->super.render_flags = nullptr; dev->super.set_default_colorspaces = nullptr; - Py_XINCREF(out); + if (PyList_Check(out)) { + Py_INCREF(out); + } + Py_INCREF(Py_None); dev->out = out; + dev->method = Py_None; dev->seqno = 0; return device; } diff --git a/tests/test_pynone.py b/tests/test_pynone.py new file mode 100644 index 000000000..629d9ae3b --- /dev/null +++ b/tests/test_pynone.py @@ -0,0 +1,13 @@ +import sys, pymupdf + +def test_none_refcount(): + doc = pymupdf.open() + page = doc.new_page() + for i in range(10): + page.insert_text((72, 72 + i * 20), f"Hello world span {i}") + + before = sys.getrefcount(None) + for _ in range(200): + page.get_texttrace() + after = sys.getrefcount(None) + assert before == after, f"refcount of None changed: {before} -> {after}" \ No newline at end of file