From 0f5d8befb0f7a77c3b1ac96e43f9924f512d7fb7 Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Tue, 4 Aug 2009 17:02:47 +0000 Subject: - Allow ``repoze.bfg.traversal.find_interface`` API to use a class object as the argument to compare against the ``model`` passed in. This means you can now do ``find_interface(model, SomeClass)`` and the first object which is found in the lineage which has ``SomeClass`` as its class (or the first object found which has ``SomeClass`` as any of its superclasses) will be returned. --- repoze/bfg/traversal.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'repoze/bfg/traversal.py') diff --git a/repoze/bfg/traversal.py b/repoze/bfg/traversal.py index 374804df0..7f6b87ea1 100644 --- a/repoze/bfg/traversal.py +++ b/repoze/bfg/traversal.py @@ -5,6 +5,7 @@ from zope.component import getMultiAdapter from zope.interface import classProvides from zope.interface import implements +from zope.interface.interfaces import IInterface from repoze.lru import lru_cache @@ -77,15 +78,22 @@ def find_model(model, path): raise KeyError('%r has no subelement %s' % (context, view_name)) return context -def find_interface(model, interface): +def find_interface(model, class_or_interface): """ Return the first object found in the parent chain of ``model`` - which provides the interface ``interface``. Return ``None`` if no - object providing ``interface`` can be found in the parent chain. - The ``model`` passed in *must* be :term:`location`-aware. + which, a) if ``interface_or_class`` is a Python class object, is + an instance of the class or any subclass of that class or b) if + ``interface_or_class`` is a Zope interface, provides the specified + interface. Return ``None`` if no object providing + ``interface_or_class`` can be found in the parent chain. The + ``model`` passed in *must* be :term:`location`-aware. """ + if IInterface.providedBy(class_or_interface): + test = class_or_interface.providedBy + else: + test = lambda arg: isinstance(arg, class_or_interface) for location in lineage(model): - if interface.providedBy(location): + if test(location): return location def model_path(model, *elements): -- cgit v1.2.3