fisallowed=<non-device method callable> does not work in high-level attribute API
According to the documentation (https://pytango.readthedocs.io/en/stable/server_api/server.html#tango.server.attribute), we're allowed to provide an ad-hoc function for the fisallowed parameter of an attribute, just like for fget and fset. However, doing this results in the provided function not being called, for example:
from tango.server import Device, attribute
from tango.test_context import DeviceTestContext
def is_A_allowed_global(*args, **kwargs):
print("is_A_allowed called globally with args", args, kwargs)
return False
class test_device(Device):
A = attribute(dtype=float, fisallowed=is_A_allowed_global)
def init_device(self):
print("init_device")
Device.init_device(self)
def read_A(self):
return 42.0
def is_A_allowed_obj(*args, **kwargs):
print("is_A_allowed called on object with args", args, kwargs)
return False
if __name__ == "__main__":
with DeviceTestContext(test_device, process=True) as proxy:
proxy.init()
print(proxy.A)
The above code results in the following output:
Can't create notifd event supplier. Notifd event not available
init_device
Ready to accept request
init_device
42.0
Even though the provided fisallowed function always returns False. Note that setting fisallowed="is_A_allowed_obj" for example, as expected, does work in the above setup, but will of course redirect the call to test_device.is_A_allowed_obj.
We use the fget/fset=<callable> construct to dynamically provide the attribute access using a derived attribute class. It would be very nice to be able to take fisallowed along in the same construct, to allow full flexibility in the attribute access definition.