[core] invalidate= becomes optional and is set to True by default

This will allow to simplify node descriptions as most of the attributes
are generally invalidating. Only non-invalidating attributes will need
to state explicitly `invalidate=False`.

For output attributes, which must not be invalidating, `invalidate` will
be automatically set to `False` at the attribute-level if it is set to
`True` in the description.
This commit is contained in:
Candice Bentéjac 2024-09-06 15:11:39 +02:00
parent 41e885d9ff
commit b981ef651c
3 changed files with 53 additions and 54 deletions

View file

@ -59,6 +59,7 @@ class Attribute(BaseObject):
self._enabled = True self._enabled = True
self._validValue = True self._validValue = True
self._description = attributeDesc.description self._description = attributeDesc.description
self._invalidate = False if self._isOutput else attributeDesc.invalidate
# invalidation value for output attributes # invalidation value for output attributes
self._invalidationValue = "" self._invalidationValue = ""
@ -448,6 +449,7 @@ class Attribute(BaseObject):
node = Property(BaseObject, node.fget, constant=True) node = Property(BaseObject, node.fget, constant=True)
enabledChanged = Signal() enabledChanged = Signal()
enabled = Property(bool, getEnabled, setEnabled, notify=enabledChanged) enabled = Property(bool, getEnabled, setEnabled, notify=enabledChanged)
invalidate = Property(bool, lambda self: self._invalidate, constant=True)
uidIgnoreValue = Property(Variant, getUidIgnoreValue, constant=True) uidIgnoreValue = Property(Variant, getUidIgnoreValue, constant=True)
validValueChanged = Signal() validValueChanged = Signal()
validValue = Property(bool, getValidValue, setValidValue, notify=validValueChanged) validValue = Property(bool, getValidValue, setValidValue, notify=validValueChanged)
@ -619,7 +621,7 @@ class ListAttribute(Attribute):
if isinstance(self.value, ListModel): if isinstance(self.value, ListModel):
uids = [] uids = []
for value in self.value: for value in self.value:
if value.desc.invalidate: if value.invalidate:
uids.append(value.uid()) uids.append(value.uid())
return hashValue(uids) return hashValue(uids)
return super(ListAttribute, self).uid() return super(ListAttribute, self).uid()
@ -755,7 +757,7 @@ class GroupAttribute(Attribute):
def uid(self): def uid(self):
uids = [] uids = []
for k, v in self._value.items(): for k, v in self._value.items():
if v.enabled and v.desc.invalidate: if v.enabled and v.invalidate:
uids.append(v.uid()) uids.append(v.uid())
return hashValue(uids) return hashValue(uids)

View file

@ -16,17 +16,17 @@ class Attribute(BaseObject):
""" """
""" """
def __init__(self, name, label, description, value, advanced, semantic, invalidate, group, enabled, uidIgnoreValue=None, def __init__(self, name, label, description, value, advanced, semantic, group, enabled, invalidate=True,
validValue=True, errorMessage="", visible=True, exposed=False): uidIgnoreValue=None, validValue=True, errorMessage="", visible=True, exposed=False):
super(Attribute, self).__init__() super(Attribute, self).__init__()
self._name = name self._name = name
self._label = label self._label = label
self._description = description self._description = description
self._value = value self._value = value
self._invalidate = invalidate
self._group = group self._group = group
self._advanced = advanced self._advanced = advanced
self._enabled = enabled self._enabled = enabled
self._invalidate = invalidate
self._semantic = semantic self._semantic = semantic
self._uidIgnoreValue = uidIgnoreValue self._uidIgnoreValue = uidIgnoreValue
self._validValue = validValue self._validValue = validValue
@ -88,10 +88,10 @@ class Attribute(BaseObject):
# The default value of the attribute's descriptor is None, so it's not an input value, # The default value of the attribute's descriptor is None, so it's not an input value,
# but an output value that is computed during the Node's process execution. # but an output value that is computed during the Node's process execution.
isDynamicValue = Property(bool, lambda self: self._isDynamicValue, constant=True) isDynamicValue = Property(bool, lambda self: self._isDynamicValue, constant=True)
invalidate = Property(Variant, lambda self: self._invalidate, constant=True)
group = Property(str, lambda self: self._group, constant=True) group = Property(str, lambda self: self._group, constant=True)
advanced = Property(bool, lambda self: self._advanced, constant=True) advanced = Property(bool, lambda self: self._advanced, constant=True)
enabled = Property(Variant, lambda self: self._enabled, constant=True) enabled = Property(Variant, lambda self: self._enabled, constant=True)
invalidate = Property(Variant, lambda self: self._invalidate, constant=True)
semantic = Property(str, lambda self: self._semantic, constant=True) semantic = Property(str, lambda self: self._semantic, constant=True)
uidIgnoreValue = Property(Variant, lambda self: self._uidIgnoreValue, constant=True) uidIgnoreValue = Property(Variant, lambda self: self._uidIgnoreValue, constant=True)
validValue = Property(Variant, lambda self: self._validValue, constant=True) validValue = Property(Variant, lambda self: self._validValue, constant=True)
@ -112,8 +112,8 @@ class Attribute(BaseObject):
class ListAttribute(Attribute): class ListAttribute(Attribute):
""" A list of Attributes """ """ A list of Attributes """
def __init__(self, elementDesc, name, label, description, group='allParams', advanced=False, semantic='', def __init__(self, elementDesc, name, label, description, group="allParams", advanced=False, semantic="",
enabled=True, joinChar=' ', visible=True, exposed=False): enabled=True, joinChar=" ", visible=True, exposed=False):
""" """
:param elementDesc: the Attribute description of elements to store in that list :param elementDesc: the Attribute description of elements to store in that list
""" """
@ -164,8 +164,8 @@ class ListAttribute(Attribute):
class GroupAttribute(Attribute): class GroupAttribute(Attribute):
""" A macro Attribute composed of several Attributes """ """ A macro Attribute composed of several Attributes """
def __init__(self, groupDesc, name, label, description, group='allParams', advanced=False, semantic='', def __init__(self, groupDesc, name, label, description, group="allParams", advanced=False, semantic="",
enabled=True, joinChar=' ', brackets=None, visible=True, exposed=False): enabled=True, joinChar=" ", brackets=None, visible=True, exposed=False):
""" """
:param groupDesc: the description of the Attributes composing this group :param groupDesc: the description of the Attributes composing this group
""" """
@ -173,7 +173,7 @@ class GroupAttribute(Attribute):
self._joinChar = joinChar self._joinChar = joinChar
self._brackets = brackets self._brackets = brackets
super(GroupAttribute, self).__init__(name=name, label=label, description=description, value={}, super(GroupAttribute, self).__init__(name=name, label=label, description=description, value={},
invalidate=False, group=group, advanced=advanced, semantic=semantic, group=group, advanced=advanced, invalidate=False, semantic=semantic,
enabled=enabled, visible=visible, exposed=exposed) enabled=enabled, visible=visible, exposed=exposed)
def getInstanceType(self): def getInstanceType(self):
@ -271,22 +271,22 @@ class GroupAttribute(Attribute):
class Param(Attribute): class Param(Attribute):
""" """
""" """
def __init__(self, name, label, description, value, invalidate, group, advanced, semantic, enabled, def __init__(self, name, label, description, value, group, advanced, semantic, enabled, invalidate=True,
uidIgnoreValue=None, validValue=True, errorMessage="", visible=True, exposed=False): uidIgnoreValue=None, validValue=True, errorMessage="", visible=True, exposed=False):
super(Param, self).__init__(name=name, label=label, description=description, value=value, super(Param, self).__init__(name=name, label=label, description=description, value=value,
invalidate=invalidate, group=group, advanced=advanced, semantic=semantic, group=group, advanced=advanced, enabled=enabled, invalidate=invalidate,
enabled=enabled, uidIgnoreValue=uidIgnoreValue, validValue=validValue, semantic=semantic, uidIgnoreValue=uidIgnoreValue, validValue=validValue,
errorMessage=errorMessage, visible=visible, exposed=exposed) errorMessage=errorMessage, visible=visible, exposed=exposed)
class File(Attribute): class File(Attribute):
""" """
""" """
def __init__(self, name, label, description, value, invalidate, group='allParams', advanced=False, semantic='', def __init__(self, name, label, description, value, group="allParams", advanced=False, invalidate=True,
enabled=True, visible=True, exposed=True): semantic="", enabled=True, visible=True, exposed=True):
super(File, self).__init__(name=name, label=label, description=description, value=value, invalidate=invalidate, super(File, self).__init__(name=name, label=label, description=description, value=value, group=group,
group=group, advanced=advanced, semantic=semantic, enabled=enabled, visible=visible, advanced=advanced, enabled=enabled, invalidate=invalidate, semantic=semantic,
exposed=exposed) visible=visible, exposed=exposed)
self._valueType = str self._valueType = str
def validateValue(self, value): def validateValue(self, value):
@ -308,11 +308,11 @@ class File(Attribute):
class BoolParam(Param): class BoolParam(Param):
""" """
""" """
def __init__(self, name, label, description, value, invalidate, group='allParams', advanced=False, semantic='', def __init__(self, name, label, description, value, group="allParams", advanced=False, enabled=True,
enabled=True, visible=True, exposed=False): invalidate=True, semantic="", visible=True, exposed=False):
super(BoolParam, self).__init__(name=name, label=label, description=description, value=value, super(BoolParam, self).__init__(name=name, label=label, description=description, value=value,
invalidate=invalidate, group=group, advanced=advanced, semantic=semantic, group=group, advanced=advanced, enabled=enabled, invalidate=invalidate,
enabled=enabled, visible=visible, exposed=exposed) semantic=semantic, visible=visible, exposed=exposed)
self._valueType = bool self._valueType = bool
def validateValue(self, value): def validateValue(self, value):
@ -336,12 +336,12 @@ class BoolParam(Param):
class IntParam(Param): class IntParam(Param):
""" """
""" """
def __init__(self, name, label, description, value, range, invalidate, group='allParams', advanced=False, def __init__(self, name, label, description, value, range, group="allParams", advanced=False, enabled=True,
semantic='', enabled=True, validValue=True, errorMessage="", visible=True, exposed=False): invalidate=True, semantic="", validValue=True, errorMessage="", visible=True, exposed=False):
self._range = range self._range = range
super(IntParam, self).__init__(name=name, label=label, description=description, value=value, super(IntParam, self).__init__(name=name, label=label, description=description, value=value,
invalidate=invalidate, group=group, advanced=advanced, semantic=semantic, group=group, advanced=advanced, enabled=enabled, invalidate=invalidate,
enabled=enabled, validValue=validValue, errorMessage=errorMessage, semantic=semantic, validValue=validValue, errorMessage=errorMessage,
visible=visible, exposed=exposed) visible=visible, exposed=exposed)
self._valueType = int self._valueType = int
@ -366,12 +366,12 @@ class IntParam(Param):
class FloatParam(Param): class FloatParam(Param):
""" """
""" """
def __init__(self, name, label, description, value, range, invalidate, group='allParams', advanced=False, def __init__(self, name, label, description, value, range, group="allParams", advanced=False, enabled=True,
semantic='', enabled=True, validValue=True, errorMessage="", visible=True, exposed=False): invalidate=True, semantic="", validValue=True, errorMessage="", visible=True, exposed=False):
self._range = range self._range = range
super(FloatParam, self).__init__(name=name, label=label, description=description, value=value, super(FloatParam, self).__init__(name=name, label=label, description=description, value=value,
invalidate=invalidate, group=group, advanced=advanced, semantic=semantic, group=group, advanced=advanced, enabled=enabled, invalidate=invalidate,
enabled=enabled, validValue=validValue, errorMessage=errorMessage, semantic=semantic, validValue=validValue, errorMessage=errorMessage,
visible=visible, exposed=exposed) visible=visible, exposed=exposed)
self._valueType = float self._valueType = float
@ -395,11 +395,11 @@ class FloatParam(Param):
class PushButtonParam(Param): class PushButtonParam(Param):
""" """
""" """
def __init__(self, name, label, description, invalidate, group='allParams', advanced=False, semantic='', def __init__(self, name, label, description, group="allParams", advanced=False, enabled=True,
enabled=True, visible=True, exposed=False): invalidate=True, semantic="", visible=True, exposed=False):
super(PushButtonParam, self).__init__(name=name, label=label, description=description, value=None, super(PushButtonParam, self).__init__(name=name, label=label, description=description, value=None,
invalidate=invalidate, group=group, advanced=advanced, semantic=semantic, group=group, advanced=advanced, enabled=enabled, invalidate=invalidate,
enabled=enabled, visible=visible, exposed=exposed) semantic=semantic, visible=visible, exposed=exposed)
self._valueType = None self._valueType = None
def getInstanceType(self): def getInstanceType(self):
@ -417,13 +417,13 @@ class PushButtonParam(Param):
class ChoiceParam(Param): class ChoiceParam(Param):
""" """
""" """
def __init__(self, name, label, description, value, values, exclusive, invalidate, group='allParams', joinChar=' ', def __init__(self, name, label, description, value, values, exclusive, group="allParams", joinChar=" ",
advanced=False, semantic='', enabled=True, validValue=True, errorMessage="", visible=True, advanced=False, enabled=True, invalidate=True, semantic="", validValue=True, errorMessage="",
exposed=False): visible=True, exposed=False):
assert values assert values
super(ChoiceParam, self).__init__(name=name, label=label, description=description, value=value, super(ChoiceParam, self).__init__(name=name, label=label, description=description, value=value,
invalidate=invalidate, group=group, advanced=advanced, semantic=semantic, group=group, advanced=advanced, enabled=enabled, invalidate=invalidate,
enabled=enabled, validValue=validValue, errorMessage=errorMessage, semantic=semantic, validValue=validValue, errorMessage=errorMessage,
visible=visible, exposed=exposed) visible=visible, exposed=exposed)
self._values = values self._values = values
self._exclusive = exclusive self._exclusive = exclusive
@ -490,11 +490,12 @@ class ChoiceParam(Param):
class StringParam(Param): class StringParam(Param):
""" """
""" """
def __init__(self, name, label, description, value, invalidate, group='allParams', advanced=False, semantic='', def __init__(self, name, label, description, value, group="allParams", advanced=False, enabled=True,
enabled=True, uidIgnoreValue=None, validValue=True, errorMessage="", visible=True, exposed=False): invalidate=True, semantic="", uidIgnoreValue=None, validValue=True, errorMessage="", visible=True,
exposed=False):
super(StringParam, self).__init__(name=name, label=label, description=description, value=value, super(StringParam, self).__init__(name=name, label=label, description=description, value=value,
invalidate=invalidate, group=group, advanced=advanced, semantic=semantic, group=group, advanced=advanced, enabled=enabled, invalidate=invalidate,
enabled=enabled, uidIgnoreValue=uidIgnoreValue, validValue=validValue, semantic=semantic, uidIgnoreValue=uidIgnoreValue, validValue=validValue,
errorMessage=errorMessage, visible=visible, exposed=exposed) errorMessage=errorMessage, visible=visible, exposed=exposed)
self._valueType = str self._valueType = str
@ -515,11 +516,11 @@ class StringParam(Param):
class ColorParam(Param): class ColorParam(Param):
""" """
""" """
def __init__(self, name, label, description, value, invalidate, group='allParams', advanced=False, semantic='', def __init__(self, name, label, description, value, group="allParams", advanced=False, enabled=True,
enabled=True, visible=True, exposed=False): invalidate=True, semantic="", visible=True, exposed=False):
super(ColorParam, self).__init__(name=name, label=label, description=description, value=value, super(ColorParam, self).__init__(name=name, label=label, description=description, value=value,
invalidate=invalidate, group=group, advanced=advanced, semantic=semantic, group=group, advanced=advanced, enabled=enabled, invalidate=invalidate,
enabled=enabled, visible=visible, exposed=exposed) semantic=semantic, visible=visible, exposed=exposed)
self._valueType = str self._valueType = str
def validateValue(self, value): def validateValue(self, value):
@ -682,7 +683,6 @@ class Node(object):
"It is displayed in bold font in the invalidation/comment messages tooltip.", "It is displayed in bold font in the invalidation/comment messages tooltip.",
value="", value="",
semantic="multiline", semantic="multiline",
invalidate=True,
advanced=True, advanced=True,
uidIgnoreValue="", # If the invalidation string is empty, it does not participate to the node's UID uidIgnoreValue="", # If the invalidation string is empty, it does not participate to the node's UID
), ),

View file

@ -1423,15 +1423,12 @@ class Node(BaseNode):
# List attributes per UID # List attributes per UID
for attr in self._attributes: for attr in self._attributes:
if attr.isInput and attr.attributeDesc.invalidate: if attr.isInput and attr.invalidate:
self.invalidatingAttributes.add(attr) self.invalidatingAttributes.add(attr)
else:
if attr.attributeDesc.invalidate:
logging.error(f"Output Attribute should not be invalidating: '{nodeType}.{attr.name}'")
# Add internal attributes with a UID to the list # Add internal attributes with a UID to the list
for attr in self._internalAttributes: for attr in self._internalAttributes:
if attr.attributeDesc.invalidate: if attr.invalidate:
self.invalidatingAttributes.add(attr) self.invalidatingAttributes.add(attr)
self.optionalCallOnDescriptor("onNodeCreated") self.optionalCallOnDescriptor("onNodeCreated")