[Checkins] SVN: Acquisition/trunk/ 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.

Hanno Schlichting hannosch at hannosch.eu
Sat Apr 3 18:35:56 EDT 2010


Log message for revision 110473:
  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.
  

Changed:
  U   Acquisition/trunk/CHANGES.txt
  U   Acquisition/trunk/src/Acquisition/tests.py

-=-
Modified: Acquisition/trunk/CHANGES.txt
===================================================================
--- Acquisition/trunk/CHANGES.txt	2010-04-03 22:13:43 UTC (rev 110472)
+++ Acquisition/trunk/CHANGES.txt	2010-04-03 22:35:55 UTC (rev 110473)
@@ -4,6 +4,11 @@
 2.13.2 (unreleased)
 -------------------
 
+- 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)
 -------------------

Modified: Acquisition/trunk/src/Acquisition/tests.py
===================================================================
--- Acquisition/trunk/src/Acquisition/tests.py	2010-04-03 22:13:43 UTC (rev 110472)
+++ Acquisition/trunk/src/Acquisition/tests.py	2010-04-03 22:35:55 UTC (rev 110473)
@@ -1565,6 +1565,116 @@
     TypeError: Can't pickle objects in acquisition wrappers.
     """
 
+def test_cant_persist_acquisition_wrappers_classic():
+    """
+    >>> import cPickle
+
+    >>> class X:
+    ...     def __getstate__(self):
+    ...         return 1
+
+    We shouldn't be able to pickle wrappers:
+
+    >>> from Acquisition import ImplicitAcquisitionWrapper
+    >>> w = ImplicitAcquisitionWrapper(X(), X())
+    >>> cPickle.dumps(w)
+    Traceback (most recent call last):
+    ...
+    TypeError: Can't pickle objects in acquisition wrappers.
+
+    Check for pickle protocol one:
+
+    >>> cPickle.dumps(w, 1)
+    Traceback (most recent call last):
+    ...
+    TypeError: Can't pickle objects in acquisition wrappers.
+
+    Check custom pickler:
+
+    >>> from cStringIO import StringIO
+    >>> file = StringIO()
+    >>> pickler = cPickle.Pickler(file, 1)
+
+    >>> pickler.dump(w)
+    Traceback (most recent call last):
+    ...
+    TypeError: Can't pickle objects in acquisition wrappers.
+
+    Check custom pickler with a persistent_id method matching the semantics
+    in ZODB.serialize.ObjectWriter.persistent_id:
+
+    >>> file = StringIO()
+    >>> pickler = cPickle.Pickler(file, 1)
+
+    >>> def persistent_id(obj):
+    ...     klass = type(obj)
+    ...     if hasattr(klass, '__getnewargs__'):
+    ...         return id(obj)
+    ...     return id(obj), klass
+
+    >>> pickler.inst_persistent_id = persistent_id
+    >>> pickler.dump(w)
+    Traceback (most recent call last):
+    ...
+    TypeError: Can't pickle objects in acquisition wrappers.
+    """
+
+
+def test_cant_persist_acquisition_wrappers_newstyle():
+    """
+    >>> import cPickle
+
+    >>> class X(object):
+    ...     def __getstate__(self):
+    ...         return 1
+
+    We shouldn't be able to pickle wrappers:
+
+    >>> from Acquisition import ImplicitAcquisitionWrapper
+    >>> w = ImplicitAcquisitionWrapper(X(), X())
+    >>> cPickle.dumps(w)
+    Traceback (most recent call last):
+    ...
+    TypeError: Can't pickle objects in acquisition wrappers.
+
+    Check for pickle protocol one:
+
+    >>> cPickle.dumps(w, 1)
+    Traceback (most recent call last):
+    ...
+    TypeError: Can't pickle objects in acquisition wrappers.
+
+    Check custom pickler:
+
+    >>> from cStringIO import StringIO
+    >>> file = StringIO()
+    >>> pickler = cPickle.Pickler(file, 1)
+
+    >>> pickler.dump(w)
+    Traceback (most recent call last):
+    ...
+    TypeError: Can't pickle objects in acquisition wrappers.
+
+    Check custom pickler with a persistent_id method matching the semantics
+    in ZODB.serialize.ObjectWriter.persistent_id:
+
+    >>> file = StringIO()
+    >>> pickler = cPickle.Pickler(file, 1)
+
+    >>> def persistent_id(obj):
+    ...     klass = type(obj)
+    ...     if hasattr(klass, '__getnewargs__'):
+    ...         return id(obj)
+    ...     return id(obj), klass
+
+    >>> pickler.inst_persistent_id = persistent_id
+    >>> pickler.dump(w)
+    Traceback (most recent call last):
+    ...
+    TypeError: Can't pickle objects in acquisition wrappers.
+    """
+
+
 def test_interfaces():
     """
     >>> from zope.interface.verify import verifyClass



More information about the checkins mailing list