Re: Re: Trellis + Python 2.6
"Sergey Schetinin" <[email protected]> Thu, 20 Nov 2008 09:44:29 +0200
| Newsgroups | gmane.comp.python.peak |
|---|---|
| Message-ID | <[email protected]> |
Whoops, just that patch is a bit out of date (uses copy instead of copy.copy) _______________________________________________ PEAK mailing list [email protected] http://www.eby-sarna.com/mailman/listinfo/peak
py26.patch
(application/octet-stream, 10 KB)
Index: stm.py
===================================================================
--- stm.py (revision 2595)
+++ stm.py (working copy)
@@ -1,6 +1,6 @@
"""Software Transactional Memory and Observers"""
-import weakref, sys, heapq, UserList, UserDict, sets
+import weakref, sys, heapq, UserList, UserDict
from peak.util.extremes import Max
from peak.util import decorators
try:
Index: trellis.py
===================================================================
--- trellis.py (revision 2595)
+++ trellis.py (working copy)
@@ -1,7 +1,7 @@
from thread import get_ident
from weakref import ref
from peak.util import addons, decorators
-import sys, UserDict, UserList, sets, stm, types, new, weakref, copy
+import sys, UserDict, UserList, stm, types, new, weakref, copy
from peak.util.extremes import Max
from peak.util.symbols import Symbol, NOT_GIVEN
@@ -42,12 +42,13 @@
try:
set = set
except NameError:
+ import sets
set = sets.Set
frozenset = sets.ImmutableSet
set_like = sets.BaseSet
dictlike = dict, sets.BaseSet
else:
- set_like = set, frozenset, sets.BaseSet
+ set_like = set, frozenset
dictlike = (dict,) + set_like
@@ -141,7 +142,7 @@
if value!=self._value:
if self._set_by not in (ctrl.current_listener, self):
# already set by someone else
- raise InputConflict(self._value, value) #self._set_by) #, value, ctrl.current_listener) # XXX
+ raise InputConflict(self._value, value, self._set_by, ctrl.current_listener) # XXX
changed(self)
change_attr(self, '_value', value)
@@ -292,8 +294,8 @@
a rule, reads performed in the function will not become dependencies of the
caller.
"""
- def wrap(__func, __module):
- """
+ def wrap(__func, __module): pass
+ wrap.__doc__ = """
if not __module.ctrl.active:
return __module.atomically(__func, $args)
elif __module.ctrl.current_listener is None:
@@ -506,7 +508,7 @@
return ReadOnlyCell(rule, None, discrete)
elif rule is None:
return Value(v, discrete)
- return ReadOnlyCell.__new__(cls, rule, value, discrete)
+ return ReadOnlyCell.__new__(cls)#, rule, value, discrete)
def _check_const(self):
pass # we can never become Constant
@@ -529,8 +531,9 @@
super(Cell, self).set_value(value)
if self._needs_init:
schedule(self)
+ else:
+ cancel(self)
-
value = property(get_value, set_value)
def dirty(self):
@@ -552,7 +555,7 @@
else:
# It should be impossible to get here unless you run the cell
# manually. Don't do that. :)
- raise AssertionError("This should never happen!")
+ raise AssertionError("This should never happen!", self)
class Effector(SensorBase, Cell):
@@ -748,6 +751,8 @@
except KeyError:
name = self.__name__
cell = cells.setdefault(name, self.make_cell(typ, ob, name))
+ if ctrl.active:
+ on_undo(cells.pop, name)
return cell.value
def __repr__(self):
@@ -1240,6 +1245,9 @@
strategy is used in each recalcultion that changes the list. If what you
really want is e.g. a sorted read-only view on a set, don't use this.
"""
+ if hasattr(UserList.UserList, '__metaclass__'):
+ class __metaclass__(Component.__metaclass__, UserList.UserList.__metaclass__):
+ pass
updated = todo(lambda self: self.data[:])
future = updated.future
@@ -1348,10 +1356,7 @@
-
-
-
-class Set(sets.Set, Component):
+class _SetBase(Component):
"""Mutable set that recalculates observers when it's changed
The ``added`` and ``removed`` attributes can be watched for changes, but
@@ -1364,28 +1369,6 @@
to_add = _added.future
to_remove = _removed.future
- def __init__(self, iterable=None, **kw):
- """Construct a set from an optional iterable."""
- Component.__init__(self, **kw)
- if iterable is not None:
- # we can update self._data in place, since no-one has seen it yet
- sets.Set._update(self, iterable)
-
- maintain(make=dict)
- def _data(self):
- """The dictionary containing the set data."""
- data = self._data
- pop = data.pop
- if self.removed:
- mark_dirty()
- for item in self.removed: pop(item, None)
- on_undo(data.update, dict.fromkeys(self.removed, True))
- if self.added:
- mark_dirty()
- data.update(dict.fromkeys(self.added, True))
- for item in self.added: on_undo(pop, item, None)
- return data
-
def __setstate__(self, data):
self.__init__(data[0])
@@ -1490,28 +1473,157 @@
else:
to_add.add(elt) # Don't got it; add it
-def to_dict_or_set(ob):
- """Return the most basic set or dict-like object for ob
- If ob is a sets.BaseSet, return its ._data; if it's something we can tell
- is dictlike, return it as-is. Otherwise, make a dict using .fromkeys()
- """
- if isinstance(ob, sets.BaseSet):
- return ob._data
- elif not isinstance(ob, dictlike):
- return dict.fromkeys(ob)
- return ob
+if sys.version >= '2.6':
+ from itertools import ifilter, ifilterfalse
+ MutableSet = getattr(__import__('collections', level=0), 'MutableSet') # absolute import
+ class Set(_SetBase, MutableSet):
+ class __metaclass__(_SetBase.__metaclass__, MutableSet.__metaclass__):
+ pass
+ def __init__(self, iterable=None, **kw):
+ """Construct a set from an optional iterable."""
+ Component.__init__(self, **kw)
+ if iterable is not None:
+ # we can update self._data in place, since no-one has seen it yet
+ self._data.update(iterable)
+ __hash__ = None
+ maintain(make=set)
+ def _data(self):
+ """The dictionary containing the set data."""
+ data = self._data
+ if self.removed:
+ mark_dirty()
+ data -= self.removed
+ on_undo(data.update, copy.copy(self.removed))
+ if self.added:
+ mark_dirty()
+ data.update(self.added)
+ on_undo(data.difference_update, copy.copy(self.added))
+ return data
+ def __getstate__(self):
+ return self._data,
+ def discard(self, item):
+ try:
+ self.remove(item)
+ except KeyError:
+ pass
+ def __len__(self):
+ return len(self._data)
+ def __iter__(self):
+ return iter(self._data)
+ def __contains__(self, item):
+ return item in self._data
+
+ def update(self, iterable):
+ self._update(iterable)
+
+ def union(self, other):
+ result = self.__class__(self._data)
+ result._data.update(other)
+ return result
+
+ def intersection(self, other):
+ other = to_dict_or_set(other)
+ if len(self) <= len(other):
+ little, big = self, other
+ else:
+ little, big = other, self
+ common = ifilter(big.__contains__, little)
+ return self.__class__(common)
+
+ def difference(self, other):
+ other = to_dict_or_set(other)
+ return self.__class__(ifilterfalse(other.__contains__, self))
+
+ def symmetric_difference(self, other):
+ other = to_dict_or_set(other)
+ result = self.__class__()
+ result._data.update(ifilterfalse(other.__contains__, self._data))
+ result._data.update(ifilterfalse(self._data.__contains__, other))
+ return result
+
+ __or__ = union
+ __xor__ = symmetric_difference
+ __and__ = intersection
+ __sub__ = difference
+
+ issubset = MutableSet.__le__
+ issuperset = MutableSet.__ge__
+
+ def __ixor__(self, other):
+ """Update a set with the symmetric difference of itself and another."""
+ self._binary_sanity_check(other)
+ self.symmetric_difference_update(other)
+ return self
+
+ def __isub__(self, other):
+ """Remove all elements of another set from this set."""
+ self._binary_sanity_check(other)
+ self.difference_update(other)
+ return self
+
+
+
+ def to_dict_or_set(ob):
+ if isinstance(ob, Set):
+ return ob._data
+ elif isinstance(ob, dictlike):
+ return ob
+ else:
+ return frozenset(ob)
+
+
+
+
+
+else:
+ import sets
+
+ class Set(_SetBase, sets.Set):
+ def __init__(self, iterable=None, **kw):
+ """Construct a set from an optional iterable."""
+ Component.__init__(self, **kw)
+ if iterable is not None:
+ # we can update self._data in place, since no-one has seen it yet
+ sets.Set._update(self, iterable)
+
+ maintain(make=dict)
+ def _data(self):
+ """The dictionary containing the set data."""
+ data = self._data
+ pop = data.pop
+ if self.removed:
+ mark_dirty()
+ for item in self.removed: pop(item, None)
+ on_undo(data.update, dict.fromkeys(self.removed, True))
+ if self.added:
+ mark_dirty()
+ data.update(dict.fromkeys(self.added, True))
+ for item in self.added: on_undo(pop, item, None)
+ return data
+
+
+ def to_dict_or_set(ob):
+ """Return the most basic set or dict-like object for ob
+ If ob is a sets.BaseSet, return its ._data; if it's something we can tell
+ is dictlike, return it as-is. Otherwise, make a dict using .fromkeys()
+ """
+ if isinstance(ob, sets.BaseSet):
+ return ob._data
+ elif not isinstance(ob, dictlike):
+ return dict.fromkeys(ob)
+ return ob