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])
|
return self.get_hw_register(HW_ADDR[pname])
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from functools import wraps
|
import functools
|
||||||
from secop.modules import Done
|
from secop.modules import Done
|
||||||
from secop.errors import ProgrammingError
|
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:
|
class Handler:
|
||||||
func = None
|
func = None
|
||||||
method_names = set() # this is shared among all instances of handlers!
|
method_names = set() # this is shared among all instances of handlers!
|
||||||
@ -120,9 +128,11 @@ class ReadHandler(Handler):
|
|||||||
def wrap(self, key):
|
def wrap(self, key):
|
||||||
def method(module, pname=key, func=self.func):
|
def method(module, pname=key, func=self.func):
|
||||||
value = func(module, pname)
|
value = func(module, pname)
|
||||||
if value is not Done:
|
if value is Done:
|
||||||
setattr(module, pname, value)
|
return getattr(module, pname)
|
||||||
|
setattr(module, pname, value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
return wraps(self.func)(method)
|
return wraps(self.func)(method)
|
||||||
|
|
||||||
|
|
||||||
@ -137,13 +147,14 @@ class CommonReadHandler(ReadHandler):
|
|||||||
self.first_key = next(iter(keys))
|
self.first_key = next(iter(keys))
|
||||||
|
|
||||||
def wrap(self, key):
|
def wrap(self, key):
|
||||||
def method(module, func=self.func):
|
def method(module, pname=key, func=self.func):
|
||||||
ret = func(module)
|
ret = func(module)
|
||||||
if ret not in (None, Done):
|
if ret not in (None, Done):
|
||||||
raise ProgrammingError('a method wrapped with CommonReadHandler must not return any value')
|
raise ProgrammingError('a method wrapped with CommonReadHandler must not return any value')
|
||||||
|
return getattr(module, pname)
|
||||||
|
|
||||||
method = wraps(self.func)(method)
|
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
|
return method
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
from secop.rwhandler import ReadHandler, WriteHandler, \
|
from secop.rwhandler import ReadHandler, WriteHandler, \
|
||||||
CommonReadHandler, CommonWriteHandler, nopoll
|
CommonReadHandler, CommonWriteHandler, nopoll
|
||||||
from secop.core import Module, Parameter, FloatRange
|
from secop.core import Module, Parameter, FloatRange, Done
|
||||||
|
|
||||||
|
|
||||||
class DispatcherStub:
|
class DispatcherStub:
|
||||||
@ -104,6 +104,10 @@ def test_handler():
|
|||||||
assert m.b == 7
|
assert m.b == 7
|
||||||
assert data.pop() == 'b'
|
assert data.pop() == 'b'
|
||||||
|
|
||||||
|
data.append(Done)
|
||||||
|
assert m.read_b() == 7
|
||||||
|
assert data.pop() == 'b'
|
||||||
|
|
||||||
assert data == []
|
assert data == []
|
||||||
|
|
||||||
|
|
||||||
@ -141,13 +145,16 @@ def test_common_handler():
|
|||||||
assert data.pop() == 'write_hdl'
|
assert data.pop() == 'write_hdl'
|
||||||
|
|
||||||
data.append((3, 4))
|
data.append((3, 4))
|
||||||
m.read_a()
|
assert m.read_a() == 3
|
||||||
assert m.a == 3
|
assert m.a == 3
|
||||||
assert m.b == 4
|
assert m.b == 4
|
||||||
assert data.pop() == 'read_hdl'
|
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))
|
data.append((1.1, 2.2))
|
||||||
m.read_b()
|
assert m.read_b() == 2.2
|
||||||
assert m.a == 1.1
|
assert m.a == 1.1
|
||||||
assert m.b == 2.2
|
assert m.b == 2.2
|
||||||
assert data.pop() == 'read_hdl'
|
assert data.pop() == 'read_hdl'
|
||||||
@ -201,3 +208,27 @@ def test_nopoll():
|
|||||||
|
|
||||||
assert Mod4.read_a.poll is False
|
assert Mod4.read_a.poll is False
|
||||||
assert Mod4.read_b.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