diff --git a/Doc/library/difflib.rst b/Doc/library/difflib.rst index 3ed4768b6a1413..2176f1b49d0f20 100644 --- a/Doc/library/difflib.rst +++ b/Doc/library/difflib.rst @@ -40,13 +40,18 @@ diffs. For comparing directories and files, see also, the :mod:`filecmp` module. complicated way on how many elements the sequences have in common; best case time is linear. - **Automatic junk heuristic:** :class:`SequenceMatcher` supports a heuristic that - automatically treats certain sequence items as junk. The heuristic counts how many - times each individual item appears in the sequence. If an item's duplicates (after - the first one) account for more than 1% of the sequence and the sequence is at least - 200 items long, this item is marked as "popular" and is treated as junk for - the purpose of sequence matching. This heuristic can be turned off by setting - the ``autojunk`` argument to ``False`` when creating the :class:`SequenceMatcher`. + **Junk**: :class:`SequenceMatcher` accepts an ``isjunk`` predicate and an + ``autojunk`` flag. Items that are considered as junk will not be considered + to find similar content blocks. This can produce better results for humans + (typically breaking on whitespace) and faster (because it reduces the number + of possible combinations). But it can also cause pathological cases where + too many items considered junk cause an unexpectedly large (but correct) + diff result. + You should consider tuning them or turning them off depending on your data. + Moreover, only the second sequence is inspected for junk. This causes the diff + output to not be symmetrical. + When ``autojunk=True``, it will consider as junk the items that account for more + than 1% of the sequence, if it is at least 200 items long. .. versionchanged:: 3.2 Added the *autojunk* parameter. @@ -558,16 +563,6 @@ The :class:`SequenceMatcher` class has this constructor: to try :meth:`quick_ratio` or :meth:`real_quick_ratio` first to get an upper bound. - .. note:: - - Caution: The result of a :meth:`ratio` call may depend on the order of - the arguments. For instance:: - - >>> SequenceMatcher(None, 'tide', 'diet').ratio() - 0.25 - >>> SequenceMatcher(None, 'diet', 'tide').ratio() - 0.5 - .. method:: quick_ratio() diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst new file mode 100644 index 00000000000000..d2d2c771a68432 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-07-24-13-15-31.gh-issue-153809.JFA6GT.rst @@ -0,0 +1,2 @@ +Fix interpreter crash while deallocating objects of :class:`asyncio.Task` on +free-threaded builds. Contributed by Sergey Miryanov. diff --git a/Misc/NEWS.d/next/Documentation/2026-07-17-22-33-43.gh-issue-118150.m7iFdP.rst b/Misc/NEWS.d/next/Documentation/2026-07-17-22-33-43.gh-issue-118150.m7iFdP.rst new file mode 100644 index 00000000000000..afa6007a46e174 --- /dev/null +++ b/Misc/NEWS.d/next/Documentation/2026-07-17-22-33-43.gh-issue-118150.m7iFdP.rst @@ -0,0 +1,2 @@ +Clarify in the :mod:`difflib` documentation what *junk* actually does, its +drawbacks, and how to control it. diff --git a/Modules/_asynciomodule.c b/Modules/_asynciomodule.c index bc0f7f3901e0ed..9c29eb8232ed3f 100644 --- a/Modules/_asynciomodule.c +++ b/Modules/_asynciomodule.c @@ -2966,13 +2966,17 @@ TaskObj_dealloc(PyObject *self) if (PyObject_CallFinalizerFromDealloc(self) < 0) { return; // resurrected } + // Untrack the object before unregistering the task, since the + // latter can cause a stop-the-world pause, after which another + // thread might call the GC and reach the object while it is + // semi-deallocated but still tracked + PyObject_GC_UnTrack(self); + // unregister the task after finalization so that // if the task gets resurrected, it remains registered unregister_task((TaskObj *)self); PyTypeObject *tp = Py_TYPE(self); - PyObject_GC_UnTrack(self); - PyObject_ClearWeakRefs(self); (void)TaskObj_clear(self);