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
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)
-
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
-
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: KeyError
– attribute 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)
-