Python:使用 lineno 引发语法错误

问题描述 投票:0回答:4

我正在为特定于域的语言实现一个解析器,并且希望能够引发语法错误。引发此异常时如何设置文件名、行号和偏移量?

异常 语法错误

当解析器遇到语法时引发 错误。这可能发生在 import 语句、exec 语句、 调用内置函数 eval() 或 input(),或者读取 初始脚本或标准输入(也可以交互)。

此类的实例具有属性 filename、lineno、offset 和 文本以便更轻松地访问详细信息。异常实例的str() 仅返回消息。

来源:https://docs.python.org/3.2/library/exceptions.html#SyntaxError

python parsing python-3.x exception syntax-error
4个回答
14
投票

答案是:

>>> raise SyntaxError('End quote missing', ("test.py", 1000, 11, "print 'bar"))                                                                             
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "test.py", line 1000
    print 'bar
              ^
SyntaxError: End quote missing

第二个参数需要是 4 元组。


2
投票

您可以在这里查看:https://github.com/python/cpython/blob/master/Objects/exceptions.c#L1273

我只能想出这个:

import traceback

print("Our exception")

try:
    print("(1)")
    raise SyntaxError('Test2', {'filename': "test.py", 'lineno': 1000, 'offset': 1, 'text': "My text ..."})
except SyntaxError as inst:
    print("(2)")
    print(inst.args)
    print("(3) Get filename %s" % inst.args[1]['filename'])
    print("(4) Traceback")
    traceback.print_tb(inst.__traceback__) 

则输出为:

Our exception
(1)
(2)
('Test2', {'offset': 1, 'filename': 'test.py', 'text': 'My text ...', 'lineno': 1000})
(3) Get filename test.py
(4) Traceback
  File "test.py", line 7, in <module>
    raise SyntaxError('Test2', {'filename': "test.py", 'lineno': 1000, 'offset': 1, 'text': "My text ..."})

0
投票

怎么样:

raise SyntaxError('filename: {}, lineno: {}, offset: {}'.format(
    filename, lineno, offset))

0
投票

@MartyIX 向我透露了固体,所以我提供了一个工作原型:

full_filename = "test_python_config_file.py"

def process_config(this_file):

    try:
        my_python_config_importer(this_file)

    except SyntaxError as e:
        raise SyntaxError(
            f"Error invalid syntax at line number {e.end_lineno}"
            f" column offset {e.end_offset}",
            {
                "filename": this_file,
                "lineno": int(e.lineno),
                "offset": int(e.offset),
                "text": e.text,
                "end_lineno": int(e.end_lineno),
                "end_offset": int(e.end_offset),
            },
        ) from e

# main
try:
    process_config(filename)
except SyntaxError as my_e:
    # Viola!
    print("Line number", my_e.value.args[1]["lineno"])
    print("Line offset", my_e.value.args[1]["offset"])
    # extract other `value[1]` fields, as needed

© www.soinside.com 2019 - 2024. All rights reserved.