diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-12-26-05-10-23.gh-issue-113480._ul8BY.rst b/Misc/NEWS.d/next/Core and Builtins/2023-12-26-05-10-23.gh-issue-113480._ul8BY.rst new file mode 100644 index 00000000000000..d77d6f90446b39 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2023-12-26-05-10-23.gh-issue-113480._ul8BY.rst @@ -0,0 +1 @@ +Check if the type attribute is really modified before label it modified diff --git a/Objects/typeobject.c b/Objects/typeobject.c index ea29a38d74ae3e..b8ecca13f57dea 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -4960,8 +4960,16 @@ type_setattro(PyObject *self, PyObject *name, PyObject *value) /* Will fail in _PyObject_GenericSetAttrWithDict. */ Py_INCREF(name); } + + // Get the global dict version of interpreter + // If the version does not change, that means we assigned the same value + // to the attribute, so the type is not modified + + PyInterpreterState *interp = _PyInterpreterState_GET(); + uint64_t prev_version = interp->dict_state.global_version; + res = _PyObject_GenericSetAttrWithDict((PyObject *)type, name, value, NULL); - if (res == 0) { + if (res == 0 && prev_version != interp->dict_state.global_version) { /* Clear the VALID_VERSION flag of 'type' and all its subclasses. This could possibly be unified with the update_subclasses() recursion in update_slot(), but carefully: