Source code for PyOpenWorm.inverse_property
"""
For declaring inverse properties of GraphObjects
"""
InverseProperties = dict()
[docs]class InversePropertyMixin(object):
"""
Mixin for inverse properties.
Augments RealSimpleProperty methods to update inverse properties as well
"""
def set(self, other):
ip_key = (self.owner_type, self.linkName)
ip = InverseProperties.get(ip_key)
if ip:
rhs_cls, rhs_linkName = ip.other(*ip_key)
if isinstance(other, rhs_cls):
rhs_prop = getattr(other.contextualize(self.context), rhs_linkName)
super(InversePropertyMixin, rhs_prop).set(self.owner)
return super(InversePropertyMixin, self).set(other)
def unset(self, other):
ip_key = (self.owner_type, self.linkName)
ip = InverseProperties.get(ip_key)
if ip:
rhs_cls, rhs_linkName = ip.other(*ip_key)
if isinstance(other, rhs_cls):
rhs_prop = getattr(other, rhs_linkName)
ctxd_rhs_prop = rhs_prop.contextualize(self.context)
super(InversePropertyMixin, ctxd_rhs_prop).unset(self.owner)
return super(InversePropertyMixin, self).unset(other)
class InverseProperty(object):
def __init__(self, lhs_class, lhs_linkName, rhs_class, rhs_linkName):
self.lhs_class = lhs_class
self.rhs_class = rhs_class
self.lhs_linkName = lhs_linkName
self.rhs_linkName = rhs_linkName
InverseProperties[(lhs_class, lhs_linkName)] = self
InverseProperties[(rhs_class, rhs_linkName)] = self
def other(self, cls, name):
if issubclass(cls, self.lhs_class) and self.lhs_linkName == name:
return (self.rhs_class, self.rhs_linkName)
elif issubclass(cls, self.rhs_class) and self.rhs_linkName == name:
return (self.lhs_class, self.lhs_linkName)
raise InversePropertyException('The property ({}, {}) has no inverse in {}'.format(cls, name, self))
def __repr__(self):
return 'InverseProperty({},{},{},{})'.format(self.lhs_class,
self.lhs_linkName,
self.rhs_class,
self.rhs_linkName)
[docs]class InversePropertyException(Exception):
pass