taucmdr.mvc.model module

TODO: FIXME: Docs

class taucmdr.mvc.model.Model(record)[source]

Bases: taucmdr.cf.storage.StorageRecord

The “M” in MVC.

name

str

Name of the model.

associations

dict

(Controller, str) tuples keyed by attribute name defining attribute associations.

references

set

(Controller, str) tuples listing foreign models referencing this model.

attributes

dict

Model attributes.

key_attribute

str

Name of an attribute that serves as a unique identifier.

associations = {}
check_compatibility(rhs)[source]

Test this record for compatibility with another record.

Operations combining data from multiple records must know that the records are mutually compatible. This routine checks the ‘compat’ property of each attribute (if set) to enforce compatibility. ‘compat’ is a dictionary where the keys are values or callables and the values are tuples of compatibility conditions. If the attribute with the ‘compat’ property is one of the key values then the conditions are checked. The general form of ‘compat’ is:

{
(value|callable): (condition, [condition, ...]),
[(value|callable): (condition, [condition, ...]), ...]
}

Use tuples to join multiple conditions. If only one condition is needed then you do not need to use a tuple.

‘value’ may either be a literal value (e.g. True or “oranges”) or a callable accepting one argument and returning either True or False. The attribute’s value is passed to the callable to determine if the listed conditions should be checked. If ‘value’ is a literal then the listed conditions are checked when the attribute’s value matches ‘value’.

See require, encourage, discourage, exclude for common conditions.

Parameters:rhs (Model) – Check compatibility with this data record.
Raises:IncompatibleRecordError – The two records are not compatible.

Examples

Suppose we have this data:

Programmer.attributes = {
    'hungry': {
        'type': 'boolean',
        'compat': {True: (CheeseShop.require('have_cheese', True),
                          CheeseShop.encourage('chedder', 'Wisconsin'),
                          ProgramManager.discourage('holding_long_meeting', True),
                          Roommate.exclude('steals_food', True)}
    }
}

bob = Programmer({'hungry': True})
world_o_cheese = CheeseShop({'have_cheese': False, 'chedder': 'Wisconsin'})
cheese_wizzard = CheeseShop({'have_cheese': True, 'chedder': 'California'})
louis = ProgramManager({'holding_long_meeting': True})
keith = Roommate({'steals_food': True})

These expressions raise IncompatibleRecordError:

bob.check_compatibility(world_o_cheese)   # Because have_cheese == False
bob.check_compatibility(keith)            # Because steals_food == True

These expressions generate warning messages:

bob.check_compatibility(cheese_wizzard)   # Because chedder != Wisconsin
bob.check_compatibility(louis)            # Because holding_long_meeting == True

If bob['hungry'] == False or if the ‘hungry’ attribute were not set then all the above expressions do nothing.

classmethod construct_condition(args, attr_defined=None, attr_undefined=None, attr_eq=None, attr_ne=None)[source]

Constructs a compatibility condition, see check_compatibility.

The returned condition is a callable that accepts four arguments:
  • lhs (Model): The left-hand side of the check_compatibility operation.
  • lhs_attr (str): Name of the attribute that defines the ‘compat’ property.
  • lhs_value: The value of the attribute that defines the ‘compat’ property.
  • rhs (Model): Controller of the data record we are checking against.

The condition callable raises a IncompatibleRecordError if the compared attributes are fatally incompatibile, i.e. the user’s operation is guaranteed to fail with the chosen records. It may emit log messages to indicate that the records are not perfectly compatible but that the user’s operation is still likely to succeed with the chosen records.

See require, encourage, discourage, exclude for common conditions.

args[0] specifies a model attribute to check. If args[1] is given, it is a value to compare the specified attribute against or a callback function. If args[1] is callable, it must check attribute existence and value correctness and throw the appropriate exception and/or emit log messages.

Parameters:
  • args (tuple) – Attribute name in args[0] and, optionally, attribute value in args[1].
  • attr_defined – Callback function to be invoked when the attribute is defined.
  • attr_undefined – Callback function to be invoked when the attribute is undefined.
  • attr_eq – Callback function to be invoked when the attribute is equal to args[1].
  • attr_ne – Callback function to be invoked when the attribute is not equal to args[1].
Returns:

Callable condition object for use with check_compatibility.

classmethod controller(storage)[source]
classmethod discourage(*args)[source]

Constructs a compatibility condition to make recommendations.

The condition will emit warnings messages if the specified attribute is defined or equal to the specified value (if given).

Parameters:*args – Corresponds to args in construct_condition.
Returns:Callable condition object for use with check_compatibility

Examples

‘have_cheese’ should not be True:

CheeseShop.discourage('have_cheese', True)

‘have_cheese’ should not be set to any value:

CheeseShop.discourage('have_cheese')

The value of ‘have_cheese’ will be checked for correctness by ‘cheese_callback’:

CheeseShop.discourage('have_cheese', cheese_callback)
classmethod encourage(*args)[source]

Constructs a compatibility condition to make recommendations.

The condition will emit warnings messages if the specified attribute is undefined or not equal to the specified value (if given).

Parameters:*args – Corresponds to args in construct_condition.
Returns:Callable condition object for use with check_compatibility

Examples

‘have_cheese’ should be True:

CheeseShop.encourage('have_cheese', True)

‘have_cheese’ should be set to any value:

CheeseShop.encourage('have_cheese')

The value of ‘have_cheese’ will be checked for correctness by ‘cheese_callback’:

CheeseShop.encourage('have_cheese', cheese_callback)
classmethod exclude(*args)[source]

Constructs a compatibility condition to enforce required conditions.

The condition will raise a IncompatibleRecordError if the specified attribute is defined or equal to the specified value (if given).

Parameters:*args – Corresponds to args in construct_condition.
Returns:Callable condition object for use with check_compatibility

Examples

‘yellow_cheese’ must not be ‘American’:

CheeseShop.exclude('yellow_cheese', 'American')

‘blue_cheese’ must not be set to any value:

CheeseShop.exclude('blue_cheese')

The value of ‘have_cheese’ will be checked for correctness by ‘cheese_callback’:

CheeseShop.exclude('have_cheese', cheese_callback)
classmethod filter_arguments(args)[source]
get_or_default(key)[source]

Returns the attribute’s value or default value.

Parameters:key (str) – Attribute name.
Returns:If the attribute is set then the attribute’s value is returned. If the attribute is not set then the attribute’s default value is returned.
Raises:If the attribute is not set and has no default value then a KeyError is raised.
name = None
on_create()[source]

Callback to be invoked after a new data record is created.

on_delete()[source]

Callback to be invoked before a data record is deleted.

on_update(changes)[source]

Callback to be invoked after a data record is updated.

populate(attribute=None, defaults=False, context=True)[source]

Shorthand for self.controller(self.storage).populate(self, attribute, defaults).

Result is cached in the object instance when possible so this should be faster than populating directly from the controller.

Parameters:
  • attribute (Optional[str]) – If given, return only the populated attribute.
  • defaults (Optional[bool]) – If given, set undefined attributes to their default values.
Returns:

If attribute is None, a dictionary of controlled data merged with associated records. If attribute is not None, the value of the populated attribute.

Raises:

KeyErrorattribute is undefined in the record.

references = set()
classmethod require(*args)[source]

Constructs a compatibility condition to enforce required conditions.

The condition will raise a IncompatibleRecordError if the specified attribute is undefined or not equal to the specified value (if given).

Parameters:*args – Corresponds to args in construct_condition.
Returns:Callable condition object for use with check_compatibility

Examples

‘have_cheese’ must be True:

CheeseShop.require('have_cheese', True)

‘have_cheese’ must be set to any value:

CheeseShop.require('have_cheese')

The value of ‘have_cheese’ will be checked for correctness by ‘cheese_callback’:

CheeseShop.require('have_cheese', cheese_callback)
classmethod validate(data)[source]

Validates data against the model.

Parameters:data (dict) – Data to validate, may be None.
Returns:Validated data or None if data is None.
Return type:dict
Raises:ModelError – The given data doesn’t fit the model.
class taucmdr.mvc.model.ModelMeta[source]

Bases: type

Constructs model attributes, configures defaults, and establishes relationships.

attributes
key_attribute