Dynamic command with no argument raises DevFailed exception
In PyTango 10.0.2, if you have a device that has a dynamic command with no argument (dtype_in=None), then calling the command raises a DevFailed exception.
Here is a device server that demonstrates the problem:
from tango.server import Device, command
class DynamicCommand(Device):
def init_device(self):
super().init_device()
device_level = True
cmd = command(f=self.command1)
self.add_command(cmd, device_level)
cmd = command(f=self.command2, dtype_out=float)
self.add_command(cmd, device_level)
cmd = command(f=self.command3, dtype_in=float, dtype_out=float)
self.add_command(cmd, device_level)
def command1(self) -> None:
print("command1 has been called")
def command2(self) -> float:
print("command2 has been called")
return 2.0
def command3(self, value: float) -> float:
print("command3 has been called")
return 2.0 * value
Calling command3 works as expected, but calling command1 or command2 raises DevFailed. The full DevFailed exception is, e.g.
DevFailed[
DevError[
desc = TypeError: DynamicCommand.command1() missing 1 required positional argument: 'self'
origin = UNKNOWN: cannot get Python's traceback. Most probably, was a failure in c++ bindings
reason = PyDs_PythonError
severity = ERR]
DevError[
desc = Cannot execute command
origin = virtual CORBA::Any *PyCmd::execute(Tango::DeviceImpl *, const CORBA::Any &) at (/Users/gitlab/builds/tango-controls/pytango/ext/server/command.cpp:311)
reason = PyDs_UnexpectedFailure
severity = ERR]
DevError[
desc = Failed to execute command_inout on device foo/bar/baz, command command1
origin = virtual DeviceData Tango::Connection::command_inout(const std::string &, const DeviceData &) at (/Users/runner/miniforge3/conda-bld/cpptango_1739462625904/work/src/client/devapi_base.cpp:1432)
reason = API_CommandFailed
severity = ERR]
]
The code works as expected with PyTango 9.5.1.