Skip to content

Commit 7b4955f

Browse files
committed
small changes
1 parent 7a5456c commit 7b4955f

File tree

3 files changed

+16
-21
lines changed

3 files changed

+16
-21
lines changed

Lib/test/test_functools.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ def test_partial_genericalias(self):
514514
self.assertEqual(alias.__args__, (int,))
515515
self.assertEqual(alias.__parameters__, ())
516516

517-
# Issue 144475
517+
# GH-144475: Tests that the partial object does not change until repr finishes
518518
def test_repr_saftey_against_reentrant_mutation(self):
519519
g_partial = None
520520

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
Fixed a bug in :func:`functools.partial` when calling :func:`repr` on a partial
2-
object that could occur when the ``fn``, ``args``, or ``kw`` arguments are modified
3-
during a call to :func:`repr`. Now, calls to :func:`repr` will use the original
4-
arguments when generating the string representation of the partial object.
5-
Subsequent calls will use the updated arguments instead.
6-
1+
Calling :func:`repr` on :func:`functools.partial` will no longer
2+
use a mutated version of the arguments ``fn``, ``args``, or ``kw``
3+
when generating the string representation of the partial object.

Modules/_functoolsmodule.c

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -689,9 +689,9 @@ partial_repr(PyObject *self)
689689
partialobject *pto = partialobject_CAST(self);
690690
PyObject *result = NULL;
691691
PyObject *fn, *args, *kw;
692-
PyObject *arglist;
693-
PyObject *mod;
694-
PyObject *name;
692+
PyObject *arglist = NULL;
693+
PyObject *mod = NULL;
694+
PyObject *name = NULL;
695695
Py_ssize_t i, n;
696696
PyObject *key, *value;
697697
int status;
@@ -712,15 +712,15 @@ partial_repr(PyObject *self)
712712

713713
arglist = Py_GetConstant(Py_CONSTANT_EMPTY_STR);
714714
if (arglist == NULL) {
715-
goto arglist_error;
715+
goto done;
716716
}
717717
/* Pack positional arguments */
718718
n = PyTuple_GET_SIZE(args);
719719
for (i = 0; i < n; i++) {
720720
Py_SETREF(arglist, PyUnicode_FromFormat("%U, %R", arglist,
721721
PyTuple_GET_ITEM(args, i)));
722722
if (arglist == NULL) {
723-
goto arglist_error;
723+
goto done;
724724
}
725725
}
726726
/* Pack keyword arguments */
@@ -731,27 +731,25 @@ partial_repr(PyObject *self)
731731
key, value));
732732
Py_DECREF(value);
733733
if (arglist == NULL) {
734-
goto arglist_error;
734+
goto done;
735735
}
736736
}
737737

738738
mod = PyType_GetModuleName(Py_TYPE(pto));
739739
if (mod == NULL) {
740-
goto mod_error;
740+
goto done;
741741
}
742742

743743
name = PyType_GetQualName(Py_TYPE(pto));
744744
if (name == NULL) {
745-
goto name_error;
745+
goto done;
746746
}
747747

748748
result = PyUnicode_FromFormat("%S.%S(%R%U)", mod, name, fn, arglist);
749-
Py_DECREF(name);
750-
name_error:
751-
Py_DECREF(mod);
752-
mod_error:
753-
Py_DECREF(arglist);
754-
arglist_error:
749+
done:
750+
Py_XDECREF(name);
751+
Py_XDECREF(mod);
752+
Py_XDECREF(arglist);
755753
Py_DECREF(fn);
756754
Py_DECREF(args);
757755
Py_DECREF(kw);

0 commit comments

Comments
 (0)