| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -149,6 +149,11 @@ PyAPI_FUNC(PyObject *) PyErr_ProgramTextObject( | |||
| 149 | 149 | PyObject *filename, | |
| 150 | 150 | int lineno); | |
| 151 | 151 | ||
| 152 | + PyAPI_FUNC(PyObject *) _PyErr_ProgramDecodedTextObject( | ||
| 153 | + PyObject *filename, | ||
| 154 | + int lineno, | ||
| 155 | + const char* encoding); | ||
| 156 | + | ||
| 152 | 157 | PyAPI_FUNC(PyObject *) _PyUnicodeTranslateError_Create( | |
| 153 | 158 | PyObject *object, | |
| 154 | 159 | Py_ssize_t start, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2353,6 +2353,19 @@ def test_encodings(self): | |||
| 2353 | 2353 | finally: | |
| 2354 | 2354 | unlink(TESTFN) | |
| 2355 | 2355 | ||
| 2356 | + # Check backwards tokenizer errors | ||
| 2357 | + source = '# -*- coding: ascii -*-\n\n(\n' | ||
| 2358 | + try: | ||
| 2359 | + with open(TESTFN, 'w', encoding='ascii') as testfile: | ||
| 2360 | + testfile.write(source) | ||
| 2361 | + rc, out, err = script_helper.assert_python_failure('-Wd', '-X', 'utf8', TESTFN) | ||
| 2362 | + err = err.decode('utf-8').splitlines() | ||
| 2363 | + | ||
| 2364 | + self.assertEqual(err[-3], ' (') | ||
| 2365 | + self.assertEqual(err[-2], ' ^') | ||
| 2366 | + finally: | ||
| 2367 | + unlink(TESTFN) | ||
| 2368 | + | ||
| 2356 | 2369 | def test_attributes_new_constructor(self): | |
| 2357 | 2370 | args = ("bad.py", 1, 2, "abcdefg", 1, 100) | |
| 2358 | 2371 | the_exception = SyntaxError("bad bad", args) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Allow the parser to obtain error lines directly from encoded files. Patch by | ||
| 2 | + Pablo Galindo | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -482,14 +482,12 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, | |||
| 482 | 482 | goto error; | |
| 483 | 483 | } | |
| 484 | 484 | ||
| 485 | - // PyErr_ProgramTextObject assumes that the text is utf-8 so we cannot call it with a file | ||
| 486 | - // with an arbitrary encoding or otherwise we could get some badly decoded text. | ||
| 487 | - int uses_utf8_codec = (!p->tok->encoding || strcmp(p->tok->encoding, "utf-8") == 0); | ||
| 488 | 485 | if (p->tok->fp_interactive) { | |
| 489 | 486 | error_line = get_error_line(p, lineno); | |
| 490 | 487 | } | |
| 491 | - else if (uses_utf8_codec && p->start_rule == Py_file_input) { | ||
| 492 | - error_line = PyErr_ProgramTextObject(p->tok->filename, (int) lineno); | ||
| 488 | + else if (p->start_rule == Py_file_input) { | ||
| 489 | + error_line = _PyErr_ProgramDecodedTextObject(p->tok->filename, | ||
| 490 | + (int) lineno, p->tok->encoding); | ||
| 493 | 491 | } | |
| 494 | 492 | ||
| 495 | 493 | if (!error_line) { | |
@@ -500,15 +498,18 @@ _PyPegen_raise_error_known_location(Parser *p, PyObject *errtype, | |||
| 500 | 498 | we're actually parsing from a file, which has an E_EOF SyntaxError and in that case | |
| 501 | 499 | `PyErr_ProgramTextObject` fails because lineno points to last_file_line + 1, which | |
| 502 | 500 | does not physically exist */ | |
| 503 | - assert(p->tok->fp == NULL || p->tok->fp == stdin || p->tok->done == E_EOF || !uses_utf8_codec); | ||
| 501 | + assert(p->tok->fp == NULL || p->tok->fp == stdin || p->tok->done == E_EOF); | ||
| 504 | 502 | ||
| 505 | 503 | if (p->tok->lineno <= lineno && p->tok->inp > p->tok->buf) { | |
| 506 | 504 | Py_ssize_t size = p->tok->inp - p->tok->buf; | |
| 507 | 505 | error_line = PyUnicode_DecodeUTF8(p->tok->buf, size, "replace"); | |
| 508 | 506 | } | |
| 509 | - else { | ||
| 507 | + else if (p->tok->fp == NULL || p->tok->fp == stdin) { | ||
| 510 | 508 | error_line = get_error_line(p, lineno); | |
| 511 | 509 | } | |
| 510 | + else { | ||
| 511 | + error_line = PyUnicode_FromStringAndSize("", 0); | ||
| 512 | + } | ||
| 512 | 513 | if (!error_line) { | |
| 513 | 514 | goto error; | |
| 514 | 515 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1692,7 +1692,7 @@ PyErr_SyntaxLocationEx(const char *filename, int lineno, int col_offset) | |||
| 1692 | 1692 | functionality in tb_displayline() in traceback.c. */ | |
| 1693 | 1693 | ||
| 1694 | 1694 | static PyObject * | |
| 1695 | - err_programtext(PyThreadState *tstate, FILE *fp, int lineno) | ||
| 1695 | + err_programtext(PyThreadState *tstate, FILE *fp, int lineno, const char* encoding) | ||
| 1696 | 1696 | { | |
| 1697 | 1697 | int i; | |
| 1698 | 1698 | char linebuf[1000]; | |
@@ -1720,7 +1720,11 @@ err_programtext(PyThreadState *tstate, FILE *fp, int lineno) | |||
| 1720 | 1720 | fclose(fp); | |
| 1721 | 1721 | if (i == lineno) { | |
| 1722 | 1722 | PyObject *res; | |
| 1723 | - res = PyUnicode_FromString(linebuf); | ||
| 1723 | + if (encoding != NULL) { | ||
| 1724 | + res = PyUnicode_Decode(linebuf, strlen(linebuf), encoding, "replace"); | ||
| 1725 | + } else { | ||
| 1726 | + res = PyUnicode_FromString(linebuf); | ||
| 1727 | + } | ||
| 1724 | 1728 | if (res == NULL) | |
| 1725 | 1729 | _PyErr_Clear(tstate); | |
| 1726 | 1730 | return res; | |
@@ -1746,7 +1750,7 @@ PyErr_ProgramText(const char *filename, int lineno) | |||
| 1746 | 1750 | } | |
| 1747 | 1751 | ||
| 1748 | 1752 | PyObject * | |
| 1749 | - PyErr_ProgramTextObject(PyObject *filename, int lineno) | ||
| 1753 | + _PyErr_ProgramDecodedTextObject(PyObject *filename, int lineno, const char* encoding) | ||
| 1750 | 1754 | { | |
| 1751 | 1755 | if (filename == NULL || lineno <= 0) { | |
| 1752 | 1756 | return NULL; | |
@@ -1758,7 +1762,13 @@ PyErr_ProgramTextObject(PyObject *filename, int lineno) | |||
| 1758 | 1762 | _PyErr_Clear(tstate); | |
| 1759 | 1763 | return NULL; | |
| 1760 | 1764 | } | |
| 1761 | - return err_programtext(tstate, fp, lineno); | ||
| 1765 | + return err_programtext(tstate, fp, lineno, encoding); | ||
| 1766 | + } | ||
| 1767 | + | ||
| 1768 | + PyObject * | ||
| 1769 | + PyErr_ProgramTextObject(PyObject *filename, int lineno) | ||
| 1770 | + { | ||
| 1771 | + return _PyErr_ProgramDecodedTextObject(filename, lineno, NULL); | ||
| 1762 | 1772 | } | |
| 1763 | 1773 | ||
| 1764 | 1774 | #ifdef __cplusplus | |
| Back | FazBrowse Home | New Git URL |
0 commit comments