summaryrefslogtreecommitdiff
path: root/repoze/bfg/location.py
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2008-07-07 04:44:57 +0000
committerChris McDonough <chrism@agendaless.com>2008-07-07 04:44:57 +0000
commit7de404bb4af2744a64c13e31a780fc0229b8f9e5 (patch)
tree49f0b91b005777071050bf72732300f3bcd8d3ad /repoze/bfg/location.py
parent93a4f5df2f74e4cbefc70733f2c0258859207106 (diff)
downloadpyramid-7de404bb4af2744a64c13e31a780fc0229b8f9e5.tar.gz
pyramid-7de404bb4af2744a64c13e31a780fc0229b8f9e5.tar.bz2
pyramid-7de404bb4af2744a64c13e31a780fc0229b8f9e5.zip
Look up a view after traversal; adapt it to IWSGIApplication.
Diffstat (limited to 'repoze/bfg/location.py')
-rw-r--r--repoze/bfg/location.py118
1 files changed, 118 insertions, 0 deletions
diff --git a/repoze/bfg/location.py b/repoze/bfg/location.py
new file mode 100644
index 000000000..37e5386b3
--- /dev/null
+++ b/repoze/bfg/location.py
@@ -0,0 +1,118 @@
+##############################################################################
+#
+# Copyright (c) 2003 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (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.
+#
+##############################################################################
+
+import zope.interface
+from zope.proxy import ProxyBase
+from zope.proxy import getProxiedObject
+from zope.proxy import non_overridable
+from zope.proxy.decorator import DecoratorSpecificationDescriptor
+from repoze.bfg.interfaces import ILocation
+
+class Location(object):
+ """Stupid mix-in that defines `__parent__` and `__name__` attributes."""
+
+ zope.interface.implements(ILocation)
+
+ __parent__ = __name__ = None
+
+def locate(object, parent, name=None):
+ """Locate an object in another
+
+ This method should only be called from trusted code, because it
+ sets attributes that are normally unsettable.
+ """
+
+ object.__parent__ = parent
+ object.__name__ = name
+
+
+def located(object, parent, name=None):
+ """Locate an object in another and return it.
+
+ If the object does not provide ILocation a LocationProxy is returned.
+
+ """
+ if ILocation.providedBy(object):
+ if parent is not object.__parent__ or name != object.__name__:
+ locate(object, parent, name)
+ return object
+ return LocationProxy(object, parent, name)
+
+
+def LocationIterator(object):
+ while object is not None:
+ yield object
+ object = getattr(object, '__parent__', None)
+
+
+def inside(l1, l2):
+ """Is l1 inside l2
+
+ L1 is inside l2 if l2 is an ancestor of l1.
+
+ """
+ while l1 is not None:
+ if l1 is l2:
+ return True
+ l1 = l1.__parent__
+
+ return False
+
+
+class ClassAndInstanceDescr(object):
+
+ def __init__(self, *args):
+ self.funcs = args
+
+ def __get__(self, inst, cls):
+ if inst is None:
+ return self.funcs[1](cls)
+ return self.funcs[0](inst)
+
+
+class LocationProxy(ProxyBase):
+ """Location-object proxy
+
+ This is a non-picklable proxy that can be put around objects that
+ don't implement `ILocation`.
+
+ """
+
+ zope.interface.implements(ILocation)
+
+ __slots__ = '__parent__', '__name__'
+ __safe_for_unpickling__ = True
+
+ def __new__(self, ob, container=None, name=None):
+ return ProxyBase.__new__(self, ob)
+
+ def __init__(self, ob, container=None, name=None):
+ ProxyBase.__init__(self, ob)
+ self.__parent__ = container
+ self.__name__ = name
+
+ @non_overridable
+ def __reduce__(self, proto=None):
+ raise TypeError("Not picklable")
+
+
+ __doc__ = ClassAndInstanceDescr(
+ lambda inst: getProxiedObject(inst).__doc__,
+ lambda cls, __doc__ = __doc__: __doc__,
+ )
+
+ __reduce_ex__ = __reduce__
+
+ __providedBy__ = DecoratorSpecificationDescriptor()
+