2013-05-24 27 views
7

私のアプリケーションにはPythonインタプリタが組み込まれています。私はPyRun_String() APIを使用してPythonスクリプトを実行するために使用します。エラー/例外が発生した場合は、PyErr_Fetch()を使用してエラー情報を取得できます。これは私に例外タイプ、例外値、例外トレースバックを与えます。私はトレースバックから元のエラーの行番号を見つける。しかし、シンタックスエラーの場合は、私はトレースバックを取得しません。誰もトレースバックなしで行番号を取得する方法を知っています..?例外タイプまたは例外値を使用してそれを検索する方法はありますか?このクラスのSyntaxErrorのファイル名とリネオ属性を取得する方法

インスタンスが細部へのアクセスを容易にするための属性のファイル名、LINENO、オフセットやテキストを持っている:

Pythonドキュメントは次のように述べています。例外インスタンスのstr()はメッセージのみを返します。

組み込みのPythonでSyntaxErrorのファイル名とリネオ属性を取得するにはどうすればよいですか?

ご協力いただければ幸いです。前もって感謝します。


お寄せいただきありがとうございます。 しかし、すでにPyObject_GetAttr()を使って試してみました。

私はテスト目的で使用したサンプルコードを参照してください。

int main(int argc, char** argv) 
{ 
    Py_Initialize(); 

    // Get a reference to the main module. 
    PyObject* main_module = 
     PyImport_AddModule("__main__"); 

    // Get the main module's dictionary 
    // and make a copy of it. 
    PyObject* main_dict = 
     PyModule_GetDict(main_module); 

    const char *script_source = "def main():\n\tprint('Hello'\n\nmain()"; 

    PyObject *res = PyRun_String(script_source,Py_file_input,main_dict,main_dict); 
    if(res == NULL) 
    { 
     PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; 
     PyErr_Fetch(&ptype,&pvalue,&ptraceback); 

     PyObject* py_filename = PyUnicode_FromString("filename"); 
     PyObject* file_name = PyObject_GetAttr(ptype,py_filename); 

     PyObject* py_lineno = PyUnicode_FromString("lineno"); 
     PyObject* line_no = PyObject_GetAttr(ptype,py_lineno); 
    } 
} 

私は意図的にscript_sourceに構文エラーを挿入しました。

file_nameとline_noオブジェクトから実際のファイル名と行番号を取得できません。

file_nameとline_noオブジェクトをデバッグしようとしましたが、コンテンツは次のようになります。 "構文エラーオブジェクトのメンバーファイル名"および "構文エラーオブジェクトのメンバーlineno"

これらのオブジェクトは呼び出し可能ではないため、これらのオブジェクトはPyObject_Call()バリアントを使用できません。

これらのオブジェクトから実際のファイル名と行番号を取得する方法はありますか?

このファイル名には、PyRun_String()を使用しています。

答えて

1

属性はPySyntaxErrorObject structに設定されていますが、Pythonの安定したABIを遵守している場合は構造体が公開されていないことに注意してください。それ以外の場合は、a PyObject_GetAttr* functionを使用して属性を取得する必要があります。

3

私は次のように解決しました。 PyErr_Fetch()の後にPyErr_NormalizeException()を使用しましたが、コードは正常に動作しています。

int main(int argc, char** argv) 
{ 
    Py_Initialize(); 

    // Get a reference to the main module. 
    PyObject* main_module = 
     PyImport_AddModule("__main__"); 

    // Get the main module's dictionary 
    // and make a copy of it. 
    PyObject* main_dict = 
     PyModule_GetDict(main_module); 

    const char *script_source = "def main():\n\tprint('Hello'\n\nmain()"; 

    PyObject *res = PyRun_String(script_source,Py_file_input,main_dict,main_dict); 
    if(res == NULL) 
    { 
     PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL; 
     PyErr_Fetch(&ptype,&pvalue,&ptraceback); 
     PyErr_NormalizeException(&ptype,&pvalue,&ptraceback); 

     char *msg; 
     char *file; 
     int line; 
     int offset; 
     char *text; 

     int res = PyArg_ParseTuple(pvalue,"s(siis)",&msg,&file,&line,&offset,&text); 

     PyObject* file_name = PyObject_GetAttrString(pvalue,"filename"); 
     PyObject* file_name_str = PyObject_Str(file_name); 
     PyObject* file_name_unicode = PyUnicode_AsEncodedString(file_name_str,"utf-8", "Error"); 
     char *actual_file_name = PyBytes_AsString(file_name_unicode); 

     PyObject* line_no = PyObject_GetAttrString(pvalue,"lineno"); 
     PyObject* line_no_str = PyObject_Str(line_no); 
     PyObject* line_no_unicode = PyUnicode_AsEncodedString(line_no_str,"utf-8", "Error"); 
     char *actual_line_no = PyBytes_AsString(line_no_unicode); 

     printf("done"); 
    } 
} 
関連する問題