Metadata-Version: 1.0
Name: Acquisition
Version: 2.13.8
Summary: Acquisition is a mechanism that allows objects to obtain attributes from the containment hierarchy they're in.
Home-page: http://pypi.python.org/pypi/Acquisition
Author: Zope Foundation and Contributors
Author-email: zope-dev@zope.org
License: ZPL 2.1
Description: .. contents::
        
        Introductory Example
        ====================
        
        Zope implements acquisition with "Extension Class" mix-in classes. To
        use acquisition your classes must inherit from an acquisition base
        class. For example::
        
          >>> import ExtensionClass, Acquisition
        
          >>> class C(ExtensionClass.Base):
          ...     color='red'
        
          >>> class A(Acquisition.Implicit):
          ...     def report(self):
          ...         print self.color
          ...
          >>> a = A()
          >>> c = C()
          >>> c.a = a
        
          >>> c.a.report()
          red
        
          >>> d = C()
          >>> d.color = 'green'
          >>> d.a = a
        
          >>> d.a.report()
          green
        
          >>> a.report() # raises an attribute error
          Traceback (most recent call last):
            ...
          AttributeError: color
        
        The class ``A`` inherits acquisition behavior from
        ``Acquisition.Implicit``. The object, ``a``, "has" the color of
        objects ``c`` and d when it is accessed through them, but it has no
        color by itself. The object ``a`` obtains attributes from its
        environment, where its environment is defined by the access path used
        to reach ``a``.
        
        Acquisition Wrappers
        ====================
        
        When an object that supports acquisition is accessed through an
        extension class instance, a special object, called an acquisition
        wrapper, is returned. In the example above, the expression ``c.a``
        returns an acquisition wrapper that contains references to both ``c``
        and ``a``. It is this wrapper that performs attribute lookup in ``c``
        when an attribute cannot be found in ``a``.
        
        Acquisition wrappers provide access to the wrapped objects through the
        attributes ``aq_parent``, ``aq_self``, ``aq_base``.  Continue the
        example from above::
        
          >>> c.a.aq_parent is c
          True
          >>> c.a.aq_self is a
          True
        
        Explicit and Implicit Acquisition
        =================================
        
        Two styles of acquisition are supported: implicit and explicit
        acquisition.
        
        Implicit acquisition
        --------------------
        
        Implicit acquisition is so named because it searches for attributes
        from the environment automatically whenever an attribute cannot be
        obtained directly from an object or through inheritance.
        
        An attribute can be implicitly acquired if its name does not begin
        with an underscore.
        
        To support implicit acquisition, your class should inherit from the
        mix-in class ``Acquisition.Implicit``.
        
        Explicit Acquisition
        --------------------
        
        When explicit acquisition is used, attributes are not automatically
        obtained from the environment. Instead, the method aq_acquire must be
        used. For example::
        
          >>> print c.a.aq_acquire('color')
          red
        
        To support explicit acquisition, your class should inherit from the
        mix-in class ``Acquisition.Explicit``.
        
        Controlling Acquisition
        -----------------------
        
        A class (or instance) can provide attribute by attribute control over
        acquisition. Your should subclass from ``Acquisition.Explicit``, and set
        all attributes that should be acquired to the special value
        ``Acquisition.Acquired``. Setting an attribute to this value also allows
        inherited attributes to be overridden with acquired ones. For example::
        
          >>> class C(Acquisition.Explicit):
          ...     id=1
          ...     secret=2
          ...     color=Acquisition.Acquired
          ...     __roles__=Acquisition.Acquired
        
        The only attributes that are automatically acquired from containing
        objects are color, and ``__roles__``. Note that the ``__roles__``
        attribute is acquired even though its name begins with an
        underscore. In fact, the special ``Acquisition.Acquired`` value can be
        used in ``Acquisition.Implicit`` objects to implicitly acquire
        selected objects that smell like private objects.
        
        Sometimes, you want to dynamically make an implicitly acquiring object
        acquire explicitly. You can do this by getting the object's
        aq_explicit attribute. This attribute provides the object with an
        explicit wrapper that replaces the original implicit wrapper.
        
        Filtered Acquisition
        ====================
        
        The acquisition method, ``aq_acquire``, accepts two optional
        arguments. The first of the additional arguments is a "filtering"
        function that is used when considering whether to acquire an
        object. The second of the additional arguments is an object that is
        passed as extra data when calling the filtering function and which
        defaults to ``None``. The filter function is called with five
        arguments:
        
        * The object that the aq_acquire method was called on,
        
        * The object where an object was found,
        
        * The name of the object, as passed to aq_acquire,
        
        * The object found, and
        
        * The extra data passed to aq_acquire.
        
        If the filter returns a true object that the object found is returned,
        otherwise, the acquisition search continues.
        
        Here's an example::
        
          >>> from Acquisition import Explicit
        
          >>> class HandyForTesting:
          ...     def __init__(self, name):
          ...         self.name = name
          ...     def __str__(self):
          ...         return "%s(%s)" % (self.name, self.__class__.__name__)
          ...     __repr__=__str__
          ...
          >>> class E(Explicit, HandyForTesting): pass
          ...
          >>> class Nice(HandyForTesting):
          ...     isNice= 1 
          ...     def __str__(self):
          ...         return HandyForTesting.__str__(self)+' and I am nice!'
          ...     __repr__=__str__
          ...
          >>> a = E('a')
          >>> a.b = E('b')
          >>> a.b.c = E('c')
          >>> a.p = Nice('spam')
          >>> a.b.p = E('p')
        
          >>> def find_nice(self, ancestor, name, object, extra):
          ...     return hasattr(object,'isNice') and object.isNice
        
          >>> print a.b.c.aq_acquire('p', find_nice)
          spam(Nice) and I am nice!
        
        The filtered acquisition in the last line skips over the first
        attribute it finds with the name ``p``, because the attribute doesn't
        satisfy the condition given in the filter.
        
        Filtered acquisition is rarely used in Zope.
        
        Acquiring from Context
        ======================
        
        Normally acquisition allows objects to acquire data from their
        containers. However an object can acquire from objects that aren't its
        containers.
        
        Most of the examples we've seen so far show establishing of an
        acquisition context using getattr semantics. For example, ``a.b`` is a
        reference to ``b`` in the context of ``a``.
        
        You can also manually set acquisition context using the ``__of__``
        method. For example::
        
          >>> from Acquisition import Implicit
          >>> class C(Implicit): pass
          ...
          >>> a = C()
          >>> b = C()
          >>> a.color = "red"
          >>> print b.__of__(a).color
          red
        
        In this case, ``a`` does not contain ``b``, but it is put in ``b``'s
        context using the ``__of__`` method.
        
        Here's another subtler example that shows how you can construct an
        acquisition context that includes non-container objects::
        
          >>> from Acquisition import Implicit
        
          >>> class C(Implicit):
          ...     def __init__(self, name):
          ...         self.name = name
        
          >>> a = C("a")
          >>> a.b = C("b")
          >>> a.b.color = "red"
          >>> a.x = C("x")
        
          >>> print a.b.x.color
          red
        
        Even though ``b`` does not contain ``x``, ``x`` can acquire the color
        attribute from ``b``. This works because in this case, ``x`` is accessed
        in the context of ``b`` even though it is not contained by ``b``.
        
        Here acquisition context is defined by the objects used to access
        another object.
        
        Containment Before Context
        ==========================
        
        If in the example above suppose both a and b have an color attribute::
        
          >>> a = C("a")
          >>> a.color = "green"
          >>> a.b = C("b")
          >>> a.b.color = "red"
          >>> a.x = C("x")
        
          >>> print a.b.x.color
          green
        
        Why does ``a.b.x.color`` acquire color from ``a`` and not from ``b``?
        The answer is that an object acquires from its containers before
        non-containers in its context.
        
        To see why consider this example in terms of expressions using the
        ``__of__`` method::
        
          a.x -> x.__of__(a)
        
          a.b -> b.__of__(a)
        
          a.b.x -> x.__of__(a).__of__(b.__of__(a))
        
        Keep in mind that attribute lookup in a wrapper is done by trying to
        look up the attribute in the wrapped object first and then in the
        parent object. So in the expressions above proceeds from left to
        right.
        
        The upshot of these rules is that attributes are looked up by
        containment before context.
        
        This rule holds true also for more complex examples. For example,
        ``a.b.c.d.e.f.g.attribute`` would search for attribute in ``g`` and
        all its containers first. (Containers are searched in order from the
        innermost parent to the outermost container.) If the attribute is not
        found in ``g`` or any of its containers, then the search moves to
        ``f`` and all its containers, and so on.
        
        Additional Attributes and Methods
        =================================
        
        You can use the special method ``aq_inner`` to access an object
        wrapped only by containment. So in the example above,
        ``a.b.x.aq_inner`` is equivalent to ``a.x``.
        
        You can find out the acquisition context of an object using the
        aq_chain method like so:
        
          >>> [obj.name for obj in a.b.x.aq_chain]
          ['x', 'b', 'a']
        
        You can find out if an object is in the containment context of another
        object using the ``aq_inContextOf`` method. For example:
        
          >>> a.b.aq_inContextOf(a)
          1
        
        .. Note: as of this writing the aq_inContextOf examples don't work the
           way they should be working. According to Jim, this is because
           aq_inContextOf works by comparing object pointer addresses, which
           (because they are actually different wrapper objects) doesn't give
           you the expected results. He acknowledges that this behavior is
           controversial, and says that there is a collector entry to change
           it so that you would get the answer you expect in the above. (We
           just need to get to it).
        
        Acquisition Module Functions
        ============================
        
        In addition to using acquisition attributes and methods directly on
        objects you can use similar functions defined in the ``Acquisition``
        module. These functions have the advantage that you don't need to
        check to make sure that the object has the method or attribute before
        calling it.
        
        ``aq_acquire(object, name [, filter, extra, explicit, default, containment])``
            Acquires an object with the given name.
        
            This function can be used to explictly acquire when using explicit
            acquisition and to acquire names that wouldn't normally be
            acquired.
        
            The function accepts a number of optional arguments:
        
            ``filter``
                A callable filter object that is used to decide if an object
                should be acquired.
        
                The filter is called with five arguments:
        
                * The object that the aq_acquire method was called on,
        
                * The object where an object was found,
        
                * The name of the object, as passed to aq_acquire,
        
                * The object found, and
        
                * The extra argument passed to aq_acquire.
        
                If the filter returns a true object that the object found is
                returned, otherwise, the acquisition search continues.
        
            ``extra``
                Extra data to be passed as the last argument to the filter.
        
            ``explicit``
                A flag (boolean value) indicating whether explicit acquisition
                should be used. The default value is true. If the flag is
                true, then acquisition will proceed regardless of whether
                wrappers encountered in the search of the acquisition
                hierarchy are explicit or implicit wrappers. If the flag is
                false, then parents of explicit wrappers are not searched.
        
                This argument is useful if you want to apply a filter without
                overriding explicit wrappers.
        
            ``default``
                A default value to return if no value can be acquired.
        
            ``containment``
                A flag indicating whether the search should be limited to the
                containment hierarchy.
        
            In addition, arguments can be provided as keywords.
        
        ``aq_base(object)``
            Return the object with all wrapping removed.
        
        ``aq_chain(object [, containment])``
            Return a list containing the object and it's acquisition
            parents. The optional argument, containment, controls whether the
            containment or access hierarchy is used.
        
        ``aq_get(object, name [, default, containment])``
            Acquire an attribute, name. A default value can be provided, as
            can a flag that limits search to the containment hierarchy.
        
        ``aq_inner(object)``
            Return the object with all but the innermost layer of wrapping
            removed.
        
        ``aq_parent(object)``
            Return the acquisition parent of the object or None if the object
            is unwrapped.
        
        ``aq_self(object)``
            Return the object with one layer of wrapping removed, unless the
            object is unwrapped, in which case the object is returned.
        
        In most cases it is more convenient to use these module functions
        instead of the acquisition attributes and methods directly.
        
        Acquisition and Methods
        =======================
        
        Python methods of objects that support acquisition can use acquired
        attributes. When a Python method is called on an object that is
        wrapped by an acquisition wrapper, the wrapper is passed to the method
        as the first argument. This rule also applies to user-defined method
        types and to C methods defined in pure mix-in classes.
        
        Unfortunately, C methods defined in extension base classes that define
        their own data structures, cannot use aquired attributes at this
        time. This is because wrapper objects do not conform to the data
        structures expected by these methods. In practice, you will seldom
        find this a problem.
        
        Conclusion
        ==========
        
        Acquisition provides a powerful way to dynamically share information
        between objects. Zope 2 uses acquisition for a number of its key
        features including security, object publishing, and DTML variable
        lookup. Acquisition also provides an elegant solution to the problem
        of circular references for many classes of problems. While acquisition
        is powerful, you should take care when using acquisition in your
        applications. The details can get complex, especially with the
        differences between acquiring from context and acquiring from
        containment.
        
        Changelog
        =========
        
        2.13.8 (2011-06-11)
        -------------------
        
        - Fixed a segfault on 64bit platforms when providing the `explicit` argument to
          the aq_acquire method of an Acquisition wrapper. Thx to LP #675064 for the
          hint to the solution. The code passed an int instead of a pointer into a
          function.
        
        2.13.7 (2011-03-02)
        -------------------
        
        - Fixed bug: When an object did not implement ``__unicode__``, calling
          ``unicode(wrapped)`` was calling ``__str__`` with an unwrapped ``self``.
        
        2.13.6 (2011-02-19)
        -------------------
        
        - Add ``aq_explicit`` to ``IAcquisitionWrapper``.
        
        - Fixed bug: ``unicode(wrapped)`` was not calling a ``__unicode__`` 
          method on wrapped objects.
        
        2.13.5 (2010-09-29)
        -------------------
        
        - Fixed unit tests that failed on 64bit Python on Windows machines.
        
        2.13.4 (2010-08-31)
        -------------------
        
        - LP 623665: Fixed typo in Acquisition.h.
        
        2.13.3 (2010-04-19)
        -------------------
        
        - Use the doctest module from the standard library and no longer depend on
          zope.testing.
        
        2.13.2 (2010-04-04)
        -------------------
        
        - Give both wrapper classes a ``__getnewargs__`` method, which causes the ZODB
          optimization to fail and create persistent references using the ``_p_oid``
          alone. This happens to be the persistent oid of the wrapped object. This lets
          these objects to be persisted correctly, even though they are passed to the
          ZODB in a wrapped state.
        
        - Added failing tests for http://dev.plone.org/plone/ticket/10318. This shows
          an edge-case where AQ wrappers can be pickled using the specific combination
          of cPickle, pickle protocol one and a custom Pickler class with an
          ``inst_persistent_id`` hook. Unfortunately this is the exact combination used
          by ZODB3.
        
        2.13.1 (2010-02-23)
        -------------------
        
        - Update to include ExtensionClass 2.13.0.
        
        - Fix the ``tp_name`` of the ImplicitAcquisitionWrapper and
          ExplicitAcquisitionWrapper to match their Python visible names and thus have
          a correct ``__name__``.
        
        - Expand the ``tp_name`` of our extension types to hold the fully qualified
          name. This ensures classes have their ``__module__`` set correctly.
        
        2.13.0 (2010-02-14)
        -------------------
        
        - Added support for method cache in Acquisition. Patch contributed by
          Yoshinori K. Okuji. See https://bugs.launchpad.net/zope2/+bug/486182.
        
        2.12.4 (2009-10-29)
        -------------------
        
        - Fix iteration proxying to pass `self` acquisition-wrapped into both
          `__iter__` as well as `__getitem__` (this fixes
          https://bugs.launchpad.net/zope2/+bug/360761).
        
        - Add tests for the __getslice__ proxying, including open-ended slicing.
        
        2.12.3 (2009-08-08)
        -------------------
        
        - More 64-bit fixes in Py_BuildValue calls.
        
        - More 64-bit issues fixed: Use correct integer size for slice operations.
        
        2.12.2 (2009-08-02)
        -------------------
        
        - Fixed 64-bit compatibility issues for Python 2.5.x / 2.6.x.  See 
          http://www.python.org/dev/peps/pep-0353/ for details.
        
        2.12.1 (2009-04-15)
        -------------------
        
        - Update for iteration proxying: The proxy for `__iter__` must not rely on the
          object to have an `__iter__` itself, but also support fall-back iteration via
          `__getitem__` (this fixes https://bugs.launchpad.net/zope2/+bug/360761).
        
        2.12 (2009-01-25)
        -----------------
        
        - Release as separate package.
        
Platform: UNKNOWN
