Re: [ZODB-Dev] PersistentMapping

2005-11-17 Thread Jeremy Hylton
On 11/17/05, Thomas Lotze [EMAIL PROTECTED] wrote:
 Hi,

 I just noticed two things about persistent.PersistentMapping:

 - It inherits from UserDict.UserDict. Is there any reason not to inherit
   from dict directly, given that this has been possible since Python 2.3
   IIRC?

It has been possible to inherit from dictionary since Python 2.2, but
it is not possible for a persistent object and it would not do what
you expect even if it were possible.  A persistent object has a custom
C layout and so does dict, so it is not possible to have them both as
base classes.  (TypeError: multiple bases have instance lay-out
conflict.  (I don't know why there is a hypen in lay-out.))  If it
were possible, it wouldn't work anyway.  If you inherit from dict and
override its builtin methods, like __setitem__, your overridden method
will be ignored by C code using methods like PyDict_SetItem().

 - Not all methods of the mapping interface are handled. In particular,
   there's no reason not to handle pop() as popitems() is handled.
   Unhandled methods that change the content of the dict lead to especially
   nasty bugs as they seem to work OK during a transaction while their
   effect is not permanent.

On the other hand, I think that this omission is just an oversight. 
It would probably be a good idea to change PersistentDict/Mapping to
use the DictMixin instead of UserDict.

Jeremy
___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev


Re: [ZODB-Dev] PersistentMapping glitches

2005-08-23 Thread Victor Safronovich
Hello Tim Peters,

Monday, August 22, 2005, 8:44:08 PM, you wrote:

 from BTrees.OOBTree import OOBTree 
 b = OOBTree()
 b.update(pm)
TP Traceback (most recent call last):
TP   File stdin, line 1, in ?
TP   File C:\python23\lib\UserDict.py, line 19, in __getitem__
TP def __getitem__(self, key): return self.data[key]
TP KeyError: 0

Some  workaround for me(the Collector 1873 poster) was to use data attribute of
the UserDict instances.
 from ZODB.PersistentMapping import PersistentMapping
 from BTrees.OOBTree import OOBTree
 r = OOBTree()
 r.update( PersistentMapping({1:1}).data)
 dict(r)
{1: 1}

i am using isinstance(obj, UserDict) condition now.

-- 
Best regards,
 Victor Safronovich
 NauMen.NauDoc.SoftwareDeveloper  http://www.naumen.ru

___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev


[ZODB-Dev] PersistentMapping glitches

2005-08-22 Thread Tim Peters
Collector

http://www.zope.org/Collectors/Zope/1873

raises some odd issues.  One (although the poster didn't realize this, it's
_part_ of their complaint) is that PersistentMapping doesn't play well with
the newer Python iteration protocol:

 from ZODB.PersistentMapping import PersistentMapping 
 pm = PersistentMapping({1: 2}) 

 for x in pm: 
... print x 
Traceback (most recent call last): 
  File stdin, line 1, in ? 
  File C:\python23\lib\UserDict.py, line 19, in __getitem__ 
def __getitem__(self, key): return self.data[key] 
KeyError: 0 

 list(pm) 
Traceback (most recent call last): 
  File stdin, line 1, in ? 
  File C:\python23\lib\UserDict.py, line 19, in __getitem__ 
def __getitem__(self, key): return self.data[key] 
KeyError: 0 

 i = iter(pm) 
 i.next() 
Traceback (most recent call last): 
  File stdin, line 1, in ? 
  File C:\python23\lib\UserDict.py, line 19, in __getitem__ 
def __getitem__(self, key): return self.data[key] 
KeyError: 0

Oddly enough, the same thing happens if you try to update a BTree with a
PersistentMapping object (which appears to be the point of the collector
issue -- and I agree it's at best surprising this doesn't work):

 from BTrees.OOBTree import OOBTree 
 b = OOBTree()
 b.update(pm)
Traceback (most recent call last):
  File stdin, line 1, in ?
  File C:\python23\lib\UserDict.py, line 19, in __getitem__
def __getitem__(self, key): return self.data[key]
KeyError: 0

That's for a related reason:  the BTree update() method, and a BTree
constructor, take _either_ a sequence (in which case it must be a sequence
of 2-tuples), or an object with an .items() method.

At the C level, PySequence_Check(pm) returns true, so the BTree code doesn't
even look for .items() in this case.  Then Python synthesizes an iterator
for pm, passing keys 0, 1, 2, ... to pm.__getitem__() in turn (well, in ZODB
3.3+, Python synthesizes this iterator; in ZODB 3.2, ZODB's C code does it
by hand).  As above, that dies on the first try, before the BTree code
gets a chance to complain that a 2-tuple isn't returned.

Making PersistentMapping play well with the iteration protocol is just a
matter of giving it an __iter__ method, akin to the __iter__ method of
Python dicts.

That's not enough to let aBTree.update(aPersistentMapping) work, though, and
I think that should work.  A sufficient change should be to look for an
.items() method first.  In some cases that could be backward incompatible.
Does anyone care?  The question there is whether this could go into a bugfix
release (3.2.10, 3.4.2), or whether people simple couldn't do
aBTree.update(aPersistentMapping) or XXBTree(aPersistentMapping)
construction before 3.6.

___
For more information about ZODB, see the ZODB Wiki:
http://www.zope.org/Wikis/ZODB/

ZODB-Dev mailing list  -  ZODB-Dev@zope.org
http://mail.zope.org/mailman/listinfo/zodb-dev