https://github.com/python/cpython/commit/ab2a3dda1d3b6668162a847bf5b6aca2855a3416
commit: ab2a3dda1d3b6668162a847bf5b6aca2855a3416
branch: main
author: sobolevn <[email protected]>
committer: sobolevn <[email protected]>
date: 2025-04-02T14:48:47+03:00
summary:
gh-132002: Fix crash of `ContextVar` on unhashable `str` subtype (#132003)
files:
A Misc/NEWS.d/next/Library/2025-04-02-11-31-15.gh-issue-132002.TMsYvE.rst
M Lib/test/test_context.py
M Python/context.c
diff --git a/Lib/test/test_context.py b/Lib/test/test_context.py
index f9cdcc3561e9d6..73f59f2cb8af4b 100644
--- a/Lib/test/test_context.py
+++ b/Lib/test/test_context.py
@@ -92,6 +92,15 @@ def test_context_new_1(self):
contextvars.Context(a=1)
contextvars.Context(**{})
+ def test_context_new_unhashable_str_subclass(self):
+ # gh-132002: it used to crash on unhashable str subtypes.
+ class weird_str(str):
+ def __eq__(self, other):
+ pass
+
+ with self.assertRaisesRegex(TypeError, 'unhashable type'):
+ contextvars.ContextVar(weird_str())
+
def test_context_typerrors_1(self):
ctx = contextvars.Context()
diff --git
a/Misc/NEWS.d/next/Library/2025-04-02-11-31-15.gh-issue-132002.TMsYvE.rst
b/Misc/NEWS.d/next/Library/2025-04-02-11-31-15.gh-issue-132002.TMsYvE.rst
new file mode 100644
index 00000000000000..b46bc25b87f1e3
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-04-02-11-31-15.gh-issue-132002.TMsYvE.rst
@@ -0,0 +1,2 @@
+Fix crash when deallocating :class:`contextvars.ContextVar` with weird
+unahashable string names.
diff --git a/Python/context.c b/Python/context.c
index 4110e6891a1070..dceaae9b42979d 100644
--- a/Python/context.c
+++ b/Python/context.c
@@ -878,14 +878,7 @@ contextvar_new(PyObject *name, PyObject *def)
return NULL;
}
- var->var_hash = contextvar_generate_hash(var, name);
- if (var->var_hash == -1) {
- Py_DECREF(var);
- return NULL;
- }
-
var->var_name = Py_NewRef(name);
-
var->var_default = Py_XNewRef(def);
#ifndef Py_GIL_DISABLED
@@ -894,6 +887,12 @@ contextvar_new(PyObject *name, PyObject *def)
var->var_cached_tsver = 0;
#endif
+ var->var_hash = contextvar_generate_hash(var, name);
+ if (var->var_hash == -1) {
+ Py_DECREF(var);
+ return NULL;
+ }
+
if (_PyObject_GC_MAY_BE_TRACKED(name) ||
(def != NULL && _PyObject_GC_MAY_BE_TRACKED(def)))
{
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]