Насколько я могу судить, его наличие используется в качестве маркера для запуска дополнительного кода в print_exception
в pythonrun.c
для распечатки файла и строки синтаксической ошибки, а также фактического текста линия и каретка, обозначающие позицию ошибки, после распечатки остальной части трассировки стека. Помните, что код с синтаксической ошибкой никогда не выполняется - в конце концов, его не удалось импортировать - поэтому он фактически не является частью трассировки стека. У меня сложилось впечатление, что print_file_and_line
- это скорее фрагмент реализации, чем то, с чем вы можете с пользой взаимодействовать.
Когда вы видите трассировку, напечатанную из-за синтаксической ошибки, эти строки, отмеченные <<<
ниже, печатаются из-за этого кода.
$ echo ')' > syntax_error.py
$ python -c 'import syntax_error'
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "syntax_error.py", line 1 <<<
) <<<
^ <<<
SyntaxError: invalid syntax
Код находится в pythonrun.c
здесь:
https://github.com/python/cpython/blob/37fcbb65d4589fbb5a72153e9338cf8e6495f64f/Python/pythonrun.c#L795 -L827
И выглядит это:
if (err == 0 &&
_PyObject_HasAttrId(value, &PyId_print_file_and_line))
{
PyObject *message, *filename, *text;
int lineno, offset;
if (!parse_syntax_error(value, &message, &filename,
&lineno, &offset, &text))
PyErr_Clear();
else {
PyObject *line;
Py_DECREF(value);
value = message;
line = PyUnicode_FromFormat(" File \"%S\", line %d\n",
filename, lineno);
Py_DECREF(filename);
if (line != NULL) {
PyFile_WriteObject(line, f, Py_PRINT_RAW);
Py_DECREF(line);
}
if (text != NULL) {
print_error_text(f, offset, text);
Py_DECREF(text);
}
/* Can't be bothered to check all those
PyFile_WriteString() calls */
if (PyErr_Occurred())
err = -1;
}
}
Я попытался провести эксперимент, чтобы проверить это. Если я запускаю этот скрипт:
class FakeSyntaxException(Exception):
print_file_and_line = None
def __init__(self):
self.text = 'Here is some text'
self.lineno = 123
self.offset = 6
self.msg = 'Something went wrong'
self.filename = 'example.txt'
raise FakeSyntaxException()
Я вижу:
$ python3 python_syntax_test.py
Traceback (most recent call last):
File "python_syntax_test.py", line 10, in <module>
raise FakeSyntaxException()
File "example.txt", line 123
Here is some text
^
__main__.FakeSyntaxException: Something went wrong
Принимая во внимание, что если я закомментирую строку print_file_and_line
, я вижу только:
$ python3 python_syntax_test.py
Traceback (most recent call last):
File "python_syntax_test.py", line 10, in <module>
raise FakeSyntaxException()
__main__.FakeSyntaxException