Commit 565750f5 authored by Gary Poster's avatar Gary Poster

- Normalize names in modules so that BTrees, Buckets, Sets, and TreeSets can

  all be accessed with those names in the modules (e.g.,
  BTrees.IOBTree.BTree).  This is in addition to the older names (e.g.,
  BTrees.IOBTree.IOBTree).  This allows easier drop-in replacement, which can
  especially be simplify code for packages that want to support both 32-bit and
  64-bit BTrees.

- Describe the interfaces for each module and actually declare the interfaces
  for each.

- Fix module references so klass.__module__ points to the Python wrapper
  module, not the C extension.
parent cd3cceb0
...@@ -11,6 +11,19 @@ BTrees ...@@ -11,6 +11,19 @@ BTrees
(For now, we're retaining compile-time support for making the (For now, we're retaining compile-time support for making the
regular integer BTrees 64-bit.) regular integer BTrees 64-bit.)
- Normalize names in modules so that BTrees, Buckets, Sets, and TreeSets can
all be accessed with those names in the modules (e.g.,
BTrees.IOBTree.BTree). This is in addition to the older names (e.g.,
BTrees.IOBTree.IOBTree). This allows easier drop-in replacement, which can
especially be simplify code for packages that want to support both 32-bit and
64-bit BTrees.
- Describe the interfaces for each module and actually declare the interfaces
for each.
- Fix module references so klass.__module__ points to the Python wrapper
module, not the C extension.
What's new in ZODB3 3.7.0? What's new in ZODB3 3.7.0?
========================== ==========================
......
...@@ -38,15 +38,17 @@ ...@@ -38,15 +38,17 @@
PER_ACCESSED(OBJ); \ PER_ACCESSED(OBJ); \
} while (0) } while (0)
/* /* The tp_name slots of the various BTree types contain the fully
The tp_name slots of the various BTree types contain the fully * qualified names of the types, e.g. zodb.btrees.OOBTree.OOBTree.
qualified names of the types, e.g. zodb.btrees.OOBTree.OOBTree. * The full name is usd to support pickling and because it is not
The full name is usd to support pickling and because it is not * possible to modify the __module__ slot of a type dynamically. (This
possible to modify the __module__ slot of a type dynamically. (This * may be a bug in Python 2.2).
may be a bug in Python 2.2). *
*/ * The MODULE_NAME here used to be "BTrees._". We actually want the module
* name to point to the Python module rather than the C, so the underline
#define MODULE_NAME "BTrees._" MOD_NAME_PREFIX "BTree." * is now removed.
*/
#define MODULE_NAME "BTrees." MOD_NAME_PREFIX "BTree."
static PyObject *sort_str, *reverse_str, *__setstate___str, static PyObject *sort_str, *reverse_str, *__setstate___str,
*_bucket_type_str; *_bucket_type_str;
...@@ -527,6 +529,23 @@ INITMODULE (void) ...@@ -527,6 +529,23 @@ INITMODULE (void)
if (PyDict_SetItemString(d, MOD_NAME_PREFIX "TreeIterator", if (PyDict_SetItemString(d, MOD_NAME_PREFIX "TreeIterator",
(PyObject *)&BTreeIter_Type) < 0) (PyObject *)&BTreeIter_Type) < 0)
return; return;
/* We also want to be able to access these constants without the prefix
* so that code can more easily exchange modules (particularly the integer
* and long modules, but also others). The TreeIterator is only internal,
* so we don't bother to expose that.
*/
if (PyDict_SetItemString(d, "Bucket",
(PyObject *)&BucketType) < 0)
return;
if (PyDict_SetItemString(d, "BTree",
(PyObject *)&BTreeType) < 0)
return;
if (PyDict_SetItemString(d, "Set",
(PyObject *)&SetType) < 0)
return;
if (PyDict_SetItemString(d, "TreeSet",
(PyObject *)&TreeSetType) < 0)
return;
#if defined(ZODB_64BIT_INTS) && defined(NEED_LONG_LONG_SUPPORT) #if defined(ZODB_64BIT_INTS) && defined(NEED_LONG_LONG_SUPPORT)
if (PyDict_SetItemString(d, "using64bits", Py_True) < 0) if (PyDict_SetItemString(d, "using64bits", Py_True) < 0)
return; return;
......
...@@ -12,5 +12,10 @@ ...@@ -12,5 +12,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
import BTrees.Interfaces
# hack to overcome dynamic-linking headache. # hack to overcome dynamic-linking headache.
from _IFBTree import * from _IFBTree import *
zope.interface.moduleProvides(BTrees.Interfaces.IIntegerFloatBTreeModule)
...@@ -12,5 +12,10 @@ ...@@ -12,5 +12,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
import BTrees.Interfaces
# hack to overcome dynamic-linking headache. # hack to overcome dynamic-linking headache.
from _IIBTree import * from _IIBTree import *
zope.interface.moduleProvides(BTrees.Interfaces.IIntegerIntegerBTreeModule)
...@@ -12,5 +12,10 @@ ...@@ -12,5 +12,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
import BTrees.Interfaces
# hack to overcome dynamic-linking headache. # hack to overcome dynamic-linking headache.
from _IOBTree import * from _IOBTree import *
zope.interface.moduleProvides(BTrees.Interfaces.IIntegerObjectBTreeModule)
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
# #
############################################################################## ##############################################################################
from zope.interface import Interface from zope.interface import Interface, Attribute
class ICollection(Interface): class ICollection(Interface):
...@@ -233,6 +233,7 @@ class IDictionaryIsh(IMinimalDictionary): ...@@ -233,6 +233,7 @@ class IDictionaryIsh(IMinimalDictionary):
raised. raised.
""" """
class IBTree(IDictionaryIsh): class IBTree(IDictionaryIsh):
def insert(key, value): def insert(key, value):
...@@ -304,6 +305,37 @@ class IMerge(Interface): ...@@ -304,6 +305,37 @@ class IMerge(Interface):
""" """
class IBTreeModule(Interface):
"""These are available in all modules (IOBTree, OIBTree, OOBTree, IIBTree,
IFBTree, LFBTree, LOBTree, OLBTree, and LLBTree).
"""
BTree = Attribute(
"""The IBTree for this module.
Also available as [prefix]BTree, as in IOBTree.""")
Bucket = Attribute(
"""The leaf-node data buckets used by the BTree.
(IBucket is not currently defined in this file, but is essentially
IDictionaryIsh, with the exception of __nonzero__, as of this
writing.)
Also available as [prefix]Bucket, as in IOBucket.""")
TreeSet = Attribute(
"""The ITreeSet for this module.
Also available as [prefix]TreeSet, as in IOTreeSet.""")
Set = Attribute(
"""The ISet for this module: the leaf-node data buckets used by the
TreeSet.
Also available as [prefix]BTree, as in IOSet.""")
class IIMerge(IMerge): class IIMerge(IMerge):
"""Merge collections with integer value type. """Merge collections with integer value type.
...@@ -408,6 +440,37 @@ class IMergeIntegerKey(IMerge): ...@@ -408,6 +440,37 @@ class IMergeIntegerKey(IMerge):
linear-time pass. linear-time pass.
""" """
class IIntegerObjectBTreeModule(IBTreeModule, IMerge):
"""keys, or set values, are integers; values are objects.
describes IOBTree and LOBTree"""
class IObjectIntegerBTreeModule(IBTreeModule, IIMerge):
"""keys, or set values, are objects; values are integers.
Object keys (and set values) must sort reliably (for instance, *not* on
object id)! Homogenous key types recommended.
describes OIBTree and LOBTree"""
class IIntegerIntegerBTreeModule(IBTreeModule, IIMerge, IMergeIntegerKey):
"""keys, or set values, are integers; values are also integers.
describes IIBTree and LLBTree"""
class IObjectObjectBTreeModule(IBTreeModule, IMerge):
"""keys, or set values, are objects; values are also objects.
Object keys (and set values) must sort reliably (for instance, *not* on
object id)! Homogenous key types recommended.
describes OOBTree"""
class IIntegerFloatBTreeModule(IBTreeModule, IMerge):
"""keys, or set values, are integers; values are floats.
describes IFBTree and LFBTree"""
############################################################### ###############################################################
# IMPORTANT NOTE # IMPORTANT NOTE
# #
......
...@@ -12,5 +12,10 @@ ...@@ -12,5 +12,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
import BTrees.Interfaces
# hack to overcome dynamic-linking headache. # hack to overcome dynamic-linking headache.
from _LFBTree import * from _LFBTree import *
zope.interface.moduleProvides(BTrees.Interfaces.IIntegerFloatBTreeModule)
...@@ -12,5 +12,10 @@ ...@@ -12,5 +12,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
import BTrees.Interfaces
# hack to overcome dynamic-linking headache. # hack to overcome dynamic-linking headache.
from _LLBTree import * from _LLBTree import *
zope.interface.moduleProvides(BTrees.Interfaces.IIntegerIntegerBTreeModule)
...@@ -12,5 +12,10 @@ ...@@ -12,5 +12,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
import BTrees.Interfaces
# hack to overcome dynamic-linking headache. # hack to overcome dynamic-linking headache.
from _LOBTree import * from _LOBTree import *
zope.interface.moduleProvides(BTrees.Interfaces.IIntegerObjectBTreeModule)
...@@ -12,5 +12,10 @@ ...@@ -12,5 +12,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
import BTrees.Interfaces
# hack to overcome dynamic-linking headache. # hack to overcome dynamic-linking headache.
from _OIBTree import * from _OIBTree import *
zope.interface.moduleProvides(BTrees.Interfaces.IObjectIntegerBTreeModule)
...@@ -12,5 +12,10 @@ ...@@ -12,5 +12,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
import BTrees.Interfaces
# hack to overcome dynamic-linking headache. # hack to overcome dynamic-linking headache.
from _OLBTree import * from _OLBTree import *
zope.interface.moduleProvides(BTrees.Interfaces.IObjectIntegerBTreeModule)
...@@ -12,5 +12,10 @@ ...@@ -12,5 +12,10 @@
# #
############################################################################## ##############################################################################
import zope.interface
import BTrees.Interfaces
# hack to overcome dynamic-linking headache. # hack to overcome dynamic-linking headache.
from _OOBTree import * from _OOBTree import *
zope.interface.moduleProvides(BTrees.Interfaces.IObjectObjectBTreeModule)
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
import random import random
from unittest import TestCase, TestSuite, TextTestRunner, makeSuite from unittest import TestCase, TestSuite, TextTestRunner, makeSuite
from types import ClassType from types import ClassType
import zope.interface.verify
from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
...@@ -25,6 +26,17 @@ from BTrees.LLBTree import LLBTree, LLBucket, LLSet, LLTreeSet ...@@ -25,6 +26,17 @@ from BTrees.LLBTree import LLBTree, LLBucket, LLSet, LLTreeSet
from BTrees.LFBTree import LFBTree, LFBucket, LFSet, LFTreeSet from BTrees.LFBTree import LFBTree, LFBucket, LFSet, LFTreeSet
from BTrees.OLBTree import OLBTree, OLBucket, OLSet, OLTreeSet from BTrees.OLBTree import OLBTree, OLBucket, OLSet, OLTreeSet
import BTrees.OOBTree
import BTrees.IOBTree
import BTrees.IIBTree
import BTrees.IFBTree
import BTrees.OIBTree
import BTrees.LOBTree
import BTrees.LLBTree
import BTrees.LFBTree
import BTrees.OLBTree
import BTrees.Interfaces
from BTrees.IIBTree import using64bits from BTrees.IIBTree import using64bits
from BTrees.check import check from BTrees.check import check
...@@ -1648,6 +1660,22 @@ class TestCmpError(TestCase): ...@@ -1648,6 +1660,22 @@ class TestCmpError(TestCase):
self.fail('incomarable objects should not be allowed into ' self.fail('incomarable objects should not be allowed into '
'the tree') 'the tree')
# test for presence of generic names in module
class ModuleTest(TestCase):
module = None
prefix = None
iface = None
def testNames(self):
for name in ('Bucket', 'BTree', 'Set', 'TreeSet'):
klass = getattr(self.module, name)
self.assertEqual(klass.__module__, self.module.__name__)
self.assert_(klass is getattr(self.module, self.prefix + name))
def testModuleProvides(self):
self.assert_(
zope.interface.verify.verifyObject(self.iface, self.module))
def test_suite(): def test_suite():
s = TestSuite() s = TestSuite()
...@@ -1662,6 +1690,25 @@ def test_suite(): ...@@ -1662,6 +1690,25 @@ def test_suite():
klass = ClassType(kv + name + 'Test', bases, klass = ClassType(kv + name + 'Test', bases,
dict(t_class=globals()[kv+name])) dict(t_class=globals()[kv+name]))
s.addTest(makeSuite(klass)) s.addTest(makeSuite(klass))
for kv, iface in (
('OO', BTrees.Interfaces.IObjectObjectBTreeModule),
('IO', BTrees.Interfaces.IIntegerObjectBTreeModule),
('LO', BTrees.Interfaces.IIntegerObjectBTreeModule),
('OI', BTrees.Interfaces.IObjectIntegerBTreeModule),
('OL', BTrees.Interfaces.IObjectIntegerBTreeModule),
('II', BTrees.Interfaces.IIntegerIntegerBTreeModule),
('LL', BTrees.Interfaces.IIntegerIntegerBTreeModule),
('IF', BTrees.Interfaces.IIntegerFloatBTreeModule),
('LF', BTrees.Interfaces.IIntegerFloatBTreeModule)):
s.addTest(
makeSuite(
ClassType(
kv + 'ModuleTest',
(ModuleTest,),
dict(
prefix=kv,
module=getattr(BTrees, kv + 'BTree'),
iface=iface))))
for klass in ( for klass in (
IIBTreeTest, IFBTreeTest, IOBTreeTest, OIBTreeTest, IIBTreeTest, IFBTreeTest, IOBTreeTest, OIBTreeTest,
...@@ -1670,7 +1717,7 @@ def test_suite(): ...@@ -1670,7 +1717,7 @@ def test_suite():
# Note: there is no TestOOBTrees. The next three are # Note: there is no TestOOBTrees. The next three are
# checking for assorted TypeErrors, and when both keys # checking for assorted TypeErrors, and when both keys
# and values oare objects (OO), there's nothing to test. # and values are objects (OO), there's nothing to test.
TestIIBTrees, TestIFBTrees, TestIOBTrees, TestOIBTrees, TestIIBTrees, TestIFBTrees, TestIOBTrees, TestOIBTrees,
TestIOSets, TestIOSets,
DegenerateBTree, DegenerateBTree,
......
...@@ -61,8 +61,8 @@ Trans #00000 tid=... time=... offset=52 ...@@ -61,8 +61,8 @@ Trans #00000 tid=... time=... offset=52
data #00000 oid=0000000000000000 size=66 class=persistent.mapping.PersistentMapping data #00000 oid=0000000000000000 size=66 class=persistent.mapping.PersistentMapping
Trans #00001 tid=... time=... offset=207 Trans #00001 tid=... time=... offset=207
status=' ' user='' description='added an OOBTree' status=' ' user='' description='added an OOBTree'
data #00000 oid=0000000000000000 size=114 class=persistent.mapping.PersistentMapping data #00000 oid=0000000000000000 size=113 class=persistent.mapping.PersistentMapping
data #00001 oid=0000000000000001 size=30 class=BTrees._OOBTree.OOBTree data #00001 oid=0000000000000001 size=29 class=BTrees.OOBTree.OOBTree
Now we see two transactions and two changed objects. Now we see two transactions and two changed objects.
......
...@@ -94,12 +94,12 @@ oid 0x00 persistent.mapping.PersistentMapping 2 revisions ...@@ -94,12 +94,12 @@ oid 0x00 persistent.mapping.PersistentMapping 2 revisions
tid user='' tid user=''
tid description='added an OOBTree' tid description='added an OOBTree'
new revision persistent.mapping.PersistentMapping at 207 new revision persistent.mapping.PersistentMapping at 207
references 0x01 BTrees._OOBTree.OOBTree at 207 references 0x01 BTrees.OOBTree.OOBTree at 207
oid 0x01 BTrees._OOBTree.OOBTree 1 revision oid 0x01 BTrees.OOBTree.OOBTree 1 revision
tid 0x... offset=168 ... tid 0x... offset=168 ...
tid user='' tid user=''
tid description='added an OOBTree' tid description='added an OOBTree'
new revision BTrees._OOBTree.OOBTree at 363 new revision BTrees.OOBTree.OOBTree at 362
referenced by 0x00 persistent.mapping.PersistentMapping at 207 referenced by 0x00 persistent.mapping.PersistentMapping at 207
So there are two revisions of oid 0 now, and the second references oid 1. So there are two revisions of oid 0 now, and the second references oid 1.
...@@ -122,22 +122,22 @@ oid 0x00 persistent.mapping.PersistentMapping 2 revisions ...@@ -122,22 +122,22 @@ oid 0x00 persistent.mapping.PersistentMapping 2 revisions
tid user='' tid user=''
tid description='added an OOBTree' tid description='added an OOBTree'
new revision persistent.mapping.PersistentMapping at 207 new revision persistent.mapping.PersistentMapping at 207
references 0x01 BTrees._OOBTree.OOBTree at 207 references 0x01 BTrees.OOBTree.OOBTree at 207
tid 0x... offset=443 ... tid 0x... offset=441 ...
tid user='' tid user=''
tid description='circling back to the root' tid description='circling back to the root'
referenced by 0x01 BTrees._OOBTree.OOBTree at 491 referenced by 0x01 BTrees.OOBTree.OOBTree at 489
oid 0x01 BTrees._OOBTree.OOBTree 2 revisions oid 0x01 BTrees.OOBTree.OOBTree 2 revisions
tid 0x... offset=168 ... tid 0x... offset=168 ...
tid user='' tid user=''
tid description='added an OOBTree' tid description='added an OOBTree'
new revision BTrees._OOBTree.OOBTree at 363 new revision BTrees.OOBTree.OOBTree at 362
referenced by 0x00 persistent.mapping.PersistentMapping at 207 referenced by 0x00 persistent.mapping.PersistentMapping at 207
tid 0x... offset=443 ... tid 0x... offset=441 ...
tid user='' tid user=''
tid description='circling back to the root' tid description='circling back to the root'
new revision BTrees._OOBTree.OOBTree at 491 new revision BTrees.OOBTree.OOBTree at 489
references 0x00 persistent.mapping.PersistentMapping at 491 references 0x00 persistent.mapping.PersistentMapping at 489
oid 0x02 <unknown> 0 revisions oid 0x02 <unknown> 0 revisions
this oid was not defined (no data record for it found) this oid was not defined (no data record for it found)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment