fsleyes_props.properties

Python descriptor framework.

This module defines the PropertyBase, ListPropertyBase, which form the basis for defining class properties; and the HasProperties class, which is intended to be sub-classed by application code.

HasProperties Base class for classes which contain PropertyBase instances.
PropertyBase The base class for properties.
ListPropertyBase A PropertyBase for properties which encapsulate more than one value.
class fsleyes_props.properties._InstanceData(instance, propVal)

Bases: object

An _InstanceData object is created for every PropertyBase object of a HasProperties instance. It stores references to the instance and the associated PropertyValue instance.

__init__(instance, propVal)

Initialize self. See help(type(self)) for accurate signature.

__dict__ = mappingproxy({'__module__': 'fsleyes_props.properties', '__doc__': 'An ``_InstanceData`` object is created for every ``PropertyBase``\n object of a ``HasProperties`` instance. It stores references to the\n instance and the associated :class:`.PropertyValue` instance.\n ', '__init__': <function _InstanceData.__init__>, '__dict__': <attribute '__dict__' of '_InstanceData' objects>, '__weakref__': <attribute '__weakref__' of '_InstanceData' objects>})
__module__ = 'fsleyes_props.properties'
__weakref__

list of weak references to the object (if defined)

exception fsleyes_props.properties.DisabledError

Bases: Exception

A DisabledError is raised when an attempt is made to assign a value to a disabled property. See the PropertyBase.enable() and PropertyBase.disable() methods.

__module__ = 'fsleyes_props.properties'
__weakref__

list of weak references to the object (if defined)

class fsleyes_props.properties.PropertyBase(default=None, validateFunc=None, equalityFunc=None, required=False, allowInvalid=True, **atts)

Bases: object

The base class for properties.

For every HasProperties instance which has this PropertyBase object as a property, one _InstanceData object is created and attached as an attribute of the HasProperties object.

One important point to note is that a PropertyBase object may exist without being bound to a HasProperties instance (in which case it will not create or manage any PropertyValue instances). This is useful if you just want validation functionality via the validate(), getAttribute() and setAttribute() methods, passing in None for the instance parameter. Nothing else will work properly though.

Several subclasses are defined in the properties_types module. All subclasses should:

  • Ensure that the superclass __init__() is called.
  • Override the validate() method to implement any built in validation rules, ensuring that the the superclass implementation is called first (see the Number property for an example).
  • Override the cast() method for implicit casting/conversion logic (see the Boolean property for an example).

Define a PropertyBase property.

Parameters:
  • default – Default/initial value.
  • required (bool) – Boolean determining whether or not this property must have a value. May alternately be a function which accepts one parameter, the owning HasProperties instance, and returns True or False.
  • validateFunc – Custom validation function. Must accept three parameters: a reference to the HasProperties instance, the owner of this property; a dictionary containing the attributes for this property; and the new property value. Should return True if the property value is valid, False otherwise.
  • equalityFunc – Function for testing equality of two values.
  • allowInvalid – If False, a ValueError will be raised on all attempts to set this property to an invalid value. This does not guarantee that the property value will never be invalid - see caveats in the PropertyValue documentation.
  • atts – Type specific attributes used to test validity - passed to the PropertyValue.__init__() method as its attributes.
__init__(default=None, validateFunc=None, equalityFunc=None, required=False, allowInvalid=True, **atts)

Define a PropertyBase property.

Parameters:
  • default – Default/initial value.
  • required (bool) – Boolean determining whether or not this property must have a value. May alternately be a function which accepts one parameter, the owning HasProperties instance, and returns True or False.
  • validateFunc – Custom validation function. Must accept three parameters: a reference to the HasProperties instance, the owner of this property; a dictionary containing the attributes for this property; and the new property value. Should return True if the property value is valid, False otherwise.
  • equalityFunc – Function for testing equality of two values.
  • allowInvalid – If False, a ValueError will be raised on all attempts to set this property to an invalid value. This does not guarantee that the property value will never be invalid - see caveats in the PropertyValue documentation.
  • atts – Type specific attributes used to test validity - passed to the PropertyValue.__init__() method as its attributes.
__copy__()

Returns a copy of this PropertyBase instance.

NOTE: This has not been rigorously tested.

_setLabel(cls, label)

Sets the property label for the given class. A RuntimeError is raised if a label already exists for the given class.

getLabel(instance)

Returns the property label for the given instance (more specifically, for the class of the given instance), or None if no such label has been defined.

enable(instance)

Enables this property for the given HasProperties instance.

See the disable() method for more details.

disable(instance)

Disables this property for the given HasProperties instance.

An attempt to set the value of a disabled property will result in a DisabledError. This behaviour can be circumvented by dealing directly with the underlying PropertyValue object.

Changes to the enabled state of a property may be detected by registering an attribute listener (see PropertyValue.addAttributeListener()) and listening for changes to the enabled attribute.

isEnabled(instance)

Returns True if this property is enabled for the given HasProperties instance, False otherwise.

See the disable() method for more details.

addListener(instance, *args, **kwargs)

Register a listener with the PropertyValue object managed by this property. See PropertyValue.addListener().

Parameters:instance – The HasProperties instance on which the listener is to be registered.
removeListener(instance, name)

De-register the named listener from the PropertyValue object managed by this property.

getConstraint(instance, constraint)

See getAttribute().

setConstraint(instance, constraint, value)

See setAttribute().

getAttribute(instance, att, *arg)

Returns the value of the named attribute for the specified HasProperties instance, or the default attribute value if instance is None. See PropertiesValue.getAttribute().

setAttribute(instance, att, value)

Sets the value of the named attribute for the specified HasProperties instance,or the default value if instance is None. See PropertiesValue.setAttribute().

getPropVal(instance)

Return the PropertyValue instance(s) for this property, associated with the given HasProperties instance, or None if there is no value for the given instance.

_getInstanceData(instance)

Returns the _InstanceData object for the given HasProperties instance, or None if there is no _InstanceData for the given instance. An _InstanceData object, which provides a binding between a PropertyBase object and a HasProperties instance, is created by that HasProperties instance when it is created (see HasProperties.__new__()).

_makePropVal(instance)

Creates and returns a PropertyValue object for the given HasProperties instance.

validate(instance, attributes, value)

Called when an attempt is made to set the property value on the given instance.

Called by PropertyValue objects when their value changes. The sole purpose of this method is to determine whether a given value is valid or invalid; it should not do anything else. In particular, it should not modify any other property values on the instance, as bad things will probably happen.

If the given value is invalid, subclass implementations should raise a ValueError containing a useful message as to why the value is invalid. Otherwise, they should not return any value. The default implementation does nothing, unless a custom validate function, and/or required=True, was passed to the constructor. If required is True, and the value is None, a ValueError is raised. If a custom validate function was set, it is called and, if it returns False, a ValueError is raised. It may also raise a ValueError of its own for invalid values.

Subclasses which override this method should therefore call this superclass implementation in addition to performing their own validation.

Parameters:
  • instance – The HasProperties instance which owns this PropertyBase instance, or None for an unbound property value.
  • attributes (dict) – Attributes of the PropertyValue object, which are used to store type-specific attributes for PropertyBase subclasses.
  • value – The value to be validated.
cast(instance, attributes, value)

This method is called when a value is assigned to this PropertyBase instance through a HasProperties attribute access. The default implementaton just returns the given value. Subclasses may override this method to perform any required implicit casting or conversion rules.

revalidate(instance)

Forces validation of this property value, for the current instance. This will result in any registered listeners being notified, but only if the validity of the value has changed.

__get__(instance, owner)

If called on the HasProperties class, and not on an instance, returns this PropertyBase object. Otherwise, returns the value contained in the PropertyValue object which is attached to the instance.

__set__(instance, value)

Set the value of this property, as attached to the given instance, to the given value.

__dict__ = mappingproxy({'__module__': 'fsleyes_props.properties', '__doc__': 'The base class for properties.\n\n For every ``HasProperties`` instance which has this ``PropertyBase``\n object as a property, one ``_InstanceData`` object is created and attached\n as an attribute of the ``HasProperties`` object.\n\n One important point to note is that a ``PropertyBase`` object may exist\n without being bound to a ``HasProperties`` instance (in which case it will\n not create or manage any ``PropertyValue`` instances). This is useful\n if you just want validation functionality via the :meth:`validate`,\n :meth:`getAttribute` and :meth:`setAttribute` methods, passing in\n ``None`` for the instance parameter. Nothing else will work properly\n though.\n\n Several subclasses are defined in the :mod:`.properties_types` module.\n All subclasses should:\n\n - Ensure that the superclass :meth:`__init__` is called.\n\n - Override the :meth:`validate` method to implement any built in\n validation rules, ensuring that the the superclass implementation\n is called first (see the :class:`.Number` property for an example).\n\n - Override the :meth:`cast` method for implicit casting/conversion logic\n (see the :class:`.Boolean` property for an example).\n ', '__init__': <function PropertyBase.__init__>, '__copy__': <function PropertyBase.__copy__>, '_setLabel': <function PropertyBase._setLabel>, 'getLabel': <function PropertyBase.getLabel>, 'enable': <function PropertyBase.enable>, 'disable': <function PropertyBase.disable>, 'isEnabled': <function PropertyBase.isEnabled>, 'addListener': <function PropertyBase.addListener>, 'removeListener': <function PropertyBase.removeListener>, 'getConstraint': <function PropertyBase.getConstraint>, 'setConstraint': <function PropertyBase.setConstraint>, 'getAttribute': <function PropertyBase.getAttribute>, 'setAttribute': <function PropertyBase.setAttribute>, 'getPropVal': <function PropertyBase.getPropVal>, '_getInstanceData': <function PropertyBase._getInstanceData>, '_makePropVal': <function PropertyBase._makePropVal>, 'validate': <function PropertyBase.validate>, 'cast': <function PropertyBase.cast>, 'revalidate': <function PropertyBase.revalidate>, '__get__': <function PropertyBase.__get__>, '__set__': <function PropertyBase.__set__>, '__dict__': <attribute '__dict__' of 'PropertyBase' objects>, '__weakref__': <attribute '__weakref__' of 'PropertyBase' objects>})
__module__ = 'fsleyes_props.properties'
__weakref__

list of weak references to the object (if defined)

class fsleyes_props.properties.ListPropertyBase(listType, **kwargs)

Bases: fsleyes_props.properties.PropertyBase

A PropertyBase for properties which encapsulate more than one value.

Define a ListPropertyBase property.

Parameters:listType – An unbound PropertyBase instance, defining the type of value allowed in the list. This is optional; if not provided, values of any type will be allowed in the list, but no validation or casting will be performed.
__init__(listType, **kwargs)

Define a ListPropertyBase property.

Parameters:listType – An unbound PropertyBase instance, defining the type of value allowed in the list. This is optional; if not provided, values of any type will be allowed in the list, but no validation or casting will be performed.
getListType()

Returns a reference to the PropertyBase instance which defines the value types allowsed in this ListPropertyBase. This may be None.

_makePropVal(instance)

Creates and returns a PropertyValueList object to be associated with the given HasProperties instance.

enableItem(instance, index)

Enables the item at the given index. See disableItem().

disableItem(instance, index)

Disables the item at the given index. See PropertyBase.disable().

Note

ListPropertyBase items cannot actually be disabled at this point in time - all this method does is set the 'enabled' attribute of the item to False.

getPropValList(instance)

Returns the list of PropertyValue objects which represent the items stored in this list.

Note that this is a list of PropertyValue instances; it is not the PropertyValueList instance. The latter can be accessed through the owning HasProperties instance with a simple attribute access.

__module__ = 'fsleyes_props.properties'
class fsleyes_props.properties.PropertyOwner

Bases: type

Deprecated.

static __new__(cls, name, bases, attrs)

Create and return a new object. See help(type) for accurate signature.

__module__ = 'fsleyes_props.properties'
class fsleyes_props.properties.HasProperties(validateOnChange=False, **kwargs)

Bases: object

Base class for classes which contain PropertyBase instances. All classes which contain PropertyBase objects must subclass this class.

Create a HasProperties instance.

If no arguments need to be passed in, HasProperties.__init__ does not need to be called.

Parameters:
  • validateOnChange – Defaults to False. If set to True, whenever any property value is changed, the value of every property is re-validated. This functionality is accomplished by using the preNotify listener on all PropertyValue instances - see the PropertyValue.setPreNotifyFunction() method.
  • kwargs – All other arguments are assumed to be name=value pairs, containing initial values for the properties defined on this HasProperties instance.

Note

The validateOnChange argument warrants some explanation.

The point of validating all other properties when one property changes is to handle the scenario where the validity of one property is dependent upon the values of other properties.

Currently, the only option is to enable this globally; i.e. whenever the value of any property changes, all other properties are validated.

At some stage, I may allow more fine grained control; e.g. validation could only occur when specific properties change, and/or only specific properties are validated. This should be fairly straightforward - we could just maintain a dict of {propName : [propNames ..]} mappings, where the key is the name of a property that should trigger validation, and the value is a list of properties that need to be validated when that property changes.

static __new__(cls, *args, **kwargs)

Here we create a new HasProperties instance, and loop through all of its PropertyBase properties to ensure that they are initialised.

__init__(validateOnChange=False, **kwargs)

Create a HasProperties instance.

If no arguments need to be passed in, HasProperties.__init__ does not need to be called.

Parameters:
  • validateOnChange – Defaults to False. If set to True, whenever any property value is changed, the value of every property is re-validated. This functionality is accomplished by using the preNotify listener on all PropertyValue instances - see the PropertyValue.setPreNotifyFunction() method.
  • kwargs – All other arguments are assumed to be name=value pairs, containing initial values for the properties defined on this HasProperties instance.

Note

The validateOnChange argument warrants some explanation.

The point of validating all other properties when one property changes is to handle the scenario where the validity of one property is dependent upon the values of other properties.

Currently, the only option is to enable this globally; i.e. whenever the value of any property changes, all other properties are validated.

At some stage, I may allow more fine grained control; e.g. validation could only occur when specific properties change, and/or only specific properties are validated. This should be fairly straightforward - we could just maintain a dict of {propName : [propNames ..]} mappings, where the key is the name of a property that should trigger validation, and the value is a list of properties that need to be validated when that property changes.

__copy__()

Default copy operator.

Creates a new instance of this type, and copies all property values across.

If a no-arguments constructor is not available, an error will be raised.

Subclasses which require arguments on initialisation, or which have more complex copy semantics, will need to implement their own __copy__ operator if this one does not suffice.

bindProps(*args, **kwargs)

See bindable.bindProps().

unbindProps(*args, **kwargs)

See bindable.unbindProps().

isBound(*args, **kwargs)

See bindable.isBound().

addProperty(propName, propObj)

Add the given PropertyBase` instance as an attribute of this HasProperties instance.

classmethod getAllProperties()

Returns two lists, the first containing the names of all properties of this object, and the second containing the corresponding PropertyBase objects.

Properties which have a name beginning with an underscore are not returned by this method

classmethod getProp(propName)

Return the PropertyBase object for the given property.

getPropVal(propName)

Return the PropertyValue object(s) for the given property.

getLastValue(propName)

Returns the most recent value of the specified property before its current one.

See the PropertyValue.getLast() method.

serialise(propName)

Returns a string containing the value of the named property, serialsied via the serialise module.

deserialise(propName, value)

Deserialises the given value (assumed to have been serialised via the serialise module), and sets the named property to the deserialised value.

enableNotification(propName, *args, **kwargs)

Enables notification of listeners on the given property.

See the PropertyValue.enableNotification() method.

disableNotification(propName, *args, **kwargs)

Disables notification of listeners on the given property.

See the PropertyValue.disableNotification() method.

getNotificationState(propName)

Returns the notification state of the given property.

See the PropertyValue.getNotificationState() method.

setNotificationState(propName, value)

Sets the notification state of the given property.

See the PropertyValue.setNotificationState() method.

enableAllNotification()

Enables notification of listeners on all properties.

disableAllNotification()

Disables notification of listeners on all properties.

enableProperty(propName, index=None)

Enables the given property.

If an index is provided, it is assumed that the property is a list property (a ListPropertyBase).

See PropertyBase.enable() and ListPropertyBase.enableItem().

disableProperty(propName, index=None)

Disables the given property - see PropertyBase.disable().

If an index is provided, it is assumed that the property is a list property (a ListPropertyBase).

See PropertyBase.disable() and ListPropertyBase.disableItem().

propertyIsEnabled(propName)

Returns the enabled state of the given property - see PropertyBase.isEnabled().

propNotify(propName)

Force notification of listeners on the given property. This will have no effect if notification for the property is disabled.

See the PropertyValue.propNotify() method.

getConstraint(propName, constraint)

See getAttribute().

setConstraint(propName, constraint, value)

See setAttribute().

getAttribute(propName, *args)

Convenience method, returns the value of the named attributes for the named property. See PropertyBase.getAttribute().

setAttribute(propName, *args)

Convenience method, sets the value of the named attribute for the named property. See PropertyBase.setAttribute().

addListener(propName, *args, **kwargs)

Convenience method, adds the specified listener to the specified property. See PropertyValue.addListener().

removeListener(propName, listenerName)

Convenience method, removes the specified listener from the specified property. See PropertyValue.removeListener().

enableListener(propName, name)

(Re-)Enables the listener on the specified property with the specified name.

disableListener(propName, name)

Disables the listener on the specified property with the specified name, but does not remove it from the list of listeners.

getListenerState(propName, name)

See PropertyValue.getListenerState().

setListenerState(propName, name, state)

See PropertyValue.setListenerState().

hasListener(propName, name)

Returns True if a listener is registered on the given property, False otherwise.

addGlobalListener(*args, **kwargs)

Registers the given listener so that it will be notified of changes to any of the properties of this HasProperties instance.

removeGlobalListener(listenerName)

De-registers the specified global listener (see addGlobalListener()).

isValid(propName)

Returns True if the current value of the specified property is valid, False otherwise.

validateAll()

Validates all of the properties of this HasProperties object. A list of tuples is returned, with each tuple containing a property name, and an associated error string. The error string is a message about the property which failed validation. If all property values are valid, the returned list will be empty.

__str__()

Returns a multi-line string containing the names and values of all the properties of this object.

_HasProperties__valueChanged(ctx, value, valid, name)

This method is only called if validateOnChange was set to true in __init__(). It is registered as the preNotify listener on all PropertyValue instances. See the note in __init__().

__dict__ = mappingproxy({'__module__': 'fsleyes_props.properties', '__doc__': 'Base class for classes which contain ``PropertyBase`` instances. All\n classes which contain ``PropertyBase`` objects must subclass this\n class.\n ', '__new__': <staticmethod object>, '__init__': <function HasProperties.__init__>, '__copy__': <function HasProperties.__copy__>, 'bindProps': <function HasProperties.bindProps>, 'unbindProps': <function HasProperties.unbindProps>, 'isBound': <function HasProperties.isBound>, 'addProperty': <function HasProperties.addProperty>, '_HasProperties__valueChanged': <function HasProperties.__valueChanged>, 'getAllProperties': <classmethod object>, 'getProp': <classmethod object>, 'getPropVal': <function HasProperties.getPropVal>, 'getLastValue': <function HasProperties.getLastValue>, 'serialise': <function HasProperties.serialise>, 'deserialise': <function HasProperties.deserialise>, 'enableNotification': <function HasProperties.enableNotification>, 'disableNotification': <function HasProperties.disableNotification>, 'getNotificationState': <function HasProperties.getNotificationState>, 'setNotificationState': <function HasProperties.setNotificationState>, 'enableAllNotification': <function HasProperties.enableAllNotification>, 'disableAllNotification': <function HasProperties.disableAllNotification>, 'enableProperty': <function HasProperties.enableProperty>, 'disableProperty': <function HasProperties.disableProperty>, 'propertyIsEnabled': <function HasProperties.propertyIsEnabled>, 'propNotify': <function HasProperties.propNotify>, 'getConstraint': <function HasProperties.getConstraint>, 'setConstraint': <function HasProperties.setConstraint>, 'getAttribute': <function HasProperties.getAttribute>, 'setAttribute': <function HasProperties.setAttribute>, 'addListener': <function HasProperties.addListener>, 'removeListener': <function HasProperties.removeListener>, 'enableListener': <function HasProperties.enableListener>, 'disableListener': <function HasProperties.disableListener>, 'getListenerState': <function HasProperties.getListenerState>, 'setListenerState': <function HasProperties.setListenerState>, 'hasListener': <function HasProperties.hasListener>, 'addGlobalListener': <function HasProperties.addGlobalListener>, 'removeGlobalListener': <function HasProperties.removeGlobalListener>, 'isValid': <function HasProperties.isValid>, 'validateAll': <function HasProperties.validateAll>, '__str__': <function HasProperties.__str__>, '__dict__': <attribute '__dict__' of 'HasProperties' objects>, '__weakref__': <attribute '__weakref__' of 'HasProperties' objects>})
__module__ = 'fsleyes_props.properties'
__weakref__

list of weak references to the object (if defined)