[Zope-CVS] CVS: Packages/pypes/pypes - __init__.py:1.2
exceptions.py:1.3 identity.py:1.5 interfaces.py:1.10
serviceconfig.py:1.3 services.py:1.4
Casey Duncan
casey at zope.com
Mon Feb 9 16:15:28 EST 2004
Update of /cvs-repository/Packages/pypes/pypes
In directory cvs.zope.org:/tmp/cvs-serv11692/pypes
Modified Files:
__init__.py exceptions.py identity.py interfaces.py
serviceconfig.py services.py
Log Message:
dos -> unix line endings
=== Packages/pypes/pypes/__init__.py 1.1.1.1 => 1.2 ===
--- Packages/pypes/pypes/__init__.py:1.1.1.1 Mon Aug 4 00:46:03 2003
+++ Packages/pypes/pypes/__init__.py Mon Feb 9 16:14:57 2004
@@ -1,37 +1,37 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Pypes: Persistence services for python
-
-Services for building object-database applications in Python
-
-$Id$"""
-
-import serviceconfig, identity, event
-
-# XXX These should probably be in a config file
-default_services = {
- 'identity': identity.IdentityService,
- 'event': event.EventService,
-}
-
-def initialize(connection):
- """Setup default pypes services for connection. Does not affect any existing
- services there.
-
- connection -- an open zodb connection object
- """
- serviceconfig.initServices(connection)
- for name, factory in default_services.items():
- serviceconfig.addService(connection, name, factory())
-
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Pypes: Persistence services for python
+
+Services for building object-database applications in Python
+
+$Id$"""
+
+import serviceconfig, identity, event
+
+# XXX These should probably be in a config file
+default_services = {
+ 'identity': identity.IdentityService,
+ 'event': event.EventService,
+}
+
+def initialize(connection):
+ """Setup default pypes services for connection. Does not affect any existing
+ services there.
+
+ connection -- an open zodb connection object
+ """
+ serviceconfig.initServices(connection)
+ for name, factory in default_services.items():
+ serviceconfig.addService(connection, name, factory())
+
=== Packages/pypes/pypes/exceptions.py 1.2 => 1.3 ===
--- Packages/pypes/pypes/exceptions.py:1.2 Sun Aug 10 22:32:15 2003
+++ Packages/pypes/pypes/exceptions.py Mon Feb 9 16:14:57 2004
@@ -1,48 +1,48 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""pypes exception types
-
-$Id$"""
-
-class PypesError(Exception):
- """General pypes error base"""
-
-class PypesLookupError(PypesError, LookupError):
- """Persistent pypes component lookup failure"""
-
-class IdentityError(PypesError):
- """General identity service error"""
-
-class IdentityKeyError(IdentityError, KeyError):
- """Identity service received invalid identifier"""
-
-class SetLookupError(PypesError, LookupError):
- """Set lookup failed"""
-
-class EventRegistrationError(PypesError):
- """Event registration operation failed"""
-
-class VetoEvent(Exception):
- """An exception used when an event listener wishes to signal an
- event sender to cancel the operation that generated the event.
- """
-
-class GraphLookupError(PypesError):
- """Lookup of object from graph failed"""
-
-class GraphValueError(PypesError):
- """Value could not be retreived from graph"""
-
-class GraphCycleError(PypesError):
- """Cycle detected during operation for acyclic graph"""
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""pypes exception types
+
+$Id$"""
+
+class PypesError(Exception):
+ """General pypes error base"""
+
+class PypesLookupError(PypesError, LookupError):
+ """Persistent pypes component lookup failure"""
+
+class IdentityError(PypesError):
+ """General identity service error"""
+
+class IdentityKeyError(IdentityError, KeyError):
+ """Identity service received invalid identifier"""
+
+class SetLookupError(PypesError, LookupError):
+ """Set lookup failed"""
+
+class EventRegistrationError(PypesError):
+ """Event registration operation failed"""
+
+class VetoEvent(Exception):
+ """An exception used when an event listener wishes to signal an
+ event sender to cancel the operation that generated the event.
+ """
+
+class GraphLookupError(PypesError):
+ """Lookup of object from graph failed"""
+
+class GraphValueError(PypesError):
+ """Value could not be retreived from graph"""
+
+class GraphCycleError(PypesError):
+ """Cycle detected during operation for acyclic graph"""
=== Packages/pypes/pypes/identity.py 1.4 => 1.5 ===
--- Packages/pypes/pypes/identity.py:1.4 Sun Feb 8 22:56:21 2004
+++ Packages/pypes/pypes/identity.py Mon Feb 9 16:14:57 2004
@@ -1,325 +1,325 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Pypes identity service
-
-Provides unique tokens for identifying persistent objects.
-
-$Id$"""
-
-from __future__ import generators
-from random import randint
-from persistent import Persistent
-from types import IntType
-from zope.interface import implements
-from BTrees.IIBTree \
- import IITreeSet, multiunion, union, intersection, difference
-from BTrees.IOBTree import IOBTree
-from BTrees.Length import Length
-from pypes import services
-from pypes.event import PypesMessage
-from pypes.interfaces import IIdentityService, IIdentitySet, IIdentityMessage
-from pypes.exceptions import PypesError, PypesLookupError
-from pypes.exceptions import IdentityError, IdentityKeyError, SetLookupError
-
-
-class IdentityService(Persistent):
- """Identity service providing integer identifiers. Before this service
- can be used, it must be committed to the database
- """
-
- implements(IIdentityService)
-
- _v_nextid = 0
-
- def __init__(self):
- self._objs = IOBTree()
- self._length = Length()
-
- def idType(self):
- return IntType
-
- def register(self, obj):
- if pypesid(obj) is not None:
- raise IdentityError, 'Object already registered'
- if self._p_jar is not None and getattr(obj, '_p_jar', 0) is None:
- # Make sure the object has a data manager so it can be
- # used as an access point back to the services
- obj._p_jar = self._p_jar
- # Ids are generated in sequence in a single thread to group
- # related objects in the tree
- while not self._v_nextid or self._objs.has_key(self._v_nextid):
- self._v_nextid = randint(-2100000000, 2100000000)
- identifier = self._v_nextid
- try:
- obj._pypes_id_ = identifier
- except AttributeError:
- raise IdentityError, ('Cannot register object. Unable to store '
- 'persistent id as attribute')
- self._objs[identifier] = obj
- self._length.change(1)
- self._v_nextid += 1
- if self._p_jar is not None:
- try:
- event_svc = services.event(self)
- except PypesLookupError:
- pass # No event service
- else:
- event_svc.send(IdRegisteredMessage(obj, identifier))
- return identifier
-
- def hasId(self, identifier):
- return bool(self._objs.has_key(identifier))
-
- def __contains__(self, obj):
- identifier = pypesid(obj)
- return isinstance(identifier, IntType) and self.hasId(identifier)
-
- def __len__(self):
- return self._length()
-
- def removeId(self, identifier):
- try:
- obj = self._objs[identifier]
- except KeyError:
- raise IdentityKeyError, identifier
- else:
- del self._objs[identifier]
- self._length.change(-1)
- obj._pypes_id_ = None
-
- def remove(self, obj):
- identifier = pypesid(obj)
- try:
- obj = self._objs[identifier]
- except (KeyError, TypeError):
- raise IdentityError, 'Object not registered'
- else:
- del self._objs[identifier]
- self._length.change(-1)
- obj._pypes_id_ = None
- if self._p_jar is not None:
- try:
- event_svc = services.event(self)
- except PypesLookupError:
- pass # No event service
- else:
- event_svc.send(IdUnregisteredMessage(obj, identifier))
-
- def getObject(self, identifier):
- try:
- return self._objs[identifier]
- except KeyError:
- raise IdentityKeyError, identifier
-
- def __iter__(self):
- return iter(self._objs.values())
-
- def iterIds(self):
- return iter(self._objs.keys())
-
- def idSet(self):
- return IITreeSet(self._objs.keys())
-
-
-class IdentitySet(Persistent):
- """Efficient persistent sets of id-registered objects"""
-
- implements(IIdentitySet)
-
- def __init__(self, objs=None):
- """Identity sets can be constructed empty, or populated by an
- iterable sequence of id-registered objects
-
- objs -- An iterable sequence of id-registered objects.
- """
- self._idset = IITreeSet()
- if objs:
- self.update(objs)
-
- def fromIdSet(cls, idset, copy=False, dbconn=None):
- """Alternate constructor to create an identity set from a btree set
- of identifiers. If copy is true, then the set is copied, otherwise it
- used by the IdentitySet directly. If a copy is not made, then the
- idset should not be mutated outside of the set. dbconn is a ZODB
- database connection which allows the set to access services before it
- is committed.
- """
- set = cls()
- if copy:
- set._idset.update(idset)
- else:
- set._idset = idset
- if dbconn is not None:
- set._p_jar = dbconn
- return set
- fromIdSet = classmethod(fromIdSet)
-
- def add(self, obj):
- if self._p_jar is None:
- # Grab the data manager from the obj passed so
- # we have access to the services before we are committed
- self._p_jar = getattr(obj, '_p_jar', None)
- ident = pypesid(obj)
- if ident is None:
- raise IdentityError, obj
- isnew = self._idset.insert(ident)
- if isnew and not isinstance(self._idset, IITreeSet):
- # Set operations may result in _idset being an IISet
- # For better database efficiency we upgrade it to an IITreeSet
- # When we are mutated in place
- self._idset = IITreeSet(self._idset)
- return bool(isnew)
-
- def remove(self, obj):
- ident = pypesid(obj)
- if ident is None:
- raise IdentityError, obj
- try:
- self._idset.remove(ident)
- except KeyError:
- raise SetLookupError, obj
- else:
- if not isinstance(self._idset, IITreeSet):
- # Upgrade to IITreeSet for storage efficiency when mutated
- self._idset = IITreeSet(self._idset)
-
- def update(self, objs):
- if self._p_jar is None:
- # Grab the data manager from one of the objects passed
- # to give us access to other services before we are commited
- objs = iter(objs)
- try:
- first = objs.next()
- except StopIteration:
- return
- self.add(first)
- insert = self._idset.insert
- try:
- for ob in objs:
- insert(ob._pypes_id_)
- except AttributeError:
- raise IdentityError, 'Set update received unregistered object(s)'
-
- def __contains__(self, obj):
- ident = pypesid(obj)
- if ident is None:
- raise IdentityError, obj
- return bool(self._idset.has_key(ident))
-
- def __nonzero__(self):
- # Efficiently determine if we are empty
- return bool(self._idset)
-
- def __len__(self):
- return len(self._idset) # XXX keep a length for efficiency?
-
- def __iter__(self):
- # If an object in the set is no longer registered None is substituted
- # This iterator is lazy and changing the set during iteration
- # has undefined results
- identity = services.identity(self)
- for ident in self._idset.keys():
- try:
- yield identity.getObject(ident)
- except IdentityKeyError:
- yield None
-
- def union(self, other):
- return self.__class__.fromIdSet(union(self._idset, other._idset))
-
- __or__ = union
-
- def difference(self, other):
- return self.__class__.fromIdSet(difference(self._idset, other._idset))
-
- __sub__ = difference
-
- def intersection(self, other):
- return self.__class__.fromIdSet(
- intersection(self._idset, other._idset))
-
- __and__ = intersection
-
- def issubset(self, other):
- return not difference(self._idset, other._idset)
-
- def issuperset(self, other):
- return not difference(other._idset, self._idset)
-
- def __eq__(self, other):
- return self.issubset(other) and self.issuperset(other)
-
- def __ne__(self, other):
- return not self.issubset(other) or not self.issuperset(other)
-
-
-## Id Event Messsage Types ##
-
-
-class IdRegisteredMessage(PypesMessage):
- """object was registered with the identity service"""
-
- implements(IIdentityMessage)
-
- def __init__(self, object, id):
- self.object = object
- self.id = id
-
-
-class IdUnregisteredMessage(PypesMessage):
- """object was removed from the identity service"""
-
- implements(IIdentityMessage)
-
- def __init__(self, object, id):
- self.object = object
- self.id = id
-
-
-## Helper Functions ##
-
-
-def pypesid(obj):
- """Return the identifier for obj if registered with an identity service
- otherwise return None"""
- return getattr(obj, '_pypes_id_', None)
-
-
-def listenForIdEvents(listener, conn=None,
- id_registered_method='_notifyIdRegistered',
- id_unregistered_method='_notifyIdUnRegistered'):
- """Register obj with the event service as a listener for identity
- service registrations/unregistrations.
-
- listener -- Object to be registered as a listener
-
- conn -- Open ZODB connection object. If None it will be derived from
- listener if possible.
-
- id_registered_method -- Name of the method of listener which will
- receive idRegisteredMessages.
-
- id_registered_method -- Name of the method of listener which will
- receive idUnRegisteredMessages.
- """
- if conn is None:
- conn = listener
- event = services.event(conn)
- if id_registered_method:
- event.registerListener(
- listener, id_registered_method, IdRegisteredMessage)
- if id_unregistered_method:
- event.registerListener(
- listener, id_unregistered_method, IdUnregisteredMessage)
-
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Pypes identity service
+
+Provides unique tokens for identifying persistent objects.
+
+$Id$"""
+
+from __future__ import generators
+from random import randint
+from persistent import Persistent
+from types import IntType
+from zope.interface import implements
+from BTrees.IIBTree \
+ import IITreeSet, multiunion, union, intersection, difference
+from BTrees.IOBTree import IOBTree
+from BTrees.Length import Length
+from pypes import services
+from pypes.event import PypesMessage
+from pypes.interfaces import IIdentityService, IIdentitySet, IIdentityMessage
+from pypes.exceptions import PypesError, PypesLookupError
+from pypes.exceptions import IdentityError, IdentityKeyError, SetLookupError
+
+
+class IdentityService(Persistent):
+ """Identity service providing integer identifiers. Before this service
+ can be used, it must be committed to the database
+ """
+
+ implements(IIdentityService)
+
+ _v_nextid = 0
+
+ def __init__(self):
+ self._objs = IOBTree()
+ self._length = Length()
+
+ def idType(self):
+ return IntType
+
+ def register(self, obj):
+ if pypesid(obj) is not None:
+ raise IdentityError, 'Object already registered'
+ if self._p_jar is not None and getattr(obj, '_p_jar', 0) is None:
+ # Make sure the object has a data manager so it can be
+ # used as an access point back to the services
+ obj._p_jar = self._p_jar
+ # Ids are generated in sequence in a single thread to group
+ # related objects in the tree
+ while not self._v_nextid or self._objs.has_key(self._v_nextid):
+ self._v_nextid = randint(-2100000000, 2100000000)
+ identifier = self._v_nextid
+ try:
+ obj._pypes_id_ = identifier
+ except AttributeError:
+ raise IdentityError, ('Cannot register object. Unable to store '
+ 'persistent id as attribute')
+ self._objs[identifier] = obj
+ self._length.change(1)
+ self._v_nextid += 1
+ if self._p_jar is not None:
+ try:
+ event_svc = services.event(self)
+ except PypesLookupError:
+ pass # No event service
+ else:
+ event_svc.send(IdRegisteredMessage(obj, identifier))
+ return identifier
+
+ def hasId(self, identifier):
+ return bool(self._objs.has_key(identifier))
+
+ def __contains__(self, obj):
+ identifier = pypesid(obj)
+ return isinstance(identifier, IntType) and self.hasId(identifier)
+
+ def __len__(self):
+ return self._length()
+
+ def removeId(self, identifier):
+ try:
+ obj = self._objs[identifier]
+ except KeyError:
+ raise IdentityKeyError, identifier
+ else:
+ del self._objs[identifier]
+ self._length.change(-1)
+ obj._pypes_id_ = None
+
+ def remove(self, obj):
+ identifier = pypesid(obj)
+ try:
+ obj = self._objs[identifier]
+ except (KeyError, TypeError):
+ raise IdentityError, 'Object not registered'
+ else:
+ del self._objs[identifier]
+ self._length.change(-1)
+ obj._pypes_id_ = None
+ if self._p_jar is not None:
+ try:
+ event_svc = services.event(self)
+ except PypesLookupError:
+ pass # No event service
+ else:
+ event_svc.send(IdUnregisteredMessage(obj, identifier))
+
+ def getObject(self, identifier):
+ try:
+ return self._objs[identifier]
+ except KeyError:
+ raise IdentityKeyError, identifier
+
+ def __iter__(self):
+ return iter(self._objs.values())
+
+ def iterIds(self):
+ return iter(self._objs.keys())
+
+ def idSet(self):
+ return IITreeSet(self._objs.keys())
+
+
+class IdentitySet(Persistent):
+ """Efficient persistent sets of id-registered objects"""
+
+ implements(IIdentitySet)
+
+ def __init__(self, objs=None):
+ """Identity sets can be constructed empty, or populated by an
+ iterable sequence of id-registered objects
+
+ objs -- An iterable sequence of id-registered objects.
+ """
+ self._idset = IITreeSet()
+ if objs:
+ self.update(objs)
+
+ def fromIdSet(cls, idset, copy=False, dbconn=None):
+ """Alternate constructor to create an identity set from a btree set
+ of identifiers. If copy is true, then the set is copied, otherwise it
+ used by the IdentitySet directly. If a copy is not made, then the
+ idset should not be mutated outside of the set. dbconn is a ZODB
+ database connection which allows the set to access services before it
+ is committed.
+ """
+ set = cls()
+ if copy:
+ set._idset.update(idset)
+ else:
+ set._idset = idset
+ if dbconn is not None:
+ set._p_jar = dbconn
+ return set
+ fromIdSet = classmethod(fromIdSet)
+
+ def add(self, obj):
+ if self._p_jar is None:
+ # Grab the data manager from the obj passed so
+ # we have access to the services before we are committed
+ self._p_jar = getattr(obj, '_p_jar', None)
+ ident = pypesid(obj)
+ if ident is None:
+ raise IdentityError, obj
+ isnew = self._idset.insert(ident)
+ if isnew and not isinstance(self._idset, IITreeSet):
+ # Set operations may result in _idset being an IISet
+ # For better database efficiency we upgrade it to an IITreeSet
+ # When we are mutated in place
+ self._idset = IITreeSet(self._idset)
+ return bool(isnew)
+
+ def remove(self, obj):
+ ident = pypesid(obj)
+ if ident is None:
+ raise IdentityError, obj
+ try:
+ self._idset.remove(ident)
+ except KeyError:
+ raise SetLookupError, obj
+ else:
+ if not isinstance(self._idset, IITreeSet):
+ # Upgrade to IITreeSet for storage efficiency when mutated
+ self._idset = IITreeSet(self._idset)
+
+ def update(self, objs):
+ if self._p_jar is None:
+ # Grab the data manager from one of the objects passed
+ # to give us access to other services before we are commited
+ objs = iter(objs)
+ try:
+ first = objs.next()
+ except StopIteration:
+ return
+ self.add(first)
+ insert = self._idset.insert
+ try:
+ for ob in objs:
+ insert(ob._pypes_id_)
+ except AttributeError:
+ raise IdentityError, 'Set update received unregistered object(s)'
+
+ def __contains__(self, obj):
+ ident = pypesid(obj)
+ if ident is None:
+ raise IdentityError, obj
+ return bool(self._idset.has_key(ident))
+
+ def __nonzero__(self):
+ # Efficiently determine if we are empty
+ return bool(self._idset)
+
+ def __len__(self):
+ return len(self._idset) # XXX keep a length for efficiency?
+
+ def __iter__(self):
+ # If an object in the set is no longer registered None is substituted
+ # This iterator is lazy and changing the set during iteration
+ # has undefined results
+ identity = services.identity(self)
+ for ident in self._idset.keys():
+ try:
+ yield identity.getObject(ident)
+ except IdentityKeyError:
+ yield None
+
+ def union(self, other):
+ return self.__class__.fromIdSet(union(self._idset, other._idset))
+
+ __or__ = union
+
+ def difference(self, other):
+ return self.__class__.fromIdSet(difference(self._idset, other._idset))
+
+ __sub__ = difference
+
+ def intersection(self, other):
+ return self.__class__.fromIdSet(
+ intersection(self._idset, other._idset))
+
+ __and__ = intersection
+
+ def issubset(self, other):
+ return not difference(self._idset, other._idset)
+
+ def issuperset(self, other):
+ return not difference(other._idset, self._idset)
+
+ def __eq__(self, other):
+ return self.issubset(other) and self.issuperset(other)
+
+ def __ne__(self, other):
+ return not self.issubset(other) or not self.issuperset(other)
+
+
+## Id Event Messsage Types ##
+
+
+class IdRegisteredMessage(PypesMessage):
+ """object was registered with the identity service"""
+
+ implements(IIdentityMessage)
+
+ def __init__(self, object, id):
+ self.object = object
+ self.id = id
+
+
+class IdUnregisteredMessage(PypesMessage):
+ """object was removed from the identity service"""
+
+ implements(IIdentityMessage)
+
+ def __init__(self, object, id):
+ self.object = object
+ self.id = id
+
+
+## Helper Functions ##
+
+
+def pypesid(obj):
+ """Return the identifier for obj if registered with an identity service
+ otherwise return None"""
+ return getattr(obj, '_pypes_id_', None)
+
+
+def listenForIdEvents(listener, conn=None,
+ id_registered_method='_notifyIdRegistered',
+ id_unregistered_method='_notifyIdUnRegistered'):
+ """Register obj with the event service as a listener for identity
+ service registrations/unregistrations.
+
+ listener -- Object to be registered as a listener
+
+ conn -- Open ZODB connection object. If None it will be derived from
+ listener if possible.
+
+ id_registered_method -- Name of the method of listener which will
+ receive idRegisteredMessages.
+
+ id_registered_method -- Name of the method of listener which will
+ receive idUnRegisteredMessages.
+ """
+ if conn is None:
+ conn = listener
+ event = services.event(conn)
+ if id_registered_method:
+ event.registerListener(
+ listener, id_registered_method, IdRegisteredMessage)
+ if id_unregistered_method:
+ event.registerListener(
+ listener, id_unregistered_method, IdUnregisteredMessage)
+
=== Packages/pypes/pypes/interfaces.py 1.9 => 1.10 ===
--- Packages/pypes/pypes/interfaces.py:1.9 Mon Feb 9 00:24:51 2004
+++ Packages/pypes/pypes/interfaces.py Mon Feb 9 16:14:57 2004
@@ -1,512 +1,513 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Pypes interface specifications
-
-$Id$"""
-
-from zope.interface import Interface, Attribute
-
-class IPersistentService(Interface):
- """Pypes Persistent services are globally accessible,
- persistent objects in the database which perform functions and store data
- on behalf of many other persistent objects. Persistent services are stored
- in a registry in the database and are accessible from any persistent object
- in the database (or a database connection object) by name.
- """
-
-class IIdentityService(IPersistentService):
- """Registry of "identified" objects known to pypes.
-
- - Creates unique identifiers for persistent objects in a database.
-
- - Guarantees access to an object by its identifier as long as it
- is registered.
-
- - Provides a count of registered objects.
-
- - Provides a set of registered objects
-
- - Allows iteration of registered objects.
-
- Identifiers must be:
-
- - True values.
-
- - Independent of the objects they identify.
-
- - Arbitrarily selected for any persistent object.
-
- - The same type for all objects.
-
- - Small, immutable, hashable and pickleable.
-
- - Comparible/consistently orderable across application runs.
- """
-
- def idType():
- """Return the type object for the identifiers generated by this
- service.
- """
-
- def register(obj):
- """Register obj with the identity service. Identity registered objects
- are considered "identified". Return the persistent unique identifier
- for obj. The service must guarantee that so long as the object remains
- registered, it can be retrieved using the identifier returned upon
- registration.
-
- If obj is already registered or cannot
- be registered for any reason, raise an IdentityError.
- """
-
- def hasId(identifier):
- """Return true if identifier refers to an object currently registered.
- If identifier is not the proper type raise TypeError.
- """
-
- def __contains__(obj):
- """Return true if obj is registered with the service."""
-
- def removeId(identifier):
- """Remove (unregister) an object by identifier. Raise IdentityKeyError
- if the identifier does not coorespond to any registered object. If
- identifier is not the proper type raise TypeError. Once an object is
- removed it can be registered again, but its identifier may not be the
- same as the first registration. It is acceptable for identifiers to be
- reused once its object is removed.
- """
-
- def remove(obj):
- """Remove (unregister) an object. Raise IdentityError if the object
- is not registered.
- """
-
- def getObject(identifier):
- """Return the registered object for identifier. Raise IdentityKeyError
- if the identifier does not coorespond to any registered object. Raise
- TypeError if identifier is not the proper type.
- """
-
- def __len__():
- """Return the number of objects registered."""
-
- def __iter__():
- """Return an iterator of registered objects."""
-
- def iterIds():
- """Return an iterator of registered object identifiers."""
-
- def idSet():
- """Return an identity set of all registered objects."""
-
-class IIdentitySet(Interface):
- """A set of unique identified objects. Since the set relies
- on persistent identity, its members may be mutable. Identity sets
- weakly reference their members, so being a member of a set does not
- guarantee continued persistence. Implementations may use the event
- service to keep informed of object registrations"""
-
- def add(obj):
- """Add obj to the set. Return true if obj was not a member already,
- false if so. In the latter case insert does not change the set. Raise
- IdentityError if obj is not identified
- """
-
- def remove(obj):
- """Remove obj from set. raise SetLookupError if obj is not in the set"""
-
- def update(objs):
- """Iterate objs and add its members to the set in place"""
-
- def __contains__(obj):
- """Return true if obj is in the set"""
-
- def __len__():
- """Return set member count"""
-
- def __iter__():
- """Return an iterator of the members of the set"""
-
- def union(other):
- """Return a set whos members are the union of self and other"""
-
- def __or__(other):
- """Alias for union in an expression"""
-
- def difference(other):
- """Return a set whos members are in self but not in other"""
-
- def __sub__(other):
- """Alias for difference"""
-
- def intersection(other):
- """Return a set whos members are in both self and other"""
-
- def __and__(other):
- """Compute the intersection between self and other and return the
- resulting set
- """
-
- def issubset(other):
- """Return true if all members of self are also in other"""
-
- def issuperset(other):
- """Return true if all members of other are also in self"""
-
- def __eq__(other):
- """Return true if this set and other contain the same members"""
-
-
-class IEventService(IPersistentService):
- """An event service dispatches messages to listeners. It allows loosely
- bound objects and services to communicate and notify one another without
- dependancies or direct knowledge of each other. Events can also be vetoed
- by listeners to enforce data integrity rules or indirectly alter behavior.
-
- Some guidelines for implementations:
-
- - The event sending overhead should be as cheap as possible.
-
- - Registering/unregistering listeners should also be as inexpensive as
- possible, but not at the expense of event sending performance.
- """
-
- def registerListener(obj, method_name, message_type):
- """Register obj as a listener via the specified method name.
- method_name must specify the name of a callable attribute of obj which
- accepts a single message argument. message_type must be a type or
- class object. May be called multiple times for the same listener."""
-
- def unregisterListener(obj, method_name, message_type):
- """Unregister a listener for the message_types specified via
- the registered method name. If obj was never registered via
- the method specified raise EventRegistrationError.
- """
-
- def unregisterAllListeners(message_type):
- """Unregister all listeners for the given message type. Only affects
- objects directly registered for a given message_type, no
- listeners for subtypes are affected. If none are registered, do nothing.
- """
-
- def send(message):
- """Send message to all registered listeners for this message type or
- its supertypes. Return true if the message was received by any
- listeners, false if not. Listeners may raise exceptions, which will be
- propagated to the sender. If the sender wishes to catch exceptions, it
- should be careful to handle ConflictErrors properly (i.e. let them
- propagate). A special exception class VetoEvent should, at the option
- of the sender, be processed as a request to cancel the operation which
- generated the event (i.e. by aborting the current transaction)
- """
-
- def wouldReceive(obj, message_type):
- """Return true if obj would receive a message of the type specified.
- This will be true if obj is a registered listener for message_type
- or any of its supertypes
- """
-
- def isListener(obj, message_type):
- """Return true if obj is registered as a listener for the specified
- message_type.
- """
-
- def iterListeners(message_type):
- """Return an iterator of (listener, methodname) pairs for all
- listeners of the message type specified.
- """
-
- def iterReceivers(message_type):
- """Return an iterator of (listener, methodname) pairs for all
- listeners that would receive a message of message_type, including
- listeners for supertypes.
- """
-
- def iterMessageTypes():
- """Return an iterator of all message types that have listeners
- registered
- """
-
-class IObjectMessage(Interface):
- """A message concerning a single object"""
-
- object = Attribute('object', 'Object that is the subject of the message')
-
-
-class IIdentityMessage(IObjectMessage):
- """A message concerning the identity of an object"""
-
- id = Attribute('id', 'The identity of the object in question')
-
-
-class IExtentService(Interface):
- """Service providing global extent sets of identified objects by class and
- interface.
-
- Extents are typically used as top-level collections by applications. They
- are generally analogous to tables in a traditional relational database. A
- strong difference however, is that extents are not directly modified.
- Objects are added and removed from extents automatically as they are
- registered and unregistered from the identity service or modified (in terms
- of interfaces provided) and signaled through the event service.
-
- XXX Once the query service is documented, explain how they work together
- """
-
- def __getitem__(key):
- """Return the canonical extent for key. For class extents the key is a
- class. For interface extents it is an interface object. Raise KeyError
- if key is not contained in the service. Raise TypeError if key type
- is not supported.
- """
-
- def __contains__(key):
- """Return true if key is an identifier of an extent, false otherwise.
- Raise TypeError if key type is not supported.
- """
-
- def __iter__():
- """Return an iterator of all extents in the service"""
-
-
-class IExtentMap(Interface):
- """Simple mapping-like container for canonical extents of a single type"""
-
- def __getitem__(key):
- """Return extent for key. Raise KeyError if key is the correct type
- but is not in the map. Raise TypeError if key is not the correct type
- for the extent map"""
-
- def __iter__():
- """Return an iterator of all extents in the mapping"""
-
- def update():
- """Update the extent map from all identified objects"""
-
-
-class IExtent(Interface):
- """Automated set of identified objects.
-
- Extents are either provided by the extent service or derived from other
- extents. Extents behave like read-only sets in most respects. They are
- updated automatically as objects are manipulated and registered with pypes.
-
- Although extents may be arbitrarily large, operations between them (such
- as union and intersection) are designed to be efficient, especially between
- extents of the same type (class or interface). Operations between extents
- and identity sets are also supported; resulting in a new identity set.
- """
-
- def __contains__(obj):
- """Return true if obj is in the extent"""
-
- def __len__():
- """Return extent member count"""
-
- def __iter__():
- """Return an iterator of the members of the extent"""
-
- def union(other):
- """Return a derived extent or identity set whos members are the union
- of self and other"""
-
- def __or__(other):
- """Alias for union in an expression"""
-
- def difference(other):
- """return a derived extent or identity set whos members are in self
- but not in other"""
-
- def __sub__(other):
- """Alias for difference"""
-
- def intersection(other):
- """Return a derived extent or identity set whos members are in both
- self and other"""
-
- def __and__(other):
- """Compute the intersection between self and other and return the
- resulting derived extent or identity set
- """
-
- def issubset(other):
- """Return true if all members of self are also in other"""
-
- def issuperset(other):
- """Return true if all members of other are also in self"""
-
- def __eq__(other):
- """Return true if this extent and other contain the same members"""
-
-
-class ICanonicalExtent(IExtent):
- """An extent of a single interface or class provided directly by the
- extent service
- """
-
- key = Attribute('key',
- """Key for this extent in the extent service""")
-
- def subExtents():
- """Return the direct sub-extents of the extent, if any, which are
- disjoint canonical sets which are subsets of the extent.
- """
-
-class IDerivedExtent(IExtent):
- """An extent derived by combining extents"""
-
-
-class IGraphNodes(Interface):
- """Collection of nodes in a graph"""
-
- def add(obj):
- """Add obj as a node of the graph. Return true if obj is not already
- a node. If obj is in the graph, return false and do nothing
- """
-
- def remove(obj):
- """Remove obj from the graph and any edges connecting to and from the
- obj. If obj is not a node, then raise GraphLookupError
- """
-
- def __contains__(obj):
- """Return true if obj is a node of the graph, false if not"""
-
- def __len__():
- """Return the graph node count"""
-
- def __iter__():
- """Return an iterator of the graph node objects"""
-
- def iterTopological():
- """Return an iterator of the nodes in topologically sorted order.
- The graph must be directed and acyclic. If a cycle is encountered
- during iteration, raise GraphCycleError.
- """
-
- def degree(node):
- """Return the degree of the node, which is the integer count
- of adjacent target nodes
- """
-
- def sources(node, transitive=False):
- """Return the set of nodes which are the source of an edge where the
- specified node is a target. If transitive is true, then the set returns
- all nodes which can reach the specified node by traversing all graph
- edges to node. If node is not in the graph, raise GraphLookupError.
- """
-
- def targets(node, transitive=False):
- """Return the set of nodes which are the targets of an edge where
- the specified node is the source. If transitive is true, then the set
- returns all nodes reachable from the specified node by traversing
- all graph edges from node. If node is not in the graph, raise
- GraphLookupError.
- """
-
-class IGraphEdges(Interface):
- """Collection of edges in a graph"""
-
- def add(source, target, value=None):
- """Add an edge to the graph from object source to target. If these
- objects are not already nodes of the graph, they are added. The order
- of source and target are significant only for directed graphs. If the
- edge did not already exist, return true. Otherwise return false.
-
- value -- Optional object used as the value for the edge between source
- and target. May be used to store the distance or magnitude of the edge
- or any desired application data. If the edge already exists value
- replaces any existing edge value; if value is omitted, the existing
- value is unchanged.
- """
-
- def remove(source, target):
- """Remove the edge between source and target from the graph. If no
- edge exists between source and target, raise GraphLookupError. The
- source and target nodes are not removed from the graph.
- """
-
- def get(source, target, default=None):
- """Return the value for the edge from node source to node target. If
- no value was assigned, raise GraphValueError or return default if
- supplied. If no edge exists, raise GraphLookupError.
- """
-
- def set(source, target, value):
- """Set the data for the edge from source to target. If no edge exists
- between source and target, raise GraphLookupError
- """
-
- def __contains__(pair):
- """Return true if the graph contains an edge cooresponding to pair, a
- sequence of two node objects. The order of these objects is significant
- only for directed graphs. If either object in the pair are not nodes
- of the graph, raise GraphLookupError
- """
-
- def __len__():
- """Return the graph edge count"""
-
- def __iter__():
- """Return an iterator of (source, target) pairs representing each
- edge in the graph
- """
-
- def iterValues():
- """Return an iterator of the values assigned to the edges in the graph
- """
-
- def iterItems():
- """Return an iterator of ((source, target), value) pairs for each
- edge with a value in the graph.
- """
-
-class IGraph(Interface):
- """Persistent graph of object nodes"""
-
- nodes = Attribute('nodes',
- """IGraphNodes object for manipulating the nodes of the graph""")
-
- edges = Attribute('edges',
- """IGraphEdges object for manipulating the edges of the graph""")
-
- def transitiveClosure(with_values=False):
- """Return the transitive closure graph for the current graph. If
- with_values is true, then the values for each edge in the resulting
- graph are computed from the exisiting values. This means that all
- edge values in the graph must be addable
- """
-
- def shortestPath(source, target, use_values=False):
- """Return the sequence of node which is the shortest path from source
- to target. For instance, If source and target are
- adjacent, return [source, target]; if they connect through a single
- intermediary return [source, intermediate, target], etc. If no
- path connects source and target, return None.
-
- If use_values is true, then the edge data is used to calculate the
- distance between nodes. This implies that all data objects in the graph
- can be added and compared to one another as distances. By default, the
- values are not used and the distance between adjacent nodes is assumed
- to be 1.
- """
-
- def allPaths(source=None, target=None):
- """Return an iterator of sequences of nodes representing all possible
- paths between nodes of the graph. If source and target are omitted,
- all possible paths between all graph nodes are returned. If source
- is specified, only paths starting from source are returned. If
- target is specified, only paths to target are returned. If both are
- specifed to compute all paths connecting source to target
- """
\ No newline at end of file
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Pypes interface specifications
+
+$Id$"""
+
+from zope.interface import Interface, Attribute
+
+class IPersistentService(Interface):
+ """Pypes Persistent services are globally accessible,
+ persistent objects in the database which perform functions and store data
+ on behalf of many other persistent objects. Persistent services are stored
+ in a registry in the database and are accessible from any persistent object
+ in the database (or a database connection object) by name.
+ """
+
+class IIdentityService(IPersistentService):
+ """Registry of "identified" objects known to pypes.
+
+ - Creates unique identifiers for persistent objects in a database.
+
+ - Guarantees access to an object by its identifier as long as it
+ is registered.
+
+ - Provides a count of registered objects.
+
+ - Provides a set of registered objects
+
+ - Allows iteration of registered objects.
+
+ Identifiers must be:
+
+ - True values.
+
+ - Independent of the objects they identify.
+
+ - Arbitrarily selected for any persistent object.
+
+ - The same type for all objects.
+
+ - Small, immutable, hashable and pickleable.
+
+ - Comparible/consistently orderable across application runs.
+ """
+
+ def idType():
+ """Return the type object for the identifiers generated by this
+ service.
+ """
+
+ def register(obj):
+ """Register obj with the identity service. Identity registered objects
+ are considered "identified". Return the persistent unique identifier
+ for obj. The service must guarantee that so long as the object remains
+ registered, it can be retrieved using the identifier returned upon
+ registration.
+
+ If obj is already registered or cannot
+ be registered for any reason, raise an IdentityError.
+ """
+
+ def hasId(identifier):
+ """Return true if identifier refers to an object currently registered.
+ If identifier is not the proper type raise TypeError.
+ """
+
+ def __contains__(obj):
+ """Return true if obj is registered with the service."""
+
+ def removeId(identifier):
+ """Remove (unregister) an object by identifier. Raise IdentityKeyError
+ if the identifier does not coorespond to any registered object. If
+ identifier is not the proper type raise TypeError. Once an object is
+ removed it can be registered again, but its identifier may not be the
+ same as the first registration. It is acceptable for identifiers to be
+ reused once its object is removed.
+ """
+
+ def remove(obj):
+ """Remove (unregister) an object. Raise IdentityError if the object
+ is not registered.
+ """
+
+ def getObject(identifier):
+ """Return the registered object for identifier. Raise IdentityKeyError
+ if the identifier does not coorespond to any registered object. Raise
+ TypeError if identifier is not the proper type.
+ """
+
+ def __len__():
+ """Return the number of objects registered."""
+
+ def __iter__():
+ """Return an iterator of registered objects."""
+
+ def iterIds():
+ """Return an iterator of registered object identifiers."""
+
+ def idSet():
+ """Return an identity set of all registered objects."""
+
+class IIdentitySet(Interface):
+ """A set of unique identified objects. Since the set relies
+ on persistent identity, its members may be mutable. Identity sets
+ weakly reference their members, so being a member of a set does not
+ guarantee continued persistence. Implementations may use the event
+ service to keep informed of object registrations"""
+
+ def add(obj):
+ """Add obj to the set. Return true if obj was not a member already,
+ false if so. In the latter case insert does not change the set. Raise
+ IdentityError if obj is not identified
+ """
+
+ def remove(obj):
+ """Remove obj from set. raise SetLookupError if obj is not in the set"""
+
+ def update(objs):
+ """Iterate objs and add its members to the set in place"""
+
+ def __contains__(obj):
+ """Return true if obj is in the set"""
+
+ def __len__():
+ """Return set member count"""
+
+ def __iter__():
+ """Return an iterator of the members of the set"""
+
+ def union(other):
+ """Return a set whos members are the union of self and other"""
+
+ def __or__(other):
+ """Alias for union in an expression"""
+
+ def difference(other):
+ """Return a set whos members are in self but not in other"""
+
+ def __sub__(other):
+ """Alias for difference"""
+
+ def intersection(other):
+ """Return a set whos members are in both self and other"""
+
+ def __and__(other):
+ """Compute the intersection between self and other and return the
+ resulting set
+ """
+
+ def issubset(other):
+ """Return true if all members of self are also in other"""
+
+ def issuperset(other):
+ """Return true if all members of other are also in self"""
+
+ def __eq__(other):
+ """Return true if this set and other contain the same members"""
+
+
+class IEventService(IPersistentService):
+ """An event service dispatches messages to listeners. It allows loosely
+ bound objects and services to communicate and notify one another without
+ dependancies or direct knowledge of each other. Events can also be vetoed
+ by listeners to enforce data integrity rules or indirectly alter behavior.
+
+ Some guidelines for implementations:
+
+ - The event sending overhead should be as cheap as possible.
+
+ - Registering/unregistering listeners should also be as inexpensive as
+ possible, but not at the expense of event sending performance.
+ """
+
+ def registerListener(obj, method_name, message_type):
+ """Register obj as a listener via the specified method name.
+ method_name must specify the name of a callable attribute of obj which
+ accepts a single message argument. message_type must be a type or
+ class object. May be called multiple times for the same listener."""
+
+ def unregisterListener(obj, method_name, message_type):
+ """Unregister a listener for the message_types specified via
+ the registered method name. If obj was never registered via
+ the method specified raise EventRegistrationError.
+ """
+
+ def unregisterAllListeners(message_type):
+ """Unregister all listeners for the given message type. Only affects
+ objects directly registered for a given message_type, no
+ listeners for subtypes are affected. If none are registered, do nothing.
+ """
+
+ def send(message):
+ """Send message to all registered listeners for this message type or
+ its supertypes. Return true if the message was received by any
+ listeners, false if not. Listeners may raise exceptions, which will be
+ propagated to the sender. If the sender wishes to catch exceptions, it
+ should be careful to handle ConflictErrors properly (i.e. let them
+ propagate). A special exception class VetoEvent should, at the option
+ of the sender, be processed as a request to cancel the operation which
+ generated the event (i.e. by aborting the current transaction)
+ """
+
+ def wouldReceive(obj, message_type):
+ """Return true if obj would receive a message of the type specified.
+ This will be true if obj is a registered listener for message_type
+ or any of its supertypes
+ """
+
+ def isListener(obj, message_type):
+ """Return true if obj is registered as a listener for the specified
+ message_type.
+ """
+
+ def iterListeners(message_type):
+ """Return an iterator of (listener, methodname) pairs for all
+ listeners of the message type specified.
+ """
+
+ def iterReceivers(message_type):
+ """Return an iterator of (listener, methodname) pairs for all
+ listeners that would receive a message of message_type, including
+ listeners for supertypes.
+ """
+
+ def iterMessageTypes():
+ """Return an iterator of all message types that have listeners
+ registered
+ """
+
+class IObjectMessage(Interface):
+ """A message concerning a single object"""
+
+ object = Attribute('object', 'Object that is the subject of the message')
+
+
+class IIdentityMessage(IObjectMessage):
+ """A message concerning the identity of an object"""
+
+ id = Attribute('id', 'The identity of the object in question')
+
+
+class IExtentService(Interface):
+ """Service providing global extent sets of identified objects by class and
+ interface.
+
+ Extents are typically used as top-level collections by applications. They
+ are generally analogous to tables in a traditional relational database. A
+ strong difference however, is that extents are not directly modified.
+ Objects are added and removed from extents automatically as they are
+ registered and unregistered from the identity service or modified (in terms
+ of interfaces provided) and signaled through the event service.
+
+ XXX Once the query service is documented, explain how they work together
+ """
+
+ def __getitem__(key):
+ """Return the canonical extent for key. For class extents the key is a
+ class. For interface extents it is an interface object. Raise KeyError
+ if key is not contained in the service. Raise TypeError if key type
+ is not supported.
+ """
+
+ def __contains__(key):
+ """Return true if key is an identifier of an extent, false otherwise.
+ Raise TypeError if key type is not supported.
+ """
+
+ def __iter__():
+ """Return an iterator of all extents in the service"""
+
+
+class IExtentMap(Interface):
+ """Simple mapping-like container for canonical extents of a single type"""
+
+ def __getitem__(key):
+ """Return extent for key. Raise KeyError if key is the correct type
+ but is not in the map. Raise TypeError if key is not the correct type
+ for the extent map"""
+
+ def __iter__():
+ """Return an iterator of all extents in the mapping"""
+
+ def update():
+ """Update the extent map from all identified objects"""
+
+
+class IExtent(Interface):
+ """Automated set of identified objects.
+
+ Extents are either provided by the extent service or derived from other
+ extents. Extents behave like read-only sets in most respects. They are
+ updated automatically as objects are manipulated and registered with pypes.
+
+ Although extents may be arbitrarily large, operations between them (such
+ as union and intersection) are designed to be efficient, especially between
+ extents of the same type (class or interface). Operations between extents
+ and identity sets are also supported; resulting in a new identity set.
+ """
+
+ def __contains__(obj):
+ """Return true if obj is in the extent"""
+
+ def __len__():
+ """Return extent member count"""
+
+ def __iter__():
+ """Return an iterator of the members of the extent"""
+
+ def union(other):
+ """Return a derived extent or identity set whos members are the union
+ of self and other"""
+
+ def __or__(other):
+ """Alias for union in an expression"""
+
+ def difference(other):
+ """return a derived extent or identity set whos members are in self
+ but not in other"""
+
+ def __sub__(other):
+ """Alias for difference"""
+
+ def intersection(other):
+ """Return a derived extent or identity set whos members are in both
+ self and other"""
+
+ def __and__(other):
+ """Compute the intersection between self and other and return the
+ resulting derived extent or identity set
+ """
+
+ def issubset(other):
+ """Return true if all members of self are also in other"""
+
+ def issuperset(other):
+ """Return true if all members of other are also in self"""
+
+ def __eq__(other):
+ """Return true if this extent and other contain the same members"""
+
+
+class ICanonicalExtent(IExtent):
+ """An extent of a single interface or class provided directly by the
+ extent service
+ """
+
+ key = Attribute('key',
+ """Key for this extent in the extent service""")
+
+ def subExtents():
+ """Return the direct sub-extents of the extent, if any, which are
+ disjoint canonical sets which are subsets of the extent.
+ """
+
+class IDerivedExtent(IExtent):
+ """An extent derived by combining extents"""
+
+
+class IGraphNodes(Interface):
+ """Collection of nodes in a graph"""
+
+ def add(obj):
+ """Add obj as a node of the graph. Return true if obj is not already
+ a node. If obj is in the graph, return false and do nothing
+ """
+
+ def remove(obj):
+ """Remove obj from the graph and any edges connecting to and from the
+ obj. If obj is not a node, then raise GraphLookupError
+ """
+
+ def __contains__(obj):
+ """Return true if obj is a node of the graph, false if not"""
+
+ def __len__():
+ """Return the graph node count"""
+
+ def __iter__():
+ """Return an iterator of the graph node objects"""
+
+ def iterTopological():
+ """Return an iterator of the nodes in topologically sorted order.
+ The graph must be directed and acyclic. If a cycle is encountered
+ during iteration, raise GraphCycleError.
+ """
+
+ def degree(node):
+ """Return the degree of the node, which is the integer count
+ of adjacent target nodes
+ """
+
+ def sources(node, transitive=False):
+ """Return the set of nodes which are the source of an edge where the
+ specified node is a target. If transitive is true, then the set returns
+ all nodes which can reach the specified node by traversing all graph
+ edges to node. If node is not in the graph, raise GraphLookupError.
+ """
+
+ def targets(node, transitive=False):
+ """Return the set of nodes which are the targets of an edge where
+ the specified node is the source. If transitive is true, then the set
+ returns all nodes reachable from the specified node by traversing
+ all graph edges from node. If node is not in the graph, raise
+ GraphLookupError.
+ """
+
+class IGraphEdges(Interface):
+ """Collection of edges in a graph"""
+
+ def add(source, target, value=None):
+ """Add an edge to the graph from object source to target. If these
+ objects are not already nodes of the graph, they are added. The order
+ of source and target are significant only for directed graphs. If the
+ edge did not already exist, return true. Otherwise return false.
+
+ value -- Optional object used as the value for the edge between source
+ and target. May be used to store the distance or magnitude of the edge
+ or any desired application data. If the edge already exists value
+ replaces any existing edge value; if value is omitted, the existing
+ value is unchanged.
+ """
+
+ def remove(source, target):
+ """Remove the edge between source and target from the graph. If no
+ edge exists between source and target, raise GraphLookupError. The
+ source and target nodes are not removed from the graph.
+ """
+
+ def get(source, target, default=None):
+ """Return the value for the edge from node source to node target. If
+ no value was assigned, raise GraphValueError or return default if
+ supplied. If no edge exists, raise GraphLookupError.
+ """
+
+ def set(source, target, value):
+ """Set the data for the edge from source to target. If no edge exists
+ between source and target, raise GraphLookupError
+ """
+
+ def __contains__(pair):
+ """Return true if the graph contains an edge cooresponding to pair, a
+ sequence of two node objects. The order of these objects is significant
+ only for directed graphs. If either object in the pair are not nodes
+ of the graph, raise GraphLookupError
+ """
+
+ def __len__():
+ """Return the graph edge count"""
+
+ def __iter__():
+ """Return an iterator of (source, target) pairs representing each
+ edge in the graph
+ """
+
+ def iterValues():
+ """Return an iterator of the values assigned to the edges in the graph
+ """
+
+ def iterItems():
+ """Return an iterator of ((source, target), value) pairs for each
+ edge with a value in the graph.
+ """
+
+class IGraph(Interface):
+ """Persistent graph of object nodes"""
+
+ nodes = Attribute('nodes',
+ """IGraphNodes object for manipulating the nodes of the graph""")
+
+ edges = Attribute('edges',
+ """IGraphEdges object for manipulating the edges of the graph""")
+
+ def transitiveClosure(with_values=False):
+ """Return the transitive closure graph for the current graph. If
+ with_values is true, then the values for each edge in the resulting
+ graph are computed from the exisiting values. This means that all
+ edge values in the graph must be addable
+ """
+
+ def shortestPath(source, target, use_values=False):
+ """Return the sequence of node which is the shortest path from source
+ to target. For instance, If source and target are
+ adjacent, return [source, target]; if they connect through a single
+ intermediary return [source, intermediate, target], etc. If no
+ path connects source and target, return None.
+
+ If use_values is true, then the edge data is used to calculate the
+ distance between nodes. This implies that all data objects in the graph
+ can be added and compared to one another as distances. By default, the
+ values are not used and the distance between adjacent nodes is assumed
+ to be 1.
+ """
+
+ def allPaths(source=None, target=None):
+ """Return an iterator of sequences of nodes representing all possible
+ paths between nodes of the graph. If source and target are omitted,
+ all possible paths between all graph nodes are returned. If source
+ is specified, only paths starting from source are returned. If
+ target is specified, only paths to target are returned. If both are
+ specifed to compute all paths connecting source to target
+ """
+
=== Packages/pypes/pypes/serviceconfig.py 1.2 => 1.3 ===
--- Packages/pypes/pypes/serviceconfig.py:1.2 Fri Jan 30 00:35:38 2004
+++ Packages/pypes/pypes/serviceconfig.py Mon Feb 9 16:14:57 2004
@@ -1,78 +1,78 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""pypes service configuration module
-
-Persistent service registration and configuration routines.
-
-$Id$"""
-
-import pypes
-from persistent.mapping import PersistentMapping
-from pypes.exceptions import PypesError, PypesLookupError
-
-registry_name = 'pypes_services' # Key to service registry in db root
-
-def initServices(connection, force=False):
- """Initialize the service registry in the database referred from connection
- then return it.
-
- connection -- an open zodb connection
-
- force -- If False (the default), the function does not replace an existing
- registry. If True then the registry is replaced if existing. This can
- lead to data loss, so be sure you really want this!
- """
- root = connection.root()
- if not root.has_key(registry_name) or force:
- root[registry_name] = PersistentMapping()
- return root[registry_name]
-
-
-def addService(connection, name, service):
- """Adds a service to the registry if it does not already exist. This
- is the safe way to add a service because it never affects existing
- services. If the service already exists, then a PypesError is raised.
-
- connection -- an open zodb connection
-
- name -- Name of the service
-
- service -- IPersistentService object
- """
- registry = connection.root()[registry_name]
- if registry.has_key(name):
- raise PypesError, 'Service %s already exists' % name
- registry[name] = service
-
-
-def setService(connection, name, service):
- """Like add service, but will also replace existing services. Use with
- care, since services can contain user data."""
- registry = connection.root()[registry_name]
- registry[name] = service
-
-
-def delService(connection, name):
- """Remove service from registry and any data contained in it"""
- registry = connection.root()[registry_name]
- try:
- del registry[name]
- except KeyError:
- raise PypesLookupError, 'No service named %s' % name
-
-
-def hasService(connection, name):
- """Return true if service name is available from connection"""
- registry = connection.root()[registry_name]
- return registry.has_key(name)
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""pypes service configuration module
+
+Persistent service registration and configuration routines.
+
+$Id$"""
+
+import pypes
+from persistent.mapping import PersistentMapping
+from pypes.exceptions import PypesError, PypesLookupError
+
+registry_name = 'pypes_services' # Key to service registry in db root
+
+def initServices(connection, force=False):
+ """Initialize the service registry in the database referred from connection
+ then return it.
+
+ connection -- an open zodb connection
+
+ force -- If False (the default), the function does not replace an existing
+ registry. If True then the registry is replaced if existing. This can
+ lead to data loss, so be sure you really want this!
+ """
+ root = connection.root()
+ if not root.has_key(registry_name) or force:
+ root[registry_name] = PersistentMapping()
+ return root[registry_name]
+
+
+def addService(connection, name, service):
+ """Adds a service to the registry if it does not already exist. This
+ is the safe way to add a service because it never affects existing
+ services. If the service already exists, then a PypesError is raised.
+
+ connection -- an open zodb connection
+
+ name -- Name of the service
+
+ service -- IPersistentService object
+ """
+ registry = connection.root()[registry_name]
+ if registry.has_key(name):
+ raise PypesError, 'Service %s already exists' % name
+ registry[name] = service
+
+
+def setService(connection, name, service):
+ """Like add service, but will also replace existing services. Use with
+ care, since services can contain user data."""
+ registry = connection.root()[registry_name]
+ registry[name] = service
+
+
+def delService(connection, name):
+ """Remove service from registry and any data contained in it"""
+ registry = connection.root()[registry_name]
+ try:
+ del registry[name]
+ except KeyError:
+ raise PypesLookupError, 'No service named %s' % name
+
+
+def hasService(connection, name):
+ """Return true if service name is available from connection"""
+ registry = connection.root()[registry_name]
+ return registry.has_key(name)
=== Packages/pypes/pypes/services.py 1.3 => 1.4 ===
--- Packages/pypes/pypes/services.py:1.3 Fri Jan 30 00:35:38 2004
+++ Packages/pypes/pypes/services.py Mon Feb 9 16:14:57 2004
@@ -1,82 +1,82 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""pypes services module
-
-Access to pypes persistent services
-
-$Id$"""
-
-from exceptions import PypesError, PypesLookupError
-from persistent import Persistent
-from ZODB.Connection import Connection
-from serviceconfig import registry_name
-
-
-def get(accesspoint, name):
- """Generic service accessor. Loads a service by name from the accesspoint
- and returns it. Services are global to a database, the same service will
- be returned for a given name for all objects in the database when used
- as accesspoints.
- If the service is not available in the datamanager, PypesLookupError is
- raised.
-
- Usage: services.get(someobj, 'identity')::
-
- accesspoint -- An IAppConnection or an IPersistent object. The database
- connection for the object must be open for the call to succeed.
-
- name -- String name of the service.
- """
- if isinstance(accesspoint, Persistent):
- accesspoint = accesspoint._p_jar
- root = accesspoint.root()
- try:
- return root[registry_name][name]
- except KeyError:
- raise PypesLookupError, 'Service %s could not be accessed.' % name
-
-
-def identity(accesspoint):
- """Convenience function to access the identity service from accesspoint
-
- Usage: services.identity(someobj)
- """
- return get(accesspoint, 'identity')
-
-def event(accesspoint):
- """Convenience function to access the event service from accesspoint
-
- Usage: services.event(someobj)
- """
- return get(accesspoint, 'event')
-
-
-def all(accesspoint):
- """Return a dictionary containing all services available from accesspoint
- This dictionary is copied from the persistent registry, therefore
- it cannot be used to add or remove services from the database.
-
- Usage: svcs = services.all(someobj)
- """
- if isinstance(accesspoint, Persistent):
- accesspoint = accesspoint._p_jar
- try:
- return dict(accesspoint.root()[registry_name])
- except KeyError:
- raise PypesLookupError, 'Service registry could not be accessed.'
- except (AttributeError, TypeError):
- raise PypesLookupError, 'Invalid connection object.'
-
-
-
+##############################################################################
+#
+# Copyright (c) 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""pypes services module
+
+Access to pypes persistent services
+
+$Id$"""
+
+from exceptions import PypesError, PypesLookupError
+from persistent import Persistent
+from ZODB.Connection import Connection
+from serviceconfig import registry_name
+
+
+def get(accesspoint, name):
+ """Generic service accessor. Loads a service by name from the accesspoint
+ and returns it. Services are global to a database, the same service will
+ be returned for a given name for all objects in the database when used
+ as accesspoints.
+ If the service is not available in the datamanager, PypesLookupError is
+ raised.
+
+ Usage: services.get(someobj, 'identity')::
+
+ accesspoint -- An IAppConnection or an IPersistent object. The database
+ connection for the object must be open for the call to succeed.
+
+ name -- String name of the service.
+ """
+ if isinstance(accesspoint, Persistent):
+ accesspoint = accesspoint._p_jar
+ root = accesspoint.root()
+ try:
+ return root[registry_name][name]
+ except KeyError:
+ raise PypesLookupError, 'Service %s could not be accessed.' % name
+
+
+def identity(accesspoint):
+ """Convenience function to access the identity service from accesspoint
+
+ Usage: services.identity(someobj)
+ """
+ return get(accesspoint, 'identity')
+
+def event(accesspoint):
+ """Convenience function to access the event service from accesspoint
+
+ Usage: services.event(someobj)
+ """
+ return get(accesspoint, 'event')
+
+
+def all(accesspoint):
+ """Return a dictionary containing all services available from accesspoint
+ This dictionary is copied from the persistent registry, therefore
+ it cannot be used to add or remove services from the database.
+
+ Usage: svcs = services.all(someobj)
+ """
+ if isinstance(accesspoint, Persistent):
+ accesspoint = accesspoint._p_jar
+ try:
+ return dict(accesspoint.root()[registry_name])
+ except KeyError:
+ raise PypesLookupError, 'Service registry could not be accessed.'
+ except (AttributeError, TypeError):
+ raise PypesLookupError, 'Invalid connection object.'
+
+
+
More information about the Zope-CVS
mailing list