diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index d049646d6e8b55a..b5905d1080ea7a9 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -3766,6 +3766,27 @@ def test_to_integral_value(self): @requires_cdecimal class CContextAPItests(ContextAPItests, unittest.TestCase): decimal = C + + def test_current_context_var_wrong_type(self): + # gh-161387 + if not self.decimal.HAVE_CONTEXTVAR: + self.skipTest("_decimal built without context variables") + value = object() + context_vars = [var for var in contextvars.copy_context() + if var.name == "decimal_context"] + self.assertTrue(context_vars) + tokens = [var.set(value) for var in context_vars] + + def restore(): + for var, token in zip(context_vars, tokens): + var.reset(token) + + self.addCleanup(restore) + with self.assertRaisesRegex(TypeError, "got object"): + self.decimal.Decimal(1) + self.decimal.Decimal(2) + for var in context_vars: + self.assertIs(var.get(), value) + class PyContextAPItests(ContextAPItests, unittest.TestCase): decimal = P diff --git a/Misc/NEWS.d/next/Library/2026-11-05-10-05-00.gh-issue-161387.def456.rst b/Misc/NEWS.d/next/Library/2026-11-05-10-05-00.gh-issue-161387.def456.rst new file mode 100644 index 000000000000000..f445980563853bb --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-11-05-10-05-00.gh-issue-161387.def456.rst @@ -0,0 +1,2 @@ +Fix a crash in :mod:`decimal` when the internal ``decimal_context`` +:class:`contextvars.ContextVar` holds a value that is not a context. diff --git a/Modules/_decimal/_decimal.c b/Modules/_decimal/_decimal.c index 4849b447e277bfc..130a0cd97e5e991 100644 --- a/Modules/_decimal/_decimal.c +++ b/Modules/_decimal/_decimal.c @@ -1997,6 +1997,13 @@ current_context(decimal_state *state) } if (tl_context != NULL) { + if (!PyDecContext_Check(state, tl_context)) { + PyErr_Format(PyExc_TypeError, + "current decimal context must be a Context " + "instance, got %T", tl_context); + Py_DECREF(tl_context); + return NULL; + } return tl_context; }