@@ -83,6 +83,7 @@ class attribute. Documentation is in strings immediately following the
8383 FieldTypedBaseDescriptorInfo ,
8484)
8585from .exceptions import (
86+ FeatureNotAvailable ,
8687 NotConnectedToServerError ,
8788 ReadOnlyPropertyError ,
8889 MissingTypeError ,
@@ -393,6 +394,38 @@ def model(self) -> type[BaseModel]:
393394 )
394395 return self ._model
395396
397+ def default (self , obj : Owner | None ) -> Value :
398+ """Return the default value of this property.
399+
400+ :param obj: the `.Thing` instance on which we are looking for the default.
401+ or `None` if referring to the class. For now, this is ignored.
402+
403+ :return: the default value of this property.
404+ :raises FeatureNotAvailable: as this must be overridden.
405+ """
406+ raise FeatureNotAvailable (
407+ f"{ obj .name if obj else self .__class__ } .{ self .name } cannot be reset, "
408+ f"as it's not supported by { self .__class__ } ."
409+ )
410+
411+ def reset (self , obj : Owner ) -> None :
412+ """Reset the property's value to a default state.
413+
414+ If there is a defined default value for the property, this method
415+ should reset the property to that default.
416+
417+ Not every property is expected to implement ``reset`` so it is important
418+ to handle `.FeatureNotAvailable` exceptions, which will be raised if this
419+ method is not overridden.
420+
421+ :param thing: the `.Thing` instance we want to reset.
422+ :raises FeatureNotAvailable: as only some subclasses implement resetting.
423+ """
424+ raise FeatureNotAvailable (
425+ f"{ obj .name } .{ self .name } cannot be reset, as it's not supported by "
426+ f"{ self .__class__ } ."
427+ )
428+
396429 def add_to_fastapi (self , app : FastAPI , thing : Owner ) -> None :
397430 """Add this action to a FastAPI app, bound to a particular Thing.
398431
@@ -612,6 +645,23 @@ def __set__(
612645 if emit_changed_event :
613646 self .emit_changed_event (obj , value )
614647
648+ def default (self , obj : Owner | None ) -> Value :
649+ """Return the default value of this property.
650+
651+ Note that this implementation is independent of the `.Thing` instance,
652+ as there's currently no way to specify a per-instance default.
653+
654+ :return: the default value of this property.
655+ """
656+ return self ._default_factory ()
657+
658+ def reset (self , obj : Owner ) -> None :
659+ r"""Reset the property to its default value.
660+
661+ This resets to the value returned by ``default`` for `.DataProperty`\ .
662+ """
663+ self .__set__ (obj , self .default (obj ))
664+
615665 def _observers_set (self , obj : Thing ) -> WeakSet :
616666 """Return the observers of this property.
617667
@@ -863,6 +913,25 @@ def model_instance(self) -> BaseModel: # noqa: DOC201
863913 raise TypeError (msg )
864914 return cls (root = value )
865915
916+ @builtins .property
917+ def default (self ) -> Value :
918+ """The default value of this property.
919+
920+ .. warning::
921+ Note that this is an optional feature, so calling code must handle
922+ `.FeatureNotAvailable` exceptions.
923+ """
924+ return self .get_descriptor ().default (self .owning_object )
925+
926+ def reset (self ) -> None :
927+ """Reset the property to a default value.
928+
929+ .. warning::
930+ Note that this is an optional feature, so calling code must handle
931+ `.FeatureNotAvailable` exceptions.
932+ """
933+ return self .get_descriptor ().reset (self .owning_object_or_error ())
934+
866935 def validate (self , value : Any ) -> Value :
867936 """Use the validation logic in `self.model`.
868937
0 commit comments