Re: Zope Tests: 41 OK, 13 Failed

Marius Gedminas <[email protected]>
Newsgroups gmane.comp.web.zope.devel
Message-ID <20101219175108.GA6564@platonas>
On Sun, Dec 19, 2010 at 06:45:11PM +0200, Marius Gedminas wrote:
> > Subject: FAILED : winbot / z3c.contents_py_265_32
> > From: buildbot at winbot.zope.org
> > Date: Sat Dec 18 23:06:16 EST 2010
> > URL: http://mail.zope.org/pipermail/zope-tests/2010-December/027073.html
> 
> Interesting.
> 
> c:\buildslave\z3c.contents\build\src\z3c\contents\README.txt, while testing
> copy & paste near line 613, ends up deep in zope.copy.clone() which barfs
> with
> 
>     TypeError: non-picklable object

tl;dr: zope.copy is badly broken.

The test here creates a simple Content object:

    class Content(object):
        """Sample content which is pickable for copy test."""

        zope.interface.implements(IContent)

        def __init__(self, title, number):
            self.title = title
            self.number = number

        def __repr__(self):
            return u'<%s %s %s>' % (self.__class__.__name__, self.title,
                self.number)

It is not persistent, so it gets wrapped in a ContainedProxy.

And then z3c.contents does

    copier = IObjectCopier(obj)
    copier.copyTo(self.context)

and zope.copypastemove.ObjectCopier.copyTo() does

    new = copy(obj)

and zope.copy.copy() does

    res = clone(obj)
    res.__parent__ = None # wrapped in an if and a try/except.

in that order, and zope.copy.clone() does

    tmp = tempfile.TemporaryFile()
    persistent = CopyPersistent(obj)
    pickler = cPickle.Pickler(tmp, 2)
    pickler.persistent_id = persistent.id
    pickler.dump(obj)

which tries to pickle an unpickleable ViewPageTemplateFile.  Why?
Because of it's reachable through this chain of references:
http://mg.pov.lt/contained-proxy-pickles-too-much.png

Yes, copying any object with zope.copypastemove makes a copy of your
entire ZODB contents, and then discards it a bit later, by dropping the
__parent__ *after* copying it.

(I have a feeling of deja-vu here, but Google doesn't support me.)

I suppose setting __parent__ to None *before* copying is out of the
question.  How about making pickler.persistent_id check the object against
a blacklist -- containing the __parent__ we don't want to copy -- before
passing it on to persistent.id?

I'll go file a bug at https://bugs.launchpad.net/zope.copy

Marius Gedminas
-- 
http://pov.lt/ -- Zope 3/BlueBream consulting and development

_______________________________________________
Zope-Dev maillist  -  [email protected]
https://mail.zope.org/mailman/listinfo/zope-dev
**  No cross posts or HTML encoding!  **
(Related lists - 
 https://mail.zope.org/mailman/listinfo/zope-announce
 https://mail.zope.org/mailman/listinfo/zope )
signature.asc (application/pgp-signature, 198 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)

iEUEARECAAYFAk0ORgwACgkQkVdEXeem14/tcgCfX+3x/CFh4KOEC75Y3HoI04U5
FAYAlj82IDVisMWRGSsu9dTwOtLXi3U=
=/hBW
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.