From 664df71d6042b9c570df705a41a7a8e9a6664749 Mon Sep 17 00:00:00 2001 From: Piotr Sawicki Date: Tue, 20 Oct 2026 12:45:37 +0200 Subject: [PATCH 1/2] [mypyc] Release boxed integers on invalid byteorder errors --- mypyc/lib-rt/int_ops.c | 1 + mypyc/test-data/run-integers.test | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/mypyc/lib-rt/int_ops.c b/mypyc/lib-rt/int_ops.c index f5dfa98a595b0..b03095d04ba0a 100644 --- a/mypyc/lib-rt/int_ops.c +++ b/mypyc/lib-rt/int_ops.c @@ -641,6 +641,7 @@ PyObject *CPyTagged_ToBytes(CPyTagged self, Py_ssize_t length, PyObject *byteord } else if (strcmp(order, "little") == 0) { little_endian = 1; } else { + Py_DECREF(pyint); PyErr_SetString(PyExc_ValueError, "byteorder must be either 'little' or 'big'"); return NULL; } diff --git a/mypyc/test-data/run-integers.test b/mypyc/test-data/run-integers.test index cbcb0d43fc9db..7a31f3cf5e3a3 100644 --- a/mypyc/test-data/run-integers.test +++ b/mypyc/test-data/run-integers.test @@ -574,6 +574,7 @@ class int: pass [case testIntToBytes] +import sys from testutil import assertRaises def to_bytes(n: int, length: int, byteorder: str, signed: bool = False) -> bytes: return n.to_bytes(length, byteorder, signed=signed) @@ -594,6 +595,17 @@ def test_to_bytes() -> None: with assertRaises(OverflowError): to_bytes(128, 1, "big", True) +def test_invalid_byteorder_refcount() -> None: + n = int("123456789012345678901234567890") + before = sys.getrefcount(n) + for _ in range(10): + with assertRaises(ValueError): + to_bytes(n, 16, "invalid") + assert sys.getrefcount(n) == before + +[file sys/__init__.pyi] +def getrefcount(n: object) -> int: ... + [case testBitLength] def bit_length(n: int) -> int: return n.bit_length() From 52223059cb67b12ee04228bb7a029e1926c2343a Mon Sep 17 00:00:00 2001 From: Piotr Sawicki Date: Tue, 20 Oct 2026 14:19:45 +0200 Subject: [PATCH 2/2] Fix test --- mypyc/test-data/run-integers.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mypyc/test-data/run-integers.test b/mypyc/test-data/run-integers.test index 7a31f3cf5e3a3..3e4f29345250a 100644 --- a/mypyc/test-data/run-integers.test +++ b/mypyc/test-data/run-integers.test @@ -602,6 +602,8 @@ def test_invalid_byteorder_refcount() -> None: with assertRaises(ValueError): to_bytes(n, 16, "invalid") assert sys.getrefcount(n) == before + # Keep n alive across both refcount checks. + assert n == int("123456789012345678901234567890") [file sys/__init__.pyi] def getrefcount(n: object) -> int: ...