Support server debugging with PyCharm and VS Code (pydevd)
Debugging
When running a Tango device server through a debugger in an integrated development environment (e.g., PyCharm or Visual Studio Code) there are some limitations to the breakpoints that can be triggered.
A breakpoint in the init_device
method is available
the first time it is called, since it is running in the main
application thread. Breakpoints in command and attribute handler methods
(and a few others, like always_executed_hook
) are only triggered
if the client (e.g., via a DeviceProxy
) is in the same process as the
Tango server. When performing tests using DeviceTestContext
we can debug
commands and attribute access as the test runner, is in the same process
of the device server under test.
When we want to debug a device with external clients (e.g., Jive, or when we
use DeviceTestContext(..., process=True)
) the debugger doesn't
work. We get a breakpoint in the initial call to init_device
, but nothing
else. This is because command and attribute access is initiated from a
cppTango thread which makes a callback into the Python code - the debugger isn't
tracing this thread.
Interestingly, debugging already works correctly with GreenMode.Asyncio
devices before this
change (and still works after it).
We now support pydevd debuggers (used by PyCharm and Visual Studio Code), so breakpoints set in all standard device methods will be triggered correctly.
The implementation is similar to that done for handling code coverage.
If a debug run is detected, the pydevd.settrace()
method is called
explicitly for these standard functions. It can be disabled by defining
the environment variable PYTANGO_DISABLE_DEBUG_TRACE_PATCHING
.
Note: if the debugger is used at the same time that a coverage run is active, the debugger takes precedence. The patching is only applied for the debugger, not for coverage.
Restore test coverage reporting in CI
Coverage results were only showing the tests
folder on CI. We want to check
the package code too! Instead of installing the wheels, we do a local install
with pip -e .
. This means we don't test building from the source wheels, but
we still test compilation from source. The test coverage reporting on the MR
diff will work as well.