diff options
author | Pablo Galindo Salgado <Pablogsal@gmail.com> | 2021-08-12 16:13:30 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-12 16:13:30 (GMT) |
commit | 8e832fb2a2cb54d7262148b6ec15563dffb48d63 (patch) | |
tree | 0b3fb52778df472a467635e1a8ca8632030ed7b6 | |
parent | 789a6af29f531f78abd2e2f6af80084ccabf80b1 (diff) | |
download | cpython-8e832fb2a2cb54d7262148b6ec15563dffb48d63.zip cpython-8e832fb2a2cb54d7262148b6ec15563dffb48d63.tar.gz cpython-8e832fb2a2cb54d7262148b6ec15563dffb48d63.tar.bz2 |
bpo-44885: Correct the ast locations of f-strings with format specs and repeated expressions (GH-27729)
-rw-r--r-- | Lib/test/test_fstring.py | 40 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2021-08-11-15-39-57.bpo-44885.i4noUO.rst | 2 | ||||
-rw-r--r-- | Parser/string_parser.c | 68 | ||||
-rw-r--r-- | Python/importlib.h | 6 | ||||
-rw-r--r-- | Python/importlib_external.h | 24 | ||||
-rw-r--r-- | Python/importlib_zipimport.h | 54 |
6 files changed, 103 insertions, 91 deletions
diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index caae1b7..14a4c67 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -212,11 +212,6 @@ f'{a * f"-{x()}-"}'""" self.assertEqual(call.col_offset, 11) def test_ast_line_numbers_duplicate_expression(self): - """Duplicate expression - - NOTE: this is currently broken, always sets location of the first - expression. - """ expr = """ a = 10 f'{a * x()} {a * x()} {a * x()}' @@ -266,9 +261,9 @@ f'{a * x()} {a * x()} {a * x()}' self.assertEqual(binop.lineno, 3) self.assertEqual(binop.left.lineno, 3) self.assertEqual(binop.right.lineno, 3) - self.assertEqual(binop.col_offset, 3) # FIXME: this is wrong - self.assertEqual(binop.left.col_offset, 3) # FIXME: this is wrong - self.assertEqual(binop.right.col_offset, 7) # FIXME: this is wrong + self.assertEqual(binop.col_offset, 13) + self.assertEqual(binop.left.col_offset, 13) + self.assertEqual(binop.right.col_offset, 17) # check the third binop location binop = t.body[1].value.values[4].value self.assertEqual(type(binop), ast.BinOp) @@ -278,9 +273,32 @@ f'{a * x()} {a * x()} {a * x()}' self.assertEqual(binop.lineno, 3) self.assertEqual(binop.left.lineno, 3) self.assertEqual(binop.right.lineno, 3) - self.assertEqual(binop.col_offset, 3) # FIXME: this is wrong - self.assertEqual(binop.left.col_offset, 3) # FIXME: this is wrong - self.assertEqual(binop.right.col_offset, 7) # FIXME: this is wrong + self.assertEqual(binop.col_offset, 23) + self.assertEqual(binop.left.col_offset, 23) + self.assertEqual(binop.right.col_offset, 27) + + def test_ast_numbers_fstring_with_formatting(self): + + t = ast.parse('f"Here is that pesky {xxx:.3f} again"') + self.assertEqual(len(t.body), 1) + self.assertEqual(t.body[0].lineno, 1) + + self.assertEqual(type(t.body[0]), ast.Expr) + self.assertEqual(type(t.body[0].value), ast.JoinedStr) + self.assertEqual(len(t.body[0].value.values), 3) + + self.assertEqual(type(t.body[0].value.values[0]), ast.Constant) + self.assertEqual(type(t.body[0].value.values[1]), ast.FormattedValue) + self.assertEqual(type(t.body[0].value.values[2]), ast.Constant) + + _, expr, _ = t.body[0].value.values + + name = expr.value + self.assertEqual(type(name), ast.Name) + self.assertEqual(name.lineno, 1) + self.assertEqual(name.end_lineno, 1) + self.assertEqual(name.col_offset, 22) + self.assertEqual(name.end_col_offset, 25) def test_ast_line_numbers_multiline_fstring(self): # See bpo-30465 for details. diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-08-11-15-39-57.bpo-44885.i4noUO.rst b/Misc/NEWS.d/next/Core and Builtins/2021-08-11-15-39-57.bpo-44885.i4noUO.rst new file mode 100644 index 0000000..c6abd73 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-08-11-15-39-57.bpo-44885.i4noUO.rst @@ -0,0 +1,2 @@ +Correct the ast locations of f-strings with format specs and repeated +expressions. Patch by Pablo Galindo diff --git a/Parser/string_parser.c b/Parser/string_parser.c index 66405b2..fb37d37 100644 --- a/Parser/string_parser.c +++ b/Parser/string_parser.c @@ -279,49 +279,48 @@ _PyPegen_parsestr(Parser *p, int *bytesmode, int *rawmode, PyObject **result, /* Fix locations for the given node and its children. `parent` is the enclosing node. + `expr_start` is the starting position of the expression (pointing to the open brace). `n` is the node which locations are going to be fixed relative to parent. `expr_str` is the child node's string representation, including braces. */ static bool -fstring_find_expr_location(Token *parent, char *expr_str, int *p_lines, int *p_cols) +fstring_find_expr_location(Token *parent, const char* expr_start, char *expr_str, int *p_lines, int *p_cols) { *p_lines = 0; *p_cols = 0; + assert(expr_start != NULL && *expr_start == '{'); if (parent && parent->bytes) { const char *parent_str = PyBytes_AsString(parent->bytes); if (!parent_str) { return false; } - const char *substr = strstr(parent_str, expr_str); - if (substr) { - // The following is needed, in order to correctly shift the column - // offset, in the case that (disregarding any whitespace) a newline - // immediately follows the opening curly brace of the fstring expression. - bool newline_after_brace = 1; - const char *start = substr + 1; - while (start && *start != '}' && *start != '\n') { - if (*start != ' ' && *start != '\t' && *start != '\f') { - newline_after_brace = 0; - break; - } - start++; + // The following is needed, in order to correctly shift the column + // offset, in the case that (disregarding any whitespace) a newline + // immediately follows the opening curly brace of the fstring expression. + bool newline_after_brace = 1; + const char *start = expr_start + 1; + while (start && *start != '}' && *start != '\n') { + if (*start != ' ' && *start != '\t' && *start != '\f') { + newline_after_brace = 0; + break; } + start++; + } - // Account for the characters from the last newline character to our - // left until the beginning of substr. - if (!newline_after_brace) { - start = substr; - while (start > parent_str && *start != '\n') { - start--; - } - *p_cols += (int)(substr - start); + // Account for the characters from the last newline character to our + // left until the beginning of expr_start. + if (!newline_after_brace) { + start = expr_start; + while (start > parent_str && *start != '\n') { + start--; } - /* adjust the start based on the number of newlines encountered - before the f-string expression */ - for (const char *p = parent_str; p < substr; p++) { - if (*p == '\n') { - (*p_lines)++; - } + *p_cols += (int)(expr_start - start); + } + /* adjust the start based on the number of newlines encountered + before the f-string expression */ + for (const char *p = parent_str; p < expr_start; p++) { + if (*p == '\n') { + (*p_lines)++; } } } @@ -365,7 +364,7 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, len = expr_end - expr_start; /* Allocate 3 extra bytes: open paren, close paren, null byte. */ - str = PyMem_Malloc(len + 3); + str = PyMem_Calloc(len + 3, sizeof(char)); if (str == NULL) { PyErr_NoMemory(); return NULL; @@ -373,17 +372,10 @@ fstring_compile_expr(Parser *p, const char *expr_start, const char *expr_end, // The call to fstring_find_expr_location is responsible for finding the column offset // the generated AST nodes need to be shifted to the right, which is equal to the number - // of the f-string characters before the expression starts. In order to correctly compute - // this offset, strstr gets called in fstring_find_expr_location which only succeeds - // if curly braces appear before and after the f-string expression (exactly like they do - // in the f-string itself), hence the following lines. - str[0] = '{'; + // of the f-string characters before the expression starts. memcpy(str+1, expr_start, len); - str[len+1] = '}'; - str[len+2] = 0; - int lines, cols; - if (!fstring_find_expr_location(t, str, &lines, &cols)) { + if (!fstring_find_expr_location(t, expr_start-1, str+1, &lines, &cols)) { PyMem_Free(str); return NULL; } diff --git a/Python/importlib.h b/Python/importlib.h index b62cc9d..da94fc3 100644 --- a/Python/importlib.h +++ b/Python/importlib.h @@ -1518,7 +1518,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 109,111,100,117,108,101,95,114,101,112,114,224,2,0,0,115, 8,0,0,0,6,7,2,1,4,255,22,2,115,6,0,0, 0,2,7,10,1,22,1,115,34,0,0,0,9,18,9,80, - 24,59,61,79,9,80,9,80,16,75,17,23,17,32,16,75, + 24,59,61,79,9,80,9,80,16,75,27,33,27,42,16,75, 16,75,48,63,48,71,16,75,16,75,16,75,9,75,114,17, 0,0,0,78,99,4,0,0,0,0,0,0,0,0,0,0, 0,5,0,0,0,3,0,0,0,115,42,0,0,0,124,2, @@ -2127,7 +2127,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 60,13,60,0,0,8,14,5,47,25,28,25,36,37,43,25, 44,9,22,9,47,13,20,21,34,36,41,43,49,13,50,13, 50,12,18,5,18,0,0,9,47,16,30,9,47,9,47,9, - 47,9,47,19,86,20,26,19,86,19,86,20,25,19,86,19, + 47,9,47,19,86,49,55,19,86,19,86,77,82,19,86,19, 86,13,16,13,22,13,47,28,31,33,46,13,47,13,47,13, 47,12,18,5,18,9,47,0,0,12,18,5,18,115,39,0, 0,0,167,3,43,0,171,23,65,2,7,193,40,4,65,52, @@ -2323,7 +2323,7 @@ const unsigned char _Py_M__importlib_bootstrap[] = { 0,15,22,15,41,27,40,15,41,5,12,12,19,12,35,24, 34,12,35,5,9,8,15,23,27,8,27,5,49,12,16,24, 28,12,28,9,56,33,40,44,48,44,55,33,55,9,56,13, - 22,13,56,28,63,29,36,28,63,28,63,29,33,29,40,28, + 22,13,56,28,63,32,39,28,63,28,63,47,51,47,58,28, 63,28,63,28,63,28,41,54,55,13,56,13,56,13,56,16, 23,9,23,10,14,22,26,10,26,5,49,16,20,16,27,9, 27,9,18,9,52,24,63,24,37,50,51,9,52,9,52,9, diff --git a/Python/importlib_external.h b/Python/importlib_external.h index 1572d0d..c49fa55 100644 --- a/Python/importlib_external.h +++ b/Python/importlib_external.h @@ -685,15 +685,15 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 41,44,52,28,52,12,53,9,43,20,24,25,28,29,42,25, 43,25,44,25,44,20,45,13,17,39,43,13,36,12,35,5, 42,25,36,37,41,25,42,9,22,9,13,15,22,12,19,23, - 31,12,31,9,42,19,29,33,41,30,41,30,41,31,35,30, + 31,12,31,9,42,19,29,33,41,30,41,30,41,33,37,30, 41,30,41,19,42,13,42,17,33,17,44,40,43,17,44,5, - 14,8,17,25,31,8,31,5,51,15,25,26,78,27,43,26, + 14,8,17,25,31,8,31,5,51,15,25,26,78,58,74,26, 78,26,78,15,79,9,79,10,19,23,24,10,24,5,51,24, 40,24,55,48,51,53,54,24,55,56,58,24,59,9,21,16, - 28,16,45,40,44,16,45,9,47,19,29,30,46,31,35,30, + 28,16,45,40,44,16,45,9,47,19,29,30,46,38,42,30, 46,30,46,19,47,13,47,21,33,34,37,38,42,34,43,34, 44,34,44,21,45,9,18,16,25,16,35,16,35,9,51,19, - 29,30,50,31,43,30,50,30,50,30,50,19,51,13,51,21, + 29,30,50,52,64,30,50,30,50,30,50,19,51,13,51,21, 37,21,52,48,51,21,52,53,54,21,55,5,18,12,22,23, 27,29,42,45,60,61,62,45,63,29,63,12,64,5,64,114, 10,0,0,0,99,1,0,0,0,0,0,0,0,0,0,0, @@ -974,15 +974,15 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 16,6,1,2,3,16,254,12,1,16,1,10,1,2,3,10, 254,12,1,8,1,16,1,6,2,2,2,16,255,16,1,4, 1,115,166,0,0,0,13,17,18,20,19,20,18,20,13,21, - 5,10,8,13,17,29,8,29,5,50,19,61,20,24,19,61, - 19,61,20,25,19,61,19,61,9,16,9,19,9,51,37,41, + 5,10,8,13,17,29,8,29,5,50,19,61,42,46,19,61, + 19,61,52,57,19,61,19,61,9,16,9,19,9,51,37,41, 43,50,9,51,9,51,15,26,27,34,15,50,15,50,38,49, 15,50,15,50,9,50,8,11,12,16,8,17,20,22,8,22, - 5,32,19,70,20,24,19,70,19,70,9,16,9,19,9,51, + 5,32,19,70,62,66,19,70,19,70,9,16,9,19,9,51, 37,41,43,50,9,51,9,51,15,23,24,31,15,32,9,32, 13,27,28,32,33,34,35,36,33,36,28,37,13,38,5,10, - 8,13,16,21,8,21,5,50,19,57,20,25,19,57,19,57, - 20,24,19,57,19,57,9,16,15,26,27,34,15,50,15,50, + 8,13,16,21,8,21,5,50,19,57,36,41,19,57,19,57, + 49,53,19,57,19,57,9,16,15,26,27,34,15,50,15,50, 38,49,15,50,15,50,9,50,12,17,5,17,114,10,0,0, 0,99,5,0,0,0,0,0,0,0,0,0,0,0,4,0, 0,0,3,0,0,0,115,124,0,0,0,116,0,124,0,100, @@ -1041,12 +1041,12 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 1,2,255,22,2,8,254,115,18,0,0,0,22,19,2,3, 10,254,12,1,16,1,6,1,2,2,22,255,32,1,115,124, 0,0,0,8,22,23,27,28,29,30,32,28,32,23,33,8, - 34,39,51,54,64,39,64,8,65,5,50,19,52,20,24,19, + 34,39,51,54,64,39,64,8,65,5,50,19,52,44,48,19, 52,19,52,9,16,9,19,9,51,37,41,43,50,9,51,9, 51,15,26,27,34,15,50,15,50,38,49,15,50,15,50,9, 50,9,20,28,32,9,32,5,76,9,23,24,28,29,31,32, 34,29,34,24,35,9,36,41,52,55,65,41,65,9,66,5, - 76,15,26,27,60,28,32,27,60,27,60,15,76,15,76,64, + 76,15,26,27,60,52,56,27,60,27,60,15,76,15,76,64, 75,15,76,15,76,9,76,5,76,5,76,5,76,5,76,114, 10,0,0,0,99,4,0,0,0,0,0,0,0,0,0,0, 0,4,0,0,0,3,0,0,0,115,42,0,0,0,124,0, @@ -1096,7 +1096,7 @@ const unsigned char _Py_M__importlib_bootstrap_external[] = { 0,0,16,17,2,1,8,1,4,255,2,2,6,254,4,255, 115,14,0,0,0,14,17,2,4,2,253,8,1,4,2,2, 255,10,1,115,42,0,0,0,8,12,13,14,15,17,13,17, - 8,18,22,33,8,33,5,10,15,26,13,71,14,18,13,71, + 8,18,22,33,8,33,5,10,15,26,13,71,63,67,13,71, 13,71,15,10,15,10,15,26,15,10,15,10,9,10,5,10, 5,10,114,10,0,0,0,99,4,0,0,0,0,0,0,0, 0,0,0,0,5,0,0,0,3,0,0,0,115,76,0,0, diff --git a/Python/importlib_zipimport.h b/Python/importlib_zipimport.h index 370c980..c12ed52 100644 --- a/Python/importlib_zipimport.h +++ b/Python/importlib_zipimport.h @@ -481,7 +481,7 @@ const unsigned char _Py_M__zipimport[] = { 0,0,10,7,6,1,20,1,10,2,2,1,2,3,14,254, 10,2,2,6,12,253,2,128,2,3,2,254,16,2,2,128, 16,1,115,128,0,0,0,14,30,31,35,37,45,14,46,9, - 11,12,14,18,22,12,22,9,83,19,33,34,67,35,43,34, + 11,12,14,18,22,12,22,9,83,19,33,34,67,55,63,34, 67,34,67,74,82,19,83,19,83,13,83,16,32,33,37,39, 47,16,48,9,13,12,14,9,36,24,43,24,54,55,59,61, 74,24,75,13,21,13,21,27,31,24,36,24,36,24,36,13, @@ -513,7 +513,7 @@ const unsigned char _Py_M__zipimport[] = { 8,0,0,0,10,6,8,1,18,1,4,1,115,8,0,0, 0,10,6,6,1,20,1,4,1,115,40,0,0,0,14,30, 31,35,37,45,14,46,9,11,12,14,18,22,12,22,9,83, - 19,33,34,67,35,43,34,67,34,67,74,82,19,83,19,83, + 19,33,34,67,55,63,34,67,34,67,74,82,19,83,19,83, 13,83,16,18,9,18,114,10,0,0,0,99,2,0,0,0, 0,0,0,0,0,0,0,0,8,0,0,0,3,0,0,0, 115,0,1,0,0,100,1,125,2,116,0,106,1,124,2,116, @@ -607,7 +607,7 @@ const unsigned char _Py_M__zipimport[] = { 13,37,0,0,9,18,9,18,9,18,17,20,17,28,29,37, 17,38,13,18,0,0,9,86,19,22,19,30,31,39,19,40, 13,16,13,16,0,0,9,86,16,24,9,86,9,86,9,86, - 9,86,19,30,31,85,32,40,31,85,31,85,31,85,19,86, + 9,86,19,30,31,85,48,56,31,85,31,85,31,85,19,86, 13,86,9,86,0,0,9,19,9,36,37,69,71,79,81,88, 9,89,9,89,16,19,9,19,115,23,0,0,0,172,40,65, 21,0,193,21,9,65,30,7,193,32,5,65,38,0,193,38, @@ -918,42 +918,42 @@ const unsigned char _Py_M__zipimport[] = { 2,128,12,2,12,1,20,1,8,1,8,1,4,202,2,6, 22,48,2,128,12,0,14,1,4,1,115,240,4,0,0,5, 80,14,17,14,27,28,35,14,36,9,11,9,11,0,0,5, - 80,12,19,5,80,5,80,5,80,5,80,15,29,30,65,31, - 38,30,65,30,65,72,79,15,80,15,80,9,80,5,80,0, + 80,12,19,5,80,5,80,5,80,5,80,15,29,30,65,54, + 61,30,65,30,65,72,79,15,80,15,80,9,80,5,80,0, 0,10,12,5,23,5,23,9,84,13,15,13,46,22,42,21, 42,44,45,13,46,13,46,31,33,31,40,31,40,13,28,22, 24,22,51,30,50,22,51,13,19,13,19,0,0,9,84,16, - 23,9,84,9,84,9,84,9,84,19,33,34,69,35,42,34, + 23,9,84,9,84,9,84,9,84,19,33,34,69,58,65,34, 69,34,69,76,83,19,84,19,84,13,84,9,84,0,0,12, - 15,16,22,12,23,27,47,12,47,9,84,19,33,34,69,35, - 42,34,69,34,69,76,83,19,84,19,84,13,84,12,18,19, + 15,16,22,12,23,27,47,12,47,9,84,19,33,34,69,58, + 65,34,69,34,69,76,83,19,84,19,84,13,84,12,18,19, 21,20,21,19,21,12,22,26,44,12,44,9,58,13,51,17, 19,17,30,25,26,28,29,17,30,17,30,29,31,29,38,29, 38,17,26,17,26,0,0,13,51,20,27,13,51,13,51,13, - 51,13,51,23,37,38,73,39,46,38,73,38,73,43,50,23, + 51,13,51,23,37,38,73,62,69,38,73,38,73,43,50,23, 51,23,51,17,51,13,51,0,0,33,36,37,46,49,64,37, 64,37,57,37,57,59,60,33,61,13,30,13,51,17,19,17, 43,25,42,17,43,17,43,24,26,24,33,24,33,17,21,17, 21,0,0,13,51,20,27,13,51,13,51,13,51,13,51,23, - 37,38,73,39,46,38,73,38,73,43,50,23,51,23,51,17, + 37,38,73,62,69,38,73,38,73,43,50,23,51,23,51,17, 51,13,51,0,0,19,23,19,49,30,48,19,49,13,16,16, - 19,22,23,16,23,13,51,23,37,38,68,39,46,38,68,38, + 19,22,23,16,23,13,51,23,37,38,68,57,64,38,68,38, 68,43,50,23,51,23,51,17,51,22,26,27,30,31,34,35, 55,31,55,27,55,22,56,13,19,16,19,20,26,16,27,31, - 51,16,51,13,51,23,37,38,70,39,46,38,70,38,70,43, + 51,16,51,13,51,23,37,38,70,59,66,38,70,38,70,43, 50,23,51,23,51,17,51,31,40,43,46,47,51,43,52,31, 52,55,58,31,58,13,28,23,37,38,44,45,47,48,50,45, 50,38,51,23,52,9,20,25,39,40,46,47,49,50,52,47, 52,40,53,25,54,9,22,12,27,30,41,12,41,9,91,19, - 33,34,76,35,42,34,76,34,76,83,90,19,91,19,91,13, - 91,12,27,30,43,12,43,9,93,19,33,34,78,35,42,34, + 33,34,76,65,72,34,76,34,76,83,90,19,91,19,91,13, + 91,12,27,30,43,12,43,9,93,19,33,34,78,67,74,34, 78,34,78,85,92,19,93,19,93,13,93,9,24,28,39,9, 39,9,24,22,37,40,53,22,53,9,19,12,22,25,26,12, - 26,9,101,9,101,19,33,34,86,35,42,34,86,34,86,93, + 26,9,101,9,101,19,33,34,86,75,82,34,86,34,86,93, 100,19,101,19,101,13,101,17,19,9,14,17,18,9,14,9, 84,13,15,13,37,21,36,13,37,13,37,13,37,0,0,9, 84,16,23,9,84,9,84,9,84,9,84,9,84,19,33,34, - 69,35,42,34,69,34,69,76,83,19,84,19,84,13,84,9, + 69,58,65,34,69,34,69,76,83,19,84,19,84,13,84,9, 84,0,0,15,19,22,24,22,33,30,32,22,33,13,19,16, 19,20,26,16,27,30,31,16,31,13,62,13,62,23,31,32, 61,23,62,17,62,16,22,23,25,24,25,23,25,16,26,30, @@ -971,18 +971,18 @@ const unsigned char _Py_M__zipimport[] = { 23,28,42,43,49,50,52,53,55,50,55,43,56,28,57,13, 25,27,41,42,48,49,51,52,54,49,54,42,55,27,56,13, 24,27,36,39,49,27,49,52,64,27,64,13,24,16,27,30, - 43,16,43,13,92,13,92,23,37,38,77,39,46,38,77,38, + 43,16,43,13,92,13,92,23,37,38,77,66,73,38,77,38, 77,84,91,23,92,23,92,17,92,13,24,28,38,13,38,13, 24,13,88,24,26,24,42,32,41,24,42,17,21,17,21,0, 0,13,88,20,27,13,88,13,88,13,88,13,88,13,88,23, - 37,38,73,39,46,38,73,38,73,80,87,23,88,23,88,17, + 37,38,73,62,69,38,73,38,73,80,87,23,88,23,88,17, 88,13,88,0,0,16,19,20,24,16,25,29,38,16,38,13, - 88,13,88,23,37,38,73,39,46,38,73,38,73,80,87,23, + 88,13,88,23,37,38,73,62,69,38,73,38,73,80,87,23, 88,23,88,17,88,13,88,20,23,24,26,24,56,32,43,46, 55,32,55,24,56,20,57,61,72,75,84,61,84,20,84,17, - 92,17,92,27,41,42,77,43,50,42,77,42,77,84,91,27, + 92,17,92,27,41,42,77,66,73,42,77,42,77,84,91,27, 92,27,92,21,92,17,92,0,0,13,88,20,27,13,88,13, - 88,13,88,13,88,13,88,23,37,38,73,39,46,38,73,38, + 88,13,88,13,88,13,88,23,37,38,73,62,69,38,73,38, 73,80,87,23,88,23,88,17,88,13,88,0,0,16,21,24, 29,16,29,13,72,13,72,24,28,24,37,24,37,17,21,17, 21,17,72,28,32,28,48,40,47,28,48,21,25,21,25,0, @@ -1137,17 +1137,17 @@ const unsigned char _Py_M__zipimport[] = { 29,30,50,15,51,9,51,10,13,10,23,24,31,10,32,5, 56,36,38,9,84,13,15,13,33,21,32,13,33,13,33,13, 33,0,0,9,84,16,23,9,84,9,84,9,84,9,84,19, - 33,34,69,35,42,34,69,34,69,76,83,19,84,19,84,13, + 33,34,69,58,65,34,69,34,69,76,83,19,84,19,84,13, 84,9,84,0,0,18,20,18,29,26,28,18,29,9,15,12, 15,16,22,12,23,27,29,12,29,9,58,19,27,28,57,19, 58,13,58,12,18,19,21,20,21,19,21,12,22,26,39,12, - 39,9,86,19,33,34,71,35,42,34,71,34,71,78,85,19, + 39,9,86,19,33,34,71,60,67,34,71,34,71,78,85,19, 86,19,86,13,86,21,35,36,42,43,45,46,48,43,48,36, 49,21,50,9,18,22,36,37,43,44,46,47,49,44,49,37, 50,22,51,9,19,23,25,28,37,23,37,40,50,23,50,9, 20,9,20,24,35,9,35,9,20,9,84,13,15,13,33,21, 32,13,33,13,33,13,33,0,0,9,84,16,23,9,84,9, - 84,9,84,9,84,19,33,34,69,35,42,34,69,34,69,76, + 84,9,84,9,84,19,33,34,69,58,65,34,69,34,69,76, 83,19,84,19,84,13,84,9,84,0,0,20,22,20,38,28, 37,20,38,9,17,12,15,16,24,12,25,29,38,12,38,9, 56,19,26,27,55,19,56,13,56,9,56,5,56,5,56,5, @@ -1241,10 +1241,10 @@ const unsigned char _Py_M__zipimport[] = { 57,13,58,9,34,9,21,23,34,12,24,9,28,21,30,31, 45,46,50,51,52,53,55,51,55,46,56,31,57,59,71,21, 72,13,28,21,35,36,40,41,43,44,46,41,46,36,47,21, - 48,52,63,21,63,13,28,17,27,17,44,21,58,22,30,21, + 48,52,63,21,63,13,28,17,27,17,44,21,58,46,54,21, 58,21,58,17,59,17,59,24,28,24,28,12,19,12,25,26, 30,31,33,31,34,31,34,26,35,12,36,5,9,12,22,23, - 27,29,39,12,40,5,78,15,24,25,77,26,34,25,77,25, + 27,29,39,12,40,5,78,15,24,25,77,44,52,25,77,25, 77,25,77,15,78,9,78,12,16,5,16,114,10,0,0,0, 99,1,0,0,0,0,0,0,0,0,0,0,0,4,0,0, 0,3,0,0,0,115,28,0,0,0,124,0,160,0,100,1, @@ -1402,7 +1402,7 @@ const unsigned char _Py_M__zipimport[] = { 25,23,32,33,34,23,35,13,20,20,24,26,35,37,44,20, 44,13,44,13,44,13,44,12,24,9,83,19,56,42,54,19, 56,19,56,13,16,19,33,34,37,44,52,19,53,19,53,59, - 71,13,71,19,33,34,67,35,43,34,67,34,67,74,82,19, + 71,13,71,19,33,34,67,55,63,34,67,34,67,74,82,19, 83,19,83,13,83,115,35,0,0,0,158,5,36,2,164,7, 46,9,173,1,46,9,190,8,65,7,2,193,7,7,65,26, 9,193,14,2,65,21,9,193,21,5,65,26,9,41,46,114, |