fix overriding Parameter with value

a property declared in a base class may be overriden
with a parameter in a subclass. this is already allowed.
if then, in the subsubclass it is overridden by a bare value,
it fails.

Patchset 1: add a test for this
Patchset 4: add the fix

Change-Id: Ia5a26076a9ee98439932643a03878342d56f8396
Reviewed-on: https://forge.frm2.tum.de/review/c/secop/frappy/+/35932
Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
Tested-by: Jenkins Automated Tests <pedersen+jenkins@frm2.tum.de>
This commit is contained in:
zolliker 2025-03-28 16:21:43 +01:00
parent 56bee015b3
commit 3b8f3586cf
2 changed files with 16 additions and 4 deletions

View File

@ -131,14 +131,16 @@ class HasProperties(HasDescriptors):
properties = {} properties = {}
# using cls.__bases__ and base.propertyDict for this would fail on some multiple inheritance cases # using cls.__bases__ and base.propertyDict for this would fail on some multiple inheritance cases
for base in reversed(cls.__mro__): for base in reversed(cls.__mro__):
properties.update({k: v for k, v in base.__dict__.items() if isinstance(v, Property)}) for key, value in base.__dict__.items():
if isinstance(value, Property):
properties[key] = value
elif isinstance(value, HasProperties): # value is a Parameter. allow to override
properties.pop(key, None)
cls.propertyDict = properties cls.propertyDict = properties
# treat overriding properties with bare values # treat overriding properties with bare values
for pn, po in list(properties.items()): for pn, po in list(properties.items()):
value = getattr(cls, pn, po) value = getattr(cls, pn, po)
if isinstance(value, HasProperties): # value is a Parameter, allow override if not isinstance(value, Property): # attribute may be a bare value
properties.pop(pn)
elif not isinstance(value, Property): # attribute may be a bare value
po = po.copy() po = po.copy()
try: try:
# try to apply bare value to Property # try to apply bare value to Property

View File

@ -31,6 +31,7 @@ from frappy.modules import Communicator, Drivable, Readable, Module, Writable
from frappy.params import Command, Parameter, Limit from frappy.params import Command, Parameter, Limit
from frappy.rwhandler import ReadHandler, WriteHandler, nopoll from frappy.rwhandler import ReadHandler, WriteHandler, nopoll
from frappy.lib import generalConfig from frappy.lib import generalConfig
from frappy.properties import Property
class DispatcherStub: class DispatcherStub:
@ -445,6 +446,15 @@ def test_override():
# inherit doc string # inherit doc string
assert Mod2.stop.description == Mod.stop.description assert Mod2.stop.description == Mod.stop.description
class Base(Module):
attr = Property('test property', FloatRange())
class Subclass(Base):
attr = Parameter('test parameter', FloatRange())
class SubSubclass(Subclass): # pylint: disable=unused-variable
attr = 5.0
def test_command_config(): def test_command_config():
class Mod(Module): class Mod(Module):