Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv4250 Modified Files: compile.c Log Message: Fix for SF bug [ #471928 ] global made w/nested list comprehensions The symbol table pass didn't have an explicit case for the list_iter node which is used only for a nested list comprehension. As a result, the target of the list comprehension was treated as a use instead of an assignment. Fix is to add a case to symtable_node() to handle list_iter. Also, rework and document a couple of the subtler implementation issues in the symbol table pass. The symtable_node() switch statement depends on falling through the last several cases, in order to handle some of the more complicated nodes like atom. Add a comment explaining the behavior before the first fall through case. Add a comment /* fall through */ at the end of case so that it is explicitly marked as such. Move the for_stmt case out of the fall through logic, which simplifies both for_stmt and default. (The default used the local variable start to skip the first three nodes of a for_stmt when it fell through.) Rename the flag argument to symtable_assign() to def_flag and add a comment explaining its use: The third argument to symatble_assign() is a flag to be passed to symtable_add_def() if it is eventually called. The flag is useful to specify the particular type of assignment that should be recorded, e.g. an assignment caused by import. Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.226 retrieving revision 2.227 diff -C2 -d -r2.226 -r2.227 *** compile.c 2001/10/17 13:22:22 2.226 --- compile.c 2001/10/18 16:15:10 2.227 *************** *** 4992,4996 **** symtable_node(struct symtable *st, node *n) { ! int i, start = 0; loop: --- 4992,4996 ---- symtable_node(struct symtable *st, node *n) { ! int i; loop: *************** *** 5106,5115 **** } goto loop; ! /* watchout for fall-through logic below */ case argument: ! if (NCH(n) == 3) { n = CHILD(n, 2); goto loop; } case listmaker: if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == list_for) { --- 5106,5141 ---- } goto loop; ! case list_iter: ! n = CHILD(n, 0); ! if (TYPE(n) == list_for) { ! st->st_tmpname++; ! symtable_list_comprehension(st, n); ! st->st_tmpname--; ! } else { ! REQ(n, list_if); ! symtable_node(st, CHILD(n, 1)); ! if (NCH(n) == 3) { ! n = CHILD(n, 2); ! goto loop; ! } ! } ! break; ! case for_stmt: ! symtable_assign(st, CHILD(n, 1), 0); ! for (i = 3; i < NCH(n); ++i) ! if (TYPE(CHILD(n, i)) >= single_input) ! symtable_node(st, CHILD(n, i)); ! break; ! /* The remaining cases fall through to default except in ! special circumstances. This requires the individual cases ! to be coded with great care, even though they look like ! rather innocuous. Each case must double-check TYPE(n). ! */ case argument: ! if (TYPE(n) == argument && NCH(n) == 3) { n = CHILD(n, 2); goto loop; } + /* fall through */ case listmaker: if (NCH(n) > 1 && TYPE(CHILD(n, 1)) == list_for) { *************** *** 5118,5123 **** symtable_node(st, CHILD(n, 0)); st->st_tmpname--; ! return; } case atom: if (TYPE(n) == atom && TYPE(CHILD(n, 0)) == NAME) { --- 5144,5150 ---- symtable_node(st, CHILD(n, 0)); st->st_tmpname--; ! break; } + /* fall through */ case atom: if (TYPE(n) == atom && TYPE(CHILD(n, 0)) == NAME) { *************** *** 5125,5139 **** break; } ! case for_stmt: ! if (TYPE(n) == for_stmt) { ! symtable_assign(st, CHILD(n, 1), 0); ! start = 3; ! } default: if (NCH(n) == 1) { n = CHILD(n, 0); goto loop; } ! for (i = start; i < NCH(n); ++i) if (TYPE(CHILD(n, i)) >= single_input) symtable_node(st, CHILD(n, i)); --- 5152,5165 ---- break; } ! /* fall through */ default: + /* Walk over every non-token child with a special case + for one child. + */ if (NCH(n) == 1) { n = CHILD(n, 0); goto loop; } ! for (i = 0; i < NCH(n); ++i) if (TYPE(CHILD(n, i)) >= single_input) symtable_node(st, CHILD(n, i)); *************** *** 5371,5376 **** } static void ! symtable_assign(struct symtable *st, node *n, int flag) { node *tmp; --- 5397,5408 ---- } + /* The third argument to symatble_assign() is a flag to be passed to + symtable_add_def() if it is eventually called. The flag is useful + to specify the particular type of assignment that should be + recorded, e.g. an assignment caused by import. + */ + static void ! symtable_assign(struct symtable *st, node *n, int def_flag) { node *tmp; *************** *** 5404,5408 **** } else { for (i = 0; i < NCH(n); i += 2) ! symtable_assign(st, CHILD(n, i), flag); } return; --- 5436,5440 ---- } else { for (i = 0; i < NCH(n); i += 2) ! symtable_assign(st, CHILD(n, i), def_flag); } return; *************** *** 5416,5420 **** int i; for (i = 0; i < NCH(n); i += 2) ! symtable_assign(st, CHILD(n, i), flag); return; } --- 5448,5452 ---- int i; for (i = 0; i < NCH(n); i += 2) ! symtable_assign(st, CHILD(n, i), def_flag); return; } *************** *** 5427,5431 **** if (strcmp(STR(tmp), "__debug__") == 0) symtable_warn(st, ASSIGN_DEBUG); ! symtable_add_def(st, STR(tmp), DEF_LOCAL | flag); } return; --- 5459,5463 ---- if (strcmp(STR(tmp), "__debug__") == 0) symtable_warn(st, ASSIGN_DEBUG); ! symtable_add_def(st, STR(tmp), DEF_LOCAL | def_flag); } return; *************** *** 5433,5448 **** if (NCH(n) == 3) symtable_add_def(st, STR(CHILD(n, 2)), ! DEF_LOCAL | flag); else symtable_add_def(st, STR(CHILD(CHILD(n, 0), 0)), ! DEF_LOCAL | flag); return; case dotted_name: ! symtable_add_def(st, STR(CHILD(n, 0)), DEF_LOCAL | flag); return; case NAME: ! symtable_add_def(st, STR(n), DEF_LOCAL | flag); return; default: --- 5465,5480 ---- if (NCH(n) == 3) symtable_add_def(st, STR(CHILD(n, 2)), ! DEF_LOCAL | def_flag); else symtable_add_def(st, STR(CHILD(CHILD(n, 0), 0)), ! DEF_LOCAL | def_flag); return; case dotted_name: ! symtable_add_def(st, STR(CHILD(n, 0)), DEF_LOCAL | def_flag); return; case NAME: ! symtable_add_def(st, STR(n), DEF_LOCAL | def_flag); return; default: *************** *** 5457,5461 **** for (i = 0; i < NCH(n); ++i) if (TYPE(CHILD(n, i)) >= single_input) ! symtable_assign(st, CHILD(n, i), flag); } } --- 5489,5493 ---- for (i = 0; i < NCH(n); ++i) if (TYPE(CHILD(n, i)) >= single_input) ! symtable_assign(st, CHILD(n, i), def_flag); } }
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4