From ae3aba977cb86877ee96055b670dde538b23bb65 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 13 Aug 2026 19:58:42 +0200 Subject: [PATCH 1/3] gh-155742: Use PyBytesWriter in Python/assemble.c Replace soft deprecated PyBytes_FromStringAndSize() with PyBytesWriter. --- Python/assemble.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/Python/assemble.c b/Python/assemble.c index 8bcb4c7bf3a9aa4..1570e82a6f6c7cc 100644 --- a/Python/assemble.c +++ b/Python/assemble.c @@ -54,7 +54,8 @@ struct assembler { int a_except_table_off; /* offset into exception table */ /* Location Info */ int a_lineno; /* lineno of last emitted instruction */ - PyObject* a_linetable; /* bytes containing location info */ + PyBytesWriter *a_linetable; /* bytes writer containing location info */ + PyObject *a_linetable_obj; /* bytes object containing location info */ int a_location_off; /* offset of last written location info frame */ }; @@ -63,14 +64,11 @@ assemble_init(struct assembler *a, int firstlineno) { memset(a, 0, sizeof(struct assembler)); a->a_lineno = firstlineno; - a->a_linetable = NULL; - a->a_location_off = 0; - a->a_except_table = NULL; a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE); if (a->a_bytecode == NULL) { goto error; } - a->a_linetable = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE); + a->a_linetable = PyBytesWriter_Create(DEFAULT_CNOTAB_SIZE); if (a->a_linetable == NULL) { goto error; } @@ -81,7 +79,7 @@ assemble_init(struct assembler *a, int firstlineno) return SUCCESS; error: Py_CLEAR(a->a_bytecode); - Py_CLEAR(a->a_linetable); + PyBytesWriter_Discard(a->a_linetable); Py_CLEAR(a->a_except_table); return ERROR; } @@ -90,7 +88,8 @@ static void assemble_free(struct assembler *a) { Py_XDECREF(a->a_bytecode); - Py_XDECREF(a->a_linetable); + PyBytesWriter_Discard(a->a_linetable); + Py_XDECREF(a->a_linetable_obj); Py_XDECREF(a->a_except_table); } @@ -195,7 +194,8 @@ assemble_exception_table(struct assembler *a, instr_sequence *instrs) static void write_location_byte(struct assembler* a, int val) { - PyBytes_AS_STRING(a->a_linetable)[a->a_location_off] = val&255; + uint8_t *a_linetable = PyBytesWriter_GetData(a->a_linetable); + a_linetable[a->a_location_off] = val & 255; a->a_location_off++; } @@ -203,8 +203,8 @@ write_location_byte(struct assembler* a, int val) static uint8_t * location_pointer(struct assembler* a) { - return (uint8_t *)PyBytes_AS_STRING(a->a_linetable) + - a->a_location_off; + uint8_t *a_linetable = PyBytesWriter_GetData(a->a_linetable); + return a_linetable + a->a_location_off; } static void @@ -285,10 +285,10 @@ write_location_info_no_column(struct assembler* a, int length, int line_delta) static int write_location_info_entry(struct assembler* a, location loc, int isize) { - Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable); + Py_ssize_t len = PyBytesWriter_GetSize(a->a_linetable); if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) { assert(len > THEORETICAL_MAX_ENTRY_SIZE); - RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2)); + RETURN_IF_ERROR(PyBytesWriter_Resize(a->a_linetable, len * 2)); } if (loc.lineno == NO_LOCATION.lineno) { write_location_info_none(a, isize); @@ -447,8 +447,13 @@ assemble_emit(struct assembler *a, instr_sequence *instrs, RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, a->a_except_table_off)); RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_except_table)); - RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, a->a_location_off)); - RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_linetable)); + a->a_linetable_obj = PyBytesWriter_FinishWithSize(a->a_linetable, + a->a_location_off); + a->a_linetable = NULL; + if (a->a_linetable_obj == NULL) { + return ERROR; + } + RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_linetable_obj)); RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, a->a_offset * sizeof(_Py_CODEUNIT))); RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_bytecode)); @@ -629,7 +634,7 @@ makecode(_PyCompile_CodeUnitMetadata *umd, struct assembler *a, PyObject *const_ .code = a->a_bytecode, .firstlineno = umd->u_firstlineno, - .linetable = a->a_linetable, + .linetable = a->a_linetable_obj, .consts = consts, .names = names, From 7862062d97804cd64799a9b445768f3d8a6582ed Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Aug 2026 16:45:53 +0200 Subject: [PATCH 2/3] Rename variables * Rename a_linetable member to a_linetable_writer * Rename a_linetable_obj member to a_linetable * Rename a_linetable variable to linetable --- Python/assemble.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/Python/assemble.c b/Python/assemble.c index 1570e82a6f6c7cc..1cbd0381d9aa0e7 100644 --- a/Python/assemble.c +++ b/Python/assemble.c @@ -54,8 +54,8 @@ struct assembler { int a_except_table_off; /* offset into exception table */ /* Location Info */ int a_lineno; /* lineno of last emitted instruction */ - PyBytesWriter *a_linetable; /* bytes writer containing location info */ - PyObject *a_linetable_obj; /* bytes object containing location info */ + PyBytesWriter *a_linetable_writer; /* writer containing location info */ + PyObject *a_linetable; /* bytes object containing location info */ int a_location_off; /* offset of last written location info frame */ }; @@ -68,8 +68,8 @@ assemble_init(struct assembler *a, int firstlineno) if (a->a_bytecode == NULL) { goto error; } - a->a_linetable = PyBytesWriter_Create(DEFAULT_CNOTAB_SIZE); - if (a->a_linetable == NULL) { + a->a_linetable_writer = PyBytesWriter_Create(DEFAULT_CNOTAB_SIZE); + if (a->a_linetable_writer == NULL) { goto error; } a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE); @@ -79,7 +79,7 @@ assemble_init(struct assembler *a, int firstlineno) return SUCCESS; error: Py_CLEAR(a->a_bytecode); - PyBytesWriter_Discard(a->a_linetable); + PyBytesWriter_Discard(a->a_linetable_writer); Py_CLEAR(a->a_except_table); return ERROR; } @@ -88,8 +88,8 @@ static void assemble_free(struct assembler *a) { Py_XDECREF(a->a_bytecode); - PyBytesWriter_Discard(a->a_linetable); - Py_XDECREF(a->a_linetable_obj); + PyBytesWriter_Discard(a->a_linetable_writer); + Py_XDECREF(a->a_linetable); Py_XDECREF(a->a_except_table); } @@ -194,8 +194,8 @@ assemble_exception_table(struct assembler *a, instr_sequence *instrs) static void write_location_byte(struct assembler* a, int val) { - uint8_t *a_linetable = PyBytesWriter_GetData(a->a_linetable); - a_linetable[a->a_location_off] = val & 255; + uint8_t *linetable = PyBytesWriter_GetData(a->a_linetable_writer); + linetable[a->a_location_off] = val & 255; a->a_location_off++; } @@ -203,8 +203,8 @@ write_location_byte(struct assembler* a, int val) static uint8_t * location_pointer(struct assembler* a) { - uint8_t *a_linetable = PyBytesWriter_GetData(a->a_linetable); - return a_linetable + a->a_location_off; + uint8_t *linetable = PyBytesWriter_GetData(a->a_linetable_writer); + return linetable + a->a_location_off; } static void @@ -285,10 +285,10 @@ write_location_info_no_column(struct assembler* a, int length, int line_delta) static int write_location_info_entry(struct assembler* a, location loc, int isize) { - Py_ssize_t len = PyBytesWriter_GetSize(a->a_linetable); + Py_ssize_t len = PyBytesWriter_GetSize(a->a_linetable_writer); if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) { assert(len > THEORETICAL_MAX_ENTRY_SIZE); - RETURN_IF_ERROR(PyBytesWriter_Resize(a->a_linetable, len * 2)); + RETURN_IF_ERROR(PyBytesWriter_Resize(a->a_linetable_writer, len * 2)); } if (loc.lineno == NO_LOCATION.lineno) { write_location_info_none(a, isize); @@ -447,13 +447,13 @@ assemble_emit(struct assembler *a, instr_sequence *instrs, RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, a->a_except_table_off)); RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_except_table)); - a->a_linetable_obj = PyBytesWriter_FinishWithSize(a->a_linetable, + a->a_linetable = PyBytesWriter_FinishWithSize(a->a_linetable_writer, a->a_location_off); - a->a_linetable = NULL; - if (a->a_linetable_obj == NULL) { + a->a_linetable_writer = NULL; + if (a->a_linetable == NULL) { return ERROR; } - RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_linetable_obj)); + RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_linetable)); RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, a->a_offset * sizeof(_Py_CODEUNIT))); RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_bytecode)); @@ -634,7 +634,7 @@ makecode(_PyCompile_CodeUnitMetadata *umd, struct assembler *a, PyObject *const_ .code = a->a_bytecode, .firstlineno = umd->u_firstlineno, - .linetable = a->a_linetable_obj, + .linetable = a->a_linetable, .consts = consts, .names = names, From 38f871dfd2d194862d0026bb9383ae677d8a437b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 14 Aug 2026 17:35:33 +0200 Subject: [PATCH 3/3] Fix indentation --- Python/assemble.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Python/assemble.c b/Python/assemble.c index 1cbd0381d9aa0e7..4bbebe30299906a 100644 --- a/Python/assemble.c +++ b/Python/assemble.c @@ -448,7 +448,7 @@ assemble_emit(struct assembler *a, instr_sequence *instrs, RETURN_IF_ERROR(_PyCompile_ConstCacheMergeOne(const_cache, &a->a_except_table)); a->a_linetable = PyBytesWriter_FinishWithSize(a->a_linetable_writer, - a->a_location_off); + a->a_location_off); a->a_linetable_writer = NULL; if (a->a_linetable == NULL) { return ERROR;