| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 2d5f4ba commit a3480ec
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -532,6 +532,23 @@ def f_with_binary_operator(): | |||
| 532 | 532 | result_lines = self.get_exception(f_with_binary_operator) | |
| 533 | 533 | self.assertEqual(result_lines, expected_error.splitlines()) | |
| 534 | 534 | ||
| 535 | + def test_caret_for_binary_operators_with_unicode(self): | ||
| 536 | + def f_with_binary_operator(): | ||
| 537 | + áóí = 20 | ||
| 538 | + return 10 + áóí / 0 + 30 | ||
| 539 | + | ||
| 540 | + lineno_f = f_with_binary_operator.__code__.co_firstlineno | ||
| 541 | + expected_error = ( | ||
| 542 | + 'Traceback (most recent call last):\n' | ||
| 543 | + f' File "{__file__}", line {self.callable_line}, in get_exception\n' | ||
| 544 | + ' callable()\n' | ||
| 545 | + f' File "{__file__}", line {lineno_f+2}, in f_with_binary_operator\n' | ||
| 546 | + ' return 10 + áóí / 0 + 30\n' | ||
| 547 | + ' ~~~~^~~\n' | ||
| 548 | + ) | ||
| 549 | + result_lines = self.get_exception(f_with_binary_operator) | ||
| 550 | + self.assertEqual(result_lines, expected_error.splitlines()) | ||
| 551 | + | ||
| 535 | 552 | def test_caret_for_binary_operators_two_char(self): | |
| 536 | 553 | def f_with_binary_operator(): | |
| 537 | 554 | divisor = 20 | |
@@ -566,6 +583,23 @@ def f_with_subscript(): | |||
| 566 | 583 | result_lines = self.get_exception(f_with_subscript) | |
| 567 | 584 | self.assertEqual(result_lines, expected_error.splitlines()) | |
| 568 | 585 | ||
| 586 | + def test_caret_for_subscript_unicode(self): | ||
| 587 | + def f_with_subscript(): | ||
| 588 | + some_dict = {'ó': {'á': {'í': {'theta': 1}}}} | ||
| 589 | + return some_dict['ó']['á']['í']['beta'] | ||
| 590 | + | ||
| 591 | + lineno_f = f_with_subscript.__code__.co_firstlineno | ||
| 592 | + expected_error = ( | ||
| 593 | + 'Traceback (most recent call last):\n' | ||
| 594 | + f' File "{__file__}", line {self.callable_line}, in get_exception\n' | ||
| 595 | + ' callable()\n' | ||
| 596 | + f' File "{__file__}", line {lineno_f+2}, in f_with_subscript\n' | ||
| 597 | + " return some_dict['ó']['á']['í']['beta']\n" | ||
| 598 | + ' ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^\n' | ||
| 599 | + ) | ||
| 600 | + result_lines = self.get_exception(f_with_subscript) | ||
| 601 | + self.assertEqual(result_lines, expected_error.splitlines()) | ||
| 602 | + | ||
| 569 | 603 | def test_traceback_specialization_with_syntax_error(self): | |
| 570 | 604 | bytecode = compile("1 / 0 / 1 / 2\n", TESTFN, "exec") | |
| 571 | 605 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -585,12 +585,15 @@ def _extract_caret_anchors_from_line_segment(segment): | |||
| 585 | 585 | if len(tree.body) != 1: | |
| 586 | 586 | return None | |
| 587 | 587 | ||
| 588 | + normalize = lambda offset: _byte_offset_to_character_offset(segment, offset) | ||
| 588 | 589 | statement = tree.body[0] | |
| 589 | 590 | match statement: | |
| 590 | 591 | case ast.Expr(expr): | |
| 591 | 592 | match expr: | |
| 592 | 593 | case ast.BinOp(): | |
| 593 | - operator_str = segment[expr.left.end_col_offset:expr.right.col_offset] | ||
| 594 | + operator_start = normalize(expr.left.end_col_offset) | ||
| 595 | + operator_end = normalize(expr.right.col_offset) | ||
| 596 | + operator_str = segment[operator_start:operator_end] | ||
| 594 | 597 | operator_offset = len(operator_str) - len(operator_str.lstrip()) | |
| 595 | 598 | ||
| 596 | 599 | left_anchor = expr.left.end_col_offset + operator_offset | |
@@ -600,9 +603,11 @@ def _extract_caret_anchors_from_line_segment(segment): | |||
| 600 | 603 | and not operator_str[operator_offset + 1].isspace() | |
| 601 | 604 | ): | |
| 602 | 605 | right_anchor += 1 | |
| 603 | - return _Anchors(left_anchor, right_anchor) | ||
| 606 | + return _Anchors(normalize(left_anchor), normalize(right_anchor)) | ||
| 604 | 607 | case ast.Subscript(): | |
| 605 | - return _Anchors(expr.value.end_col_offset, expr.slice.end_col_offset + 1) | ||
| 608 | + subscript_start = normalize(expr.value.end_col_offset) | ||
| 609 | + subscript_end = normalize(expr.slice.end_col_offset + 1) | ||
| 610 | + return _Anchors(subscript_start, subscript_end) | ||
| 606 | 611 | ||
| 607 | 612 | return None | |
| 608 | 613 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Fix the error reporting positions of specialized traceback anchors when the | ||
| 2 | + source line contains Unicode characters. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -705,8 +705,13 @@ extract_anchors_from_line(PyObject *filename, PyObject *line, | |||
| 705 | 705 | ||
| 706 | 706 | done: | |
| 707 | 707 | if (res > 0) { | |
| 708 | - *left_anchor += start_offset; | ||
| 709 | - *right_anchor += start_offset; | ||
| 708 | + // Normalize the AST offsets to byte offsets and adjust them with the | ||
| 709 | + // start of the actual line (instead of the source code segment). | ||
| 710 | + assert(segment != NULL); | ||
| 711 | + assert(*left_anchor >= 0); | ||
| 712 | + assert(*right_anchor >= 0); | ||
| 713 | + *left_anchor = _PyPegen_byte_offset_to_character_offset(segment, *left_anchor) + start_offset; | ||
| 714 | + *right_anchor = _PyPegen_byte_offset_to_character_offset(segment, *right_anchor) + start_offset; | ||
| 710 | 715 | } | |
| 711 | 716 | Py_XDECREF(segment); | |
| 712 | 717 | if (arena) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments