From ef09f8c0cb1aaeba47175ee9ac91c1812270afa7 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 19 Jul 2026 07:06:21 +0300 Subject: [PATCH 1/3] gh-154037: Fix race in the Decimal.__hash__() --- Modules/_decimal/_decimal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index dc1b3c06bed952..9536ad1fac2892 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -5921,11 +5921,11 @@ static Py_hash_t dec_hash(PyObject *op) { PyDecObject *self = _PyDecObject_CAST(op); - if (self->hash == -1) { - self->hash = _dec_hash(self); - } - return self->hash; + if (FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hash) == -1) { + FT_ATOMIC_STORE_SSIZE_RELAXED(self->hash, _dec_hash(self)); + } + return FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hash); } /*[clinic input] From d3d8268501c588764afe5599578f0294a8105ac7 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 19 Jul 2026 19:43:24 +0300 Subject: [PATCH 2/3] use local variable --- Modules/_decimal/_decimal.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 9536ad1fac2892..4091453e708be1 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -5921,11 +5921,13 @@ static Py_hash_t dec_hash(PyObject *op) { PyDecObject *self = _PyDecObject_CAST(op); + Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hash) - if (FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hash) == -1) { - FT_ATOMIC_STORE_SSIZE_RELAXED(self->hash, _dec_hash(self)); + if (hash == -1) { + hash = _dec_hash(self); + FT_ATOMIC_STORE_SSIZE_RELAXED(self->hash, hash); } - return FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hash); + return hash; } /*[clinic input] From c9e1c79619670e31406a53915e54aa468dbe8dc6 Mon Sep 17 00:00:00 2001 From: Sergey B Kirpichev Date: Sun, 19 Jul 2026 19:51:55 +0300 Subject: [PATCH 3/3] +1 --- Modules/_decimal/_decimal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 4091453e708be1..ac9c5437d2c577 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -5921,7 +5921,7 @@ static Py_hash_t dec_hash(PyObject *op) { PyDecObject *self = _PyDecObject_CAST(op); - Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hash) + Py_hash_t hash = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->hash); if (hash == -1) { hash = _dec_hash(self);