[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