Index: Python/ceval.c =================================================================== --- Python/ceval.c (revision 42536) +++ Python/ceval.c (working copy) @@ -998,6 +998,21 @@ SET_SECOND(w); SET_THIRD(v); goto fast_next_opcode; + } else if (oparg == 4) { + x = TOP(); + Py_INCREF(x); + w = SECOND(); + Py_INCREF(w); + v = THIRD(); + Py_INCREF(v); + u = FOURTH(); + Py_INCREF(u); + STACKADJ(4); + SET_TOP(x); + SET_SECOND(w); + SET_THIRD(v); + SET_FOURTH(u); + goto fast_next_opcode; } Py_FatalError("invalid argument to DUP_TOPX" " (bytecode corruption?)"); @@ -4359,3 +4374,4 @@ } #endif + Index: Python/graminit.c =================================================================== --- Python/graminit.c (revision 42536) +++ Python/graminit.c (working copy) @@ -688,23 +688,24 @@ {1, arcs_34_3}, {1, arcs_34_4}, }; -static arc arcs_35_0[6] = { +static arc arcs_35_0[7] = { {84, 1}, {85, 1}, {86, 1}, {87, 1}, + {88, 1}, {17, 1}, - {88, 1}, + {89, 1}, }; static arc arcs_35_1[1] = { {0, 1}, }; static state states_35[2] = { - {6, arcs_35_0}, + {7, arcs_35_0}, {1, arcs_35_1}, }; static arc arcs_36_0[1] = { - {89, 1}, + {90, 1}, }; static arc arcs_36_1[1] = { {26, 2}, @@ -716,8 +717,8 @@ {22, 4}, }; static arc arcs_36_4[3] = { - {90, 1}, - {91, 5}, + {91, 1}, + {92, 5}, {0, 4}, }; static arc arcs_36_5[1] = { @@ -740,7 +741,7 @@ {1, arcs_36_7}, }; static arc arcs_37_0[1] = { - {92, 1}, + {93, 1}, }; static arc arcs_37_1[1] = { {26, 2}, @@ -752,7 +753,7 @@ {22, 4}, }; static arc arcs_37_4[2] = { - {91, 5}, + {92, 5}, {0, 4}, }; static arc arcs_37_5[1] = { @@ -775,7 +776,7 @@ {1, arcs_37_7}, }; static arc arcs_38_0[1] = { - {93, 1}, + {94, 1}, }; static arc arcs_38_1[1] = { {59, 2}, @@ -793,7 +794,7 @@ {22, 6}, }; static arc arcs_38_6[2] = { - {91, 7}, + {92, 7}, {0, 6}, }; static arc arcs_38_7[1] = { @@ -818,7 +819,7 @@ {1, arcs_38_9}, }; static arc arcs_39_0[1] = { - {94, 1}, + {95, 1}, }; static arc arcs_39_1[1] = { {21, 2}, @@ -827,8 +828,8 @@ {22, 3}, }; static arc arcs_39_3[2] = { - {95, 4}, - {96, 5}, + {96, 4}, + {97, 5}, }; static arc arcs_39_4[1] = { {21, 6}, @@ -843,9 +844,9 @@ {22, 9}, }; static arc arcs_39_8[4] = { - {95, 4}, - {91, 10}, - {96, 5}, + {96, 4}, + {92, 10}, + {97, 5}, {0, 8}, }; static arc arcs_39_9[1] = { @@ -858,7 +859,7 @@ {22, 12}, }; static arc arcs_39_12[2] = { - {96, 5}, + {97, 5}, {0, 12}, }; static state states_39[13] = { @@ -877,101 +878,126 @@ {2, arcs_39_12}, }; static arc arcs_40_0[1] = { - {97, 1}, + {98, 1}, }; -static arc arcs_40_1[2] = { +static arc arcs_40_1[1] = { {26, 2}, - {0, 1}, }; static arc arcs_40_2[2] = { - {27, 3}, - {0, 2}, + {99, 3}, + {21, 4}, }; static arc arcs_40_3[1] = { - {26, 4}, + {21, 4}, }; static arc arcs_40_4[1] = { - {0, 4}, + {22, 5}, }; -static state states_40[5] = { +static arc arcs_40_5[1] = { + {0, 5}, +}; +static state states_40[6] = { {1, arcs_40_0}, - {2, arcs_40_1}, + {1, arcs_40_1}, {2, arcs_40_2}, {1, arcs_40_3}, {1, arcs_40_4}, + {1, arcs_40_5}, }; -static arc arcs_41_0[2] = { - {3, 1}, - {2, 2}, +static arc arcs_41_0[1] = { + {19, 1}, }; -static arc arcs_41_1[1] = { - {0, 1}, +static arc arcs_41_1[2] = { + {12, 2}, + {13, 3}, }; static arc arcs_41_2[1] = { - {98, 3}, + {0, 2}, }; static arc arcs_41_3[1] = { - {6, 4}, + {12, 4}, }; static arc arcs_41_4[2] = { - {6, 4}, - {99, 1}, + {27, 3}, + {15, 2}, }; static state states_41[5] = { - {2, arcs_41_0}, - {1, arcs_41_1}, + {1, arcs_41_0}, + {2, arcs_41_1}, {1, arcs_41_2}, {1, arcs_41_3}, {2, arcs_41_4}, }; -static arc arcs_42_0[2] = { +static arc arcs_42_0[1] = { {100, 1}, - {102, 2}, }; static arc arcs_42_1[2] = { - {101, 3}, + {26, 2}, {0, 1}, }; -static arc arcs_42_2[1] = { +static arc arcs_42_2[2] = { + {27, 3}, {0, 2}, }; static arc arcs_42_3[1] = { - {100, 1}, + {26, 4}, }; -static state states_42[4] = { - {2, arcs_42_0}, +static arc arcs_42_4[1] = { + {0, 4}, +}; +static state states_42[5] = { + {1, arcs_42_0}, {2, arcs_42_1}, - {1, arcs_42_2}, + {2, arcs_42_2}, {1, arcs_42_3}, + {1, arcs_42_4}, }; -static arc arcs_43_0[1] = { - {103, 1}, +static arc arcs_43_0[2] = { + {3, 1}, + {2, 2}, }; -static arc arcs_43_1[2] = { - {104, 0}, +static arc arcs_43_1[1] = { {0, 1}, }; -static state states_43[2] = { - {1, arcs_43_0}, - {2, arcs_43_1}, +static arc arcs_43_2[1] = { + {101, 3}, }; +static arc arcs_43_3[1] = { + {6, 4}, +}; +static arc arcs_43_4[2] = { + {6, 4}, + {102, 1}, +}; +static state states_43[5] = { + {2, arcs_43_0}, + {1, arcs_43_1}, + {1, arcs_43_2}, + {1, arcs_43_3}, + {2, arcs_43_4}, +}; static arc arcs_44_0[2] = { - {105, 1}, - {106, 2}, + {103, 1}, + {105, 2}, }; -static arc arcs_44_1[1] = { - {103, 2}, +static arc arcs_44_1[2] = { + {104, 3}, + {0, 1}, }; static arc arcs_44_2[1] = { {0, 2}, }; -static state states_44[3] = { +static arc arcs_44_3[1] = { + {103, 1}, +}; +static state states_44[4] = { {2, arcs_44_0}, - {1, arcs_44_1}, + {2, arcs_44_1}, {1, arcs_44_2}, + {1, arcs_44_3}, }; static arc arcs_45_0[1] = { - {81, 1}, + {106, 1}, }; static arc arcs_45_1[2] = { {107, 0}, @@ -981,61 +1007,65 @@ {1, arcs_45_0}, {2, arcs_45_1}, }; -static arc arcs_46_0[10] = { +static arc arcs_46_0[2] = { {108, 1}, - {109, 1}, - {110, 1}, - {111, 1}, - {112, 1}, - {113, 1}, - {114, 1}, - {82, 1}, - {105, 2}, - {115, 3}, + {109, 2}, }; static arc arcs_46_1[1] = { - {0, 1}, + {106, 2}, }; static arc arcs_46_2[1] = { - {82, 1}, + {0, 2}, }; -static arc arcs_46_3[2] = { - {105, 1}, - {0, 3}, -}; -static state states_46[4] = { - {10, arcs_46_0}, +static state states_46[3] = { + {2, arcs_46_0}, {1, arcs_46_1}, {1, arcs_46_2}, - {2, arcs_46_3}, }; static arc arcs_47_0[1] = { - {116, 1}, + {81, 1}, }; static arc arcs_47_1[2] = { - {117, 0}, + {110, 0}, {0, 1}, }; static state states_47[2] = { {1, arcs_47_0}, {2, arcs_47_1}, }; -static arc arcs_48_0[1] = { - {118, 1}, +static arc arcs_48_0[10] = { + {111, 1}, + {112, 1}, + {113, 1}, + {114, 1}, + {115, 1}, + {116, 1}, + {117, 1}, + {82, 1}, + {108, 2}, + {118, 3}, }; -static arc arcs_48_1[2] = { - {119, 0}, +static arc arcs_48_1[1] = { {0, 1}, }; -static state states_48[2] = { - {1, arcs_48_0}, - {2, arcs_48_1}, +static arc arcs_48_2[1] = { + {82, 1}, }; +static arc arcs_48_3[2] = { + {108, 1}, + {0, 3}, +}; +static state states_48[4] = { + {10, arcs_48_0}, + {1, arcs_48_1}, + {1, arcs_48_2}, + {2, arcs_48_3}, +}; static arc arcs_49_0[1] = { - {120, 1}, + {119, 1}, }; static arc arcs_49_1[2] = { - {121, 0}, + {120, 0}, {0, 1}, }; static state states_49[2] = { @@ -1043,660 +1073,682 @@ {2, arcs_49_1}, }; static arc arcs_50_0[1] = { - {122, 1}, + {121, 1}, }; -static arc arcs_50_1[3] = { - {123, 0}, - {57, 0}, +static arc arcs_50_1[2] = { + {122, 0}, {0, 1}, }; static state states_50[2] = { {1, arcs_50_0}, - {3, arcs_50_1}, + {2, arcs_50_1}, }; static arc arcs_51_0[1] = { - {124, 1}, + {123, 1}, }; -static arc arcs_51_1[3] = { - {125, 0}, - {126, 0}, +static arc arcs_51_1[2] = { + {124, 0}, {0, 1}, }; static state states_51[2] = { {1, arcs_51_0}, - {3, arcs_51_1}, + {2, arcs_51_1}, }; static arc arcs_52_0[1] = { + {125, 1}, +}; +static arc arcs_52_1[3] = { + {126, 0}, + {57, 0}, + {0, 1}, +}; +static state states_52[2] = { + {1, arcs_52_0}, + {3, arcs_52_1}, +}; +static arc arcs_53_0[1] = { {127, 1}, }; -static arc arcs_52_1[5] = { - {28, 0}, +static arc arcs_53_1[3] = { {128, 0}, {129, 0}, - {130, 0}, {0, 1}, }; -static state states_52[2] = { - {1, arcs_52_0}, - {5, arcs_52_1}, +static state states_53[2] = { + {1, arcs_53_0}, + {3, arcs_53_1}, }; -static arc arcs_53_0[4] = { - {125, 1}, - {126, 1}, - {131, 1}, - {132, 2}, +static arc arcs_54_0[1] = { + {130, 1}, }; -static arc arcs_53_1[1] = { - {127, 2}, +static arc arcs_54_1[5] = { + {28, 0}, + {131, 0}, + {132, 0}, + {133, 0}, + {0, 1}, }; -static arc arcs_53_2[1] = { +static state states_54[2] = { + {1, arcs_54_0}, + {5, arcs_54_1}, +}; +static arc arcs_55_0[4] = { + {128, 1}, + {129, 1}, + {134, 1}, + {135, 2}, +}; +static arc arcs_55_1[1] = { + {130, 2}, +}; +static arc arcs_55_2[1] = { {0, 2}, }; -static state states_53[3] = { - {4, arcs_53_0}, - {1, arcs_53_1}, - {1, arcs_53_2}, +static state states_55[3] = { + {4, arcs_55_0}, + {1, arcs_55_1}, + {1, arcs_55_2}, }; -static arc arcs_54_0[1] = { - {133, 1}, +static arc arcs_56_0[1] = { + {136, 1}, }; -static arc arcs_54_1[3] = { - {134, 1}, +static arc arcs_56_1[3] = { + {137, 1}, {29, 2}, {0, 1}, }; -static arc arcs_54_2[1] = { - {127, 3}, +static arc arcs_56_2[1] = { + {130, 3}, }; -static arc arcs_54_3[1] = { +static arc arcs_56_3[1] = { {0, 3}, }; -static state states_54[4] = { - {1, arcs_54_0}, - {3, arcs_54_1}, - {1, arcs_54_2}, - {1, arcs_54_3}, +static state states_56[4] = { + {1, arcs_56_0}, + {3, arcs_56_1}, + {1, arcs_56_2}, + {1, arcs_56_3}, }; -static arc arcs_55_0[7] = { +static arc arcs_57_0[7] = { {13, 1}, - {136, 2}, - {139, 3}, - {142, 4}, + {139, 2}, + {142, 3}, + {145, 4}, {19, 5}, - {144, 5}, - {145, 6}, + {147, 5}, + {148, 6}, }; -static arc arcs_55_1[3] = { +static arc arcs_57_1[3] = { {43, 7}, - {135, 7}, + {138, 7}, {15, 5}, }; -static arc arcs_55_2[2] = { - {137, 8}, - {138, 5}, -}; -static arc arcs_55_3[2] = { - {140, 9}, +static arc arcs_57_2[2] = { + {140, 8}, {141, 5}, }; -static arc arcs_55_4[1] = { - {143, 10}, +static arc arcs_57_3[2] = { + {143, 9}, + {144, 5}, }; -static arc arcs_55_5[1] = { +static arc arcs_57_4[1] = { + {146, 10}, +}; +static arc arcs_57_5[1] = { {0, 5}, }; -static arc arcs_55_6[2] = { - {145, 6}, +static arc arcs_57_6[2] = { + {148, 6}, {0, 6}, }; -static arc arcs_55_7[1] = { +static arc arcs_57_7[1] = { {15, 5}, }; -static arc arcs_55_8[1] = { - {138, 5}, -}; -static arc arcs_55_9[1] = { +static arc arcs_57_8[1] = { {141, 5}, }; -static arc arcs_55_10[1] = { - {142, 5}, +static arc arcs_57_9[1] = { + {144, 5}, }; -static state states_55[11] = { - {7, arcs_55_0}, - {3, arcs_55_1}, - {2, arcs_55_2}, - {2, arcs_55_3}, - {1, arcs_55_4}, - {1, arcs_55_5}, - {2, arcs_55_6}, - {1, arcs_55_7}, - {1, arcs_55_8}, - {1, arcs_55_9}, - {1, arcs_55_10}, +static arc arcs_57_10[1] = { + {145, 5}, }; -static arc arcs_56_0[1] = { +static state states_57[11] = { + {7, arcs_57_0}, + {3, arcs_57_1}, + {2, arcs_57_2}, + {2, arcs_57_3}, + {1, arcs_57_4}, + {1, arcs_57_5}, + {2, arcs_57_6}, + {1, arcs_57_7}, + {1, arcs_57_8}, + {1, arcs_57_9}, + {1, arcs_57_10}, +}; +static arc arcs_58_0[1] = { {26, 1}, }; -static arc arcs_56_1[3] = { - {146, 2}, +static arc arcs_58_1[3] = { + {149, 2}, {27, 3}, {0, 1}, }; -static arc arcs_56_2[1] = { +static arc arcs_58_2[1] = { {0, 2}, }; -static arc arcs_56_3[2] = { +static arc arcs_58_3[2] = { {26, 4}, {0, 3}, }; -static arc arcs_56_4[2] = { +static arc arcs_58_4[2] = { {27, 3}, {0, 4}, }; -static state states_56[5] = { - {1, arcs_56_0}, - {3, arcs_56_1}, - {1, arcs_56_2}, - {2, arcs_56_3}, - {2, arcs_56_4}, +static state states_58[5] = { + {1, arcs_58_0}, + {3, arcs_58_1}, + {1, arcs_58_2}, + {2, arcs_58_3}, + {2, arcs_58_4}, }; -static arc arcs_57_0[1] = { +static arc arcs_59_0[1] = { {26, 1}, }; -static arc arcs_57_1[3] = { - {147, 2}, +static arc arcs_59_1[3] = { + {150, 2}, {27, 3}, {0, 1}, }; -static arc arcs_57_2[1] = { +static arc arcs_59_2[1] = { {0, 2}, }; -static arc arcs_57_3[2] = { +static arc arcs_59_3[2] = { {26, 4}, {0, 3}, }; -static arc arcs_57_4[2] = { +static arc arcs_59_4[2] = { {27, 3}, {0, 4}, }; -static state states_57[5] = { - {1, arcs_57_0}, - {3, arcs_57_1}, - {1, arcs_57_2}, - {2, arcs_57_3}, - {2, arcs_57_4}, +static state states_59[5] = { + {1, arcs_59_0}, + {3, arcs_59_1}, + {1, arcs_59_2}, + {2, arcs_59_3}, + {2, arcs_59_4}, }; -static arc arcs_58_0[1] = { - {148, 1}, +static arc arcs_60_0[1] = { + {151, 1}, }; -static arc arcs_58_1[2] = { +static arc arcs_60_1[2] = { {23, 2}, {21, 3}, }; -static arc arcs_58_2[1] = { +static arc arcs_60_2[1] = { {21, 3}, }; -static arc arcs_58_3[1] = { +static arc arcs_60_3[1] = { {26, 4}, }; -static arc arcs_58_4[1] = { +static arc arcs_60_4[1] = { {0, 4}, }; -static state states_58[5] = { - {1, arcs_58_0}, - {2, arcs_58_1}, - {1, arcs_58_2}, - {1, arcs_58_3}, - {1, arcs_58_4}, +static state states_60[5] = { + {1, arcs_60_0}, + {2, arcs_60_1}, + {1, arcs_60_2}, + {1, arcs_60_3}, + {1, arcs_60_4}, }; -static arc arcs_59_0[3] = { +static arc arcs_61_0[3] = { {13, 1}, - {136, 2}, + {139, 2}, {75, 3}, }; -static arc arcs_59_1[2] = { +static arc arcs_61_1[2] = { {14, 4}, {15, 5}, }; -static arc arcs_59_2[1] = { - {149, 6}, +static arc arcs_61_2[1] = { + {152, 6}, }; -static arc arcs_59_3[1] = { +static arc arcs_61_3[1] = { {19, 5}, }; -static arc arcs_59_4[1] = { +static arc arcs_61_4[1] = { {15, 5}, }; -static arc arcs_59_5[1] = { +static arc arcs_61_5[1] = { {0, 5}, }; -static arc arcs_59_6[1] = { - {138, 5}, +static arc arcs_61_6[1] = { + {141, 5}, }; -static state states_59[7] = { - {3, arcs_59_0}, - {2, arcs_59_1}, - {1, arcs_59_2}, - {1, arcs_59_3}, - {1, arcs_59_4}, - {1, arcs_59_5}, - {1, arcs_59_6}, +static state states_61[7] = { + {3, arcs_61_0}, + {2, arcs_61_1}, + {1, arcs_61_2}, + {1, arcs_61_3}, + {1, arcs_61_4}, + {1, arcs_61_5}, + {1, arcs_61_6}, }; -static arc arcs_60_0[1] = { - {150, 1}, +static arc arcs_62_0[1] = { + {153, 1}, }; -static arc arcs_60_1[2] = { +static arc arcs_62_1[2] = { {27, 2}, {0, 1}, }; -static arc arcs_60_2[2] = { - {150, 1}, +static arc arcs_62_2[2] = { + {153, 1}, {0, 2}, }; -static state states_60[3] = { - {1, arcs_60_0}, - {2, arcs_60_1}, - {2, arcs_60_2}, +static state states_62[3] = { + {1, arcs_62_0}, + {2, arcs_62_1}, + {2, arcs_62_2}, }; -static arc arcs_61_0[3] = { +static arc arcs_63_0[3] = { {75, 1}, {26, 2}, {21, 3}, }; -static arc arcs_61_1[1] = { +static arc arcs_63_1[1] = { {75, 4}, }; -static arc arcs_61_2[2] = { +static arc arcs_63_2[2] = { {21, 3}, {0, 2}, }; -static arc arcs_61_3[3] = { +static arc arcs_63_3[3] = { {26, 5}, - {151, 6}, + {154, 6}, {0, 3}, }; -static arc arcs_61_4[1] = { +static arc arcs_63_4[1] = { {75, 6}, }; -static arc arcs_61_5[2] = { - {151, 6}, +static arc arcs_63_5[2] = { + {154, 6}, {0, 5}, }; -static arc arcs_61_6[1] = { +static arc arcs_63_6[1] = { {0, 6}, }; -static state states_61[7] = { - {3, arcs_61_0}, - {1, arcs_61_1}, - {2, arcs_61_2}, - {3, arcs_61_3}, - {1, arcs_61_4}, - {2, arcs_61_5}, - {1, arcs_61_6}, +static state states_63[7] = { + {3, arcs_63_0}, + {1, arcs_63_1}, + {2, arcs_63_2}, + {3, arcs_63_3}, + {1, arcs_63_4}, + {2, arcs_63_5}, + {1, arcs_63_6}, }; -static arc arcs_62_0[1] = { +static arc arcs_64_0[1] = { {21, 1}, }; -static arc arcs_62_1[2] = { +static arc arcs_64_1[2] = { {26, 2}, {0, 1}, }; -static arc arcs_62_2[1] = { +static arc arcs_64_2[1] = { {0, 2}, }; -static state states_62[3] = { - {1, arcs_62_0}, - {2, arcs_62_1}, - {1, arcs_62_2}, +static state states_64[3] = { + {1, arcs_64_0}, + {2, arcs_64_1}, + {1, arcs_64_2}, }; -static arc arcs_63_0[1] = { +static arc arcs_65_0[1] = { {81, 1}, }; -static arc arcs_63_1[2] = { +static arc arcs_65_1[2] = { {27, 2}, {0, 1}, }; -static arc arcs_63_2[2] = { +static arc arcs_65_2[2] = { {81, 1}, {0, 2}, }; -static state states_63[3] = { - {1, arcs_63_0}, - {2, arcs_63_1}, - {2, arcs_63_2}, +static state states_65[3] = { + {1, arcs_65_0}, + {2, arcs_65_1}, + {2, arcs_65_2}, }; -static arc arcs_64_0[1] = { +static arc arcs_66_0[1] = { {26, 1}, }; -static arc arcs_64_1[2] = { +static arc arcs_66_1[2] = { {27, 2}, {0, 1}, }; -static arc arcs_64_2[2] = { +static arc arcs_66_2[2] = { {26, 1}, {0, 2}, }; -static state states_64[3] = { - {1, arcs_64_0}, - {2, arcs_64_1}, - {2, arcs_64_2}, +static state states_66[3] = { + {1, arcs_66_0}, + {2, arcs_66_1}, + {2, arcs_66_2}, }; -static arc arcs_65_0[1] = { +static arc arcs_67_0[1] = { {26, 1}, }; -static arc arcs_65_1[2] = { +static arc arcs_67_1[2] = { {27, 2}, {0, 1}, }; -static arc arcs_65_2[1] = { +static arc arcs_67_2[1] = { {26, 3}, }; -static arc arcs_65_3[2] = { +static arc arcs_67_3[2] = { {27, 4}, {0, 3}, }; -static arc arcs_65_4[2] = { +static arc arcs_67_4[2] = { {26, 3}, {0, 4}, }; -static state states_65[5] = { - {1, arcs_65_0}, - {2, arcs_65_1}, - {1, arcs_65_2}, - {2, arcs_65_3}, - {2, arcs_65_4}, +static state states_67[5] = { + {1, arcs_67_0}, + {2, arcs_67_1}, + {1, arcs_67_2}, + {2, arcs_67_3}, + {2, arcs_67_4}, }; -static arc arcs_66_0[1] = { +static arc arcs_68_0[1] = { {26, 1}, }; -static arc arcs_66_1[1] = { +static arc arcs_68_1[1] = { {21, 2}, }; -static arc arcs_66_2[1] = { +static arc arcs_68_2[1] = { {26, 3}, }; -static arc arcs_66_3[2] = { +static arc arcs_68_3[2] = { {27, 4}, {0, 3}, }; -static arc arcs_66_4[2] = { +static arc arcs_68_4[2] = { {26, 1}, {0, 4}, }; -static state states_66[5] = { - {1, arcs_66_0}, - {1, arcs_66_1}, - {1, arcs_66_2}, - {2, arcs_66_3}, - {2, arcs_66_4}, +static state states_68[5] = { + {1, arcs_68_0}, + {1, arcs_68_1}, + {1, arcs_68_2}, + {2, arcs_68_3}, + {2, arcs_68_4}, }; -static arc arcs_67_0[1] = { - {153, 1}, +static arc arcs_69_0[1] = { + {156, 1}, }; -static arc arcs_67_1[1] = { +static arc arcs_69_1[1] = { {19, 2}, }; -static arc arcs_67_2[2] = { +static arc arcs_69_2[2] = { {13, 3}, {21, 4}, }; -static arc arcs_67_3[2] = { +static arc arcs_69_3[2] = { {9, 5}, {15, 6}, }; -static arc arcs_67_4[1] = { +static arc arcs_69_4[1] = { {22, 7}, }; -static arc arcs_67_5[1] = { +static arc arcs_69_5[1] = { {15, 6}, }; -static arc arcs_67_6[1] = { +static arc arcs_69_6[1] = { {21, 4}, }; -static arc arcs_67_7[1] = { +static arc arcs_69_7[1] = { {0, 7}, }; -static state states_67[8] = { - {1, arcs_67_0}, - {1, arcs_67_1}, - {2, arcs_67_2}, - {2, arcs_67_3}, - {1, arcs_67_4}, - {1, arcs_67_5}, - {1, arcs_67_6}, - {1, arcs_67_7}, +static state states_69[8] = { + {1, arcs_69_0}, + {1, arcs_69_1}, + {2, arcs_69_2}, + {2, arcs_69_3}, + {1, arcs_69_4}, + {1, arcs_69_5}, + {1, arcs_69_6}, + {1, arcs_69_7}, }; -static arc arcs_68_0[3] = { - {154, 1}, +static arc arcs_70_0[3] = { + {157, 1}, {28, 2}, {29, 3}, }; -static arc arcs_68_1[2] = { +static arc arcs_70_1[2] = { {27, 4}, {0, 1}, }; -static arc arcs_68_2[1] = { +static arc arcs_70_2[1] = { {26, 5}, }; -static arc arcs_68_3[1] = { +static arc arcs_70_3[1] = { {26, 6}, }; -static arc arcs_68_4[4] = { - {154, 1}, +static arc arcs_70_4[4] = { + {157, 1}, {28, 2}, {29, 3}, {0, 4}, }; -static arc arcs_68_5[2] = { +static arc arcs_70_5[2] = { {27, 7}, {0, 5}, }; -static arc arcs_68_6[1] = { +static arc arcs_70_6[1] = { {0, 6}, }; -static arc arcs_68_7[1] = { +static arc arcs_70_7[1] = { {29, 3}, }; -static state states_68[8] = { - {3, arcs_68_0}, - {2, arcs_68_1}, - {1, arcs_68_2}, - {1, arcs_68_3}, - {4, arcs_68_4}, - {2, arcs_68_5}, - {1, arcs_68_6}, - {1, arcs_68_7}, +static state states_70[8] = { + {3, arcs_70_0}, + {2, arcs_70_1}, + {1, arcs_70_2}, + {1, arcs_70_3}, + {4, arcs_70_4}, + {2, arcs_70_5}, + {1, arcs_70_6}, + {1, arcs_70_7}, }; -static arc arcs_69_0[1] = { +static arc arcs_71_0[1] = { {26, 1}, }; -static arc arcs_69_1[3] = { - {147, 2}, +static arc arcs_71_1[3] = { + {150, 2}, {25, 3}, {0, 1}, }; -static arc arcs_69_2[1] = { +static arc arcs_71_2[1] = { {0, 2}, }; -static arc arcs_69_3[1] = { +static arc arcs_71_3[1] = { {26, 4}, }; -static arc arcs_69_4[2] = { +static arc arcs_71_4[2] = { {13, 5}, {0, 4}, }; -static arc arcs_69_5[1] = { - {147, 6}, +static arc arcs_71_5[1] = { + {150, 6}, }; -static arc arcs_69_6[1] = { +static arc arcs_71_6[1] = { {15, 2}, }; -static state states_69[7] = { - {1, arcs_69_0}, - {3, arcs_69_1}, - {1, arcs_69_2}, - {1, arcs_69_3}, - {2, arcs_69_4}, - {1, arcs_69_5}, - {1, arcs_69_6}, +static state states_71[7] = { + {1, arcs_71_0}, + {3, arcs_71_1}, + {1, arcs_71_2}, + {1, arcs_71_3}, + {2, arcs_71_4}, + {1, arcs_71_5}, + {1, arcs_71_6}, }; -static arc arcs_70_0[2] = { - {146, 1}, - {156, 1}, +static arc arcs_72_0[2] = { + {149, 1}, + {159, 1}, }; -static arc arcs_70_1[1] = { +static arc arcs_72_1[1] = { {0, 1}, }; -static state states_70[2] = { - {2, arcs_70_0}, - {1, arcs_70_1}, +static state states_72[2] = { + {2, arcs_72_0}, + {1, arcs_72_1}, }; -static arc arcs_71_0[1] = { - {93, 1}, +static arc arcs_73_0[1] = { + {94, 1}, }; -static arc arcs_71_1[1] = { +static arc arcs_73_1[1] = { {59, 2}, }; -static arc arcs_71_2[1] = { +static arc arcs_73_2[1] = { {82, 3}, }; -static arc arcs_71_3[1] = { - {152, 4}, +static arc arcs_73_3[1] = { + {155, 4}, }; -static arc arcs_71_4[2] = { - {155, 5}, +static arc arcs_73_4[2] = { + {158, 5}, {0, 4}, }; -static arc arcs_71_5[1] = { +static arc arcs_73_5[1] = { {0, 5}, }; -static state states_71[6] = { - {1, arcs_71_0}, - {1, arcs_71_1}, - {1, arcs_71_2}, - {1, arcs_71_3}, - {2, arcs_71_4}, - {1, arcs_71_5}, +static state states_73[6] = { + {1, arcs_73_0}, + {1, arcs_73_1}, + {1, arcs_73_2}, + {1, arcs_73_3}, + {2, arcs_73_4}, + {1, arcs_73_5}, }; -static arc arcs_72_0[1] = { - {89, 1}, +static arc arcs_74_0[1] = { + {90, 1}, }; -static arc arcs_72_1[1] = { +static arc arcs_74_1[1] = { {26, 2}, }; -static arc arcs_72_2[2] = { - {155, 3}, +static arc arcs_74_2[2] = { + {158, 3}, {0, 2}, }; -static arc arcs_72_3[1] = { +static arc arcs_74_3[1] = { {0, 3}, }; -static state states_72[4] = { - {1, arcs_72_0}, - {1, arcs_72_1}, - {2, arcs_72_2}, - {1, arcs_72_3}, +static state states_74[4] = { + {1, arcs_74_0}, + {1, arcs_74_1}, + {2, arcs_74_2}, + {1, arcs_74_3}, }; -static arc arcs_73_0[2] = { - {147, 1}, - {158, 1}, +static arc arcs_75_0[2] = { + {150, 1}, + {161, 1}, }; -static arc arcs_73_1[1] = { +static arc arcs_75_1[1] = { {0, 1}, }; -static state states_73[2] = { - {2, arcs_73_0}, - {1, arcs_73_1}, +static state states_75[2] = { + {2, arcs_75_0}, + {1, arcs_75_1}, }; -static arc arcs_74_0[1] = { - {93, 1}, +static arc arcs_76_0[1] = { + {94, 1}, }; -static arc arcs_74_1[1] = { +static arc arcs_76_1[1] = { {59, 2}, }; -static arc arcs_74_2[1] = { +static arc arcs_76_2[1] = { {82, 3}, }; -static arc arcs_74_3[1] = { +static arc arcs_76_3[1] = { {26, 4}, }; -static arc arcs_74_4[2] = { - {157, 5}, +static arc arcs_76_4[2] = { + {160, 5}, {0, 4}, }; -static arc arcs_74_5[1] = { +static arc arcs_76_5[1] = { {0, 5}, }; -static state states_74[6] = { - {1, arcs_74_0}, - {1, arcs_74_1}, - {1, arcs_74_2}, - {1, arcs_74_3}, - {2, arcs_74_4}, - {1, arcs_74_5}, +static state states_76[6] = { + {1, arcs_76_0}, + {1, arcs_76_1}, + {1, arcs_76_2}, + {1, arcs_76_3}, + {2, arcs_76_4}, + {1, arcs_76_5}, }; -static arc arcs_75_0[1] = { - {89, 1}, +static arc arcs_77_0[1] = { + {90, 1}, }; -static arc arcs_75_1[1] = { +static arc arcs_77_1[1] = { {26, 2}, }; -static arc arcs_75_2[2] = { - {157, 3}, +static arc arcs_77_2[2] = { + {160, 3}, {0, 2}, }; -static arc arcs_75_3[1] = { +static arc arcs_77_3[1] = { {0, 3}, }; -static state states_75[4] = { - {1, arcs_75_0}, - {1, arcs_75_1}, - {2, arcs_75_2}, - {1, arcs_75_3}, +static state states_77[4] = { + {1, arcs_77_0}, + {1, arcs_77_1}, + {2, arcs_77_2}, + {1, arcs_77_3}, }; -static arc arcs_76_0[1] = { +static arc arcs_78_0[1] = { {26, 1}, }; -static arc arcs_76_1[2] = { +static arc arcs_78_1[2] = { {27, 0}, {0, 1}, }; -static state states_76[2] = { - {1, arcs_76_0}, - {2, arcs_76_1}, +static state states_78[2] = { + {1, arcs_78_0}, + {2, arcs_78_1}, }; -static arc arcs_77_0[1] = { +static arc arcs_79_0[1] = { {19, 1}, }; -static arc arcs_77_1[1] = { +static arc arcs_79_1[1] = { {0, 1}, }; -static state states_77[2] = { - {1, arcs_77_0}, - {1, arcs_77_1}, +static state states_79[2] = { + {1, arcs_79_0}, + {1, arcs_79_1}, }; -static arc arcs_78_0[1] = { - {160, 1}, +static arc arcs_80_0[1] = { + {163, 1}, }; -static arc arcs_78_1[2] = { +static arc arcs_80_1[2] = { {9, 2}, {0, 1}, }; -static arc arcs_78_2[1] = { +static arc arcs_80_2[1] = { {0, 2}, }; -static state states_78[3] = { - {1, arcs_78_0}, - {2, arcs_78_1}, - {1, arcs_78_2}, +static state states_80[3] = { + {1, arcs_80_0}, + {2, arcs_80_1}, + {1, arcs_80_2}, }; -static dfa dfas[79] = { +static dfa dfas[81] = { {256, "single_input", 0, 3, states_0, - "\004\050\014\000\000\000\000\025\074\205\011\162\000\002\000\140\010\111\023\002\001"}, + "\004\050\014\000\000\000\000\025\074\205\011\344\004\020\000\000\103\110\232\020\010"}, {257, "file_input", 0, 2, states_1, - "\204\050\014\000\000\000\000\025\074\205\011\162\000\002\000\140\010\111\023\002\001"}, + "\204\050\014\000\000\000\000\025\074\205\011\344\004\020\000\000\103\110\232\020\010"}, {258, "eval_input", 0, 3, states_2, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, {259, "decorator", 0, 7, states_3, "\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {260, "decorators", 0, 2, states_4, @@ -1712,13 +1764,13 @@ {265, "fplist", 0, 3, states_9, "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {266, "stmt", 0, 2, states_10, - "\000\050\014\000\000\000\000\025\074\205\011\162\000\002\000\140\010\111\023\002\001"}, + "\000\050\014\000\000\000\000\025\074\205\011\344\004\020\000\000\103\110\232\020\010"}, {267, "simple_stmt", 0, 4, states_11, - "\000\040\010\000\000\000\000\025\074\205\011\000\000\002\000\140\010\111\023\000\001"}, + "\000\040\010\000\000\000\000\025\074\205\011\000\000\020\000\000\103\110\232\000\010"}, {268, "small_stmt", 0, 2, states_12, - "\000\040\010\000\000\000\000\025\074\205\011\000\000\002\000\140\010\111\023\000\001"}, + "\000\040\010\000\000\000\000\025\074\205\011\000\000\020\000\000\103\110\232\000\010"}, {269, "expr_stmt", 0, 6, states_13, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, {270, "augassign", 0, 2, states_14, "\000\000\000\000\000\360\377\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {271, "print_stmt", 0, 9, states_15, @@ -1728,7 +1780,7 @@ {273, "pass_stmt", 0, 2, states_17, "\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000\000"}, {274, "flow_stmt", 0, 2, states_18, - "\000\000\000\000\000\000\000\000\074\000\000\000\000\000\000\000\000\000\000\000\001"}, + "\000\000\000\000\000\000\000\000\074\000\000\000\000\000\000\000\000\000\000\000\010"}, {275, "break_stmt", 0, 2, states_19, "\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000\000"}, {276, "continue_stmt", 0, 2, states_20, @@ -1736,7 +1788,7 @@ {277, "return_stmt", 0, 3, states_21, "\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000\000\000\000"}, {278, "yield_stmt", 0, 2, states_22, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010"}, {279, "raise_stmt", 0, 7, states_23, "\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000"}, {280, "import_stmt", 0, 2, states_24, @@ -1762,95 +1814,99 @@ {290, "assert_stmt", 0, 5, states_34, "\000\000\000\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\000\000\000"}, {291, "compound_stmt", 0, 2, states_35, - "\000\010\004\000\000\000\000\000\000\000\000\162\000\000\000\000\000\000\000\002\000"}, + "\000\010\004\000\000\000\000\000\000\000\000\344\004\000\000\000\000\000\000\020\000"}, {292, "if_stmt", 0, 8, states_36, - "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"}, {293, "while_stmt", 0, 8, states_37, - "\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, {294, "for_stmt", 0, 10, states_38, - "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, + "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"}, {295, "try_stmt", 0, 13, states_39, + "\000\000\000\000\000\000\000\000\000\000\000\200\000\000\000\000\000\000\000\000\000"}, + {296, "with_stmt", 0, 6, states_40, + "\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000"}, + {297, "with_var", 0, 5, states_41, + "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {298, "except_clause", 0, 5, states_42, + "\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000\000\000\000\000\000\000"}, + {299, "suite", 0, 5, states_43, + "\004\040\010\000\000\000\000\025\074\205\011\000\000\020\000\000\103\110\232\000\010"}, + {300, "test", 0, 4, states_44, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, + {301, "and_test", 0, 2, states_45, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\032\000\000"}, + {302, "not_test", 0, 3, states_46, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\032\000\000"}, + {303, "comparison", 0, 2, states_47, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\103\110\032\000\000"}, + {304, "comp_op", 0, 4, states_48, + "\000\000\000\000\000\000\000\000\000\000\004\000\000\220\177\000\000\000\000\000\000"}, + {305, "expr", 0, 2, states_49, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\103\110\032\000\000"}, + {306, "xor_expr", 0, 2, states_50, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\103\110\032\000\000"}, + {307, "and_expr", 0, 2, states_51, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\103\110\032\000\000"}, + {308, "shift_expr", 0, 2, states_52, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\103\110\032\000\000"}, + {309, "arith_expr", 0, 2, states_53, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\103\110\032\000\000"}, + {310, "term", 0, 2, states_54, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\103\110\032\000\000"}, + {311, "factor", 0, 3, states_55, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\103\110\032\000\000"}, + {312, "power", 0, 4, states_56, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\110\032\000\000"}, + {313, "atom", 0, 11, states_57, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\110\032\000\000"}, + {314, "listmaker", 0, 5, states_58, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, + {315, "testlist_gexp", 0, 5, states_59, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, + {316, "lambdef", 0, 5, states_60, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\200\000\000"}, + {317, "trailer", 0, 7, states_61, + "\000\040\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\010\000\000\000"}, + {318, "subscriptlist", 0, 3, states_62, + "\000\040\050\000\000\000\000\000\000\010\000\000\000\020\000\000\103\110\232\000\000"}, + {319, "subscript", 0, 7, states_63, + "\000\040\050\000\000\000\000\000\000\010\000\000\000\020\000\000\103\110\232\000\000"}, + {320, "sliceop", 0, 3, states_64, + "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, + {321, "exprlist", 0, 3, states_65, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\103\110\032\000\000"}, + {322, "testlist", 0, 3, states_66, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, + {323, "testlist_safe", 0, 5, states_67, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, + {324, "dictmaker", 0, 5, states_68, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, + {325, "classdef", 0, 8, states_69, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000"}, + {326, "arglist", 0, 8, states_70, + "\000\040\010\060\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, + {327, "argument", 0, 7, states_71, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, + {328, "list_iter", 0, 2, states_72, + "\000\000\000\000\000\000\000\000\000\000\000\104\000\000\000\000\000\000\000\000\000"}, + {329, "list_for", 0, 6, states_73, "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"}, - {296, "except_clause", 0, 5, states_40, - "\000\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000"}, - {297, "suite", 0, 5, states_41, - "\004\040\010\000\000\000\000\025\074\205\011\000\000\002\000\140\010\111\023\000\001"}, - {298, "test", 0, 4, states_42, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, - {299, "and_test", 0, 2, states_43, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\003\000\000"}, - {300, "not_test", 0, 3, states_44, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\003\000\000"}, - {301, "comparison", 0, 2, states_45, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, - {302, "comp_op", 0, 4, states_46, - "\000\000\000\000\000\000\000\000\000\000\004\000\000\362\017\000\000\000\000\000\000"}, - {303, "expr", 0, 2, states_47, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, - {304, "xor_expr", 0, 2, states_48, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, - {305, "and_expr", 0, 2, states_49, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, - {306, "shift_expr", 0, 2, states_50, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, - {307, "arith_expr", 0, 2, states_51, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, - {308, "term", 0, 2, states_52, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, - {309, "factor", 0, 3, states_53, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, - {310, "power", 0, 4, states_54, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\111\003\000\000"}, - {311, "atom", 0, 11, states_55, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\111\003\000\000"}, - {312, "listmaker", 0, 5, states_56, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, - {313, "testlist_gexp", 0, 5, states_57, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, - {314, "lambdef", 0, 5, states_58, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\020\000\000"}, - {315, "trailer", 0, 7, states_59, - "\000\040\000\000\000\000\000\000\000\010\000\000\000\000\000\000\000\001\000\000\000"}, - {316, "subscriptlist", 0, 3, states_60, - "\000\040\050\000\000\000\000\000\000\010\000\000\000\002\000\140\010\111\023\000\000"}, - {317, "subscript", 0, 7, states_61, - "\000\040\050\000\000\000\000\000\000\010\000\000\000\002\000\140\010\111\023\000\000"}, - {318, "sliceop", 0, 3, states_62, - "\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {319, "exprlist", 0, 3, states_63, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\000\000\140\010\111\003\000\000"}, - {320, "testlist", 0, 3, states_64, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, - {321, "testlist_safe", 0, 5, states_65, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, - {322, "dictmaker", 0, 5, states_66, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, - {323, "classdef", 0, 8, states_67, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\000"}, - {324, "arglist", 0, 8, states_68, - "\000\040\010\060\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, - {325, "argument", 0, 7, states_69, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, - {326, "list_iter", 0, 2, states_70, - "\000\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000\000"}, - {327, "list_for", 0, 6, states_71, - "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, - {328, "list_if", 0, 4, states_72, - "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, - {329, "gen_iter", 0, 2, states_73, - "\000\000\000\000\000\000\000\000\000\000\000\042\000\000\000\000\000\000\000\000\000"}, - {330, "gen_for", 0, 6, states_74, - "\000\000\000\000\000\000\000\000\000\000\000\040\000\000\000\000\000\000\000\000\000"}, - {331, "gen_if", 0, 4, states_75, - "\000\000\000\000\000\000\000\000\000\000\000\002\000\000\000\000\000\000\000\000\000"}, - {332, "testlist1", 0, 2, states_76, - "\000\040\010\000\000\000\000\000\000\000\000\000\000\002\000\140\010\111\023\000\000"}, - {333, "encoding_decl", 0, 2, states_77, + {330, "list_if", 0, 4, states_74, + "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"}, + {331, "gen_iter", 0, 2, states_75, + "\000\000\000\000\000\000\000\000\000\000\000\104\000\000\000\000\000\000\000\000\000"}, + {332, "gen_for", 0, 6, states_76, + "\000\000\000\000\000\000\000\000\000\000\000\100\000\000\000\000\000\000\000\000\000"}, + {333, "gen_if", 0, 4, states_77, + "\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000"}, + {334, "testlist1", 0, 2, states_78, + "\000\040\010\000\000\000\000\000\000\000\000\000\000\020\000\000\103\110\232\000\000"}, + {335, "encoding_decl", 0, 2, states_79, "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"}, - {334, "yield_expr", 0, 3, states_78, - "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001"}, + {336, "yield_expr", 0, 3, states_80, + "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\010"}, }; -static label labels[161] = { +static label labels[164] = { {0, "EMPTY"}, {256, 0}, {4, 0}, @@ -1860,12 +1916,12 @@ {266, 0}, {0, 0}, {258, 0}, - {320, 0}, + {322, 0}, {259, 0}, {50, 0}, {287, 0}, {7, 0}, - {324, 0}, + {326, 0}, {8, 0}, {260, 0}, {261, 0}, @@ -1873,11 +1929,11 @@ {1, 0}, {262, 0}, {11, 0}, - {297, 0}, + {299, 0}, {263, 0}, {264, 0}, {22, 0}, - {298, 0}, + {300, 0}, {12, 0}, {16, 0}, {36, 0}, @@ -1894,7 +1950,7 @@ {289, 0}, {290, 0}, {270, 0}, - {334, 0}, + {336, 0}, {37, 0}, {38, 0}, {39, 0}, @@ -1910,7 +1966,7 @@ {1, "print"}, {35, 0}, {1, "del"}, - {319, 0}, + {321, 0}, {1, "pass"}, {275, 0}, {276, 0}, @@ -1932,33 +1988,36 @@ {284, 0}, {1, "global"}, {1, "exec"}, - {303, 0}, + {305, 0}, {1, "in"}, {1, "assert"}, {292, 0}, {293, 0}, {294, 0}, {295, 0}, - {323, 0}, + {296, 0}, + {325, 0}, {1, "if"}, {1, "elif"}, {1, "else"}, {1, "while"}, {1, "for"}, {1, "try"}, - {296, 0}, + {298, 0}, {1, "finally"}, + {1, "with"}, + {297, 0}, {1, "except"}, {5, 0}, {6, 0}, - {299, 0}, + {301, 0}, {1, "or"}, - {314, 0}, - {300, 0}, + {316, 0}, + {302, 0}, {1, "and"}, {1, "not"}, - {301, 0}, - {302, 0}, + {303, 0}, + {304, 0}, {20, 0}, {21, 0}, {28, 0}, @@ -1967,55 +2026,55 @@ {29, 0}, {29, 0}, {1, "is"}, - {304, 0}, + {306, 0}, {18, 0}, - {305, 0}, + {307, 0}, {33, 0}, - {306, 0}, + {308, 0}, {19, 0}, - {307, 0}, + {309, 0}, {34, 0}, - {308, 0}, + {310, 0}, {14, 0}, {15, 0}, - {309, 0}, + {311, 0}, {17, 0}, {24, 0}, {48, 0}, {32, 0}, - {310, 0}, - {311, 0}, + {312, 0}, + {313, 0}, + {317, 0}, {315, 0}, - {313, 0}, {9, 0}, - {312, 0}, + {314, 0}, {10, 0}, {26, 0}, - {322, 0}, + {324, 0}, {27, 0}, {25, 0}, - {332, 0}, + {334, 0}, {2, 0}, {3, 0}, - {327, 0}, - {330, 0}, + {329, 0}, + {332, 0}, {1, "lambda"}, - {316, 0}, - {317, 0}, {318, 0}, - {321, 0}, + {319, 0}, + {320, 0}, + {323, 0}, {1, "class"}, - {325, 0}, - {326, 0}, + {327, 0}, {328, 0}, - {329, 0}, + {330, 0}, {331, 0}, {333, 0}, + {335, 0}, {1, "yield"}, }; grammar _PyParser_Grammar = { - 79, + 81, dfas, - {161, labels}, + {164, labels}, 256 }; Index: Python/ast.c =================================================================== --- Python/ast.c (revision 42536) +++ Python/ast.c (working copy) @@ -2660,7 +2660,91 @@ return TryFinally(body, finally, LINENO(n), c->c_arena); } +static expr_ty +with_var_name(struct compiling *c, const node *n, int child_num) +{ + const node *child = CHILD(n, child_num); + expr_ty result; + + REQ(child, dotted_name); + if (strcmp(STR(CHILD(child, 0)), "None") == 0) { + ast_error(child, "assignment to None"); + return NULL; + } + result = ast_for_dotted_name(c, child); + return set_context(result, Store, n) != -1 ? result : NULL; +} + +static expr_ty +ast_for_with_var(struct compiling *c, const node *n) +{ + int i, first_child = 1, len = 1; /* The standard case is "as NAME" */ + asdl_seq *variables; + char *child_str; + + REQ(n, with_var); + if (strcmp(STR(CHILD(n, 0)), "as") != 0) { + ast_error(n, "expected \"with [context_expr] as [var]\""); + return NULL; + } + child_str = STR(CHILD(n, 1)); + if (child_str && (strcmp(child_str, "(") == 0)) { + /* (NCH(n) - 2) / 2: If a tuple of variables, subtract "as", "(", and + * ")" from the child count, add one back to count the first element + * of the tuple, and divide by two to eliminate "," between remaining + * elements. */ + len = (NCH(n) - 2) / 2; + assert(len > 0); /* Grammar should enforce this */ + first_child = 2; + } + else { + return with_var_name(c, n, first_child); + } + variables = asdl_seq_new(len, c->c_arena); + + if (!variables) + return NULL; + + for (i = 0; i != len; ++i) { + expr_ty variable = with_var_name(c, n, (2 * i) + first_child); + if (!variable) { + return NULL; + } + asdl_seq_SET(variables, i, variable); + } + return Tuple(variables, Store, LINENO(n), c->c_arena); +} + +/* with_stmt: 'with' test [ with_var ] ':' suite */ static stmt_ty +ast_for_with_stmt(struct compiling *c, const node *n) +{ + expr_ty context_expr, optional_vars = NULL; + int suite_index = 3; /* skip 'with', test, and ':' */ + asdl_seq *suite_seq; + + assert(TYPE(n) == with_stmt); + context_expr = ast_for_expr(c, CHILD(n, 1)); + if (set_context(context_expr, Load, n) == -1) { + return NULL; + } + if (TYPE(CHILD(n, 2)) == with_var) { + optional_vars = ast_for_with_var(c, CHILD(n, 2)); + + if (!optional_vars) { + return NULL; + } + suite_index = 4; + } + + suite_seq = ast_for_suite(c, CHILD(n, suite_index)); + if (!suite_seq) { + return NULL; + } + return With(context_expr, optional_vars, suite_seq, LINENO(n), c->c_arena); +} + +static stmt_ty ast_for_classdef(struct compiling *c, const node *n) { /* classdef: 'class' NAME ['(' testlist ')'] ':' suite */ @@ -2760,6 +2844,8 @@ return ast_for_for_stmt(c, ch); case try_stmt: return ast_for_try_stmt(c, ch); + case with_stmt: + return ast_for_with_stmt(c, ch); case funcdef: return ast_for_funcdef(c, ch); case classdef: Index: Python/symtable.c =================================================================== --- Python/symtable.c (revision 42536) +++ Python/symtable.c (working copy) @@ -1051,6 +1051,13 @@ case Continue_kind: /* nothing to do here */ break; + case With_kind: + VISIT(st, expr, s->v.With.context_expr); + if (s->v.With.optional_vars) { + VISIT(st, expr, s->v.With.optional_vars); + } + VISIT_SEQ(st, stmt, s->v.With.body); + break; } return 1; } Index: Python/compile.c =================================================================== --- Python/compile.c (revision 42536) +++ Python/compile.c (working copy) @@ -191,6 +191,8 @@ static int inplace_binop(struct compiler *, operator_ty); static int expr_constant(expr_ty e); +static int compiler_with(struct compiler *, stmt_ty); + static PyCodeObject *assemble(struct compiler *, int addNone); static PyObject *__doc__; @@ -2639,6 +2641,8 @@ break; case Continue_kind: return compiler_continue(c); + case With_kind: + return compiler_with(c, s); } return 1; } @@ -3267,7 +3271,158 @@ } } +/* + Implements the with statement from PEP 343. + + The semantics outlined in that PEP are as follows: + + with EXPR as VAR: + BLOCK + + context = (EXPR).__context__() + exc = (None, None, None) + VAR = context.__enter__() + try: + try: + BLOCK + except: + exc = sys.exc_info() + raise + finally: + context.__exit__(*exc) + + Here, it's implemented roughly as: + + context = (EXPR).__context__() + VAR = context.__enter__() + try: + BLOCK + exc = (None, None, None) + finally: + if an exception was raised: + exc = copy of (exception, instance, traceback) + context.__exit__(*exc) + reraise the exception, if one was raised + */ static int +compiler_with(struct compiler *c, stmt_ty s) +{ + static identifier context_attr, enter_attr, exit_attr; + basicblock *block, *finally, *finally_end; + + assert(s->kind == With_kind); + + if (!context_attr) { + context_attr = PyString_InternFromString("__context__"); + if (!context_attr) + return 0; + } + if (!enter_attr) { + enter_attr = PyString_InternFromString("__enter__"); + if (!enter_attr) + return 0; + } + if (!exit_attr) { + exit_attr = PyString_InternFromString("__exit__"); + if (!exit_attr) + return 0; + } + + block = compiler_new_block(c); + finally = compiler_new_block(c); + finally_end = compiler_new_block(c); + if (!(block || finally || finally_end)) { + return 0; + } + + /* Evaluate EXPR, evaluate __context__() on the result, and grab a handle + * to the result of __context__() */ + VISIT(c, expr, s->v.With.context_expr); + ADDOP_O(c, LOAD_ATTR, context_attr, names); + ADDOP_I(c, CALL_FUNCTION, 0); + + ADDOP(c, DUP_TOP); + ADDOP_O(c, LOAD_ATTR, enter_attr, names); + ADDOP_I(c, CALL_FUNCTION, 0); + + if (s->v.With.optional_vars) { + /* bind context.__enter__() to VAR */ + VISIT(c, expr, s->v.With.optional_vars); + } + else { + ADDOP(c, POP_TOP); + } + ADDOP_O(c, LOAD_ATTR, exit_attr, names); + ADDOP_JREL(c, SETUP_FINALLY, finally); + + compiler_use_next_block(c, block); + if (!compiler_push_fblock(c, FINALLY_TRY, block)) { + return 0; + } + + /* BLOCK code */ + VISIT_SEQ(c, stmt, s->v.With.body); + ADDOP(c, POP_BLOCK); + compiler_pop_fblock(c, FINALLY_TRY, block); + + /* BLOCK finished without error. Put None after __exit__ reference result + * to keep END_FINALLY happy after the eventual call to __exit__(). */ + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP(c, ROT_TWO); + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_I(c, BUILD_TUPLE, 3); + + /* Push None to indicate that no error occurred during the comparison at + * the start of the finally block. */ + ADDOP_O(c, LOAD_CONST, Py_None, consts); + compiler_use_next_block(c, finally); + if (!compiler_push_fblock(c, FINALLY_END, finally)) { + return 0; + } + + /* If an exception occurred, we need to preserve the exception information + on the stack, for the sake of the END_FINALLY operation, but make a + copy of it to pass to __exit__() before that operation occurs. + + It's ugly. I know. + + * if error occurred: */ + ADDOP(c, DUP_TOP); + ADDOP_O(c, LOAD_CONST, Py_None, consts); + ADDOP_I(c, COMPARE_OP, PyCmp_IS); + ADDOP_JREL(c, JUMP_IF_TRUE, finally_end); + ADDOP(c, POP_TOP); + /* move __exit__ reference to top of stack */ + ADDOP(c, ROT_FOUR); + ADDOP(c, ROT_FOUR); + ADDOP(c, ROT_FOUR); + /* copy __exit__ reference and three exception values */ + ADDOP_I(c, DUP_TOPX, 4); + /* move topmost __exit__ underneath exception values and make a tuple */ + ADDOP(c, ROT_FOUR); + ADDOP(c, ROT_THREE); + ADDOP(c, ROT_TWO); + ADDOP_I(c, BUILD_TUPLE, 3); + /* place two stale __exit__references on top (popped in the next block) */ + ADDOP(c, ROT_TWO); + ADDOP(c, DUP_TOP); + + /* Final block starts; should start with two discardable references (i.e. + the comparison result from the previous block, and the object used in + * the comparison). */ + compiler_use_next_block(c, finally_end); + ADDOP(c, POP_TOP); + ADDOP(c, POP_TOP); + ADDOP_I(c, CALL_FUNCTION_VAR, 0); + ADDOP(c, POP_TOP); /* discard the result of the function call */ + ADDOP(c, END_FINALLY); + compiler_pop_fblock(c, FINALLY_END, finally); + return 1; +} + +static int compiler_visit_expr(struct compiler *c, expr_ty e) { int i, n; Index: Python/Python-ast.c =================================================================== --- Python/Python-ast.c (revision 42536) +++ Python/Python-ast.c (working copy) @@ -307,6 +307,29 @@ } stmt_ty +With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int lineno, + PyArena *arena) +{ + stmt_ty p; + if (!context_expr) { + PyErr_SetString(PyExc_ValueError, + "field context_expr is required for With"); + return NULL; + } + p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); + if (!p) { + PyErr_NoMemory(); + return NULL; + } + p->kind = With_kind; + p->v.With.context_expr = context_expr; + p->v.With.optional_vars = optional_vars; + p->v.With.body = body; + p->lineno = lineno; + return p; +} + +stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, PyArena *arena) { stmt_ty p; @@ -1333,8 +1356,24 @@ marshal_write_stmt(buf, off, (stmt_ty)elt); } break; + case With_kind: + marshal_write_int(buf, off, 11); + marshal_write_expr(buf, off, o->v.With.context_expr); + if (o->v.With.optional_vars) { + marshal_write_int(buf, off, 1); + marshal_write_expr(buf, off, o->v.With.optional_vars); + } + else { + marshal_write_int(buf, off, 0); + } + marshal_write_int(buf, off, asdl_seq_LEN(o->v.With.body)); + for (i = 0; i < asdl_seq_LEN(o->v.With.body); i++) { + void *elt = asdl_seq_GET(o->v.With.body, i); + marshal_write_stmt(buf, off, (stmt_ty)elt); + } + break; case Raise_kind: - marshal_write_int(buf, off, 11); + marshal_write_int(buf, off, 12); if (o->v.Raise.type) { marshal_write_int(buf, off, 1); marshal_write_expr(buf, off, o->v.Raise.type); @@ -1358,7 +1397,7 @@ } break; case TryExcept_kind: - marshal_write_int(buf, off, 12); + marshal_write_int(buf, off, 13); marshal_write_int(buf, off, asdl_seq_LEN(o->v.TryExcept.body)); for (i = 0; i < asdl_seq_LEN(o->v.TryExcept.body); i++) { void *elt = asdl_seq_GET(o->v.TryExcept.body, i); @@ -1379,7 +1418,7 @@ } break; case TryFinally_kind: - marshal_write_int(buf, off, 13); + marshal_write_int(buf, off, 14); marshal_write_int(buf, off, asdl_seq_LEN(o->v.TryFinally.body)); for (i = 0; i < asdl_seq_LEN(o->v.TryFinally.body); i++) { void *elt = asdl_seq_GET(o->v.TryFinally.body, i); @@ -1393,7 +1432,7 @@ } break; case Assert_kind: - marshal_write_int(buf, off, 14); + marshal_write_int(buf, off, 15); marshal_write_expr(buf, off, o->v.Assert.test); if (o->v.Assert.msg) { marshal_write_int(buf, off, 1); @@ -1404,7 +1443,7 @@ } break; case Import_kind: - marshal_write_int(buf, off, 15); + marshal_write_int(buf, off, 16); marshal_write_int(buf, off, asdl_seq_LEN(o->v.Import.names)); for (i = 0; i < asdl_seq_LEN(o->v.Import.names); i++) { void *elt = asdl_seq_GET(o->v.Import.names, i); @@ -1412,7 +1451,7 @@ } break; case ImportFrom_kind: - marshal_write_int(buf, off, 16); + marshal_write_int(buf, off, 17); marshal_write_identifier(buf, off, o->v.ImportFrom.module); marshal_write_int(buf, off, asdl_seq_LEN(o->v.ImportFrom.names)); @@ -1422,7 +1461,7 @@ } break; case Exec_kind: - marshal_write_int(buf, off, 17); + marshal_write_int(buf, off, 18); marshal_write_expr(buf, off, o->v.Exec.body); if (o->v.Exec.globals) { marshal_write_int(buf, off, 1); @@ -1440,7 +1479,7 @@ } break; case Global_kind: - marshal_write_int(buf, off, 18); + marshal_write_int(buf, off, 19); marshal_write_int(buf, off, asdl_seq_LEN(o->v.Global.names)); for (i = 0; i < asdl_seq_LEN(o->v.Global.names); i++) { void *elt = asdl_seq_GET(o->v.Global.names, i); @@ -1448,17 +1487,17 @@ } break; case Expr_kind: - marshal_write_int(buf, off, 19); + marshal_write_int(buf, off, 20); marshal_write_expr(buf, off, o->v.Expr.value); break; case Pass_kind: - marshal_write_int(buf, off, 20); + marshal_write_int(buf, off, 21); break; case Break_kind: - marshal_write_int(buf, off, 21); + marshal_write_int(buf, off, 22); break; case Continue_kind: - marshal_write_int(buf, off, 22); + marshal_write_int(buf, off, 23); break; } return 1; Index: Include/graminit.h =================================================================== --- Include/graminit.h (revision 42536) +++ Include/graminit.h (working copy) @@ -38,42 +38,44 @@ #define while_stmt 293 #define for_stmt 294 #define try_stmt 295 -#define except_clause 296 -#define suite 297 -#define test 298 -#define and_test 299 -#define not_test 300 -#define comparison 301 -#define comp_op 302 -#define expr 303 -#define xor_expr 304 -#define and_expr 305 -#define shift_expr 306 -#define arith_expr 307 -#define term 308 -#define factor 309 -#define power 310 -#define atom 311 -#define listmaker 312 -#define testlist_gexp 313 -#define lambdef 314 -#define trailer 315 -#define subscriptlist 316 -#define subscript 317 -#define sliceop 318 -#define exprlist 319 -#define testlist 320 -#define testlist_safe 321 -#define dictmaker 322 -#define classdef 323 -#define arglist 324 -#define argument 325 -#define list_iter 326 -#define list_for 327 -#define list_if 328 -#define gen_iter 329 -#define gen_for 330 -#define gen_if 331 -#define testlist1 332 -#define encoding_decl 333 -#define yield_expr 334 +#define with_stmt 296 +#define with_var 297 +#define except_clause 298 +#define suite 299 +#define test 300 +#define and_test 301 +#define not_test 302 +#define comparison 303 +#define comp_op 304 +#define expr 305 +#define xor_expr 306 +#define and_expr 307 +#define shift_expr 308 +#define arith_expr 309 +#define term 310 +#define factor 311 +#define power 312 +#define atom 313 +#define listmaker 314 +#define testlist_gexp 315 +#define lambdef 316 +#define trailer 317 +#define subscriptlist 318 +#define subscript 319 +#define sliceop 320 +#define exprlist 321 +#define testlist 322 +#define testlist_safe 323 +#define dictmaker 324 +#define classdef 325 +#define arglist 326 +#define argument 327 +#define list_iter 328 +#define list_for 329 +#define list_if 330 +#define gen_iter 331 +#define gen_for 332 +#define gen_if 333 +#define testlist1 334 +#define encoding_decl 335 +#define yield_expr 336 Index: Include/Python-ast.h =================================================================== --- Include/Python-ast.h (revision 42536) +++ Include/Python-ast.h (working copy) @@ -61,11 +61,11 @@ struct _stmt { enum { FunctionDef_kind=1, ClassDef_kind=2, Return_kind=3, Delete_kind=4, Assign_kind=5, AugAssign_kind=6, Print_kind=7, - For_kind=8, While_kind=9, If_kind=10, Raise_kind=11, - TryExcept_kind=12, TryFinally_kind=13, Assert_kind=14, - Import_kind=15, ImportFrom_kind=16, Exec_kind=17, - Global_kind=18, Expr_kind=19, Pass_kind=20, Break_kind=21, - Continue_kind=22 } kind; + For_kind=8, While_kind=9, If_kind=10, With_kind=11, + Raise_kind=12, TryExcept_kind=13, TryFinally_kind=14, + Assert_kind=15, Import_kind=16, ImportFrom_kind=17, + Exec_kind=18, Global_kind=19, Expr_kind=20, Pass_kind=21, + Break_kind=22, Continue_kind=23 } kind; union { struct { identifier name; @@ -125,6 +125,12 @@ } If; struct { + expr_ty context_expr; + expr_ty optional_vars; + asdl_seq *body; + } With; + + struct { expr_ty type; expr_ty inst; expr_ty tback; @@ -349,6 +355,8 @@ PyArena *arena); stmt_ty If(expr_ty test, asdl_seq * body, asdl_seq * orelse, int lineno, PyArena *arena); +stmt_ty With(expr_ty context_expr, expr_ty optional_vars, asdl_seq * body, int + lineno, PyArena *arena); stmt_ty Raise(expr_ty type, expr_ty inst, expr_ty tback, int lineno, PyArena *arena); stmt_ty TryExcept(asdl_seq * body, asdl_seq * handlers, asdl_seq * orelse, int Index: Grammar/Grammar =================================================================== --- Grammar/Grammar (revision 42536) +++ Grammar/Grammar (working copy) @@ -70,7 +70,7 @@ exec_stmt: 'exec' expr ['in' test [',' test]] assert_stmt: 'assert' test [',' test] -compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef +compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt | funcdef | classdef if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] while_stmt: 'while' test ':' suite ['else' ':' suite] for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite] @@ -79,6 +79,8 @@ ['else' ':' suite] ['finally' ':' suite] | 'finally' ':' suite)) +with_stmt: 'with' test [ with_var ] ':' suite +with_var: NAME (dotted_name | '(' dotted_name (',' dotted_name)* ')') # NB compile.c makes sure that the default except clause is last except_clause: 'except' [test [',' test]] suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT Index: Misc/ACKS =================================================================== --- Misc/ACKS (revision 42536) +++ Misc/ACKS (working copy) @@ -62,6 +62,7 @@ Philippe Biondi Stuart Bishop Roy Bixler +Mike Bland Martin Bless Pablo Bleyer Erik van Blokland Index: Misc/NEWS =================================================================== --- Misc/NEWS (revision 42536) +++ Misc/NEWS (working copy) @@ -12,6 +12,8 @@ Core and builtins ----------------- +- PEP 343: with statement implemented. + - Fix the encodings package codec search function to only search inside its own package. Fixes problem reported in patch #1433198. Index: Parser/Python.asdl =================================================================== --- Parser/Python.asdl (revision 42536) +++ Parser/Python.asdl (working copy) @@ -25,6 +25,7 @@ | For(expr target, expr iter, stmt* body, stmt* orelse) | While(expr test, stmt* body, stmt* orelse) | If(expr test, stmt* body, stmt* orelse) + | With(expr context_expr, expr? optional_vars, stmt* body) -- 'type' is a bad name | Raise(expr? type, expr? inst, expr? tback) Index: Tools/compiler/ast.txt =================================================================== --- Tools/compiler/ast.txt (revision 42536) +++ Tools/compiler/ast.txt (working copy) @@ -20,6 +20,7 @@ Continue: For: assign, list, body, else_& While: test, body, else_& +With: expr, vars&, body If: tests!, else_& Exec: expr, locals&, globals& From: modname*, names* @@ -42,7 +43,7 @@ ListComp: expr, quals! ListCompFor: assign, list, ifs! ListCompIf: test -GenExpr: code +GenExpr: code GenExprInner: expr, quals! GenExprFor: assign, iter, ifs! GenExprIf: test Index: Doc/lib/asttable.tex =================================================================== --- Doc/lib/asttable.tex (revision 42536) +++ Doc/lib/asttable.tex (working copy) @@ -272,6 +272,11 @@ \lineiii{}{\member{else_}}{} \hline +\lineiii{With}{\member{expr}}{} +\lineiii{}{\member{vars&}}{} +\lineiii{}{\member{body}}{} +\hline + \lineiii{Yield}{\member{value}}{} \hline Index: Doc/ref/ref7.tex =================================================================== --- Doc/ref/ref7.tex (revision 42536) +++ Doc/ref/ref7.tex (working copy) @@ -308,6 +308,12 @@ statement to generate exceptions may be found in section~\ref{raise}. +\section{The \keyword{with} statement\label{with}} +\stindex{with} + +The \keyword{with} statement specifies + + \section{Function definitions\label{function}} \indexii{function}{definition} \stindex{def} Index: Lib/symbol.py =================================================================== --- Lib/symbol.py (revision 42536) +++ Lib/symbol.py (working copy) @@ -50,45 +50,47 @@ while_stmt = 293 for_stmt = 294 try_stmt = 295 -except_clause = 296 -suite = 297 -test = 298 -and_test = 299 -not_test = 300 -comparison = 301 -comp_op = 302 -expr = 303 -xor_expr = 304 -and_expr = 305 -shift_expr = 306 -arith_expr = 307 -term = 308 -factor = 309 -power = 310 -atom = 311 -listmaker = 312 -testlist_gexp = 313 -lambdef = 314 -trailer = 315 -subscriptlist = 316 -subscript = 317 -sliceop = 318 -exprlist = 319 -testlist = 320 -testlist_safe = 321 -dictmaker = 322 -classdef = 323 -arglist = 324 -argument = 325 -list_iter = 326 -list_for = 327 -list_if = 328 -gen_iter = 329 -gen_for = 330 -gen_if = 331 -testlist1 = 332 -encoding_decl = 333 -yield_expr = 334 +with_stmt = 296 +with_var = 297 +except_clause = 298 +suite = 299 +test = 300 +and_test = 301 +not_test = 302 +comparison = 303 +comp_op = 304 +expr = 305 +xor_expr = 306 +and_expr = 307 +shift_expr = 308 +arith_expr = 309 +term = 310 +factor = 311 +power = 312 +atom = 313 +listmaker = 314 +testlist_gexp = 315 +lambdef = 316 +trailer = 317 +subscriptlist = 318 +subscript = 319 +sliceop = 320 +exprlist = 321 +testlist = 322 +testlist_safe = 323 +dictmaker = 324 +classdef = 325 +arglist = 326 +argument = 327 +list_iter = 328 +list_for = 329 +list_if = 330 +gen_iter = 331 +gen_for = 332 +gen_if = 333 +testlist1 = 334 +encoding_decl = 335 +yield_expr = 336 #--end constants-- sym_name = {} Index: Lib/nested.py =================================================================== --- Lib/nested.py (revision 0) +++ Lib/nested.py (revision 0) @@ -0,0 +1,41 @@ +import sys +from collections import deque + + +class nested(object): + def __init__(self, *contexts): + self.contexts = contexts + self.entered = None + + def __context__(self): + return self + + def __enter__(self): + if self.entered is not None: + raise RuntimeError("Context is not reentrant") + self.entered = deque() + vars = [] + try: + for context in self.contexts: + mgr = context.__context__() + vars.append(mgr.__enter__()) + self.entered.appendleft(mgr) + except: + self.__exit__(*sys.exc_info()) + raise + return vars + + def __exit__(self, *exc_info): + # Behave like nested with statements + # first in, last out + # New exceptions override old ones + ex = exc_info + for mgr in self.entered: + try: + mgr.__exit__(*ex) + except: + ex = sys.exc_info() + self.entered = None + if ex is not exc_info: + raise ex[0], ex[1], ex[2] + Index: Lib/contextmanager.py =================================================================== --- Lib/contextmanager.py (revision 0) +++ Lib/contextmanager.py (revision 0) @@ -0,0 +1,34 @@ +class GeneratorContextManager(object): + def __init__(self, gen): + self.gen = gen + + def __context__(self): + return self + + def __enter__(self): + try: + return self.gen.next() + except StopIteration: + raise RuntimeError("generator didn't yield") + + def __exit__(self, type, value, traceback): + if type is None: + try: + self.gen.next() + except StopIteration: + return + else: + raise RuntimeError("generator didn't stop") + else: + try: + self.gen.throw(type, value, traceback) + except (type, StopIteration): + return + else: + raise RuntimeError("generator caught exception") + +def contextmanager(func): + def helper(*args, **kwds): + return GeneratorContextManager(func(*args, **kwds)) + return helper + Index: Lib/compiler/ast.py =================================================================== --- Lib/compiler/ast.py (revision 42536) +++ Lib/compiler/ast.py (working copy) @@ -553,9 +553,9 @@ self.varargs = 1 if flags & CO_VARKEYWORDS: self.kwargs = 1 + - def getChildren(self): children = [] children.append(self.decorators) @@ -584,9 +584,9 @@ self.lineno = lineno self.argnames = ['[outmost-iterable]'] self.varargs = self.kwargs = None + - def getChildren(self): return self.code, @@ -763,9 +763,9 @@ self.varargs = 1 if flags & CO_VARKEYWORDS: self.kwargs = 1 + - def getChildren(self): children = [] children.append(self.argnames) @@ -1297,6 +1297,31 @@ def __repr__(self): return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_)) +class With(Node): + def __init__(self, expr, vars, body, lineno=None): + self.expr = expr + self.vars = vars + self.body = body + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.append(self.vars) + children.append(self.body) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + if self.vars is not None: + nodelist.append(self.vars) + nodelist.append(self.body) + return tuple(nodelist) + + def __repr__(self): + return "With(%s, %s, %s)" % (repr(self.expr), repr(self.vars), repr(self.body)) + class Yield(Node): def __init__(self, value, lineno=None): self.value = value Index: Lib/test/test_with.py =================================================================== --- Lib/test/test_with.py (revision 0) +++ Lib/test/test_with.py (revision 0) @@ -0,0 +1,453 @@ +#!/usr/bin/env python + +''' +Tests for the with statement specified in PEP 343. +''' + +__author__ = "Mike Bland" +__email__ = "mbland at acm dot org" +__version__ = "" + +import unittest +from contextmanager import GeneratorContextManager +from nested import nested +from test.test_support import run_unittest + + +class MockContextManager(GeneratorContextManager): + def __init__(self, gen): + GeneratorContextManager.__init__(self, gen) + self.context_called = False + self.enter_called = False + self.exit_called = False + self.exit_args = None + + def __context__(self): + self.context_called = True + return GeneratorContextManager.__context__(self) + + def __enter__(self): + self.enter_called = True + return GeneratorContextManager.__enter__(self) + + def __exit__(self, type, value, traceback): + self.exit_called = True + self.exit_args = (type, value, traceback) + return GeneratorContextManager.__exit__(self, type, value, traceback) + + +def mock_contextmanager(func): + def helper(*args, **kwds): + return MockContextManager(func(*args, **kwds)) + return helper + + +class MockResource(object): + def __init__(self): + self.yielded = False + self.stopped = False + + +@mock_contextmanager +def mock_contextmanager_generator(): + mock = MockResource() + try: + mock.yielded = True + yield mock + finally: + mock.stopped = True + + +class MockNested(nested): + def __init__(self, *contexts): + nested.__init__(self, *contexts) + self.context_called = False + self.enter_called = False + self.exit_called = False + self.exit_args = None + + def __context__(self): + self.context_called = True + return nested.__context__(self) + + def __enter__(self): + self.enter_called = True + return nested.__enter__(self) + + def __exit__(self, *exc_info): + self.exit_called = True + self.exit_args = exc_info + return nested.__exit__(self, *exc_info) + + +class FailureTestCase(unittest.TestCase): + def testNameError(self): + def fooNotDeclared(): + with foo: pass + self.assertRaises(NameError, fooNotDeclared) + + def testContextAttributeError(self): + class LacksContext(object): + def __enter__(self): + pass + + def __exit__(self, type, value, traceback): + pass + + def fooLacksContext(): + foo = LacksContext() + with foo: pass + self.assertRaises(AttributeError, fooLacksContext) + + def testEnterAttributeError(self): + class LacksEnter(object): + def __context__(self): + pass + + def __exit__(self, type, value, traceback): + pass + + def fooLacksEnter(): + foo = LacksEnter() + with foo: pass + self.assertRaises(AttributeError, fooLacksEnter) + + def testExitAttributeError(self): + class LacksExit(object): + def __context__(self): + pass + + def __enter__(self): + pass + + def fooLacksExit(): + foo = LacksExit() + with foo: pass + self.assertRaises(AttributeError, fooLacksExit) + + def assertRaisesSyntaxError(self, codestr): + def shouldRaiseSyntaxError(s): + compile(s, '', 'single') + self.assertRaises(SyntaxError, shouldRaiseSyntaxError, codestr) + + def testAssignmentToNoneError(self): + self.assertRaisesSyntaxError('with mock as None:\n pass') + self.assertRaisesSyntaxError( + 'with mock as (None):\n' + ' pass') + + def testAssignmentToEmptyTupleError(self): + self.assertRaisesSyntaxError( + 'with mock as ():\n' + ' pass') + + def testAssignmentToTupleOnlyContainingNoneError(self): + self.assertRaisesSyntaxError('with mock as None,:\n pass') + self.assertRaisesSyntaxError( + 'with mock as (None,):\n' + ' pass') + + def testAssignmentToTupleContainingNoneError(self): + self.assertRaisesSyntaxError( + 'with mock as (foo, None, bar):\n' + ' pass') + + def testContextThrows(self): + class ContextThrows(object): + def __context__(self): + raise RuntimeError("Context threw") + + def shouldThrow(): + ct = ContextThrows() + self.foo = None + with ct as self.foo: + pass + self.assertRaises(RuntimeError, shouldThrow) + self.assertEqual(self.foo, None) + + def testEnterThrows(self): + class EnterThrows(object): + def __context__(self): + return self + + def __enter__(self): + raise RuntimeError("Context threw") + + def shouldThrow(): + ct = EnterThrows() + self.foo = None + with ct as self.foo: + pass + self.assertRaises(RuntimeError, shouldThrow) + self.assertEqual(self.foo, None) + + # We don't test throwing from __exit__ because that would be bad, m'kay? + + +class ContextmanagerAssertionMixin(object): + TEST_EXCEPTION = RuntimeError("test exception") + + def assertInWithManagerInvariants(self, mock_manager): + self.assertTrue(mock_manager.context_called) + self.assertTrue(mock_manager.enter_called) + self.assertFalse(mock_manager.exit_called) + self.assertEqual(mock_manager.exit_args, None) + + def assertAfterWithManagerInvariants(self, mock_manager, exit_args): + self.assertTrue(mock_manager.context_called) + self.assertTrue(mock_manager.enter_called) + self.assertTrue(mock_manager.exit_called) + self.assertEqual(mock_manager.exit_args, exit_args) + + def assertAfterWithManagerInvariantsNoError(self, mock_manager): + self.assertAfterWithManagerInvariants(mock_manager, + (None, None, None)) + + def assertInWithGeneratorInvariants(self, mock_generator): + self.assertTrue(mock_generator.yielded) + self.assertFalse(mock_generator.stopped) + + def assertAfterWithGeneratorInvariantsNoError(self, mock_generator): + self.assertTrue(mock_generator.yielded) + self.assertTrue(mock_generator.stopped) + + def raiseTestException(self): + raise self.TEST_EXCEPTION + + def assertAfterWithManagerInvariantsWithError(self, mock_manager): + self.assertTrue(mock_manager.context_called) + self.assertTrue(mock_manager.enter_called) + self.assertTrue(mock_manager.exit_called) + self.assertEqual(mock_manager.exit_args[0], RuntimeError) + self.assertEqual(mock_manager.exit_args[1], self.TEST_EXCEPTION) + + def assertAfterWithGeneratorInvariantsWithError(self, mock_generator): + self.assertTrue(mock_generator.yielded) + self.assertTrue(mock_generator.stopped) + + +class NonexceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin): + def testInlineGeneratorSyntax(self): + with mock_contextmanager_generator(): + pass + + def testUnboundGenerator(self): + mock = mock_contextmanager_generator() + with mock: + pass + self.assertAfterWithManagerInvariantsNoError(mock) + + def testInlineGeneratorBoundSyntax(self): + with mock_contextmanager_generator() as foo: + self.assertInWithGeneratorInvariants(foo) + # FIXME: In the future, we'll try to keep the bound names from leaking + self.assertAfterWithGeneratorInvariantsNoError(foo) + + def testInlineGeneratorBoundToExistingVariable(self): + foo = None + with mock_contextmanager_generator() as foo: + self.assertInWithGeneratorInvariants(foo) + self.assertAfterWithGeneratorInvariantsNoError(foo) + + def testInlineGeneratorBoundToDottedVariable(self): + with mock_contextmanager_generator() as self.foo: + self.assertInWithGeneratorInvariants(self.foo) + self.assertAfterWithGeneratorInvariantsNoError(self.foo) + + def testBoundGenerator(self): + mock = mock_contextmanager_generator() + with mock as foo: + self.assertInWithGeneratorInvariants(foo) + self.assertInWithManagerInvariants(mock) + self.assertAfterWithGeneratorInvariantsNoError(foo) + self.assertAfterWithManagerInvariantsNoError(mock) + + def testNestedSingleStatements(self): + mock_a = mock_contextmanager_generator() + with mock_a as foo: + mock_b = mock_contextmanager_generator() + with mock_b as bar: + self.assertInWithManagerInvariants(mock_a) + self.assertInWithManagerInvariants(mock_b) + self.assertInWithGeneratorInvariants(foo) + self.assertInWithGeneratorInvariants(bar) + self.assertAfterWithManagerInvariantsNoError(mock_b) + self.assertAfterWithGeneratorInvariantsNoError(bar) + self.assertInWithManagerInvariants(mock_a) + self.assertInWithGeneratorInvariants(foo) + self.assertAfterWithManagerInvariantsNoError(mock_a) + self.assertAfterWithGeneratorInvariantsNoError(foo) + + +class NestedNonexceptionalTestCase(unittest.TestCase, + ContextmanagerAssertionMixin): + def testSingleArgInlineGeneratorSyntax(self): + with nested(mock_contextmanager_generator()): + pass + + def testSingleArgUnbound(self): + mock_contextmanager = mock_contextmanager_generator() + mock_nested = MockNested(mock_contextmanager) + with mock_nested: + self.assertInWithManagerInvariants(mock_contextmanager) + self.assertInWithManagerInvariants(mock_nested) + self.assertAfterWithManagerInvariantsNoError(mock_contextmanager) + self.assertAfterWithManagerInvariantsNoError(mock_nested) + + def testSingleArgBoundToNonTuple(self): + m = mock_contextmanager_generator() + # This will bind all the arguments to nested() into a single list + # assigned to foo. + with nested(m) as foo: + self.assertInWithManagerInvariants(m) + self.assertAfterWithManagerInvariantsNoError(m) + + def testSingleArgBoundToSingleElementParenthesizedList(self): + m = mock_contextmanager_generator() + # This will bind all the arguments to nested() into a single list + # assigned to foo. + # FIXME: what should this do: with nested(m) as (foo,): + with nested(m) as (foo): + self.assertInWithManagerInvariants(m) + self.assertAfterWithManagerInvariantsNoError(m) + + def testSingleArgBoundToMultipleElementTupleError(self): + def shouldThrowValueError(): + with nested(mock_contextmanager_generator()) as (foo, bar): + pass + self.assertRaises(ValueError, shouldThrowValueError) + + def testSingleArgUnbound(self): + mock_contextmanager = mock_contextmanager_generator() + mock_nested = MockNested(mock_contextmanager) + with mock_nested: + self.assertInWithManagerInvariants(mock_contextmanager) + self.assertInWithManagerInvariants(mock_nested) + self.assertAfterWithManagerInvariantsNoError(mock_contextmanager) + self.assertAfterWithManagerInvariantsNoError(mock_nested) + + def testMultipleArgUnbound(self): + m = mock_contextmanager_generator() + n = mock_contextmanager_generator() + o = mock_contextmanager_generator() + mock_nested = MockNested(m, n, o) + with mock_nested: + self.assertInWithManagerInvariants(m) + self.assertInWithManagerInvariants(n) + self.assertInWithManagerInvariants(o) + self.assertInWithManagerInvariants(mock_nested) + self.assertAfterWithManagerInvariantsNoError(m) + self.assertAfterWithManagerInvariantsNoError(n) + self.assertAfterWithManagerInvariantsNoError(o) + self.assertAfterWithManagerInvariantsNoError(mock_nested) + + def testMultipleArgBound(self): + mock_nested = MockNested(mock_contextmanager_generator(), + mock_contextmanager_generator(), mock_contextmanager_generator()) + with mock_nested as (m, n, o): + self.assertInWithGeneratorInvariants(m) + self.assertInWithGeneratorInvariants(n) + self.assertInWithGeneratorInvariants(o) + self.assertInWithManagerInvariants(mock_nested) + self.assertAfterWithGeneratorInvariantsNoError(m) + self.assertAfterWithGeneratorInvariantsNoError(n) + self.assertAfterWithGeneratorInvariantsNoError(o) + self.assertAfterWithManagerInvariantsNoError(mock_nested) + + +class ExceptionalTestCase(unittest.TestCase, ContextmanagerAssertionMixin): + def testSingleResource(self): + cm = mock_contextmanager_generator() + def shouldThrow(): + with cm as self.resource: + self.assertInWithManagerInvariants(cm) + self.assertInWithGeneratorInvariants(self.resource) + self.raiseTestException() + self.assertRaises(RuntimeError, shouldThrow) + self.assertAfterWithManagerInvariantsWithError(cm) + self.assertAfterWithGeneratorInvariantsWithError(self.resource) + + def testNestedSingleStatements(self): + mock_a = mock_contextmanager_generator() + mock_b = mock_contextmanager_generator() + def shouldThrow(): + with mock_a as self.foo: + with mock_b as self.bar: + self.assertInWithManagerInvariants(mock_a) + self.assertInWithManagerInvariants(mock_b) + self.assertInWithGeneratorInvariants(self.foo) + self.assertInWithGeneratorInvariants(self.bar) + self.raiseTestException() + self.assertRaises(RuntimeError, shouldThrow) + self.assertAfterWithManagerInvariantsWithError(mock_a) + self.assertAfterWithManagerInvariantsWithError(mock_b) + self.assertAfterWithGeneratorInvariantsWithError(self.foo) + self.assertAfterWithGeneratorInvariantsWithError(self.bar) + + def testMultipleResourcesInSingleStatement(self): + cm_a = mock_contextmanager_generator() + cm_b = mock_contextmanager_generator() + mock_nested = MockNested(cm_a, cm_b) + def shouldThrow(): + with mock_nested as (self.resource_a, self.resource_b): + self.assertInWithManagerInvariants(cm_a) + self.assertInWithManagerInvariants(cm_b) + self.assertInWithManagerInvariants(mock_nested) + self.assertInWithGeneratorInvariants(self.resource_a) + self.assertInWithGeneratorInvariants(self.resource_b) + self.raiseTestException() + self.assertRaises(RuntimeError, shouldThrow) + self.assertAfterWithManagerInvariantsWithError(cm_a) + self.assertAfterWithManagerInvariantsWithError(cm_b) + self.assertAfterWithManagerInvariantsWithError(mock_nested) + self.assertAfterWithGeneratorInvariantsWithError(self.resource_a) + self.assertAfterWithGeneratorInvariantsWithError(self.resource_b) + + def testNestedExceptionBeforeInnerStatement(self): + mock_a = mock_contextmanager_generator() + mock_b = mock_contextmanager_generator() + self.bar = None + def shouldThrow(): + with mock_a as self.foo: + self.assertInWithManagerInvariants(mock_a) + self.assertInWithGeneratorInvariants(self.foo) + self.raiseTestException() + with mock_b as self.bar: + pass + self.assertRaises(RuntimeError, shouldThrow) + self.assertAfterWithManagerInvariantsWithError(mock_a) + self.assertAfterWithGeneratorInvariantsWithError(self.foo) + + # The inner statement stuff should never have been touched + self.assertEqual(self.bar, None) + self.assertFalse(mock_b.context_called) + self.assertFalse(mock_b.enter_called) + self.assertFalse(mock_b.exit_called) + self.assertEqual(mock_b.exit_args, None) + + def testNestedExceptionAfterInnerStatement(self): + mock_a = mock_contextmanager_generator() + mock_b = mock_contextmanager_generator() + def shouldThrow(): + with mock_a as self.foo: + with mock_b as self.bar: + self.assertInWithManagerInvariants(mock_a) + self.assertInWithManagerInvariants(mock_b) + self.assertInWithGeneratorInvariants(self.foo) + self.assertInWithGeneratorInvariants(self.bar) + self.raiseTestException() + self.assertRaises(RuntimeError, shouldThrow) + self.assertAfterWithManagerInvariantsWithError(mock_a) + self.assertAfterWithManagerInvariantsNoError(mock_b) + self.assertAfterWithGeneratorInvariantsWithError(self.foo) + self.assertAfterWithGeneratorInvariantsNoError(self.bar) + + +def test_main(): + run_unittest(FailureTestCase, NonexceptionalTestCase, + NestedNonexceptionalTestCase, ExceptionalTestCase) + + +if __name__ == '__main__': + test_main() +