From 3b8f3586cff9d49cf77731f564541c405a8cb2dd Mon Sep 17 00:00:00 2001 From: Markus Zolliker Date: Fri, 28 Mar 2025 16:21:43 +0100 Subject: [PATCH] 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 Tested-by: Jenkins Automated Tests --- frappy/properties.py | 10 ++++++---- test/test_modules.py | 10 ++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/frappy/properties.py b/frappy/properties.py index 910002d..5e8775c 100644 --- a/frappy/properties.py +++ b/frappy/properties.py @@ -131,14 +131,16 @@ class HasProperties(HasDescriptors): properties = {} # using cls.__bases__ and base.propertyDict for this would fail on some multiple inheritance cases 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 # treat overriding properties with bare values for pn, po in list(properties.items()): value = getattr(cls, pn, po) - if isinstance(value, HasProperties): # value is a Parameter, allow override - properties.pop(pn) - elif not isinstance(value, Property): # attribute may be a bare value + if not isinstance(value, Property): # attribute may be a bare value po = po.copy() try: # try to apply bare value to Property diff --git a/test/test_modules.py b/test/test_modules.py index 86982b3..cf788ac 100644 --- a/test/test_modules.py +++ b/test/test_modules.py @@ -31,6 +31,7 @@ from frappy.modules import Communicator, Drivable, Readable, Module, Writable from frappy.params import Command, Parameter, Limit from frappy.rwhandler import ReadHandler, WriteHandler, nopoll from frappy.lib import generalConfig +from frappy.properties import Property class DispatcherStub: @@ -445,6 +446,15 @@ def test_override(): # inherit doc string 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(): class Mod(Module):