commit | author | age
|
cbdc36
|
1 |
############################################################################## |
CM |
2 |
# |
|
3 |
# Copyright (c) 2003 Zope Corporation and Contributors. |
|
4 |
# All Rights Reserved. |
|
5 |
# |
|
6 |
# This software is subject to the provisions of the Zope Public License, |
|
7 |
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. |
|
8 |
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED |
|
9 |
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
10 |
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS |
|
11 |
# FOR A PARTICULAR PURPOSE. |
|
12 |
# |
|
13 |
############################################################################## |
|
14 |
|
3e2f12
|
15 |
def inside(resource1, resource2): |
CM |
16 |
"""Is ``resource1`` 'inside' ``resource2``? Return ``True`` if so, else |
cbdc36
|
17 |
``False``. |
CM |
18 |
|
3e2f12
|
19 |
``resource1`` is 'inside' ``resource2`` if ``resource2`` is a |
CM |
20 |
:term:`lineage` ancestor of ``resource1``. It is a lineage ancestor |
8b1f6e
|
21 |
if its parent (or one of its parent's parents, etc.) is an |
CM |
22 |
ancestor. |
cbdc36
|
23 |
""" |
3e2f12
|
24 |
while resource1 is not None: |
CM |
25 |
if resource1 is resource2: |
cbdc36
|
26 |
return True |
3e2f12
|
27 |
resource1 = resource1.__parent__ |
cbdc36
|
28 |
|
CM |
29 |
return False |
|
30 |
|
3e2f12
|
31 |
def lineage(resource): |
cbdc36
|
32 |
""" |
8b1f6e
|
33 |
Return a generator representing the :term:`lineage` of the |
3e2f12
|
34 |
:term:`resource` object implied by the ``resource`` argument. The |
CM |
35 |
generator first returns ``resource`` unconditionally. Then, if |
f4f41f
|
36 |
``resource`` supplies a ``__parent__`` attribute, return the resource |
CM |
37 |
represented by ``resource.__parent__``. If *that* resource has a |
|
38 |
``__parent__`` attribute, return that resource's parent, and so on, |
|
39 |
until the resource being inspected either has no ``__parent__`` |
8b1f6e
|
40 |
attribute or which has a ``__parent__`` attribute of ``None``. |
f4f41f
|
41 |
For example, if the resource tree is:: |
cbdc36
|
42 |
|
CM |
43 |
thing1 = Thing() |
|
44 |
thing2 = Thing() |
|
45 |
thing2.__parent__ = thing1 |
|
46 |
|
|
47 |
Calling ``lineage(thing2)`` will return a generator. When we turn |
|
48 |
it into a list, we will get:: |
|
49 |
|
|
50 |
list(lineage(thing2)) |
|
51 |
[ <Thing object at thing2>, <Thing object at thing1> ] |
|
52 |
""" |
3e2f12
|
53 |
while resource is not None: |
CM |
54 |
yield resource |
02e1fe
|
55 |
# The common case is that the AttributeError exception below |
CM |
56 |
# is exceptional as long as the developer is a "good citizen" |
|
57 |
# who has a root object with a __parent__ of None. Using an |
|
58 |
# exception here instead of a getattr with a default is an |
|
59 |
# important micro-optimization, because this function is |
|
60 |
# called in any non-trivial application over and over again to |
|
61 |
# generate URLs and paths. |
|
62 |
try: |
3e2f12
|
63 |
resource = resource.__parent__ |
02e1fe
|
64 |
except AttributeError: |
3e2f12
|
65 |
resource = None |
cbdc36
|
66 |
|