All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
   2 Provides lazy implementations for Task and TaskQuerySet.
 
   6 class LazyUUIDTask(object):
 
   8     A lazy wrapper around Task object, referenced by UUID.
 
  10     - Supports comparison with LazyUUIDTask or Task objects (equality by UUIDs)
 
  11     - If any attribute other than 'uuid' requested, a lookup in the
 
  12       backend will be performed and this object will be replaced by a proper
 
  16     def __init__(self, tw, uuid):
 
  20     def __getitem__(self, key):
 
  21         # LazyUUIDTask does not provide anything else other than 'uuid'
 
  28     def __getattr__(self, name):
 
  29         # Getattr is called only if the attribute could not be found using
 
  32         return getattr(self, name)
 
  34     def __eq__(self, other):
 
  36             # For saved Tasks, just define equality by equality of uuids
 
  37             return self['uuid'] == other['uuid']
 
  40         return self['uuid'].__hash__()
 
  43         return "LazyUUIDTask: {0}".format(self._uuid)
 
  48         Implementation of the 'saved' property. Always returns True.
 
  54         Performs conversion to the regular Task object, referenced by the
 
  58         replacement = self._tw.tasks.get(uuid=self._uuid)
 
  59         self.__class__ = replacement.__class__
 
  60         self.__dict__ = replacement.__dict__
 
  63 class LazyUUIDTaskSet(object):
 
  65     A lazy wrapper around TaskQuerySet object, for tasks referenced by UUID.
 
  67     - Supports 'in' operator with LazyUUIDTask or Task objects
 
  68     - If iteration over the objects in the LazyUUIDTaskSet is requested, the
 
  69       LazyUUIDTaskSet will be converted to QuerySet and evaluated
 
  72     def __init__(self, tw, uuids):
 
  74         self._uuids = set(uuids)
 
  76     def __getattr__(self, name):
 
  77         # Getattr is called only if the attribute could not be found using
 
  80         if name.startswith('__'):
 
  81             # If some internal method was being search, do not convert
 
  82             # to TaskQuerySet just because of that
 
  86             return getattr(self, name)
 
  89         return "LazyUUIDTaskSet([{0}])".format(', '.join(self._uuids))
 
  91     def __eq__(self, other):
 
  92         return set(t['uuid'] for t in other) == self._uuids
 
  94     def __ne__(self, other):
 
  95         return not (self == other)
 
  97     def __contains__(self, task):
 
  98         return task['uuid'] in self._uuids
 
 101         return len(self._uuids)
 
 104         for uuid in self._uuids:
 
 105             yield LazyUUIDTask(self._tw, uuid)
 
 107     def __sub__(self, other):
 
 108         return self.difference(other)
 
 110     def __isub__(self, other):
 
 111         return self.difference_update(other)
 
 113     def __rsub__(self, other):
 
 114         return LazyUUIDTaskSet(self._tw,
 
 115             set(t['uuid'] for t in other) - self._uuids)
 
 117     def __or__(self, other):
 
 118         return self.union(other)
 
 120     def __ior__(self, other):
 
 121         return self.update(other)
 
 123     def __ror__(self, other):
 
 124         return self.union(other)
 
 126     def __xor__(self, other):
 
 127         return self.symmetric_difference(other)
 
 129     def __ixor__(self, other):
 
 130         return self.symmetric_difference_update(other)
 
 132     def __rxor__(self, other):
 
 133         return self.symmetric_difference(other)
 
 135     def __and__(self, other):
 
 136         return self.intersection(other)
 
 138     def __iand__(self, other):
 
 139         return self.intersection_update(other)
 
 141     def __rand__(self, other):
 
 142         return self.intersection(other)
 
 144     def __le__(self, other):
 
 145         return self.issubset(other)
 
 147     def __ge__(self, other):
 
 148         return self.issuperset(other)
 
 150     def issubset(self, other):
 
 151         return all([task in other for task in self])
 
 153     def issuperset(self, other):
 
 154         return all([task in self for task in other])
 
 156     def union(self, other):
 
 157         return LazyUUIDTaskSet(self._tw,
 
 158             self._uuids | set(t['uuid'] for t in other))
 
 160     def intersection(self, other):
 
 161         return LazyUUIDTaskSet(self._tw,
 
 162             self._uuids & set(t['uuid'] for t in other))
 
 164     def difference(self, other):
 
 165         return LazyUUIDTaskSet(self._tw,
 
 166             self._uuids - set(t['uuid'] for t in other))
 
 168     def symmetric_difference(self, other):
 
 169         return LazyUUIDTaskSet(self._tw,
 
 170             self._uuids ^ set(t['uuid'] for t in other))
 
 172     def update(self, other):
 
 173         self._uuids |= set(t['uuid'] for t in other)
 
 176     def intersection_update(self, other):
 
 177         self._uuids &= set(t['uuid'] for t in other)
 
 180     def difference_update(self, other):
 
 181         self._uuids -= set(t['uuid'] for t in other)
 
 184     def symmetric_difference_update(self, other):
 
 185         self._uuids ^= set(t['uuid'] for t in other)
 
 189         self._uuids.add(task['uuid'])
 
 191     def remove(self, task):
 
 192         self._uuids.remove(task['uuid'])
 
 195         return self._uuids.pop()
 
 202         Performs conversion to the regular TaskQuerySet object, referenced by
 
 206         replacement = self._tw.tasks.filter(' '.join(self._uuids))
 
 207         self.__class__ = replacement.__class__
 
 208         self.__dict__ = replacement.__dict__