Greetings!
Python scripting is indeed very fun but debugging it can be a bit difficult inside of KeyShot. This is due to how KeyShot manages its own Python interpreter. While our interpreter will load site-packages from a system-installed Python, if major and minor versions match, it is still executing via our own interpreter. Furthermore, KeyShot’s Python interpreter lives in the main thread (for implementation-specific reasons) so if this thread is suspended, so is the entirety of KeyShot.
However, if KeyShot is started from the command-line with the -script
argument, then it will be possible to interact with a debugger on stdin
(this is needed in order to give commands to the debugger while trapped inside it).
I’ll show a short example using Python’s built-in pdb
debugging module:
if __name__ == "__main__":
i = 0
breakpoint()
while i < 2:
i += 1
# Only needed if not using argument `-headless` or executable `keyshot_headless.exe`.
exit(0)
Save that to “test.py”.
Figure out the absolute path to the folder containing the KeyShot executable from your installation folder (let’s call that $abspath
).
Run KeyShot in either headless or GUI mode
$abspath/keyshot -script test.py # GUI
$abspath/keyshot -headless -script test.py # Headless *nix
$abspath/keyshot_headless.exe -script test.py # Headless Windows
The script will enter the debugger when breakpoint()
is invoked.
It will look similar to the following depending on the shell:
...a lot of text ignored...
[pyout] > <string>(4)<module>()
[pyout] (Pdb)
It will look weird because KeyShot is not supporting the debugging mode specifically!
At this point, pdb
will have trapped on line 4: while i < 2:
.
Inspect the i
variable:
p i
[pyout] 0
[pyout] (Pdb)
Then we could create a watch point whenever the the variable changes:
display i
[pyout] display i: 0
[pyout] (Pdb)
Then we step through the execution using n
(shorthand for next
) and see the variable changes:
n
[pyout] > <string>(5)<module>()
[pyout] (Pdb)
n
[pyout] > <string>(4)<module>()
[pyout] display i: 1 [old: 0]
[pyout] (Pdb)
n
[pyout] > <string>(5)<module>()
[pyout] (Pdb)
n
[pyout] > <string>(4)<module>()
[pyout] display i: 2 [old: 1]
[pyout] (Pdb)
n
[pyout] > <string>(7)<module>()
[pyout] (Pdb)
n
[pyout] SystemExit: 0
[pyout] > <string>(7)<module>()
[pyout] (Pdb)
Note the lines containing “display i: NEW [old: OLD]”.
Also note that KeyShot may behave with I/O errors when exitting the debugger.
Since you cannot interact easily via the GUI to introduce breakpoints, you can add them in code while testing. Like the following example:
if __name__ == "__main__":
i = 0
while i < 10:
if i == 5:
breakpoint()
i += 1
# Only needed if not using argument `-headless` or executable `keyshot_headless.exe`.
exit(0)
Here we enter the debugger when i == 5
:
p i
[pyout] 5
[pyout] (pdb)
c
c
is shorthand for continue
which resumes the program execution.
I recommend reading the documentation of pdf
.
Including the section about “Debugger Commands”.
You can also get help by using the help
command while trapped inside pdb
.
This was just a very simple example, and I hope it might be of some help.
/Morten