Mercurial > cpython-lru_cache-weakref
comparison Python/pythonrun.c @ 16831:27f04d714ecb legacy-trunk
Print the offending line of code in the traceback for SyntaxErrors
raised by the compiler.
XXX For now, text entered into the interactive intepreter is not
printed in the traceback.
Inspired by a patch from Roman Sulzhyk
compile.c:
Add helper fetch_program_text() that opens a file and reads until it
finds the specified line number. The code is a near duplicate of
similar code in traceback.c.
Modify com_error() to pass two arguments to SyntaxError constructor,
where the second argument contains the offending text when possible.
Modify set_error_location(), now used only by the symtable pass, to
set the text attribute on existing exceptions.
pythonrun.c:
Change parse_syntax_error() to continue of the offset attribute of a
SyntaxError is None. In this case, it sets offset to -1.
Move code from PyErr_PrintEx() into helper function
print_error_text(). In the helper, only print the caret for a
SyntaxError if offset > 0.
| author | Jeremy Hylton <jeremy@alum.mit.edu> |
|---|---|
| date | Wed, 28 Feb 2001 07:07:43 +0000 |
| parents | a51b9961f3bb |
| children | 09dcf5ebcd80 |
comparison
equal
deleted
inserted
replaced
| 16830:f5370e1e2392 | 16831:27f04d714ecb |
|---|---|
| 691 goto finally; | 691 goto finally; |
| 692 *lineno = (int)hold; | 692 *lineno = (int)hold; |
| 693 | 693 |
| 694 if (!(v = PyObject_GetAttrString(err, "offset"))) | 694 if (!(v = PyObject_GetAttrString(err, "offset"))) |
| 695 goto finally; | 695 goto finally; |
| 696 hold = PyInt_AsLong(v); | 696 if (v == Py_None) { |
| 697 Py_DECREF(v); | 697 *offset = -1; |
| 698 v = NULL; | 698 Py_DECREF(v); |
| 699 if (hold < 0 && PyErr_Occurred()) | 699 v = NULL; |
| 700 goto finally; | 700 } else { |
| 701 *offset = (int)hold; | 701 hold = PyInt_AsLong(v); |
| 702 Py_DECREF(v); | |
| 703 v = NULL; | |
| 704 if (hold < 0 && PyErr_Occurred()) | |
| 705 goto finally; | |
| 706 *offset = (int)hold; | |
| 707 } | |
| 702 | 708 |
| 703 if (!(v = PyObject_GetAttrString(err, "text"))) | 709 if (!(v = PyObject_GetAttrString(err, "text"))) |
| 704 goto finally; | 710 goto finally; |
| 705 if (v == Py_None) | 711 if (v == Py_None) |
| 706 *text = NULL; | 712 *text = NULL; |
| 716 | 722 |
| 717 void | 723 void |
| 718 PyErr_Print(void) | 724 PyErr_Print(void) |
| 719 { | 725 { |
| 720 PyErr_PrintEx(1); | 726 PyErr_PrintEx(1); |
| 727 } | |
| 728 | |
| 729 static void | |
| 730 print_error_text(PyObject *f, int offset, char *text) | |
| 731 { | |
| 732 char *nl; | |
| 733 if (offset >= 0) { | |
| 734 if (offset > 0 && offset == (int)strlen(text)) | |
| 735 offset--; | |
| 736 for (;;) { | |
| 737 nl = strchr(text, '\n'); | |
| 738 if (nl == NULL || nl-text >= offset) | |
| 739 break; | |
| 740 offset -= (nl+1-text); | |
| 741 text = nl+1; | |
| 742 } | |
| 743 while (*text == ' ' || *text == '\t') { | |
| 744 text++; | |
| 745 offset--; | |
| 746 } | |
| 747 } | |
| 748 PyFile_WriteString(" ", f); | |
| 749 PyFile_WriteString(text, f); | |
| 750 if (*text == '\0' || text[strlen(text)-1] != '\n') | |
| 751 PyFile_WriteString("\n", f); | |
| 752 if (offset == -1) | |
| 753 return; | |
| 754 PyFile_WriteString(" ", f); | |
| 755 offset--; | |
| 756 while (offset > 0) { | |
| 757 PyFile_WriteString(" ", f); | |
| 758 offset--; | |
| 759 } | |
| 760 PyFile_WriteString("^\n", f); | |
| 721 } | 761 } |
| 722 | 762 |
| 723 void | 763 void |
| 724 PyErr_PrintEx(int set_sys_last_vars) | 764 PyErr_PrintEx(int set_sys_last_vars) |
| 725 { | 765 { |
| 793 PyFile_WriteString(filename, f); | 833 PyFile_WriteString(filename, f); |
| 794 PyFile_WriteString("\", line ", f); | 834 PyFile_WriteString("\", line ", f); |
| 795 sprintf(buf, "%d", lineno); | 835 sprintf(buf, "%d", lineno); |
| 796 PyFile_WriteString(buf, f); | 836 PyFile_WriteString(buf, f); |
| 797 PyFile_WriteString("\n", f); | 837 PyFile_WriteString("\n", f); |
| 798 if (text != NULL) { | 838 if (text != NULL) |
| 799 char *nl; | 839 print_error_text(f, offset, text); |
| 800 if (offset > 0 && | |
| 801 offset == (int)strlen(text)) | |
| 802 offset--; | |
| 803 for (;;) { | |
| 804 nl = strchr(text, '\n'); | |
| 805 if (nl == NULL || | |
| 806 nl-text >= offset) | |
| 807 break; | |
| 808 offset -= (nl+1-text); | |
| 809 text = nl+1; | |
| 810 } | |
| 811 while (*text == ' ' || *text == '\t') { | |
| 812 text++; | |
| 813 offset--; | |
| 814 } | |
| 815 PyFile_WriteString(" ", f); | |
| 816 PyFile_WriteString(text, f); | |
| 817 if (*text == '\0' || | |
| 818 text[strlen(text)-1] != '\n') | |
| 819 PyFile_WriteString("\n", f); | |
| 820 PyFile_WriteString(" ", f); | |
| 821 offset--; | |
| 822 while (offset > 0) { | |
| 823 PyFile_WriteString(" ", f); | |
| 824 offset--; | |
| 825 } | |
| 826 PyFile_WriteString("^\n", f); | |
| 827 } | |
| 828 Py_INCREF(message); | 840 Py_INCREF(message); |
| 829 Py_DECREF(v); | 841 Py_DECREF(v); |
| 830 v = message; | 842 v = message; |
| 831 /* Can't be bothered to check all those | 843 /* Can't be bothered to check all those |
| 832 PyFile_WriteString() calls */ | 844 PyFile_WriteString() calls */ |
