summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Galindo Salgado <Pablogsal@gmail.com>2021-08-12 16:13:30 (GMT)
committerGitHub <noreply@github.com>2021-08-12 16:13:30 (GMT)
commit8e832fb2a2cb54d7262148b6ec15563dffb48d63 (patch)
tree0b3fb52778df472a467635e1a8ca8632030ed7b6
parent789a6af29f531f78abd2e2f6af80084ccabf80b1 (diff)
downloadcpython-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.py40
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2021-08-11-15-39-57.bpo-44885.i4noUO.rst2
-rw-r--r--Parser/string_parser.c68
-rw-r--r--Python/importlib.h6
-rw-r--r--Python/importlib_external.h24
-rw-r--r--Python/importlib_zipimport.h54
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,