mirror of
https://github.com/ynput/ayon-core.git
synced 2025-12-24 21:04:40 +01:00
added 'is_value_valid' implementation for attribute definitions
This commit is contained in:
parent
b0001f9a58
commit
ed36077292
1 changed files with 98 additions and 19 deletions
|
|
@ -228,8 +228,21 @@ class AbstractAttrDef(metaclass=AbstractAttrDefMeta):
|
|||
and (ignore_enabled or self.enabled == other.enabled)
|
||||
)
|
||||
|
||||
def _def_type_compare(self, other: "AbstractAttrDef") -> bool:
|
||||
return True
|
||||
@abstractmethod
|
||||
def is_value_valid(self, value: Any) -> bool:
|
||||
"""Check if value is valid.
|
||||
|
||||
This should return False if value is not valid based
|
||||
on definition type.
|
||||
|
||||
Args:
|
||||
value (Any): Value to validate based on definition type.
|
||||
|
||||
Returns:
|
||||
bool: True if value is valid.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
|
|
@ -286,6 +299,9 @@ class AbstractAttrDef(metaclass=AbstractAttrDefMeta):
|
|||
|
||||
return cls(**data)
|
||||
|
||||
def _def_type_compare(self, other: "AbstractAttrDef") -> bool:
|
||||
return True
|
||||
|
||||
|
||||
# -----------------------------------------
|
||||
# UI attribute definitions won't hold value
|
||||
|
|
@ -297,6 +313,9 @@ class UIDef(AbstractAttrDef):
|
|||
def __init__(self, key=None, default=None, *args, **kwargs):
|
||||
super().__init__(key, default, *args, **kwargs)
|
||||
|
||||
def is_value_valid(self, value: Any) -> bool:
|
||||
return True
|
||||
|
||||
def convert_value(self, value):
|
||||
return value
|
||||
|
||||
|
|
@ -332,6 +351,9 @@ class UnknownDef(AbstractAttrDef):
|
|||
kwargs["default"] = default
|
||||
super().__init__(key, **kwargs)
|
||||
|
||||
def is_value_valid(self, value: Any) -> bool:
|
||||
return True
|
||||
|
||||
def convert_value(self, value):
|
||||
return value
|
||||
|
||||
|
|
@ -352,6 +374,9 @@ class HiddenDef(AbstractAttrDef):
|
|||
kwargs["visible"] = False
|
||||
super().__init__(key, **kwargs)
|
||||
|
||||
def is_value_valid(self, value: Any) -> bool:
|
||||
return True
|
||||
|
||||
def convert_value(self, value):
|
||||
return value
|
||||
|
||||
|
|
@ -407,12 +432,15 @@ class NumberDef(AbstractAttrDef):
|
|||
self.maximum = maximum
|
||||
self.decimals = 0 if decimals is None else decimals
|
||||
|
||||
def _def_type_compare(self, other: "NumberDef") -> bool:
|
||||
return (
|
||||
self.decimals == other.decimals
|
||||
and self.maximum == other.maximum
|
||||
and self.maximum == other.maximum
|
||||
)
|
||||
def is_value_valid(self, value: Any) -> bool:
|
||||
if self.decimals == 0:
|
||||
if not isinstance(value, int):
|
||||
return False
|
||||
elif not isinstance(value, float):
|
||||
return False
|
||||
if self.minimum > value > self.maximum:
|
||||
return False
|
||||
return True
|
||||
|
||||
def convert_value(self, value):
|
||||
if isinstance(value, str):
|
||||
|
|
@ -428,6 +456,13 @@ class NumberDef(AbstractAttrDef):
|
|||
return int(value)
|
||||
return round(float(value), self.decimals)
|
||||
|
||||
def _def_type_compare(self, other: "NumberDef") -> bool:
|
||||
return (
|
||||
self.decimals == other.decimals
|
||||
and self.maximum == other.maximum
|
||||
and self.maximum == other.maximum
|
||||
)
|
||||
|
||||
|
||||
class TextDef(AbstractAttrDef):
|
||||
"""Text definition.
|
||||
|
|
@ -474,11 +509,12 @@ class TextDef(AbstractAttrDef):
|
|||
self.placeholder = placeholder
|
||||
self.regex = regex
|
||||
|
||||
def _def_type_compare(self, other: "TextDef") -> bool:
|
||||
return (
|
||||
self.multiline == other.multiline
|
||||
and self.regex == other.regex
|
||||
)
|
||||
def is_value_valid(self, value: Any) -> bool:
|
||||
if not isinstance(value, str):
|
||||
return False
|
||||
if self.regex and not self.regex.match(value):
|
||||
return False
|
||||
return True
|
||||
|
||||
def convert_value(self, value):
|
||||
if isinstance(value, str):
|
||||
|
|
@ -492,6 +528,12 @@ class TextDef(AbstractAttrDef):
|
|||
data["placeholder"] = self.placeholder
|
||||
return data
|
||||
|
||||
def _def_type_compare(self, other: "TextDef") -> bool:
|
||||
return (
|
||||
self.multiline == other.multiline
|
||||
and self.regex == other.regex
|
||||
)
|
||||
|
||||
|
||||
class EnumDef(AbstractAttrDef):
|
||||
"""Enumeration of items.
|
||||
|
|
@ -536,12 +578,6 @@ class EnumDef(AbstractAttrDef):
|
|||
self._item_values = item_values_set
|
||||
self.multiselection = multiselection
|
||||
|
||||
def _def_type_compare(self, other: "EnumDef") -> bool:
|
||||
return (
|
||||
self.items == other.items
|
||||
and self.multiselection == other.multiselection
|
||||
)
|
||||
|
||||
def convert_value(self, value):
|
||||
if not self.multiselection:
|
||||
if value in self._item_values:
|
||||
|
|
@ -552,6 +588,17 @@ class EnumDef(AbstractAttrDef):
|
|||
return copy.deepcopy(self.default)
|
||||
return list(self._item_values.intersection(value))
|
||||
|
||||
def is_value_valid(self, value: Any) -> bool:
|
||||
"""Check if item is available in possible values."""
|
||||
if isinstance(value, list):
|
||||
if not self.multiselection:
|
||||
return False
|
||||
return all(value in self._item_values for value in value)
|
||||
|
||||
if self.multiselection:
|
||||
return False
|
||||
return value in self._item_values
|
||||
|
||||
def serialize(self):
|
||||
data = super().serialize()
|
||||
data["items"] = copy.deepcopy(self.items)
|
||||
|
|
@ -620,6 +667,12 @@ class EnumDef(AbstractAttrDef):
|
|||
|
||||
return output
|
||||
|
||||
def _def_type_compare(self, other: "EnumDef") -> bool:
|
||||
return (
|
||||
self.items == other.items
|
||||
and self.multiselection == other.multiselection
|
||||
)
|
||||
|
||||
|
||||
class BoolDef(AbstractAttrDef):
|
||||
"""Boolean representation.
|
||||
|
|
@ -635,6 +688,9 @@ class BoolDef(AbstractAttrDef):
|
|||
default = False
|
||||
super().__init__(key, default=default, **kwargs)
|
||||
|
||||
def is_value_valid(self, value: Any) -> bool:
|
||||
return isinstance(value, bool)
|
||||
|
||||
def convert_value(self, value):
|
||||
if isinstance(value, bool):
|
||||
return value
|
||||
|
|
@ -944,6 +1000,29 @@ class FileDef(AbstractAttrDef):
|
|||
and self.allow_sequences == other.allow_sequences
|
||||
)
|
||||
|
||||
def is_value_valid(self, value: Any) -> bool:
|
||||
if self.single_item:
|
||||
if not isinstance(value, dict):
|
||||
return False
|
||||
try:
|
||||
FileDefItem.from_dict(value)
|
||||
return True
|
||||
except (ValueError, KeyError):
|
||||
return False
|
||||
|
||||
if not isinstance(value, list):
|
||||
return False
|
||||
|
||||
for item in value:
|
||||
if not isinstance(item, dict):
|
||||
return False
|
||||
|
||||
try:
|
||||
FileDefItem.from_dict(item)
|
||||
except (ValueError, KeyError):
|
||||
return False
|
||||
return True
|
||||
|
||||
def convert_value(self, value):
|
||||
if isinstance(value, (str, dict)):
|
||||
value = [value]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue