[Zope-dev] zc.relationship - can't pickle module objects
Martin Aspeli
optilude+lists at gmail.com
Mon Mar 16 04:02:44 EDT 2009
Hi,
I *think* this is a bug in zc.relationship, but I'm not quite sure.
I'm using ZODB3 3.8.1 (to get BLOB support) and trying to install
plone.app.relations, which depends on zc.relationship 1.0.2. In
particular, it subclasses zc.relationship.shared.Container, and stores
a zc.relationship.index.Index object in self.relationIndex.
Now, the __init__ of zc.relationship.index.Index, which derives from
Persistent, contains the code below. In self._relTools and and
self._attrs, there are a pile of modules, types and functions being
stored. I think these are causing the ZODB to barf. Interestingly, with
whatever version of ZODB that comes with Zope 2.10 (3.7?), there's no
problem.
Any ideas how to work around this, or even why it's a problem in one
version of the ZODB but not another?
zc.relationship.index.Index's initialiser:
def __init__(self, attrs, defaultTransitiveQueriesFactory=None,
dumpRel=generateToken, loadRel=resolveToken,
relFamily=IFBTree, deactivateSets=False):
self._name_TO_mapping = OOBTree.OOBTree()
# held mappings are objtoken to (relcount, relset)
self._EMPTY_name_TO_relcount_relset = OOBTree.OOBTree()
self._reltoken_name_TO_objtokenset = OOBTree.OOBTree()
self.defaultTransitiveQueriesFactory =
defaultTransitiveQueriesFactory
self._relTools = getModuleTools(relFamily)
self._relTools['load'] = loadRel
self._relTools['dump'] = dumpRel
self._relLength = Length.Length()
self._relTokens = self._relTools['TreeSet']()
self.deactivateSets = deactivateSets
self._attrs = _attrs = {} # this is private, and it's not
expected to
# mutate after this initial setting.
seen = set()
for data in attrs:
# see README.txt for description of attrs.
if zope.interface.interfaces.IElement.providedBy(data):
data = {'element': data}
res = getModuleTools(data.get('btree', IFBTree))
res['element'] = val = data['element']
res['attrname'] = val.__name__
res['name'] = data.get('name', res['attrname'])
if res['name'] in _attrs or val in seen:
raise ValueError('Duplicate in attrs', name, val)
seen.add(val)
_attrs[res['name']] = res
res['dump'] = data.get('dump', generateToken)
res['load'] = data.get('load', resolveToken)
if (res['dump'] is None) ^ (res['load'] is None):
raise ValueError(
"either both of 'dump' and 'load' must be None, or
neither")
# when both load and dump are None, this is a small
# optimization that can be a large optimization if the
returned
# value is one of the main four options of the selected
btree
# family (BTree, TreeSet, Set, Bucket).
res['interface'] = val.interface
res['multiple'] = data.get('multiple', False)
res['call'] = zope.interface.interfaces.IMethod.providedBy(val)
if res['TreeSet'].__name__.startswith('I'):
Mapping = IOBTree.IOBTree
else:
assert res['TreeSet'].__name__.startswith('O')
Mapping = OOBTree.OOBTree
self._name_TO_mapping[res['name']] = Mapping()
# these are objtoken to (relcount, relset)
Regards,
Martin
--
Author of `Professional Plone Development`, a book for developers who
want to work with Plone. See http://martinaspeli.net/plone-book
More information about the Zope-Dev
mailing list