Metadata-Version: 2.1
Name: grokcore.annotation
Version: 4.0
Summary: Grok-like configuration for Zope annotations
Home-page: https://github.com/zopefoundation/grokcore.annotation
Author: Grok Team
Author-email: zope-dev@zope.dev
License: ZPL 2.1
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Framework :: Zope :: 3
Requires-Python: >=3.7
Provides-Extra: test
License-File: LICENSE.txt

This package provides a support to simplify the use of annotations in
Zope.

.. contents::

Setting up ``grokcore.annotation``
==================================

This package is essentially set up like the `grokcore.component`_
package, please refer to its documentation for details.  The only
additional ZCML line you will need is::

  <include package="grokcore.annotation" />

Put this somewhere near the top of your root ZCML file but below the
line where you include ``grokcore.component``'s configuration.

Example
=======

Here a simple example of use of an annotation::

    import grokcore.annotation
    from zope import interface

    # Create a model and an interface you want to adapt it to
    # and an annotation class to implement the persistent adapter.
    class Mammoth(grokcore.annotation.Model):
        pass

    class ISerialBrand(interface.Interface):
        unique = interface.Attribute("Brands")

    class Branding(grokcore.annotation.Annotation):
        grokcore.annotation.implements(ISerialBrand)
        unique = 0

    # Grok the above code, then create some mammoths
    manfred = Mammoth()
    mumbles = Mammoth()

    # creating Annotations work just like Adapters
    livestock1 = ISerialBrand(manfred)
    livestock2 = ISerialBrand(mumbles)

    # except you can store data in them, this data will transparently persist
    # in the database for as long as the object exists
    livestock1.unique = 101
    livestock2.unique = 102

    # attributes not listed in the interface will also be persisted
    # on the annotation
    livestock2.foo = "something"

API Overview
============

Base classes
------------

``Annotation``
   Base class for an Annotation. Inherits from the
   persistent.Persistent class.

``Model``
   Base class for a Model on which you want to use an annotation.

``queryAnnotation(model, interface)``
   Query the annotation on the given model for the given
   interface. Return the annotation if found, None otherwise. This
   will not *make* any write operation.

``deleteAnnotation(model, interface)``
   Look for the given annotation and delete it from the model.

``LazyAnnotation``
   Base class for an annotation. It only writes a database object when
   explicitly setting values on the lazy properties.

``LazyAnnotationProperty``
   Property implementation that works with ``LazyAnnotation``.

In addition, the ``grokcore.annotation`` package exposes the
`grokcore.component`_ API.

.. _grokcore.component: http://pypi.python.org/pypi/grokcore.component

Changes
=======

4.0 (2023-07-12)
----------------

- Add support for Python 3.10, 3.11.

- Drop support for Python 2.7, 3.5, 3.6.

- Drop support for deprecated ``python setup.py test``.


3.2 (2021-08-31)
----------------

- ``grokcore.annotation.testing.warn`` was removed as it was not used
  internally. If you still need it, a copy is in ``grokcore.view.testing``.

- Add ``_p_changed`` property to the LazyAnnotation object, proxying it to
  the actual Storage object. That way the "API" for explicitely marking
  objects as changed is the same regaredless of a "normal" annotation object
  or an lazy annotation object.

- Add support for Python 3.7, 3.8 and 3.9.

- Drop support for Python 3.4.


3.1 (2020-10-27)
----------------

- Add support for `FieldUpdatedEvent` in `LazyPropertyAnnotation` to
  mirror the behavior of zope.schema.


3.0.1 (2018-01-17)
------------------

- Replace the use of `grok.implements()` with the `@grok.implementer()`
  directive throughout.

3.0.0 (2018-01-12)
------------------

- Rearrange tests such that Travis CI can pick up all functional tests too.

1.6 (2017-05-30)
----------------

- Add LazyAnnotation and LazyAnnotationProperty.

- Drop support of Python 2.6 and claim support for Python 3.4, 3.5, 3.6 and PyPy.

1.5.1 (2016-01-29)
------------------

- Update tests.

1.5 (2014-10-20)
----------------

- Updating MANIFEST.in, fixing a brown paper bag release.

1.4 (2014-10-17)
----------------

- Add ``queryAnnotation()`` to return an annotation. Return None if it
  doesn't exists. This helper will never do any write operation in the
  database.

- Add ``deleteAnnotation()`` to delete an annotation (if it exists).

1.3 (2012-05-01)
----------------

- Use ``provideAdapter()`` from grokcore.component.util.

- Made package comply to zope.org repository policy.

1.2 (2009-12-13)
----------------

* Use zope.container instead of zope.app.container.

1.1 (2009-09-18)
----------------

* The annotation object become really a contained object to be aware
  of its context, and name.

* Use 1.0b1 versions.cfg in Grok's release info instead of a local
  copy; a local copy for all grokcore packages is just too hard to
  maintain.

1.0.1 (2009-06-30)
------------------

* Reupload to pypi with a correct version of Python which doesn't
  have a distutils bug.

1.0 (2009-06-29)
----------------

* Created ``grokcore.Annotation`` by factoring annotation components,
  grokkers and directives out of Grok.
