diff --git a/secop/modules.py b/secop/modules.py index 2c39a51..5947f61 100644 --- a/secop/modules.py +++ b/secop/modules.py @@ -176,11 +176,17 @@ class HasAccessibles(HasProperties): setattr(cls, 'write_' + pname, wrapped_wfunc) wrapped_wfunc.__wrapped__ = True - # check information about Command's + # check for programming errors for attrname in cls.__dict__: - if attrname.startswith('do_'): + prefix, _, pname = attrname.partition('_') + if not pname: + continue + if prefix == 'do': raise ProgrammingError('%r: old style command %r not supported anymore' % (cls.__name__, attrname)) + if prefix in ('read', 'write') and not isinstance(accessibles.get(pname), Parameter): + raise ProgrammingError('%s.%s defined, but %r is no parameter' + % (cls.__name__, attrname, pname)) res = {} # collect info about properties diff --git a/test/test_modules.py b/test/test_modules.py index 0b37951..7d24038 100644 --- a/test/test_modules.py +++ b/test/test_modules.py @@ -458,3 +458,23 @@ def test_command_none(): assert 'stop' in Mod('o', logger, {'description': ''}, srv).accessibles assert 'stop' not in Mod2('o', logger, {'description': ''}, srv).accessibles + + +def test_bad_method(): + class Mod0(Drivable): # pylint: disable=unused-variable + def write_target(self, value): + pass + + with pytest.raises(ProgrammingError): + class Mod1(Drivable): # pylint: disable=unused-variable + def write_taget(self, value): + pass + + class Mod2(Drivable): # pylint: disable=unused-variable + def read_value(self, value): + pass + + with pytest.raises(ProgrammingError): + class Mod3(Drivable): # pylint: disable=unused-variable + def read_valu(self, value): + pass