https://github.com/python/cpython/commit/b3cf1f27e94d65eba4ed300bdf5851c0326a2a44 commit: b3cf1f27e94d65eba4ed300bdf5851c0326a2a44 branch: 3.12 author: Miss Islington (bot) <31488909+miss-isling...@users.noreply.github.com> committer: sobolevn <m...@sobolevn.me> date: 2025-04-02T12:05:30Z summary:
[3.12] gh-132002: Fix crash of `ContextVar` on unhashable `str` subtype (GH-132003) (#132008) gh-132002: Fix crash of `ContextVar` on unhashable `str` subtype (GH-132003) (cherry picked from commit ab2a3dda1d3b6668162a847bf5b6aca2855a3416) Co-authored-by: sobolevn <m...@sobolevn.me> 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 dc6856509a40a0..e8e5b76ced90ea 100644 --- a/Lib/test/test_context.py +++ b/Lib/test/test_context.py @@ -83,6 +83,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 7bccfad11a45b1..e5899219daac8c 100644 --- a/Python/context.c +++ b/Python/context.c @@ -821,20 +821,19 @@ 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); var->var_cached = NULL; var->var_cached_tsid = 0; var->var_cached_tsver = 0; + 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 -- python-checkins@python.org To unsubscribe send an email to python-checkins-le...@python.org https://mail.python.org/mailman3/lists/python-checkins.python.org/ Member address: arch...@mail-archive.com