Skip to content

Incorrect error place reported in python traceback #542

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
testrunner123 opened this issue Sep 15, 2017 · 6 comments
Closed

Incorrect error place reported in python traceback #542

testrunner123 opened this issue Sep 15, 2017 · 6 comments

Comments

@testrunner123
Copy link
Contributor

Environment

  • Pythonnet version: 2.3.0
  • Python version: 3.4 64-bit
  • Operating System: Ubuntu 14.04

Details

  • I tried to run test program and got following:

GetPreferredSize
Traceback (most recent call last):
File "t.py", line 29, in
main()
File "t.py", line 24, in main
form = StatusWindow()
File "t.py", line 19, in init
self.Controls.Add(_StagesGroup())
NameError: name 'xyz' is not defined

As we see, function GetPrefferedSize() got called. But stack traceback shows error in line 19 that is wrong. Bacause error is in line 14.

python3 t.py

import clr, sys
import System.Windows.Forms as WinForms
import System.Drawing as Drawing

class _StagesGroup(WinForms.GroupBox):
    __namespace__ = "System.Windows.Forms"
    def __init__(self):
        self.Text = "Stages"
        self.AutoSize = True

    def GetPreferredSize(self, proposedSize):
        print ("GetPreferredSize")
        retsz = WinForms.GroupBox.GetPreferredSize(self, proposedSize)
        print("GetPreferredSize",xyz)
        return retsz

class StatusWindow(WinForms.Form):
    def __init__(self):
        self.Controls.Add(_StagesGroup())
    def run(self):
        WinForms.Application.Run(self)

def main():
    form = StatusWindow()
    app = WinForms.Application
    app.Run(form)

if __name__ == '__main__':
    main()

So why the error place is incorrect in traceback?

@den-run-ai
Copy link
Contributor

Oh, I see that this is caused by __namespace__ = "System.Windows.Forms". Can you explain how GetPreferredSize gets called? The traceback is likely broken due to callback to CLR?

@testrunner123
Copy link
Contributor Author

Can you explain how GetPreferredSize gets called?

GetPreferredSize() here is an overload for virtual method of System.Windows.Forms.GroupBox class. It is called from .NET code inside self.Controls.Add() method of System.Windows.Forms.Form class. So callstack is: Python -> .NET ->Python GetPreferredSize().

It is really difficult to debug Python script with such traceback. Situation is slightly better if Exception was thrown - by changing in source "WinForms.GroupBox.GetPreferredSize" to "WinForms.GroupBox" I get:

Traceback (most recent call last):
File "t1.py", line 32, in
main()
File "t1.py", line 24, in main
form = StatusWindow()
File "t1.py", line 18, in init
self.Controls.Add(_StagesGroup())
System.InvalidCastException: cannot convert object to target type
at Python.Runtime.PyObject.AsManagedObject (System.Type t) [0x00016] in <90f56f11bd4c4fbf9e32746d89de693d>:0
at Python.Runtime.PythonDerivedType.InvokeMethod[T] (Python.Runtime.IPythonDerivedType obj, System.String methodName, System.String origMethodName, System.Object[] args) [0x00107] in <90f56f11bd4c4fbf9e32746d89de693d>:0
at System.Windows.Forms._StagesGroup.GetPreferredSize (System.Drawing.Size ) [0x00021] in <9b9523702e53439da45ef812ca9b9c8a>:0

Here I see at least method name "System.Windows.Forms._StagesGroup.GetPreferredSize" but also no line number.

@dmitriyse
Copy link
Contributor

Valid line numbers for the C# code in a stacktrace could appears only if .dll files are paired with .pdb files.
Please firstly verify that your setup contains .pdb files at the right location.

@testrunner123
Copy link
Contributor Author

@dmitriyse
The problem is that I can't generate .pdb for python code.

@denfromufa
My python script implements event handler or virtual method. At some points .NET class calls it through Pythonnet. I think you use in pythonnet something like PyObject_CallObject() for calling python callback, but I can't find a exact place where it is done.

Now, imagine python callback function got some interpreter error or exception. In this case PyObject_CallObject() returns NULL. Then pythonnet creates new exception object, isn't it ?
At this point pythonnet can fetch a traceback from exception and reattach it to new exception.

But at the moment pythonnet doesn't save traceback, so not possible to localize the source of error. I think this can be improved.
Do you know where in pythonnet source python virtual method or event callback are called ?

@tonyroberts
Copy link
Contributor

The Python method gets called via PyObject.Invoke in pyobject.cs (called from PythonDerivedType.InvokeMethod in classderived.cs). You could fetch the Python traceback in there and use that to add more information to the .net PythonException thrown.

@filmor
Copy link
Member

filmor commented Aug 6, 2021

I think this is fixed now.

@filmor filmor closed this as completed Aug 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants