[Zope3-checkins] SVN: Zope3/branches/3.3/src/zope/app/ Merge
PersistentInterfaceClass fix from trunk r72109 as described in
Christian Theune
ct at gocept.com
Mon Jan 22 02:06:32 EST 2007
Hi,
I didn't spot a comment in the CHANGELOG for this.
Christian
Am Freitag, den 19.01.2007, 16:58 -0500 schrieb Ross Patterson:
> Log message for revision 72110:
> Merge PersistentInterfaceClass fix from trunk r72109 as described in
> http://www.zope.org/Collectors/Zope3-dev/747.
>
>
> Changed:
> U Zope3/branches/3.3/src/zope/app/component/tests/test_registration.py
> U Zope3/branches/3.3/src/zope/app/interface/__init__.py
> U Zope3/branches/3.3/src/zope/app/interface/tests/test_interface.py
>
> -=-
> Modified: Zope3/branches/3.3/src/zope/app/component/tests/test_registration.py
> ===================================================================
> --- Zope3/branches/3.3/src/zope/app/component/tests/test_registration.py 2007-01-19 21:06:58 UTC (rev 72109)
> +++ Zope3/branches/3.3/src/zope/app/component/tests/test_registration.py 2007-01-19 21:58:52 UTC (rev 72110)
> @@ -419,7 +419,81 @@
>
> """
>
> +barcode = """
> +from zope.interface import Interface
> +class IBar(Interface): pass
> +class IBaz(Interface): pass
> +"""
>
> +class Bar(persistent.Persistent): pass
> +class Baz(persistent.Persistent): pass
> +
> +def test_persistent_interfaces():
> + """
> +Registrations for persistent interfaces are accessible from separate
> +connections.
> +
> +Setup the DB and our first connection::
> +
> + >>> import ZODB.tests.util
> + >>> db = ZODB.tests.util.DB()
> + >>> conn1 = db.open()
> + >>> root1 = conn1.root()
> +
> +Setup the persistent module registry and the local component
> +registry::
> +
> + >>> from zodbcode.module import ManagedRegistry
> + >>> registry = root1['registry'] = ManagedRegistry()
> + >>> from zope.component.persistentregistry import PersistentComponents
> + >>> manager = root1['manager'] = PersistentComponents()
> +
> +Create a persistent module::
> +
> + >>> registry.newModule('barmodule', barcode)
> + >>> barmodule = registry.findModule('barmodule')
> +
> +Create a persistent instance::
> +
> + >>> bar = root1['bar'] = Bar()
> + >>> from zope.interface import directlyProvides
> + >>> directlyProvides(bar, barmodule.IBar)
> + >>> from transaction import commit
> + >>> commit()
> +
> +Register an adapter::
> +
> + >>> manager.queryAdapter(bar, barmodule.IBaz)
> + >>> manager.registerAdapter(Baz, [barmodule.IBar], barmodule.IBaz)
> + >>> manager.getAdapter(bar, barmodule.IBaz) # doctest: +ELLIPSIS
> + <zope.app.component.tests.test_registration.Baz object at ...>
> +
> +Before commit, the adapter is not available from another connection::
> +
> + >>> conn2 = db.open()
> + >>> root2 = conn2.root()
> + >>> registry2 = root2['registry']
> + >>> barmodule2 = registry2.findModule('barmodule')
> + >>> bar2 = root2['bar']
> + >>> manager2 = root2['manager']
> + >>> manager2.queryAdapter(bar2, barmodule2.IBaz)
> +
> +After commit, it is::
> +
> + >>> commit()
> + >>> conn2.sync()
> + >>> manager2.getAdapter(bar2, barmodule2.IBaz)
> + ... # doctest: +ELLIPSIS
> + <zope.app.component.tests.test_registration.Baz object at ...>
> +
> +Cleanup::
> +
> + >>> conn1.close()
> + >>> conn2.close()
> + >>> db.close()
> +"""
> +
> +
> def test_suite():
> suite = unittest.TestSuite((
> doctest.DocFileSuite('deprecated35_statusproperty.txt',
>
> Modified: Zope3/branches/3.3/src/zope/app/interface/__init__.py
> ===================================================================
> --- Zope3/branches/3.3/src/zope/app/interface/__init__.py 2007-01-19 21:06:58 UTC (rev 72109)
> +++ Zope3/branches/3.3/src/zope/app/interface/__init__.py 2007-01-19 21:58:52 UTC (rev 72110)
> @@ -19,22 +19,90 @@
> """
> __docformat__ = 'restructuredtext'
>
> +
> from persistent import Persistent
> -from persistent.dict import PersistentDict
> +from persistent.wref import PersistentWeakKeyDictionary
> from zodbcode.patch import registerWrapper, Wrapper
>
> from zope.interface.interface import InterfaceClass
> from zope.interface import Interface
> from zope.security.proxy import removeSecurityProxy
>
> +persistentFactories = {}
> +def getPersistentKey(v_key):
> + if not hasattr(v_key, '__reduce__'):
> + return
> + reduce = v_key.__reduce__()
> + lookups = reduce[0], type(v_key), getattr(v_key, '__class__')
> + for lookup in lookups:
> + p_factory = persistentFactories.get(lookup, None)
> + if p_factory is not None:
> + return p_factory(v_key)
> +
> +class DependentsDict(PersistentWeakKeyDictionary):
> + """Intercept non-persistent keys and swap in persistent
> + equivalents."""
> +
> + def __setstate__(self, state):
> + data = state['data']
> + for v_key, value in data:
> + p_key = getPersistentKey(v_key)
> + if p_key is not None:
> + data[p_key] = data[v_key]
> + state['data'] = data
> + return super(DependentsDict, self).__setstate__(state)
> +
> + def __setitem__(self, key, value):
> + p_key = getPersistentKey(key)
> + if p_key is not None: key = p_key
> + return super(DependentsDict, self).__setitem__(key, value)
> +
> + def __len__(self): return len(self.data)
> +
> + def get(self, key, default=None):
> + if not hasattr(key, '_p_oid') or not hasattr(key, '_p_jar'):
> + return default
> + return super(DependentsDict, self).get(key, default)
> +
> + def update(self, adict):
> + for v_key in adict.keys():
> + p_key = getPersistentKey(v_key)
> + if p_key is not None:
> + adict[p_key] = adict[v_key]
> + return super(DependentsDict, self).update(adict)
> +
> + def keys(self): return [k() for k in self.data.keys()]
> +
> +from zope.interface.declarations import ProvidesClass, Provides
> +class PersistentProvidesClass(Persistent, ProvidesClass):
> + """A persistent Provides class."""
> + def __init__(self, *args, **kw):
> + Persistent.__init__(self)
> + ProvidesClass.__init__(self, *args, **kw)
> + self.dependents = DependentsDict()
> +def persistentProvides(obj):
> + return PersistentProvidesClass(*obj.__reduce__()[1:])
> +persistentFactories[Provides] = persistentProvides
> +
> +from zope.interface.declarations import Implements
> +class PersistentImplements(Persistent, Implements):
> + """A persistent Implements class."""
> + def __init__(self, *args, **kw):
> + Persistent.__init__(self)
> + Implements.__init__(self, *args, **kw)
> + self.dependents = DependentsDict()
> +def persistentImplements(obj):
> + return PersistentImplements(*obj.__bases__)
> +persistentFactories[Implements] = persistentImplements
> +
> class PersistentInterfaceClass(Persistent, InterfaceClass):
>
> def __init__(self, *args, **kw):
> Persistent.__init__(self)
> InterfaceClass.__init__(self, *args, **kw)
> +
> + self.dependents = DependentsDict()
>
> - self.dependents = PersistentDict()
> -
> # PersistentInterface is equivalent to the zope.interface.Interface object
> # except that it is also persistent. It is used in conjunction with
> # zodb.code to support interfaces in persistent modules.
> @@ -50,7 +118,7 @@
> def getInterfaceStateForPersistentInterfaceCreation(iface):
> # Need to convert the dependents weakref dict to a persistent dict
> dict = iface.__dict__.copy()
> - dependents = PersistentDict()
> + dependents = DependentsDict()
> for k, v in dict['dependents'].iteritems():
> dependents[k] = v
> dict['dependents'] = dependents
>
> Modified: Zope3/branches/3.3/src/zope/app/interface/tests/test_interface.py
> ===================================================================
> --- Zope3/branches/3.3/src/zope/app/interface/tests/test_interface.py 2007-01-19 21:06:58 UTC (rev 72109)
> +++ Zope3/branches/3.3/src/zope/app/interface/tests/test_interface.py 2007-01-19 21:58:52 UTC (rev 72110)
> @@ -17,14 +17,18 @@
> """
> __docformat__ = 'restructuredtext'
>
> +from gc import collect
> +
> import unittest
>
> +from persistent import Persistent
> +
> import transaction
>
> from ZODB.tests.util import DB
> from zodbcode.module import ManagedRegistry
>
> -from zope.interface import Interface, implements
> +from zope.interface import Interface, implements, directlyProvides
> from zope.app.interface import PersistentInterface
>
> # TODO: for some reason changing this code to use implements() does not
> @@ -42,11 +46,24 @@
> aFoo = Foo()
> """
>
> +bar_code = """\
> +from zope.interface import Interface
> +class IBar(Interface): pass
> +class IBaz(Interface): pass
> +"""
> +
> +class Bar(Persistent): pass
> +class Baz(Persistent): pass
> +
> +class IQux(Interface): pass
> +
> class PersistentInterfaceTest(unittest.TestCase):
>
> def setUp(self):
> +
> self.db = DB()
> - self.root = self.db.open().root()
> + self.conn = self.db.open()
> + self.root = self.conn.root()
> self.registry = ManagedRegistry()
> self.root["registry"] = self.registry
> transaction.commit()
> @@ -76,6 +93,55 @@
> # the conversion should not affect Interface
> self.assert_(imodule.Interface is Interface)
>
> + def test_provides(self):
> + """Provides are persistent."""
> +
> + self.registry.newModule("barmodule", bar_code)
> + barmodule = self.registry.findModule("barmodule")
> + bar = Bar()
> + directlyProvides(bar, barmodule.IBar)
> + self.root['bar'] = bar
> + self.assertTrue(barmodule.IBar.providedBy(bar))
> + transaction.commit()
> + self.db.close()
>
> + root = self.db.open().root()
> + barmodule = root['registry'].findModule("barmodule")
> + bar = root['bar']
> + self.assertTrue(barmodule.IBar.providedBy(bar))
> +
> + def test_weakref(self):
> + """Weak references to persistent objects don't remain after
> + ZODB pack and garbage collection."""
> +
> + bar = self.root['bar'] = Bar()
> + baz = self.root['baz'] = Baz()
> +
> + self.registry.newModule("barmodule", bar_code)
> + barmodule = self.registry.findModule("barmodule")
> +
> + self.assertEqual(IQux.dependents.keys(), [])
> + self.assertEqual(barmodule.IBar.dependents.keys(), [])
> +
> + directlyProvides(baz, IQux)
> + directlyProvides(bar, barmodule.IBar)
> +
> + self.assertEqual(len(IQux.dependents), 1)
> + self.assertEqual(len(barmodule.IBar.dependents), 1)
> +
> + transaction.commit()
> + del bar
> + del self.root['bar']
> + del baz
> + del self.root['baz']
> + self.db.pack()
> + transaction.commit()
> + collect()
> +
> + root = self.db.open().root()
> + barmodule = root['registry'].findModule("barmodule")
> +
> + self.assertEqual(barmodule.IBar.dependents.keys(), [])
> +
> def test_suite():
> return unittest.makeSuite(PersistentInterfaceTest)
>
> _______________________________________________
> Zope3-Checkins mailing list
> Zope3-Checkins at zope.org
> http://mail.zope.org/mailman/listinfo/zope3-checkins
--
gocept gmbh & co. kg - forsterstraße 29 - 06112 halle/saale - germany
www.gocept.com - ct at gocept.com - phone +49 345 122 9889 7 -
fax +49 345 122 9889 1 - zope and plone consulting and development
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Dies ist ein digital signierter Nachrichtenteil
Url : http://mail.zope.org/pipermail/zope3-checkins/attachments/20070122/5c419174/attachment.bin
More information about the Zope3-Checkins
mailing list