[Zope3-checkins] CVS: Zope3/src/zope/app - dependable.py:1.5
Guido van Rossum
guido@python.org
Thu, 12 Jun 2003 15:28:38 -0400
Update of /cvs-repository/Zope3/src/zope/app
In directory cvs.zope.org:/tmp/cvs-serv16761
Modified Files:
dependable.py
Log Message:
Add relative/absolute path equivalence to the Dependable class, a la
UseConfiguration, and add unit tests for this.
Refactoring: share more code between Dependable and UseConfiguration.
The common base is in zope/app/dependable.py, for want of a better place.
=== Zope3/src/zope/app/dependable.py 1.4 => 1.5 ===
--- Zope3/src/zope/app/dependable.py:1.4 Tue Jun 3 11:33:55 2003
+++ Zope3/src/zope/app/dependable.py Thu Jun 12 15:28:08 2003
@@ -19,32 +19,83 @@
from zope.app.interfaces.dependable import IDependable
from zope.app.interfaces.annotation import IAnnotations
+from zope.app.traversing import getParent, canonicalPath, getPath
from zope.component import getAdapter
from zope.interface import implements
-key = 'zope.app.dependable.Dependents'
-class Dependable:
- __doc__ = IDependable.__doc__
+class PathSetAnnotation:
- implements(IDependable)
+ """Abstract base class for annotations that are sets of paths.
+
+ To make this into a concrete class, a subclass must set the class
+ attribute 'key' to a unique annotation key. A subclass may also
+ choose to rename the methods.
+ """
def __init__(self, context):
self.context = context
+ try:
+ pp = getPath(getParent(self.context))
+ if not pp.endswith("/"):
+ pp += "/"
+ self.pp = pp # parentpath
+ except TypeError:
+ self.pp = ""
+ self.pplen = len(self.pp)
- def addDependent(self, location):
- "See IDependable"
+ def addPath(self, path):
+ path = self._make_relative(path)
annotations = getAdapter(self.context, IAnnotations)
- annotations [key] = annotations.get(key, ()) + (location, )
+ old = annotations.get(self.key, ())
+ fixed = map(self._make_relative, old)
+ if path not in fixed:
+ fixed.append(path)
+ new = tuple(fixed)
+ if new != old:
+ annotations[self.key] = new
- def removeDependent(self, location):
- "See IDependable"
+ def removePath(self, path):
+ path = self._make_relative(path)
annotations = getAdapter(self.context, IAnnotations)
- annotations[key] = tuple([loc
- for loc in annotations.get(key, ())
- if loc != location])
+ old = annotations.get(self.key, ())
+ if old:
+ fixed = map(self._make_relative, old)
+ fixed = [loc for loc in fixed if loc != path]
+ new = tuple(fixed)
+ if new != old:
+ if new:
+ annotations[self.key] = new
+ else:
+ del annotations[self.key]
- def dependents(self):
- "See IDependable"
+ def getPaths(self):
annotations = getAdapter(self.context, IAnnotations)
- return annotations.get(key, ())
+ locs = annotations.get(self.key, ())
+ return tuple(map(self._make_absolute, locs))
+
+ def _make_relative(self, path):
+ if path.startswith("/") and self.pp:
+ path = canonicalPath(path)
+ if path.startswith(self.pp):
+ path = path[self.pplen:]
+ while path.startswith("/"):
+ path = path[1:]
+ return path
+
+ def _make_absolute(self, path):
+ if not path.startswith("/") and self.pp:
+ path = self.pp + path
+ return path
+
+
+class Dependable(PathSetAnnotation):
+ """See IDependable."""
+
+ implements(IDependable)
+
+ key = "zope.app.dependable.Dependents"
+
+ addDependent = PathSetAnnotation.addPath
+ removeDependent = PathSetAnnotation.removePath
+ dependents = PathSetAnnotation.getPaths