removed old style syntax

- removed secop/metaclass.py
- moved code from ModuleMeta to modules.HasAccessibles.__init_subclass__
- reworked properties:
  assignment obj.property = value now always allowed
- reworked Parameters and Command to be true descriptors
- Command must now be solely used as decorator
- renamed 'usercommand' to 'Command'
- command methods no longer start with 'do_'
- reworked mechanism to determine accessible order:
  the attribute paramOrder, if given, determines order of accessibles
+ fixed some issues makeing the IDE more happy
+ simplified code for StatusType and added a test for it

Change-Id: I8045cf38ee6f4d4862428272df0b12a7c8abaca7
Reviewed-on: https://forge.frm2.tum.de/review/c/sine2020/secop/playground/+/25049
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:
2021-02-12 18:37:04 +01:00
parent f9a2152883
commit 07b758c3dd
34 changed files with 1678 additions and 1978 deletions

View File

@ -24,38 +24,58 @@
import pytest
from secop.datatypes import IntRange, StringType, FloatRange, ValueType
from secop.errors import ProgrammingError, ConfigError
from secop.properties import Property, Properties, HasProperties
from secop.errors import ProgrammingError, ConfigError, BadValueError
from secop.properties import Property, HasProperties
# args are: datatype, default, extname, export, mandatory, settable
def Prop(*args, name=None, **kwds):
# collect the args for Property
return name, args, kwds
# Property(description, datatype, default, ...)
V_test_Property = [
[(StringType(), 'default', 'extname', False, False),
dict(default='default', extname='extname', export=True, mandatory=False)],
[(IntRange(), '42', '_extname', False, True),
dict(default=42, extname='_extname', export=True, mandatory=True)],
[(IntRange(), '42', '_extname', True, False),
dict(default=42, extname='_extname', export=True, mandatory=False)],
[(IntRange(), 42, '_extname', True, True),
dict(default=42, extname='_extname', export=True, mandatory=True)],
[(IntRange(), 0, '', True, True),
dict(default=0, extname='', export=True, mandatory=True)],
[(IntRange(), 0, '', True, False),
dict(default=0, extname='', export=True, mandatory=False)],
[(IntRange(), 0, '', False, True),
dict(default=0, extname='', export=False, mandatory=True)],
[(IntRange(), 0, '', False, False),
dict(default=0, extname='', export=False, mandatory=False)],
[(IntRange(), None, '', None),
dict(default=0, extname='', export=False, mandatory=True)], # mandatory not given, no default -> mandatory
[(ValueType(), 1, '', False),
dict(default=1, extname='', export=False, mandatory=False)], # mandatory not given, default given -> NOT mandatory
[Prop(StringType(), 'default', extname='extname', mandatory=False),
dict(default='default', extname='extname', export=True, mandatory=False)
],
[Prop(IntRange(), '42', export=True, name='custom', mandatory=True),
dict(default=42, extname='_custom', export=True, mandatory=True),
],
[Prop(IntRange(), '42', export=True, name='name'),
dict(default=42, extname='_name', export=True, mandatory=False)
],
[Prop(IntRange(), 42, '_extname', mandatory=True),
dict(default=42, extname='_extname', export=True, mandatory=True)
],
[Prop(IntRange(), 0, export=True, mandatory=True),
dict(default=0, extname='', export=True, mandatory=True)
],
[Prop(IntRange(), 0, export=True, mandatory=False),
dict(default=0, extname='', export=True, mandatory=False)
],
[Prop(IntRange(), 0, export=False, mandatory=True),
dict(default=0, extname='', export=False, mandatory=True)
],
[Prop(IntRange(), 0, export=False, mandatory=False),
dict(default=0, extname='', export=False, mandatory=False)
],
[Prop(IntRange()),
dict(default=0, extname='', export=False, mandatory=True) # mandatory not given, no default -> mandatory
],
[Prop(ValueType(), 1),
dict(default=1, extname='', export=False, mandatory=False) # mandatory not given, default given -> NOT mandatory
],
]
@pytest.mark.parametrize('args, check', V_test_Property)
def test_Property(args, check):
p = Property('', *args)
@pytest.mark.parametrize('propargs, check', V_test_Property)
def test_Property(propargs, check):
name, args, kwds = propargs
p = Property('', *args, **kwds)
if name:
p.__set_name__(None, name)
result = {k: getattr(p, k) for k in check}
assert result == check
def test_Property_basic():
with pytest.raises(TypeError):
# pylint: disable=no-value-for-parameter
@ -67,47 +87,47 @@ def test_Property_basic():
Property('', 1)
Property('', IntRange(), '42', 'extname', False, False)
def test_Properties():
p = Properties()
with pytest.raises(ProgrammingError):
p[1] = 2
p['a'] = Property('', IntRange(), '42', export=True)
assert p['a'].default == 42
assert p['a'].export is True
assert p['a'].extname == '_a'
with pytest.raises(ProgrammingError):
p['a'] = 137
with pytest.raises(ProgrammingError):
del p[1]
with pytest.raises(ProgrammingError):
del p['a']
p['a'] = Property('', IntRange(), 0, export=False)
assert p['a'].default == 0
assert p['a'].export is False
assert p['a'].extname == ''
class Cls(HasProperties):
aa = Property('', IntRange(0, 99), '42', export=True)
bb = Property('', IntRange(), 0, export=False)
assert Cls.aa.default == 42
assert Cls.aa.export is True
assert Cls.aa.extname == '_aa'
cc = Cls()
with pytest.raises(BadValueError):
cc.aa = 137
assert Cls.bb.default == 0
assert Cls.bb.export is False
assert Cls.bb.extname == ''
class c(HasProperties):
properties = {
'a' : Property('', IntRange(), 1),
}
# properties
a = Property('', IntRange(), 1)
class cl(c):
properties = {
'a' : Property('', IntRange(), 3),
'b' : Property('', FloatRange(), 3.14),
'minabc': Property('', IntRange(), 8),
'maxabc': Property('', IntRange(), 9),
'minx': Property('', IntRange(), 2),
'maxy': Property('', IntRange(), 1),
}
# properties
a = Property('', IntRange(), 3)
b = Property('', FloatRange(), 3.14)
minabc = Property('', IntRange(), 8)
maxabc = Property('', IntRange(), 9)
minx = Property('', IntRange(), 2)
maxy = Property('', IntRange(), 1)
def test_HasProperties():
o = c()
assert o.properties['a'] == 1
assert o.a == 1
o = cl()
assert o.properties['a'] == 3
assert o.properties['b'] == 3.14
assert o.a == 3
assert o.b == 3.14
def test_Property_checks():
o = c()
@ -119,6 +139,7 @@ def test_Property_checks():
with pytest.raises(ConfigError):
o.checkProperties()
def test_Property_override():
o1 = c()
class co(c):
@ -131,10 +152,10 @@ def test_Property_override():
class cx(c): # pylint: disable=unused-variable
def a(self):
pass
assert 'collides with method' in str(e.value)
assert 'collides with' in str(e.value)
with pytest.raises(ProgrammingError) as e:
class cz(c): # pylint: disable=unused-variable
a = 's'
assert 'can not be set to' in str(e.value)
assert 'can not set' in str(e.value)