https://github.com/python/cpython/commit/109a192eb5c4b3ac3ed4c029b9032215bd079c6e
commit: 109a192eb5c4b3ac3ed4c029b9032215bd079c6e
branch: main
author: Marc Mueller <[email protected]>
committer: ZeroIntensity <[email protected]>
date: 2026-09-26T12:49:38-04:00
summary:
gh-151907: Reduce duplication in codegen comprehension functions (GH-154846)
files:
M Python/codegen.c
diff --git a/Python/codegen.c b/Python/codegen.c
index 0ae13e40d4a1ee..71ec33724684dc 100644
--- a/Python/codegen.c
+++ b/Python/codegen.c
@@ -4625,6 +4625,78 @@ codegen_unpack_starred(compiler *c, location loc,
expr_ty value, bool yield)
return SUCCESS;
}
+static int
+codegen_comprehension_generator_helper(compiler *c, location elt_loc, int
depth,
+ expr_ty elt, expr_ty val, int type,
+ bool avoid_creation)
+{
+ switch (type) {
+ case COMP_GENEXP:
+ assert(!avoid_creation);
+ if (elt->kind == Starred_kind) {
+ RETURN_IF_ERROR(codegen_unpack_starred(c, elt_loc,
elt->v.Starred.value, /*yield=*/true));
+ }
+ else {
+ VISIT(c, expr, elt);
+ ADDOP_YIELD(c, elt_loc);
+ ADDOP(c, elt_loc, POP_TOP);
+ }
+ break;
+ case COMP_LISTCOMP:
+ if (avoid_creation) {
+ if (elt->kind == Starred_kind) {
+ RETURN_IF_ERROR(codegen_unpack_starred(c, elt_loc,
elt->v.Starred.value, /*yield=*/false));
+ } else {
+ VISIT(c, expr, elt);
+ ADDOP(c, elt_loc, POP_TOP);
+ }
+ break;
+ }
+ if (elt->kind == Starred_kind) {
+ VISIT(c, expr, elt->v.Starred.value);
+ ADDOP_I(c, elt_loc, LIST_EXTEND, depth + 1);
+ }
+ else {
+ VISIT(c, expr, elt);
+ ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
+ }
+ break;
+ case COMP_SETCOMP:
+ assert(!avoid_creation);
+ if (elt->kind == Starred_kind) {
+ VISIT(c, expr, elt->v.Starred.value);
+ ADDOP_I(c, elt_loc, SET_UPDATE, depth + 1);
+ }
+ else {
+ VISIT(c, expr, elt);
+ ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
+ }
+ break;
+ case COMP_DICTCOMP:
+ assert(!avoid_creation);
+ if (val == NULL) {
+ /* unpacking (**) case */
+ VISIT(c, expr, elt);
+ ADDOP_I(c, elt_loc, DICT_UPDATE, depth + 1);
+ }
+ else {
+ /* With '{k: v}', k is evaluated before v, so we do
+ the same. */
+ VISIT(c, expr, elt);
+ VISIT(c, expr, val);
+ elt_loc = LOCATION(elt->lineno,
+ val->end_lineno,
+ elt->col_offset,
+ val->end_col_offset);
+ ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
+ }
+ break;
+ default:
+ return ERROR;
+ }
+ return SUCCESS;
+}
+
static int
codegen_sync_comprehension_generator(compiler *c, location loc,
asdl_comprehension_seq *generators,
@@ -4706,67 +4778,14 @@ codegen_sync_comprehension_generator(compiler *c,
location loc,
/* only append after the last for generator */
if (gen_index >= asdl_seq_LEN(generators)) {
/* comprehension specific code */
- switch (type) {
- case COMP_GENEXP:
- assert(!avoid_creation);
- if (elt->kind == Starred_kind) {
- RETURN_IF_ERROR(codegen_unpack_starred(c, elt_loc,
elt->v.Starred.value, /*yield=*/true));
- }
- else {
- VISIT(c, expr, elt);
- ADDOP_YIELD(c, elt_loc);
- ADDOP(c, elt_loc, POP_TOP);
- }
- break;
- case COMP_LISTCOMP:
- if (avoid_creation) {
- if (elt->kind == Starred_kind) {
- RETURN_IF_ERROR(codegen_unpack_starred(c, elt_loc,
elt->v.Starred.value, /*yield=*/false));
- } else {
- VISIT(c, expr, elt);
- ADDOP(c, elt_loc, POP_TOP);
- }
- break;
- }
- if (elt->kind == Starred_kind) {
- VISIT(c, expr, elt->v.Starred.value);
- ADDOP_I(c, elt_loc, LIST_EXTEND, depth + 1);
- }
- else {
- VISIT(c, expr, elt);
- ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
- }
- break;
- case COMP_SETCOMP:
- if (elt->kind == Starred_kind) {
- VISIT(c, expr, elt->v.Starred.value);
- ADDOP_I(c, elt_loc, SET_UPDATE, depth + 1);
- }
- else {
- VISIT(c, expr, elt);
- ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
- }
- break;
- case COMP_DICTCOMP:
- if (val == NULL) {
- /* unpacking (**) case */
- VISIT(c, expr, elt);
- ADDOP_I(c, elt_loc, DICT_UPDATE, depth+1);
- }
- else {
- /* With '{k: v}', k is evaluated before v, so we do
- the same. */
- VISIT(c, expr, elt);
- VISIT(c, expr, val);
- elt_loc = LOCATION(elt->lineno,
- val->end_lineno,
- elt->col_offset,
- val->end_col_offset);
- ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
- }
- break;
- default:
- return ERROR;
+ RETURN_IF_ERROR(codegen_comprehension_generator_helper(c, elt_loc,
depth,
+ elt, val, type,
+
avoid_creation));
+ if (type == COMP_DICTCOMP && val != NULL) {
+ elt_loc = LOCATION(elt->lineno,
+ val->end_lineno,
+ elt->col_offset,
+ val->end_col_offset);
}
}
@@ -4848,81 +4867,14 @@ codegen_async_comprehension_generator(compiler *c,
location loc,
/* only append after the last for generator */
if (gen_index >= asdl_seq_LEN(generators)) {
/* comprehension specific code */
- switch (type) {
- case COMP_GENEXP:
- assert(!avoid_creation);
- if (elt->kind == Starred_kind) {
- NEW_JUMP_TARGET_LABEL(c, unpack_start);
- NEW_JUMP_TARGET_LABEL(c, unpack_end);
- VISIT(c, expr, elt->v.Starred.value);
- ADDOP_I(c, elt_loc, GET_ITER, 0);
- USE_LABEL(c, unpack_start);
- ADDOP_JUMP(c, elt_loc, FOR_ITER, unpack_end);
- ADDOP_YIELD(c, elt_loc);
- ADDOP(c, elt_loc, POP_TOP);
- ADDOP_JUMP(c, NO_LOCATION, JUMP, unpack_start);
- USE_LABEL(c, unpack_end);
- ADDOP(c, NO_LOCATION, END_FOR);
- ADDOP(c, NO_LOCATION, POP_ITER);
- }
- else {
- VISIT(c, expr, elt);
- ADDOP_YIELD(c, elt_loc);
- ADDOP(c, elt_loc, POP_TOP);
- }
- break;
- case COMP_LISTCOMP:
- if (avoid_creation) {
- if (elt->kind == Starred_kind) {
- RETURN_IF_ERROR(codegen_unpack_starred(c, elt_loc,
elt->v.Starred.value, /*yield=*/false));
- } else {
- VISIT(c, expr, elt);
- ADDOP(c, elt_loc, POP_TOP);
- }
- break;
- }
-
- if (elt->kind == Starred_kind) {
- VISIT(c, expr, elt->v.Starred.value);
- ADDOP_I(c, elt_loc, LIST_EXTEND, depth + 1);
- }
- else {
- VISIT(c, expr, elt);
- ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
- }
- break;
- case COMP_SETCOMP:
- assert(!avoid_creation);
- if (elt->kind == Starred_kind) {
- VISIT(c, expr, elt->v.Starred.value);
- ADDOP_I(c, elt_loc, SET_UPDATE, depth + 1);
- }
- else {
- VISIT(c, expr, elt);
- ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
- }
- break;
- case COMP_DICTCOMP:
- assert(!avoid_creation);
- if (val == NULL) {
- /* unpacking (**) case */
- VISIT(c, expr, elt);
- ADDOP_I(c, elt_loc, DICT_UPDATE, depth+1);
- }
- else {
- /* With '{k: v}', k is evaluated before v, so we do
- the same. */
- VISIT(c, expr, elt);
- VISIT(c, expr, val);
- elt_loc = LOCATION(elt->lineno,
- val->end_lineno,
- elt->col_offset,
- val->end_col_offset);
- ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
- }
- break;
- default:
- return ERROR;
+ RETURN_IF_ERROR(codegen_comprehension_generator_helper(c, elt_loc,
depth,
+ elt, val, type,
+
avoid_creation));
+ if (type == COMP_DICTCOMP && val != NULL) {
+ elt_loc = LOCATION(elt->lineno,
+ val->end_lineno,
+ elt->col_offset,
+ val->end_col_offset);
}
}
_______________________________________________
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]