proper return value in handler read_* methods
wrapped read_* methods must always return a value + do not copy __name__ attribute of handler method to wrapped method Change-Id: I54cd4b37cf7452621ee734be393aec4611fe809b Reviewed-on: https://forge.frm2.tum.de/review/c/sine2020/secop/playground/+/27870 Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de> Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de> Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
This commit is contained in:
parent
c2596a9629
commit
aa82bc580d
@ -53,11 +53,19 @@ Example 2: addressable HW parameters
|
||||
return self.get_hw_register(HW_ADDR[pname])
|
||||
"""
|
||||
|
||||
from functools import wraps
|
||||
import functools
|
||||
from secop.modules import Done
|
||||
from secop.errors import ProgrammingError
|
||||
|
||||
|
||||
def wraps(func):
|
||||
"""decorator to copy function attributes of wrapped function"""
|
||||
# we modify the default here:
|
||||
# copy __doc__ , __module___ and attributes from __dict__
|
||||
# but not __name__ and __qualname__
|
||||
return functools.wraps(func, assigned=('__doc__', '__module__'))
|
||||
|
||||
|
||||
class Handler:
|
||||
func = None
|
||||
method_names = set() # this is shared among all instances of handlers!
|
||||
@ -120,9 +128,11 @@ class ReadHandler(Handler):
|
||||
def wrap(self, key):
|
||||
def method(module, pname=key, func=self.func):
|
||||
value = func(module, pname)
|
||||
if value is not Done:
|
||||
setattr(module, pname, value)
|
||||
if value is Done:
|
||||
return getattr(module, pname)
|
||||
setattr(module, pname, value)
|
||||
return value
|
||||
|
||||
return wraps(self.func)(method)
|
||||
|
||||
|
||||
@ -137,13 +147,14 @@ class CommonReadHandler(ReadHandler):
|
||||
self.first_key = next(iter(keys))
|
||||
|
||||
def wrap(self, key):
|
||||
def method(module, func=self.func):
|
||||
def method(module, pname=key, func=self.func):
|
||||
ret = func(module)
|
||||
if ret not in (None, Done):
|
||||
raise ProgrammingError('a method wrapped with CommonReadHandler must not return any value')
|
||||
return getattr(module, pname)
|
||||
|
||||
method = wraps(self.func)(method)
|
||||
method.poll = self.poll if key == self.first_key else False
|
||||
method.poll = self.poll and getattr(method, 'poll', True) if key == self.first_key else False
|
||||
return method
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
from secop.rwhandler import ReadHandler, WriteHandler, \
|
||||
CommonReadHandler, CommonWriteHandler, nopoll
|
||||
from secop.core import Module, Parameter, FloatRange
|
||||
from secop.core import Module, Parameter, FloatRange, Done
|
||||
|
||||
|
||||
class DispatcherStub:
|
||||
@ -104,6 +104,10 @@ def test_handler():
|
||||
assert m.b == 7
|
||||
assert data.pop() == 'b'
|
||||
|
||||
data.append(Done)
|
||||
assert m.read_b() == 7
|
||||
assert data.pop() == 'b'
|
||||
|
||||
assert data == []
|
||||
|
||||
|
||||
@ -141,13 +145,16 @@ def test_common_handler():
|
||||
assert data.pop() == 'write_hdl'
|
||||
|
||||
data.append((3, 4))
|
||||
m.read_a()
|
||||
assert m.read_a() == 3
|
||||
assert m.a == 3
|
||||
assert m.b == 4
|
||||
assert data.pop() == 'read_hdl'
|
||||
data.append((5, 6))
|
||||
assert m.read_b() == 6
|
||||
assert data.pop() == 'read_hdl'
|
||||
|
||||
data.append((1.1, 2.2))
|
||||
m.read_b()
|
||||
assert m.read_b() == 2.2
|
||||
assert m.a == 1.1
|
||||
assert m.b == 2.2
|
||||
assert data.pop() == 'read_hdl'
|
||||
@ -201,3 +208,27 @@ def test_nopoll():
|
||||
|
||||
assert Mod4.read_a.poll is False
|
||||
assert Mod4.read_b.poll is False
|
||||
|
||||
class Mod5(ModuleTest):
|
||||
a = Parameter('', FloatRange(), readonly=False)
|
||||
b = Parameter('', FloatRange(), readonly=False)
|
||||
|
||||
@CommonReadHandler(['a', 'b'])
|
||||
@nopoll
|
||||
def read_hdl(self):
|
||||
pass
|
||||
|
||||
assert Mod5.read_a.poll is False
|
||||
assert Mod5.read_b.poll is False
|
||||
|
||||
class Mod6(ModuleTest):
|
||||
a = Parameter('', FloatRange(), readonly=False)
|
||||
b = Parameter('', FloatRange(), readonly=False)
|
||||
|
||||
@nopoll
|
||||
@CommonReadHandler(['a', 'b'])
|
||||
def read_hdl(self):
|
||||
pass
|
||||
|
||||
assert Mod6.read_a.poll is False
|
||||
assert Mod6.read_b.poll is False
|
||||
|
Loading…
x
Reference in New Issue
Block a user