[Checkins] SVN: zope.annotation/tags/3.4.1/ Release 3.4.1.

Marius Gedminas marius at pov.lt
Tue Aug 26 18:00:32 EDT 2008


Log message for revision 90367:
  Release 3.4.1.
  
  

Changed:
  A   zope.annotation/tags/3.4.1/
  D   zope.annotation/tags/3.4.1/CHANGES.txt
  A   zope.annotation/tags/3.4.1/CHANGES.txt
  D   zope.annotation/tags/3.4.1/buildout.cfg
  A   zope.annotation/tags/3.4.1/buildout.cfg
  D   zope.annotation/tags/3.4.1/setup.py
  A   zope.annotation/tags/3.4.1/setup.py
  D   zope.annotation/tags/3.4.1/src/zope/annotation/README.txt
  A   zope.annotation/tags/3.4.1/src/zope/annotation/README.txt
  D   zope.annotation/tags/3.4.1/src/zope/annotation/factory.py
  A   zope.annotation/tags/3.4.1/src/zope/annotation/factory.py

-=-
Copied: zope.annotation/tags/3.4.1 (from rev 90362, zope.annotation/branches/3.4)

Deleted: zope.annotation/tags/3.4.1/CHANGES.txt
===================================================================
--- zope.annotation/branches/3.4/CHANGES.txt	2008-08-26 19:44:03 UTC (rev 90362)
+++ zope.annotation/tags/3.4.1/CHANGES.txt	2008-08-26 22:00:31 UTC (rev 90367)
@@ -1,12 +0,0 @@
-===========================
-Changes for zope.annotation
-===========================
-
-
-==================
-3.4.0 (2007-08-29)
-==================
-
-- Annotation factories are no longer containing the factored object.
-  Instead the objects are located using zope.location .  This removes
-  a dependency to zope.app.container .

Copied: zope.annotation/tags/3.4.1/CHANGES.txt (from rev 90366, zope.annotation/branches/3.4/CHANGES.txt)
===================================================================
--- zope.annotation/tags/3.4.1/CHANGES.txt	                        (rev 0)
+++ zope.annotation/tags/3.4.1/CHANGES.txt	2008-08-26 22:00:31 UTC (rev 90367)
@@ -0,0 +1,21 @@
+===========================
+Changes for zope.annotation
+===========================
+
+
+==================
+3.4.1 (2008-08-26)
+==================
+
+- Annotation factories take care not to store proxies in the database, so
+  adapting an object wrapped in a LocationProxy works correctly.
+  Fixes https://bugs.launchpad.net/zope3/+bug/261620
+
+
+==================
+3.4.0 (2007-08-29)
+==================
+
+- Annotation factories are no longer containing the factored object.
+  Instead the objects are located using zope.location .  This removes
+  a dependency to zope.app.container .

Deleted: zope.annotation/tags/3.4.1/buildout.cfg
===================================================================
--- zope.annotation/branches/3.4/buildout.cfg	2008-08-26 19:44:03 UTC (rev 90362)
+++ zope.annotation/tags/3.4.1/buildout.cfg	2008-08-26 22:00:31 UTC (rev 90367)
@@ -1,8 +0,0 @@
-[buildout]
-develop = . 
-parts = test
-find-links = http://download.zope.org/distribution/
-
-[test]
-recipe = zc.recipe.testrunner
-eggs = zope.annotation [test]

Copied: zope.annotation/tags/3.4.1/buildout.cfg (from rev 90364, zope.annotation/branches/3.4/buildout.cfg)
===================================================================
--- zope.annotation/tags/3.4.1/buildout.cfg	                        (rev 0)
+++ zope.annotation/tags/3.4.1/buildout.cfg	2008-08-26 22:00:31 UTC (rev 90367)
@@ -0,0 +1,12 @@
+[buildout]
+develop = . 
+parts = test
+find-links = http://download.zope.org/distribution/
+
+[test]
+recipe = zc.recipe.testrunner
+eggs = zope.annotation [test]
+
+[ctags]
+recipe = z3c.recipe.tag:tags
+eggs = zope.annotation

Deleted: zope.annotation/tags/3.4.1/setup.py
===================================================================
--- zope.annotation/branches/3.4/setup.py	2008-08-26 19:44:03 UTC (rev 90362)
+++ zope.annotation/tags/3.4.1/setup.py	2008-08-26 22:00:31 UTC (rev 90367)
@@ -1,70 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006-2007 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.
-#
-##############################################################################
-"""Setup for zope.annotation package
-
-$Id$
-"""
-
-import os
-
-from setuptools import setup, find_packages
-
-def read(*rnames):
-    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
-
-long_description = (
-    read('README.txt')
-    + '\n' +
-    read('CHANGES.txt')
-    + '\n' +
-    'Detailed Documentation\n'
-    '**********************\n'
-    + '\n' +
-    read('src', 'zope', 'annotation', 'README.txt') 
-    )
-
-setup(
-    name = 'zope.annotation',
-    version = '3.4.1dev',
-    url = 'http://pypi.python.org/pypi/zope.annotation',
-    license = 'ZPL 2.1',
-    description = 'Zope annotation',
-    author = 'Zope Corporation and Contributors',
-    author_email = 'zope3-dev at zope.org',
-    classifiers = [
-        'Development Status :: 5 - Production/Stable',
-        'Intended Audience :: Developers',
-        'License :: OSI Approved :: Zope Public License',
-        'Programming Language :: Python',
-        'Natural Language :: English',
-        'Operating System :: OS Independent',
-        'Topic :: Internet :: WWW/HTTP',
-        'Topic :: Software Development',
-        ],
-    long_description = long_description,
-    packages = find_packages('src'),
-    package_dir = {'': 'src'},
-    namespace_packages = ['zope',],
-    install_requires = ['setuptools',
-                        'zope.interface',
-                        'zope.component',
-                        'zope.location>=3.4.0b1.dev-r78903',
-                        ],
-    extras_require = dict(
-        test = ['zope.testing',
-                'ZODB3'],
-        ),
-    include_package_data = True,
-    zip_safe = False,
-    )

Copied: zope.annotation/tags/3.4.1/setup.py (from rev 90366, zope.annotation/branches/3.4/setup.py)
===================================================================
--- zope.annotation/tags/3.4.1/setup.py	                        (rev 0)
+++ zope.annotation/tags/3.4.1/setup.py	2008-08-26 22:00:31 UTC (rev 90367)
@@ -0,0 +1,71 @@
+##############################################################################
+#
+# Copyright (c) 2006-2007 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.
+#
+##############################################################################
+"""Setup for zope.annotation package
+
+$Id$
+"""
+
+import os
+
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+long_description = (
+    read('README.txt')
+    + '\n' +
+    read('CHANGES.txt')
+    + '\n' +
+    'Detailed Documentation\n'
+    '**********************\n'
+    + '\n' +
+    read('src', 'zope', 'annotation', 'README.txt') 
+    )
+
+setup(
+    name = 'zope.annotation',
+    version = '3.4.1',
+    url = 'http://pypi.python.org/pypi/zope.annotation',
+    license = 'ZPL 2.1',
+    description = 'Zope annotation',
+    author = 'Zope Corporation and Contributors',
+    author_email = 'zope3-dev at zope.org',
+    classifiers = [
+        'Development Status :: 5 - Production/Stable',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: Zope Public License',
+        'Programming Language :: Python',
+        'Natural Language :: English',
+        'Operating System :: OS Independent',
+        'Topic :: Internet :: WWW/HTTP',
+        'Topic :: Software Development',
+        ],
+    long_description = long_description,
+    packages = find_packages('src'),
+    package_dir = {'': 'src'},
+    namespace_packages = ['zope',],
+    install_requires = ['setuptools',
+                        'zope.interface',
+                        'zope.component',
+                        'zope.location>=3.4.0b1.dev-r78903',
+                        'zope.proxy',
+                        ],
+    extras_require = dict(
+        test = ['zope.testing',
+                'ZODB3'],
+        ),
+    include_package_data = True,
+    zip_safe = False,
+    )

Deleted: zope.annotation/tags/3.4.1/src/zope/annotation/README.txt
===================================================================
--- zope.annotation/branches/3.4/src/zope/annotation/README.txt	2008-08-26 19:44:03 UTC (rev 90362)
+++ zope.annotation/tags/3.4.1/src/zope/annotation/README.txt	2008-08-26 22:00:31 UTC (rev 90367)
@@ -1,126 +0,0 @@
-Annotations
-===========
-
-There is more to document about annotations, but we'll just sketch out
-a scenario on how to use the annotation factory for now. This is one
-of the easiest ways to use annotations -- basically you can see them
-as persistent, writable adapters.
-
-First, let's make a persistent object we can create annotations for:
-
-  >>> from zope import interface
-  >>> class IFoo(interface.Interface):
-  ...     pass
-  >>> from zope.annotation.interfaces import IAttributeAnnotatable
-  >>> from persistent import Persistent
-  >>> class Foo(Persistent):
-  ...     interface.implements(IFoo, IAttributeAnnotatable)
-
-We directly say that Foo implements IAttributeAnnotatable here. In
-practice this is often done in ZCML, using the `implements`
-subdirective of the `content` or `class` directive.
-
-Now let's create an annotation for this:
-  
-  >>> class IBar(interface.Interface):
-  ...     a = interface.Attribute('A')
-  ...     b = interface.Attribute('B')
-  >>> from zope import component
-  >>> class Bar(Persistent):
-  ...     interface.implements(IBar)
-  ...     component.adapts(IFoo)
-  ...     def __init__(self):
-  ...         self.a = 1
-  ...         self.b = 2
-
-Note that the annotation implementation does not expect any arguments
-to its `__init__`. Otherwise it's basically an adapter.
-
-Now, we'll register the annotation as an adapter. To do this we use
-the `factory` function provided by `zope.annotation`:
-
-  >>> from zope.annotation import factory
-  >>> component.provideAdapter(factory(Bar))
-
-Note that we do not need to specify what the adapter provides or what
-it adapts - we already do this on the annotation class itself.
-
-Now let's make an instance of `Foo`, and make an annotation for it.
-
-  >>> foo = Foo()
-  >>> bar = IBar(foo)
-  >>> bar.a
-  1
-  >>> bar.b
-  2
-
-We'll change `a` and get the annotation again. Our change is still
-there:
-
-  >>> bar.a = 3
-  >>> IBar(foo).a
-  3
-
-Of course it's still different for another instance of `Foo`:
-
-  >>> foo2 = Foo()
-  >>> IBar(foo2).a
-  1
-
-What if our annotation does not provide what it adapts with
-`component.adapts`? It will complain:
-
-  >>> class IQux(interface.Interface):
-  ...     pass
-  >>> class Qux(Persistent):
-  ...     interface.implements(IQux)
-  >>> component.provideAdapter(factory(Qux)) # doctest: +ELLIPSIS
-  Traceback (most recent call last):
-  ...
-  TypeError: Missing 'zope.component.adapts' on annotation
-
-It's possible to provide an annotation with an explicit key. (If the
-key is not supplied, the key is deduced from the annotation's dotted
-name, provided it is a class.)
-
-  >>> class IHoi(interface.Interface):
-  ...     pass
-  >>> class Hoi(Persistent):
-  ...     interface.implements(IHoi)
-  ...     component.adapts(IFoo)
-  >>> component.provideAdapter(factory(Hoi, 'my.unique.key'))
-  >>> isinstance(IHoi(foo), Hoi)
-  True
-
-
-Location
---------
-
-Annotation factories are put into the location hierarchy with their parent
-pointing to the annotated object and the name to the dotted name of the
-annotation's class (or the name the adapter was registered under):
-
-  >>> foo3 = Foo()
-  >>> new_hoi = IHoi(foo3)
-  >>> new_hoi.__parent__
-  <Foo object at 0x...>
-  >>> new_hoi.__name__
-  'my.unique.key'
-  >>> import zope.location.interfaces
-  >>> zope.location.interfaces.ILocation.providedBy(new_hoi)
-  True
-
-Please notice, that our Hoi object does not implement ILocation, so a
-location proxy will be used. This has to be re-established every time we
-retrieve the object
-
-(Guard against former bug: proxy wasn't established when the annotation
-existed already.)
-
-  >>> old_hoi = IHoi(foo3)
-  >>> old_hoi.__parent__
-  <Foo object at 0x...>
-  >>> old_hoi.__name__
-  'my.unique.key'
-  >>> zope.location.interfaces.ILocation.providedBy(old_hoi)
-  True

Copied: zope.annotation/tags/3.4.1/src/zope/annotation/README.txt (from rev 90365, zope.annotation/branches/3.4/src/zope/annotation/README.txt)
===================================================================
--- zope.annotation/tags/3.4.1/src/zope/annotation/README.txt	                        (rev 0)
+++ zope.annotation/tags/3.4.1/src/zope/annotation/README.txt	2008-08-26 22:00:31 UTC (rev 90367)
@@ -0,0 +1,169 @@
+Annotations
+===========
+
+There is more to document about annotations, but we'll just sketch out
+a scenario on how to use the annotation factory for now. This is one
+of the easiest ways to use annotations -- basically you can see them
+as persistent, writable adapters.
+
+First, let's make a persistent object we can create annotations for:
+
+  >>> from zope import interface
+  >>> class IFoo(interface.Interface):
+  ...     pass
+  >>> from zope.annotation.interfaces import IAttributeAnnotatable
+  >>> from persistent import Persistent
+  >>> class Foo(Persistent):
+  ...     interface.implements(IFoo, IAttributeAnnotatable)
+
+We directly say that Foo implements IAttributeAnnotatable here. In
+practice this is often done in ZCML, using the `implements`
+subdirective of the `content` or `class` directive.
+
+Now let's create an annotation for this:
+  
+  >>> class IBar(interface.Interface):
+  ...     a = interface.Attribute('A')
+  ...     b = interface.Attribute('B')
+  >>> from zope import component
+  >>> class Bar(Persistent):
+  ...     interface.implements(IBar)
+  ...     component.adapts(IFoo)
+  ...     def __init__(self):
+  ...         self.a = 1
+  ...         self.b = 2
+
+Note that the annotation implementation does not expect any arguments
+to its `__init__`. Otherwise it's basically an adapter.
+
+Now, we'll register the annotation as an adapter. To do this we use
+the `factory` function provided by `zope.annotation`:
+
+  >>> from zope.annotation import factory
+  >>> component.provideAdapter(factory(Bar))
+
+Note that we do not need to specify what the adapter provides or what
+it adapts - we already do this on the annotation class itself.
+
+Now let's make an instance of `Foo`, and make an annotation for it.
+
+  >>> foo = Foo()
+  >>> bar = IBar(foo)
+  >>> bar.a
+  1
+  >>> bar.b
+  2
+
+We'll change `a` and get the annotation again. Our change is still
+there:
+
+  >>> bar.a = 3
+  >>> IBar(foo).a
+  3
+
+Of course it's still different for another instance of `Foo`:
+
+  >>> foo2 = Foo()
+  >>> IBar(foo2).a
+  1
+
+What if our annotation does not provide what it adapts with
+`component.adapts`? It will complain:
+
+  >>> class IQux(interface.Interface):
+  ...     pass
+  >>> class Qux(Persistent):
+  ...     interface.implements(IQux)
+  >>> component.provideAdapter(factory(Qux)) # doctest: +ELLIPSIS
+  Traceback (most recent call last):
+  ...
+  TypeError: Missing 'zope.component.adapts' on annotation
+
+It's possible to provide an annotation with an explicit key. (If the
+key is not supplied, the key is deduced from the annotation's dotted
+name, provided it is a class.)
+
+  >>> class IHoi(interface.Interface):
+  ...     pass
+  >>> class Hoi(Persistent):
+  ...     interface.implements(IHoi)
+  ...     component.adapts(IFoo)
+  >>> component.provideAdapter(factory(Hoi, 'my.unique.key'))
+  >>> isinstance(IHoi(foo), Hoi)
+  True
+
+
+Location
+--------
+
+Annotation factories are put into the location hierarchy with their parent
+pointing to the annotated object and the name to the dotted name of the
+annotation's class (or the name the adapter was registered under):
+
+  >>> foo3 = Foo()
+  >>> new_hoi = IHoi(foo3)
+  >>> new_hoi.__parent__
+  <Foo object at 0x...>
+  >>> new_hoi.__name__
+  'my.unique.key'
+  >>> import zope.location.interfaces
+  >>> zope.location.interfaces.ILocation.providedBy(new_hoi)
+  True
+
+Please notice, that our Hoi object does not implement ILocation, so a
+location proxy will be used. This has to be re-established every time we
+retrieve the object
+
+(Guard against former bug: proxy wasn't established when the annotation
+existed already.)
+
+  >>> old_hoi = IHoi(foo3)
+  >>> old_hoi.__parent__
+  <Foo object at 0x...>
+  >>> old_hoi.__name__
+  'my.unique.key'
+  >>> zope.location.interfaces.ILocation.providedBy(old_hoi)
+  True
+
+
+LocationProxies
+---------------
+
+Suppose your annotation proxy provides ILocation.
+
+  >>> class IPolloi(interface.Interface):
+  ...     pass
+  >>> class Polloi(Persistent):
+  ...     interface.implements(IPolloi, zope.location.interfaces.ILocation)
+  ...     component.adapts(IFoo)
+  ...     __name__ = __parent__ = 0
+  >>> component.provideAdapter(factory(Polloi, 'my.other.key'))
+
+Sometimes you're adapting an object wrapped in a LocationProxy.
+
+  >>> foo4 = Foo()
+  >>> import zope.location.location
+  >>> wrapped_foo4 = zope.location.location.LocationProxy(foo4, None, 'foo4')
+  >>> located_polloi = IPolloi(wrapped_foo4)
+
+At first glance it looks as if located_polloi is located under wrapped_foo4.
+
+  >>> located_polloi.__parent__ is wrapped_foo4
+  True
+  >>> located_polloi.__name__
+  'my.other.key'
+
+but that's because we received a LocationProxy
+
+  >>> print type(located_polloi).__name__
+  LocationProxy
+
+If we unwrap located_polloi and look at it directly, we'll see it stores a
+reference to the real Foo object
+
+  >>> from zope.proxy import removeAllProxies
+  >>> removeAllProxies(located_polloi).__parent__ is foo4
+  True
+  >>> removeAllProxies(located_polloi).__name__
+  'my.other.key'
+

Deleted: zope.annotation/tags/3.4.1/src/zope/annotation/factory.py
===================================================================
--- zope.annotation/branches/3.4/src/zope/annotation/factory.py	2008-08-26 19:44:03 UTC (rev 90362)
+++ zope.annotation/tags/3.4.1/src/zope/annotation/factory.py	2008-08-26 22:00:31 UTC (rev 90367)
@@ -1,54 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 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.
-#
-##############################################################################
-"""Annotation factory helper
-
-$Id$
-"""
-import zope.component
-import zope.interface
-import zope.location.location
-
-import zope.annotation.interfaces
-
-
-def factory(factory, key=None):
-    """Adapter factory to help create annotations easily.
-    """
-    # if no key is provided,
-    # we'll determine the unique key based on the factory's dotted name
-    if key is None:
-        key = factory.__module__ + '.' + factory.__name__
-
-    adapts = zope.component.adaptedBy(factory)
-    if adapts is None:
-        raise TypeError("Missing 'zope.component.adapts' on annotation")
-
-    @zope.component.adapter(list(adapts)[0])
-    @zope.interface.implementer(list(zope.component.implementedBy(factory))[0])
-    def getAnnotation(context):
-        annotations = zope.annotation.interfaces.IAnnotations(context)
-        try:
-            result = annotations[key]
-        except KeyError:
-            result = factory()
-            annotations[key] = result
-        # Location has to be set up late to allow location proxies
-        # to be applied, if needed. This does not trigger an event and is idempotent
-        # if location or containment is set up already.
-        located_result = zope.location.location.located(result, context, key)
-        return located_result
-
-    # Convention to make adapter introspectable, used by apidoc
-    getAnnotation.factory = factory
-    return getAnnotation

Copied: zope.annotation/tags/3.4.1/src/zope/annotation/factory.py (from rev 90365, zope.annotation/branches/3.4/src/zope/annotation/factory.py)
===================================================================
--- zope.annotation/tags/3.4.1/src/zope/annotation/factory.py	                        (rev 0)
+++ zope.annotation/tags/3.4.1/src/zope/annotation/factory.py	2008-08-26 22:00:31 UTC (rev 90367)
@@ -0,0 +1,59 @@
+##############################################################################
+#
+# Copyright (c) 2006 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.
+#
+##############################################################################
+"""Annotation factory helper
+
+$Id$
+"""
+import zope.component
+import zope.interface
+import zope.location.location
+import zope.location.interfaces
+import zope.proxy
+
+import zope.annotation.interfaces
+
+
+def factory(factory, key=None):
+    """Adapter factory to help create annotations easily.
+    """
+    # if no key is provided,
+    # we'll determine the unique key based on the factory's dotted name
+    if key is None:
+        key = factory.__module__ + '.' + factory.__name__
+
+    adapts = zope.component.adaptedBy(factory)
+    if adapts is None:
+        raise TypeError("Missing 'zope.component.adapts' on annotation")
+
+    @zope.component.adapter(list(adapts)[0])
+    @zope.interface.implementer(list(zope.component.implementedBy(factory))[0])
+    def getAnnotation(context):
+        annotations = zope.annotation.interfaces.IAnnotations(context)
+        try:
+            result = annotations[key]
+        except KeyError:
+            result = factory()
+            annotations[key] = result
+            if zope.location.interfaces.ILocation.providedBy(result):
+                zope.location.location.locate(result,
+                        zope.proxy.removeAllProxies(context), key)
+        if not (zope.location.interfaces.ILocation.providedBy(result)
+                and result.__parent__ is context
+                and result.__name__ == key):
+            result = zope.location.location.LocationProxy(result, context, key)
+        return result
+
+    # Convention to make adapter introspectable, used by apidoc
+    getAnnotation.factory = factory
+    return getAnnotation



More information about the Checkins mailing list