From b0ffe74edfadb2e9e2e6e7f56b3ed7cffc03ecf9 Mon Sep 17 00:00:00 2001 From: Brij Date: Sat, 7 Feb 2026 11:14:38 -0500 Subject: [PATCH 01/15] Fix a heap buffer overflow in partial_repr --- Modules/_functoolsmodule.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 5773083ff68b46..11064553ae229d 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -693,6 +693,7 @@ partial_repr(PyObject *self) PyObject *name; Py_ssize_t i, n; PyObject *key, *value; + PyObject* args; int status; status = Py_ReprEnter(self); @@ -707,13 +708,15 @@ partial_repr(PyObject *self) goto done; /* Pack positional arguments */ assert(PyTuple_Check(pto->args)); + args = Py_NewRef(pto->args); n = PyTuple_GET_SIZE(pto->args); for (i = 0; i < n; i++) { Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist, - PyTuple_GET_ITEM(pto->args, i))); + PyTuple_GET_ITEM(args, i))); if (arglist == NULL) goto done; } + Py_DECREF(args); /* Pack keyword arguments */ assert (PyDict_Check(pto->kw)); for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) { From 7c1ed7edcc6339e87b82f86116fe3d8d7aa711c2 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Sat, 7 Feb 2026 16:37:43 +0000 Subject: [PATCH 02/15] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20b?= =?UTF-8?q?lurb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst new file mode 100644 index 00000000000000..de46dc90f885c9 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -0,0 +1,3 @@ +Fixed a bug in partial.__repr__() that could occur when objects replaced the +args tuple during __repr__ evaluation. Now, partial.__repr__() uses the +original args tuple for but subsequent calls would use an updated args tuple From 272318682bb344fcf015bfa0994a61b7e4a3b86e Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sat, 7 Feb 2026 11:41:27 -0500 Subject: [PATCH 03/15] Update 2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst --- .../next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst index de46dc90f885c9..c7e9848c60babf 100644 --- a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -1,3 +1,5 @@ Fixed a bug in partial.__repr__() that could occur when objects replaced the + args tuple during __repr__ evaluation. Now, partial.__repr__() uses the -original args tuple for but subsequent calls would use an updated args tuple + +original args tuple for but subsequent calls would use an updated args tuple From 239c40d4b05351db5eb6fb5d2979b560186ea9e2 Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sat, 7 Feb 2026 11:45:58 -0500 Subject: [PATCH 04/15] Update 2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst --- .../C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst index c7e9848c60babf..19688701bb5346 100644 --- a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -1,5 +1,6 @@ -Fixed a bug in partial.__repr__() that could occur when objects replaced the +Fixed a bug in partial.__repr__() that could occur when objects replaced the -args tuple during __repr__ evaluation. Now, partial.__repr__() uses the +args tuple during __repr__ evaluation. Now, partial.__repr__() uses the original args tuple for but subsequent calls would use an updated args tuple + From e53d7e9b326f3f1cd60f34fd5040ac092f2833d4 Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sat, 7 Feb 2026 13:45:51 -0500 Subject: [PATCH 05/15] Apply suggestion from @picnixz MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Modules/_functoolsmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 11064553ae229d..b8612a0f634d77 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -693,7 +693,7 @@ partial_repr(PyObject *self) PyObject *name; Py_ssize_t i, n; PyObject *key, *value; - PyObject* args; + PyObject *args; int status; status = Py_ReprEnter(self); From 661af78a63740e81dfbb075ae097f99593b66176 Mon Sep 17 00:00:00 2001 From: Brij Date: Sat, 7 Feb 2026 16:39:32 -0500 Subject: [PATCH 06/15] Updates to partial_repr --- Modules/_functoolsmodule.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index b8612a0f634d77..a2f3878a91181f 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -707,14 +707,16 @@ partial_repr(PyObject *self) if (arglist == NULL) goto done; /* Pack positional arguments */ - assert(PyTuple_Check(pto->args)); args = Py_NewRef(pto->args); - n = PyTuple_GET_SIZE(pto->args); + assert(PyTuple_Check(args)); + n = PyTuple_GET_SIZE(args); for (i = 0; i < n; i++) { Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist, PyTuple_GET_ITEM(args, i))); - if (arglist == NULL) + if (arglist == NULL) { + Py_DECREF(args); goto done; + } } Py_DECREF(args); /* Pack keyword arguments */ From 5ce61d9633c2f0f91c7a910c32212d212c5bb186 Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sat, 7 Feb 2026 16:38:58 -0500 Subject: [PATCH 07/15] Update 2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst --- .../C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst index 19688701bb5346..9bd31d0f38b7af 100644 --- a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -1,6 +1,3 @@ -Fixed a bug in partial.__repr__() that could occur when objects replaced the - -args tuple during __repr__ evaluation. Now, partial.__repr__() uses the - +Fixed a bug in partial.__repr__() that could occur when objects replaced the +args tuple during __repr__ evaluation. Now, partial.__repr__() uses the original args tuple for but subsequent calls would use an updated args tuple - From 92eb6ea816c49eef35daca545fef53247ff11b86 Mon Sep 17 00:00:00 2001 From: Brij Date: Sat, 7 Feb 2026 20:01:05 -0500 Subject: [PATCH 08/15] Added test and fixed bug in functions/keword arguments --- Lib/test/test_functools.py | 64 ++++++++++++++++++++++++++++++++++++++ Modules/_functoolsmodule.c | 36 +++++++++++---------- 2 files changed, 84 insertions(+), 16 deletions(-) diff --git a/Lib/test/test_functools.py b/Lib/test/test_functools.py index 3801a82a610891..6d0c0f4ef0e869 100644 --- a/Lib/test/test_functools.py +++ b/Lib/test/test_functools.py @@ -514,6 +514,70 @@ def test_partial_genericalias(self): self.assertEqual(alias.__args__, (int,)) self.assertEqual(alias.__parameters__, ()) + # Issue 144475 + def test_repr_for_segfault(self): + g_partial = None + + class Function: + def __init__(self, name): + self.name = name + + def __call__(self): + return None + + def __repr__(self): + return f"Function({self.name})" + + class EvilObject: + def __init__(self, name, is_trigger=False): + self.name = name + self.is_trigger = is_trigger + self.triggered = False + + def __repr__(self): + if self.is_trigger and not self.triggered and g_partial is not None: + self.triggered = True + new_args_tuple = (None,) + new_keywords_dict = {"keyword": None} + new_tuple_state = (Function("new_function"), new_args_tuple, new_keywords_dict, None) + g_partial.__setstate__(new_tuple_state) + gc.collect() + return f"EvilObject({self.name})" + + trigger = EvilObject("trigger", is_trigger=True) + victim = EvilObject("victim") + + p = functools.partial(Function("old_function"), victim, victim=trigger) + g_partial = p + self.assertEqual(repr(g_partial),"functools.partial(Function(old_function), EvilObject(victim), victim=EvilObject(trigger))") + + trigger.triggered = False + g_partial = None + p = functools.partial(Function("old_function"), trigger, victim=victim) + g_partial = p + self.assertEqual(repr(g_partial),"functools.partial(Function(old_function), EvilObject(trigger), victim=EvilObject(victim))") + + + trigger.triggered = False + p = functools.partial(Function("old_function"), trigger, victim) + g_partial = p + + trigger.triggered = False + p = functools.partial(Function("old_function"), trigger=trigger, victim=victim) + g_partial = p + self.assertEqual(repr(g_partial),"functools.partial(Function(old_function), trigger=EvilObject(trigger), victim=EvilObject(victim))") + + trigger.triggered = False + victim1 = EvilObject("victim") + victim2 = EvilObject("victim") + victim3 = EvilObject("victim") + victim4 = EvilObject("victim") + victim5 = EvilObject("victim") + p = functools.partial(Function("old_function"), trigger, victim1, victim2, victim3, victim4, victim=victim5) + g_partial = p + self.assertEqual(repr(g_partial),"functools.partial(Function(old_function), EvilObject(trigger), EvilObject(victim), EvilObject(victim), EvilObject(victim), EvilObject(victim), victim=EvilObject(victim))") + + @unittest.skipUnless(c_functools, 'requires the C _functools module') class TestPartialC(TestPartial, unittest.TestCase): diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index a2f3878a91181f..c2bc6d2e6b9c96 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -689,11 +689,13 @@ partial_repr(PyObject *self) partialobject *pto = partialobject_CAST(self); PyObject *result = NULL; PyObject *arglist; + PyObject *fn; + PyObject *args; + PyObject *kw; PyObject *mod; PyObject *name; Py_ssize_t i, n; PyObject *key, *value; - PyObject *args; int status; status = Py_ReprEnter(self); @@ -702,26 +704,27 @@ partial_repr(PyObject *self) return NULL; return PyUnicode_FromString("..."); } + /* Reference arguments in case they change */ + fn = Py_NewRef(pto->fn); + args = Py_NewRef(pto->args); + kw = Py_NewRef(pto->kw); + assert(PyTuple_Check(args)); + assert(PyDict_Check(kw)); arglist = Py_GetConstant(Py_CONSTANT_EMPTY_STR); if (arglist == NULL) goto done; /* Pack positional arguments */ - args = Py_NewRef(pto->args); - assert(PyTuple_Check(args)); n = PyTuple_GET_SIZE(args); for (i = 0; i < n; i++) { Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist, PyTuple_GET_ITEM(args, i))); - if (arglist == NULL) { - Py_DECREF(args); + if (arglist == NULL) goto done; - } + } - Py_DECREF(args); /* Pack keyword arguments */ - assert (PyDict_Check(pto->kw)); - for (i = 0; PyDict_Next(pto->kw, &i, &key, &value);) { + for (i = 0; PyDict_Next(kw, &i, &key, &value);) { /* Prevent key.__str__ from deleting the value. */ Py_INCREF(value); Py_SETREF(arglist, PyUnicode_FromFormat("%U, %S=%R", arglist, @@ -733,25 +736,26 @@ partial_repr(PyObject *self) mod = PyType_GetModuleName(Py_TYPE(pto)); if (mod == NULL) { - goto error; + Py_DECREF(arglist); + goto done; } name = PyType_GetQualName(Py_TYPE(pto)); if (name == NULL) { + Py_DECREF(arglist); Py_DECREF(mod); - goto error; + goto done; } - result = PyUnicode_FromFormat("%S.%S(%R%U)", mod, name, pto->fn, arglist); + result = PyUnicode_FromFormat("%S.%S(%R%U)", mod, name, fn, arglist); Py_DECREF(mod); Py_DECREF(name); Py_DECREF(arglist); done: Py_ReprLeave(self); + Py_DECREF(fn); + Py_DECREF(args); + Py_DECREF(kw); return result; - error: - Py_DECREF(arglist); - Py_ReprLeave(self); - return NULL; } /* Pickle strategy: From 5bf71f90487255f191647a8b60550f3495332596 Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sat, 7 Feb 2026 21:17:19 -0500 Subject: [PATCH 09/15] Update 2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst --- .../C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst index 9bd31d0f38b7af..bf209af03001de 100644 --- a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -1,3 +1,4 @@ -Fixed a bug in partial.__repr__() that could occur when objects replaced the -args tuple during __repr__ evaluation. Now, partial.__repr__() uses the +Fixed a bug in partial.__repr__() that could occur when objects replaced the +args tuple during __repr__ evaluation. Now, partial.__repr__() uses the original args tuple for but subsequent calls would use an updated args tuple + From cf6306721385f376ac903d2218828850d130f469 Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sat, 7 Feb 2026 21:22:17 -0500 Subject: [PATCH 10/15] Update 2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst --- .../C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst index bf209af03001de..82587fb2288d67 100644 --- a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -1,4 +1,4 @@ -Fixed a bug in partial.__repr__() that could occur when objects replaced the -args tuple during __repr__ evaluation. Now, partial.__repr__() uses the -original args tuple for but subsequent calls would use an updated args tuple - +Fixed a bug in ``partial.__repr__()`` that could occur when ``fn``, ``args``, +or ``kw`` are modified during a ``repr`` call. Now, ``partial.__repr__()`` +will use the original arguments when generating the return string. +Subsequent calls will use the updated arguments instead. From cb25ea51b054ecc3e91b47524f5c9e7444c07640 Mon Sep 17 00:00:00 2001 From: Brij Date: Sun, 8 Feb 2026 00:15:39 -0500 Subject: [PATCH 11/15] improved goto logic --- Modules/_functoolsmodule.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index c2bc6d2e6b9c96..d8940269d495d1 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -713,14 +713,14 @@ partial_repr(PyObject *self) arglist = Py_GetConstant(Py_CONSTANT_EMPTY_STR); if (arglist == NULL) - goto done; + goto free_arguments; /* Pack positional arguments */ n = PyTuple_GET_SIZE(args); for (i = 0; i < n; i++) { Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist, PyTuple_GET_ITEM(args, i))); if (arglist == NULL) - goto done; + goto free_arguments; } /* Pack keyword arguments */ @@ -731,30 +731,28 @@ partial_repr(PyObject *self) key, value)); Py_DECREF(value); if (arglist == NULL) - goto done; + goto free_arguments; } mod = PyType_GetModuleName(Py_TYPE(pto)); if (mod == NULL) { - Py_DECREF(arglist); - goto done; + goto free_arglist; } name = PyType_GetQualName(Py_TYPE(pto)); if (name == NULL) { - Py_DECREF(arglist); - Py_DECREF(mod); - goto done; + goto free_mod; } result = PyUnicode_FromFormat("%S.%S(%R%U)", mod, name, fn, arglist); - Py_DECREF(mod); Py_DECREF(name); + free_mod: + Py_DECREF(mod); + free_arglist: Py_DECREF(arglist); - - done: - Py_ReprLeave(self); + free_arguments: Py_DECREF(fn); Py_DECREF(args); Py_DECREF(kw); + Py_ReprLeave(self); return result; } From 30d39f45a745a55c63b984cd5f67340d721f1bcd Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sun, 8 Feb 2026 16:44:32 -0500 Subject: [PATCH 12/15] Update 2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst --- .../next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst index 82587fb2288d67..7c38abde47ed50 100644 --- a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -1,4 +1,4 @@ -Fixed a bug in ``partial.__repr__()`` that could occur when ``fn``, ``args``, -or ``kw`` are modified during a ``repr`` call. Now, ``partial.__repr__()`` +Fixed a bug in :meth:`functools.partial.__repr__()` that could occur when ``fn``, ``args``, +or ``kw`` are modified during a :func:`repr` call. Now, ``partial.__repr__()`` will use the original arguments when generating the return string. Subsequent calls will use the updated arguments instead. From a004007c09411352fe37b27236ca74eca25ce56b Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sun, 8 Feb 2026 16:52:26 -0500 Subject: [PATCH 13/15] Update 2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst --- .../C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst index 7c38abde47ed50..336be227916f6b 100644 --- a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -1,4 +1,5 @@ -Fixed a bug in :meth:`functools.partial.__repr__()` that could occur when ``fn``, ``args``, -or ``kw`` are modified during a :func:`repr` call. Now, ``partial.__repr__()`` +Fixed a bug in :meth:`functools.partial.__repr__` that could occur when ``fn``, ``args``, +or ``kw`` are modified during a :func:`repr` call. Now, ``partial.__repr__`` will use the original arguments when generating the return string. Subsequent calls will use the updated arguments instead. + From 24307a25544c61e0969055bb5d2453f6e55b116a Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sun, 8 Feb 2026 17:32:39 -0500 Subject: [PATCH 14/15] Update 2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst --- .../C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst index 336be227916f6b..a549cc3254a8f2 100644 --- a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -1,5 +1,5 @@ -Fixed a bug in :meth:`functools.partial.__repr__` that could occur when ``fn``, ``args``, -or ``kw`` are modified during a :func:`repr` call. Now, ``partial.__repr__`` -will use the original arguments when generating the return string. +Fixed a bug in :func:`functools.partial` when calling :func:`repr` on a partial +object that could occur when the ``fn``, ``args``, or ``kw`` arguments are modified +during a call to :func:`repr`. Now, calls to :func:`repr` will use the original +arguments when generating the string representation of the partial object. Subsequent calls will use the updated arguments instead. - From 192ff1ebb21217603a26fa3694d59115eac9cc11 Mon Sep 17 00:00:00 2001 From: bkap123 <97006829+bkap123@users.noreply.github.com> Date: Sun, 8 Feb 2026 17:35:00 -0500 Subject: [PATCH 15/15] Update 2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst --- .../C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst index a549cc3254a8f2..9f9e866348b088 100644 --- a/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst +++ b/Misc/NEWS.d/next/C_API/2026-02-07-16-37-42.gh-issue-144475.8tFEXw.rst @@ -1,5 +1,6 @@ -Fixed a bug in :func:`functools.partial` when calling :func:`repr` on a partial -object that could occur when the ``fn``, ``args``, or ``kw`` arguments are modified -during a call to :func:`repr`. Now, calls to :func:`repr` will use the original -arguments when generating the string representation of the partial object. +Fixed a bug in :func:`functools.partial` when calling :func:`repr` on a partial +object that could occur when the ``fn``, ``args``, or ``kw`` arguments are modified +during a call to :func:`repr`. Now, calls to :func:`repr` will use the original +arguments when generating the string representation of the partial object. Subsequent calls will use the updated arguments instead. +