simple possiblity for overriding properties

When a class attribute is assigned with the same name as a property
from an inherited class, the property default is overridden.
If the type does not match, a ProgrammingError is raised.

Change-Id: Ifdab5c8bbdaae008370a9b297c770f5c04db9311
Reviewed-on: https://forge.frm2.tum.de/review/c/sine2020/secop/playground/+/21989
Reviewed-by: Markus Zolliker <markus.zolliker@psi.ch>
Tested-by: JenkinsCodeReview <bjoern_pedersen@frm2.tum.de>
This commit is contained in:
2019-12-10 17:25:57 +01:00
parent 1521e0a34b
commit f5af074015
2 changed files with 53 additions and 7 deletions

View File

@ -24,7 +24,7 @@
from collections import OrderedDict
from secop.errors import ProgrammingError, ConfigError
from secop.errors import ProgrammingError, ConfigError, BadValueError
# storage for 'properties of a property'
@ -52,8 +52,9 @@ class Property:
self.settable = settable or mandatory # settable means settable from the cfg file
def __repr__(self):
return 'Property(%r, %s, default=%r, extname=%r, export=%r, mandatory=%r)' % (
self.description, self.datatype, self.default, self.extname, self.export, self.mandatory)
return 'Property(%r, %s, default=%r, extname=%r, export=%r, mandatory=%r, settable=%r)' % (
self.description, self.datatype, self.default, self.extname, self.export,
self.mandatory, self.settable)
class Properties(OrderedDict):
@ -100,7 +101,8 @@ class PropertyMeta(type):
for base in reversed(bases):
properties.update(getattr(base, "properties", {}))
# update with properties from new class
properties.update(attrs.get('properties', {}))
aprops = attrs.get('properties', {})
properties.update(aprops)
newtype.properties = properties
# generate getters
@ -108,9 +110,23 @@ class PropertyMeta(type):
def getter(self, pname=k):
val = self.__class__.properties[pname].default
return self.properties.get(pname, val)
if k in attrs:
if not isinstance(attrs[k], property):
raise ProgrammingError('Name collision with property %r' % k)
if k in attrs and not isinstance(attrs[k], property):
if callable(attrs[k]):
raise ProgrammingError('%r: property %r collides with method'
% (newtype, k))
if k in aprops:
# this property was defined in the same class
raise ProgrammingError('%r: name collision with property %r'
% (newtype, k))
# assume the attribute value should be assigned to the property
try:
# make a copy first!
prop = Property(**newtype.properties[k].__dict__)
prop.default = prop.datatype(attrs[k])
newtype.properties[k] = prop
except BadValueError:
raise ProgrammingError('%r: property %r can not be set to %r'
% (newtype, k, attrs[k]))
setattr(newtype, k, property(getter))
return newtype