[Checkins] SVN: BTrees/trunk/ Merge 'BTrees-pure_python' branch.
Tres Seaver
cvs-admin at zope.org
Mon Dec 10 19:38:16 UTC 2012
Log message for revision 128563:
Merge 'BTrees-pure_python' branch.
Changed:
_U BTrees/trunk/
U BTrees/trunk/BTrees/IFBTree.py
U BTrees/trunk/BTrees/IIBTree.py
U BTrees/trunk/BTrees/IOBTree.py
U BTrees/trunk/BTrees/Interfaces.py
U BTrees/trunk/BTrees/LFBTree.py
U BTrees/trunk/BTrees/LLBTree.py
U BTrees/trunk/BTrees/LOBTree.py
U BTrees/trunk/BTrees/Length.py
U BTrees/trunk/BTrees/OIBTree.py
U BTrees/trunk/BTrees/OLBTree.py
U BTrees/trunk/BTrees/OOBTree.py
A BTrees/trunk/BTrees/_base.py
U BTrees/trunk/BTrees/check.py
U BTrees/trunk/BTrees/fsBTree.py
A BTrees/trunk/BTrees/tests/common.py
U BTrees/trunk/BTrees/tests/testBTrees.py
U BTrees/trunk/BTrees/tests/testConflict.py
D BTrees/trunk/BTrees/tests/testLength.py
D BTrees/trunk/BTrees/tests/testSetOps.py
A BTrees/trunk/BTrees/tests/test_IFBTree.py
A BTrees/trunk/BTrees/tests/test_IIBTree.py
A BTrees/trunk/BTrees/tests/test_IOBTree.py
A BTrees/trunk/BTrees/tests/test_LFBTree.py
A BTrees/trunk/BTrees/tests/test_LLBTree.py
A BTrees/trunk/BTrees/tests/test_LOBTree.py
A BTrees/trunk/BTrees/tests/test_Length.py
A BTrees/trunk/BTrees/tests/test_OIBTree.py
A BTrees/trunk/BTrees/tests/test_OLBTree.py
A BTrees/trunk/BTrees/tests/test_OOBTree.py
A BTrees/trunk/BTrees/tests/test__base.py
U BTrees/trunk/BTrees/tests/test_check.py
U BTrees/trunk/BTrees/tests/test_fsBTree.py
A BTrees/trunk/BTrees/tests/test_utils.py
U BTrees/trunk/BTrees/utils.py
U BTrees/trunk/CHANGES.txt
U BTrees/trunk/setup.py
U BTrees/trunk/tox.ini
-=-
Property changes on: BTrees/trunk
___________________________________________________________________
Added: svn:mergeinfo
+ /BTrees/branches/pure_python:128123-128130,128182-128183,128197-128212,128221-128238,128254-128268,128274-128280,128286-128295,128318-128320,128332-128334,128357-128363,128496-128532
Added: svk:merge
+ 62d5b8a3-27da-0310-9561-8e5933582275:/BTrees/branches/pure_python:128532
Modified: BTrees/trunk/BTrees/IFBTree.py
===================================================================
--- BTrees/trunk/BTrees/IFBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/IFBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -12,10 +12,118 @@
#
##############################################################################
-import zope.interface
-import BTrees.Interfaces
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'IFBucket', 'IFSet', 'IFBTree', 'IFTreeSet',
+ 'union', 'intersection', 'difference',
+ 'weightedUnion', 'weightedIntersection', 'multiunion',
+ )
-# hack to overcome dynamic-linking headache.
-from _IFBTree import *
+from zope.interface import moduleProvides
-zope.interface.moduleProvides(BTrees.Interfaces.IIntegerFloatBTreeModule)
+from .Interfaces import IIntegerFloatBTreeModule
+from ._base import Bucket
+from ._base import MERGE
+from ._base import MERGE_WEIGHT_numeric
+from ._base import MERGE_DEFAULT_float
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import multiunion as _multiunion
+from ._base import set_operation as _set_operation
+from ._base import to_int as _to_key
+from ._base import to_float as _to_value
+from ._base import union as _union
+from ._base import weightedIntersection as _weightedIntersection
+from ._base import weightedUnion as _weightedUnion
+
+_BUCKET_SIZE = 120
+_TREE_SIZE = 500
+using64bits = False
+
+class IFBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+class IFSetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+class IFBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+class IFTreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+IFBucketPy._mapping_type = IFBucketPy._bucket_type = IFBucketPy
+IFBucketPy._set_type = IFSetPy
+
+IFSetPy._mapping_type = IFBucketPy
+IFSetPy._set_type = IFSetPy._bucket_type = IFSetPy
+
+IFBTreePy._mapping_type = IFBTreePy._bucket_type = IFBucketPy
+IFBTreePy._set_type = IFSetPy
+
+IFTreeSetPy._mapping_type = IFBucketPy
+IFTreeSetPy._set_type = IFTreeSetPy._bucket_type = IFSetPy
+
+
+differencePy = _set_operation(_difference, IFSetPy)
+unionPy = _set_operation(_union, IFSetPy)
+intersectionPy = _set_operation(_intersection, IFSetPy)
+multiunionPy = _set_operation(_multiunion, IFSetPy)
+weightedUnionPy = _set_operation(_weightedUnion, IFSetPy)
+weightedIntersectionPy = _set_operation(_weightedIntersection, IFSetPy)
+
+try:
+ from _IFBTree import IFBucket
+ from _IFBTree import IFSet
+ from _IFBTree import IFBTree
+ from _IFBTree import IFTreeSet
+ from _IFBTree import difference
+ from _IFBTree import union
+ from _IFBTree import intersection
+ from _IFBTree import multiunion
+ from _OIBTree import weightedUnion
+ from _OIBTree import weightedIntersection
+except ImportError: #pragma NO COVER
+ IFBucket = IFBucketPy
+ IFSet = IFSetPy
+ IFBTree = IFBTreePy
+ IFTreeSet = IFTreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+ multiunion = multiunionPy
+ weightedUnion = weightedUnionPy
+ weightedIntersection = weightedIntersectionPy
+
+Bucket = IFBucket
+Set = IFSet
+BTree = IFBTree
+TreeSet = IFTreeSet
+
+moduleProvides(IIntegerFloatBTreeModule)
Modified: BTrees/trunk/BTrees/IIBTree.py
===================================================================
--- BTrees/trunk/BTrees/IIBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/IIBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -12,10 +12,119 @@
#
##############################################################################
-import zope.interface
-import BTrees.Interfaces
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'IIBucket', 'IISet', 'IIBTree', 'IITreeSet',
+ 'union', 'intersection', 'difference',
+ 'weightedUnion', 'weightedIntersection', 'multiunion',
+ )
-# hack to overcome dynamic-linking headache.
-from _IIBTree import *
+from zope.interface import moduleProvides
-zope.interface.moduleProvides(BTrees.Interfaces.IIntegerIntegerBTreeModule)
+from .Interfaces import IIntegerIntegerBTreeModule
+from ._base import Bucket
+from ._base import MERGE
+from ._base import MERGE_WEIGHT_numeric
+from ._base import MERGE_DEFAULT_int
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import multiunion as _multiunion
+from ._base import set_operation as _set_operation
+from ._base import to_int as _to_key
+from ._base import to_int as _to_value
+from ._base import union as _union
+from ._base import weightedIntersection as _weightedIntersection
+from ._base import weightedUnion as _weightedUnion
+
+_BUCKET_SIZE = 120
+_TREE_SIZE = 500
+using64bits = False
+
+
+class IIBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+class IISetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+class IIBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+class IITreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+IIBucketPy._mapping_type = IIBucketPy._bucket_type = IIBucketPy
+IIBucketPy._set_type = IISetPy
+
+IISetPy._mapping_type = IIBucketPy
+IISetPy._set_type = IISetPy._bucket_type = IISetPy
+
+IIBTreePy._mapping_type = IIBTreePy._bucket_type = IIBucketPy
+IIBTreePy._set_type = IISetPy
+
+IITreeSetPy._mapping_type = IIBucketPy
+IITreeSetPy._set_type = IITreeSetPy._bucket_type = IISetPy
+
+
+differencePy = _set_operation(_difference, IISetPy)
+unionPy = _set_operation(_union, IISetPy)
+intersectionPy = _set_operation(_intersection, IISetPy)
+multiunionPy = _set_operation(_multiunion, IISetPy)
+weightedUnionPy = _set_operation(_weightedUnion, IISetPy)
+weightedIntersectionPy = _set_operation(_weightedIntersection, IISetPy)
+
+try:
+ from _IIBTree import IIBucket
+ from _IIBTree import IISet
+ from _IIBTree import IIBTree
+ from _IIBTree import IITreeSet
+ from _IIBTree import difference
+ from _IIBTree import union
+ from _IIBTree import intersection
+ from _IIBTree import multiunion
+ from _IIBTree import weightedUnion
+ from _IIBTree import weightedIntersection
+except ImportError: #pragma NO COVER
+ IIBucket = IIBucketPy
+ IISet = IISetPy
+ IIBTree = IIBTreePy
+ IITreeSet = IITreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+ multiunion = multiunionPy
+ weightedUnion = weightedUnionPy
+ weightedIntersection = weightedIntersectionPy
+
+Bucket = IIBucket
+Set = IISet
+BTree = IIBTree
+TreeSet = IITreeSet
+
+moduleProvides(IIntegerIntegerBTreeModule)
Modified: BTrees/trunk/BTrees/IOBTree.py
===================================================================
--- BTrees/trunk/BTrees/IOBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/IOBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -12,10 +12,98 @@
#
##############################################################################
-import zope.interface
-import BTrees.Interfaces
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'IOBucket', 'IOSet', 'IOBTree', 'IOTreeSet',
+ 'union', 'intersection', 'difference', 'multiunion',
+ )
-# hack to overcome dynamic-linking headache.
-from _IOBTree import *
+from zope.interface import moduleProvides
-zope.interface.moduleProvides(BTrees.Interfaces.IIntegerObjectBTreeModule)
+from .Interfaces import IIntegerObjectBTreeModule
+from ._base import Bucket
+from ._base import MERGE_WEIGHT_default
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import multiunion as _multiunion
+from ._base import set_operation as _set_operation
+from ._base import to_int as _to_key
+from ._base import to_ob as _to_value
+from ._base import union as _union
+
+_BUCKET_SIZE = 60
+_TREE_SIZE = 500
+using64bits = False
+
+
+class IOBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE_WEIGHT = MERGE_WEIGHT_default
+
+
+class IOSetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+
+
+class IOBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE_WEIGHT = MERGE_WEIGHT_default
+
+
+class IOTreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+IOBucketPy._mapping_type = IOBucketPy._bucket_type = IOBucketPy
+IOBucketPy._set_type = IOSetPy
+
+IOSetPy._mapping_type = IOBucketPy
+IOSetPy._set_type = IOSetPy._bucket_type = IOSetPy
+
+IOBTreePy._mapping_type = IOBTreePy._bucket_type = IOBucketPy
+IOBTreePy._set_type = IOSetPy
+
+IOTreeSetPy._mapping_type = IOBucketPy
+IOTreeSetPy._set_type = IOTreeSetPy._bucket_type = IOSetPy
+
+
+differencePy = _set_operation(_difference, IOSetPy)
+unionPy = _set_operation(_union, IOSetPy)
+intersectionPy = _set_operation(_intersection, IOSetPy)
+multiunionPy = _set_operation(_multiunion, IOSetPy)
+
+try:
+ from _IOBTree import IOBucket
+ from _IOBTree import IOSet
+ from _IOBTree import IOBTree
+ from _IOBTree import IOTreeSet
+ from _IOBTree import difference
+ from _IOBTree import union
+ from _IOBTree import intersection
+ from _IOBTree import multiunion
+except ImportError: #pragma NO COVER
+ IOBucket = IOBucketPy
+ IOSet = IOSetPy
+ IOBTree = IOBTreePy
+ IOTreeSet = IOTreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+ multiunion = multiunionPy
+
+Bucket = IOBucket
+Set = IOSet
+BTree = IOBTree
+TreeSet = IOTreeSet
+
+moduleProvides(IIntegerObjectBTreeModule)
Modified: BTrees/trunk/BTrees/Interfaces.py
===================================================================
--- BTrees/trunk/BTrees/Interfaces.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/Interfaces.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -511,7 +511,9 @@
from ZODB.POSException import BTreesConflictError
except ImportError:
class BTreesConflictError(ValueError):
- pass
+ @property
+ def reason(self):
+ return self.args[-1]
###############################################################
# IMPORTANT NOTE
Modified: BTrees/trunk/BTrees/LFBTree.py
===================================================================
--- BTrees/trunk/BTrees/LFBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/LFBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -12,10 +12,119 @@
#
##############################################################################
-import zope.interface
-import BTrees.Interfaces
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'LFBucket', 'LFSet', 'LFBTree', 'LFTreeSet',
+ 'union', 'intersection', 'difference',
+ 'weightedUnion', 'weightedIntersection', 'multiunion',
+ )
-# hack to overcome dynamic-linking headache.
-from _LFBTree import *
+from zope.interface import moduleProvides
-zope.interface.moduleProvides(BTrees.Interfaces.IIntegerFloatBTreeModule)
+from .Interfaces import IIntegerFloatBTreeModule
+from ._base import Bucket
+from ._base import MERGE
+from ._base import MERGE_WEIGHT_numeric
+from ._base import MERGE_DEFAULT_float
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import multiunion as _multiunion
+from ._base import set_operation as _set_operation
+from ._base import to_long as _to_key
+from ._base import to_float as _to_value
+from ._base import union as _union
+from ._base import weightedIntersection as _weightedIntersection
+from ._base import weightedUnion as _weightedUnion
+
+_BUCKET_SIZE = 120
+_TREE_SIZE = 500
+using64bits = True
+
+
+class LFBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+class LFSetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+class LFBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+class LFTreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+LFBucketPy._mapping_type = LFBucketPy._bucket_type = LFBucketPy
+LFBucketPy._set_type = LFSetPy
+
+LFSetPy._mapping_type = LFBucketPy
+LFSetPy._set_type = LFSetPy._bucket_type = LFSetPy
+
+LFBTreePy._mapping_type = LFBTreePy._bucket_type = LFBucketPy
+LFBTreePy._set_type = LFSetPy
+
+LFTreeSetPy._mapping_type = LFBucketPy
+LFTreeSetPy._set_type = LFTreeSetPy._bucket_type = LFSetPy
+
+
+differencePy = _set_operation(_difference, LFSetPy)
+unionPy = _set_operation(_union, LFSetPy)
+intersectionPy = _set_operation(_intersection, LFSetPy)
+multiunionPy = _set_operation(_multiunion, LFSetPy)
+weightedUnionPy = _set_operation(_weightedUnion, LFSetPy)
+weightedIntersectionPy = _set_operation(_weightedIntersection, LFSetPy)
+
+try:
+ from _LFBTree import LFBucket
+ from _LFBTree import LFSet
+ from _LFBTree import LFBTree
+ from _LFBTree import LFTreeSet
+ from _LFBTree import difference
+ from _LFBTree import union
+ from _LFBTree import intersection
+ from _LFBTree import multiunion
+ from _OIBTree import weightedUnion
+ from _OIBTree import weightedIntersection
+except ImportError: #pragma NO COVER
+ LFBucket = LFBucketPy
+ LFSet = LFSetPy
+ LFBTree = LFBTreePy
+ LFTreeSet = LFTreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+ multiunion = multiunionPy
+ weightedUnion = weightedUnionPy
+ weightedIntersection = weightedIntersectionPy
+
+Bucket = LFBucket
+Set = LFSet
+BTree = LFBTree
+TreeSet = LFTreeSet
+
+moduleProvides(IIntegerFloatBTreeModule)
Modified: BTrees/trunk/BTrees/LLBTree.py
===================================================================
--- BTrees/trunk/BTrees/LLBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/LLBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -12,10 +12,119 @@
#
##############################################################################
-import zope.interface
-import BTrees.Interfaces
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'LLBucket', 'LLSet', 'LLBTree', 'LLTreeSet',
+ 'union', 'intersection', 'difference',
+ 'weightedUnion', 'weightedIntersection', 'multiunion',
+ )
-# hack to overcome dynamic-linking headache.
-from _LLBTree import *
+from zope.interface import moduleProvides
-zope.interface.moduleProvides(BTrees.Interfaces.IIntegerIntegerBTreeModule)
+from .Interfaces import IIntegerIntegerBTreeModule
+from ._base import Bucket
+from ._base import MERGE
+from ._base import MERGE_WEIGHT_numeric
+from ._base import MERGE_DEFAULT_int
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import multiunion as _multiunion
+from ._base import set_operation as _set_operation
+from ._base import to_long as _to_key
+from ._base import to_long as _to_value
+from ._base import union as _union
+from ._base import weightedIntersection as _weightedIntersection
+from ._base import weightedUnion as _weightedUnion
+
+_BUCKET_SIZE = 120
+_TREE_SIZE = 500
+using64bits = True
+
+
+class LLBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+class LLSetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+class LLBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+class LLTreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+LLBucketPy._mapping_type = LLBucketPy._bucket_type = LLBucketPy
+LLBucketPy._set_type = LLSetPy
+
+LLSetPy._mapping_type = LLBucketPy
+LLSetPy._set_type = LLSetPy._bucket_type = LLSetPy
+
+LLBTreePy._mapping_type = LLBTreePy._bucket_type = LLBucketPy
+LLBTreePy._set_type = LLSetPy
+
+LLTreeSetPy._mapping_type = LLBucketPy
+LLTreeSetPy._set_type = LLTreeSetPy._bucket_type = LLSetPy
+
+
+differencePy = _set_operation(_difference, LLSetPy)
+unionPy = _set_operation(_union, LLSetPy)
+intersectionPy = _set_operation(_intersection, LLSetPy)
+multiunionPy = _set_operation(_multiunion, LLSetPy)
+weightedUnionPy = _set_operation(_weightedUnion, LLSetPy)
+weightedIntersectionPy = _set_operation(_weightedIntersection, LLSetPy)
+
+try:
+ from _LLBTree import LLBucket
+ from _LLBTree import LLSet
+ from _LLBTree import LLBTree
+ from _LLBTree import LLTreeSet
+ from _LLBTree import difference
+ from _LLBTree import union
+ from _LLBTree import intersection
+ from _LLBTree import multiunion
+ from _LLBTree import weightedUnion
+ from _LLBTree import weightedIntersection
+except ImportError: #pragma NO COVER
+ LLBucket = LLBucketPy
+ LLSet = LLSetPy
+ LLBTree = LLBTreePy
+ LLTreeSet = LLTreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+ multiunion = multiunionPy
+ weightedUnion = weightedUnionPy
+ weightedIntersection = weightedIntersectionPy
+
+Bucket = LLBucket
+Set = LLSet
+BTree = LLBTree
+TreeSet = LLTreeSet
+
+moduleProvides(IIntegerIntegerBTreeModule)
Modified: BTrees/trunk/BTrees/LOBTree.py
===================================================================
--- BTrees/trunk/BTrees/LOBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/LOBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -12,10 +12,98 @@
#
##############################################################################
-import zope.interface
-import BTrees.Interfaces
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'LOBucket', 'LOSet', 'LOBTree', 'LOTreeSet',
+ 'union', 'intersection', 'difference', 'multiunion',
+ )
-# hack to overcome dynamic-linking headache.
-from _LOBTree import *
+from zope.interface import moduleProvides
-zope.interface.moduleProvides(BTrees.Interfaces.IIntegerObjectBTreeModule)
+from .Interfaces import IIntegerObjectBTreeModule
+from ._base import Bucket
+from ._base import MERGE_WEIGHT_default
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import multiunion as _multiunion
+from ._base import set_operation as _set_operation
+from ._base import to_long as _to_key
+from ._base import to_ob as _to_value
+from ._base import union as _union
+
+_BUCKET_SIZE = 60
+_TREE_SIZE = 500
+using64bits = True
+
+
+class LOBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE_WEIGHT = MERGE_WEIGHT_default
+
+
+class LOSetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+
+
+class LOBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE_WEIGHT = MERGE_WEIGHT_default
+
+
+class LOTreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+LOBucketPy._mapping_type = LOBucketPy._bucket_type = LOBucketPy
+LOBucketPy._set_type = LOSetPy
+
+LOSetPy._mapping_type = LOBucketPy
+LOSetPy._set_type = LOSetPy._bucket_type = LOSetPy
+
+LOBTreePy._mapping_type = LOBTreePy._bucket_type = LOBucketPy
+LOBTreePy._set_type = LOSetPy
+
+LOTreeSetPy._mapping_type = LOBucketPy
+LOTreeSetPy._set_type = LOTreeSetPy._bucket_type = LOSetPy
+
+
+differencePy = _set_operation(_difference, LOSetPy)
+unionPy = _set_operation(_union, LOSetPy)
+intersectionPy = _set_operation(_intersection, LOSetPy)
+multiunionPy = _set_operation(_multiunion, LOSetPy)
+
+try:
+ from _LOBTree import LOBucket
+ from _LOBTree import LOSet
+ from _LOBTree import LOBTree
+ from _LOBTree import LOTreeSet
+ from _LOBTree import difference
+ from _LOBTree import union
+ from _LOBTree import intersection
+ from _LOBTree import multiunion
+except ImportError: #pragma NO COVER
+ LOBucket = LOBucketPy
+ LOSet = LOSetPy
+ LOBTree = LOBTreePy
+ LOTreeSet = LOTreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+ multiunion = multiunionPy
+
+Bucket = LOBucket
+Set = LOSet
+BTree = LOBTree
+TreeSet = LOTreeSet
+
+moduleProvides(IIntegerObjectBTreeModule)
Modified: BTrees/trunk/BTrees/Length.py
===================================================================
--- BTrees/trunk/BTrees/Length.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/Length.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -28,8 +28,9 @@
longer works as expected, because new-style classes cache
class-defined slot methods (like __len__) in C type slots. Thus,
instance-defined slot fillers are ignored.
-
"""
+ # class-level default required to keep copy.deepcopy happy -- see
+ # https://bugs.launchpad.net/zodb/+bug/516653
value = 0
def __init__(self, v=0):
Modified: BTrees/trunk/BTrees/OIBTree.py
===================================================================
--- BTrees/trunk/BTrees/OIBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/OIBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -12,10 +12,115 @@
#
##############################################################################
-import zope.interface
-import BTrees.Interfaces
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'OIBucket', 'OISet', 'OIBTree', 'OITreeSet',
+ 'union', 'intersection', 'difference',
+ 'weightedUnion', 'weightedIntersection',
+ )
-# hack to overcome dynamic-linking headache.
-from _OIBTree import *
+from zope.interface import moduleProvides
-zope.interface.moduleProvides(BTrees.Interfaces.IObjectIntegerBTreeModule)
+from .Interfaces import IObjectIntegerBTreeModule
+from ._base import Bucket
+from ._base import MERGE
+from ._base import MERGE_WEIGHT_numeric
+from ._base import MERGE_DEFAULT_float
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import set_operation as _set_operation
+from ._base import to_ob as _to_key
+from ._base import to_int as _to_value
+from ._base import union as _union
+from ._base import weightedIntersection as _weightedIntersection
+from ._base import weightedUnion as _weightedUnion
+
+_BUCKET_SIZE = 60
+_TREE_SIZE = 250
+using64bits = True
+
+class OIBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+class OISetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+class OIBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+class OITreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_float
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+OIBucketPy._mapping_type = OIBucketPy._bucket_type = OIBucketPy
+OIBucketPy._set_type = OISetPy
+
+OISetPy._mapping_type = OIBucketPy
+OISetPy._set_type = OISetPy._bucket_type = OISetPy
+
+OIBTreePy._mapping_type = OIBTreePy._bucket_type = OIBucketPy
+OIBTreePy._set_type = OISetPy
+
+OITreeSetPy._mapping_type = OIBucketPy
+OITreeSetPy._set_type = OITreeSetPy._bucket_type = OISetPy
+
+
+differencePy = _set_operation(_difference, OISetPy)
+unionPy = _set_operation(_union, OISetPy)
+intersectionPy = _set_operation(_intersection, OISetPy)
+weightedUnionPy = _set_operation(_weightedUnion, OISetPy)
+weightedIntersectionPy = _set_operation(_weightedIntersection, OISetPy)
+
+try:
+ from _OIBTree import OIBucket
+ from _OIBTree import OISet
+ from _OIBTree import OIBTree
+ from _OIBTree import OITreeSet
+ from _OIBTree import difference
+ from _OIBTree import union
+ from _OIBTree import intersection
+ from _OIBTree import weightedUnion
+ from _OIBTree import weightedIntersection
+except ImportError: #pragma NO COVER
+ OIBucket = OIBucketPy
+ OISet = OISetPy
+ OIBTree = OIBTreePy
+ OITreeSet = OITreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+ weightedUnion = weightedUnionPy
+ weightedIntersection = weightedIntersectionPy
+
+
+Bucket = OIBucket
+Set = OISet
+BTree = OIBTree
+TreeSet = OITreeSet
+
+moduleProvides(IObjectIntegerBTreeModule)
Modified: BTrees/trunk/BTrees/OLBTree.py
===================================================================
--- BTrees/trunk/BTrees/OLBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/OLBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -12,10 +12,115 @@
#
##############################################################################
-import zope.interface
-import BTrees.Interfaces
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'OLBucket', 'OLSet', 'OLBTree', 'OLTreeSet',
+ 'union', 'intersection', 'difference',
+ 'weightedUnion', 'weightedIntersection',
+ )
-# hack to overcome dynamic-linking headache.
-from _OLBTree import *
+from zope.interface import moduleProvides
-zope.interface.moduleProvides(BTrees.Interfaces.IObjectIntegerBTreeModule)
+from .Interfaces import IObjectIntegerBTreeModule
+from ._base import Bucket
+from ._base import MERGE
+from ._base import MERGE_WEIGHT_numeric
+from ._base import MERGE_DEFAULT_int
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import set_operation as _set_operation
+from ._base import to_ob as _to_key
+from ._base import to_int as _to_value
+from ._base import union as _union
+from ._base import weightedIntersection as _weightedIntersection
+from ._base import weightedUnion as _weightedUnion
+
+_BUCKET_SIZE = 60
+_TREE_SIZE = 250
+using64bits = True
+
+
+class OLBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+class OLSetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+class OLBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+class OLTreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ MERGE = MERGE
+ MERGE_WEIGHT = MERGE_WEIGHT_numeric
+ MERGE_DEFAULT = MERGE_DEFAULT_int
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+OLBucketPy._mapping_type = OLBucketPy._bucket_type = OLBucketPy
+OLBucketPy._set_type = OLSetPy
+
+OLSetPy._mapping_type = OLBucketPy
+OLSetPy._set_type = OLSetPy._bucket_type = OLSetPy
+
+OLBTreePy._mapping_type = OLBTreePy._bucket_type = OLBucketPy
+OLBTreePy._set_type = OLSetPy
+
+OLTreeSetPy._mapping_type = OLBucketPy
+OLTreeSetPy._set_type = OLTreeSetPy._bucket_type = OLSetPy
+
+
+differencePy = _set_operation(_difference, OLSetPy)
+unionPy = _set_operation(_union, OLSetPy)
+intersectionPy = _set_operation(_intersection, OLSetPy)
+weightedUnionPy = _set_operation(_weightedUnion, OLSetPy)
+weightedIntersectionPy = _set_operation(_weightedIntersection, OLSetPy)
+
+try:
+ from _OLBTree import OLBucket
+ from _OLBTree import OLSet
+ from _OLBTree import OLBTree
+ from _OLBTree import OLTreeSet
+ from _OLBTree import difference
+ from _OLBTree import union
+ from _OLBTree import intersection
+ from _OLBTree import weightedUnion
+ from _OLBTree import weightedIntersection
+except ImportError: #pragma NO COVER
+ OLBucket = OLBucketPy
+ OLSet = OLSetPy
+ OLBTree = OLBTreePy
+ OLTreeSet = OLTreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+ weightedUnion = weightedUnionPy
+ weightedIntersection = weightedIntersectionPy
+
+Bucket = OLBucket
+Set = OLSet
+BTree = OLBTree
+TreeSet = OLTreeSet
+
+moduleProvides(IObjectIntegerBTreeModule)
Modified: BTrees/trunk/BTrees/OOBTree.py
===================================================================
--- BTrees/trunk/BTrees/OOBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/OOBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -12,10 +12,91 @@
#
##############################################################################
-import zope.interface
-import BTrees.Interfaces
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'OOBucket', 'OOSet', 'OOBTree', 'OOTreeSet',
+ 'union', 'intersection','difference',
+ )
-# hack to overcome dynamic-linking headache.
-from _OOBTree import *
+from zope.interface import moduleProvides
-zope.interface.moduleProvides(BTrees.Interfaces.IObjectObjectBTreeModule)
+from .Interfaces import IObjectObjectBTreeModule
+from ._base import Bucket
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import set_operation as _set_operation
+from ._base import to_ob as _to_key
+from ._base import to_ob as _to_value
+from ._base import union as _union
+
+_BUCKET_SIZE = 30
+_TREE_SIZE = 250
+using64bits = False
+
+
+class OOBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+
+
+class OOSetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+
+
+class OOBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+
+
+class OOTreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+OOBucketPy._mapping_type = OOBucketPy._bucket_type = OOBucketPy
+OOBucketPy._set_type = OOSetPy
+
+OOSetPy._mapping_type = OOBucketPy
+OOSetPy._set_type = OOSetPy._bucket_type = OOSetPy
+
+OOBTreePy._mapping_type = OOBTreePy._bucket_type = OOBucketPy
+OOBTreePy._set_type = OOSetPy
+
+OOTreeSetPy._mapping_type = OOBucketPy
+OOTreeSetPy._set_type = OOTreeSetPy._bucket_type = OOSetPy
+
+
+differencePy = _set_operation(_difference, OOSetPy)
+unionPy = _set_operation(_union, OOSetPy)
+intersectionPy = _set_operation(_intersection, OOSetPy)
+
+try:
+ from _OOBTree import OOBucket
+ from _OOBTree import OOSet
+ from _OOBTree import OOBTree
+ from _OOBTree import OOTreeSet
+ from _OOBTree import difference
+ from _OOBTree import union
+ from _OOBTree import intersection
+except ImportError: #pragma NO COVER
+ OOBucket = OOBucketPy
+ OOSet = OOSetPy
+ OOBTree = OOBTreePy
+ OOTreeSet = OOTreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+
+Bucket = OOBucket
+Set = OOSet
+BTree = OOBTree
+TreeSet = OOTreeSet
+
+moduleProvides(IObjectObjectBTreeModule)
Copied: BTrees/trunk/BTrees/_base.py (from rev 128532, BTrees/branches/pure_python/BTrees/_base.py)
===================================================================
--- BTrees/trunk/BTrees/_base.py (rev 0)
+++ BTrees/trunk/BTrees/_base.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,1442 @@
+##############################################################################
+#
+# Copyright 2011 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Python BTree implementation
+"""
+
+from struct import pack
+from struct import unpack
+from struct import error as struct_error
+
+from persistent import Persistent
+
+from .Interfaces import BTreesConflictError
+
+
+_marker = object()
+
+
+class _Base(Persistent):
+
+ __slots__ = ()
+ _key_type = list
+
+ def __init__(self, items=None):
+ self.clear()
+ if items:
+ self.update(items)
+
+
+class _BucketBase(_Base):
+
+ __slots__ = ('_keys',
+ '_next',
+ '_to_key',
+ )
+
+ def clear(self):
+ self._keys = self._key_type()
+ self._next = None
+
+ def __len__(self):
+ return len(self._keys)
+
+ @property
+ def size(self):
+ return len(self._keys)
+
+ def _deleteNextBucket(self):
+ next = self._next
+ if next is not None:
+ self._next = next._next
+
+ def _search(self, key):
+ # Return non-negative index on success
+ # return -(insertion_index + 1) on fail
+ low = 0
+ keys = self._keys
+ high = len(keys)
+ while low < high:
+ i = (low + high) // 2
+ k = keys[i]
+ if k == key:
+ return i
+ if k < key:
+ low = i + 1
+ else:
+ high = i
+ return -1 - low
+
+ def minKey(self, key=_marker):
+ if key is _marker:
+ return self._keys[0]
+ key = self._to_key(key)
+ index = self._search(key)
+ if index >= 0:
+ return key
+ index = -index - 1
+ if index < len(self._keys):
+ return self._keys[index]
+ else:
+ raise ValueError("no key satisfies the conditions")
+
+ def maxKey(self, key=_marker):
+ if key is _marker:
+ return self._keys[-1]
+ key = self._to_key(key)
+ index = self._search(key)
+ if index >= 0:
+ return key
+ else:
+ index = -index-1
+ if index:
+ return self._keys[index-1]
+ else:
+ raise ValueError("no key satisfies the conditions")
+
+ def _range(self, min=_marker, max=_marker,
+ excludemin=False, excludemax=False):
+ if min is _marker:
+ start = 0
+ if excludemin:
+ start = 1
+ else:
+ min = self._to_key(min)
+ start = self._search(min)
+ if start >= 0:
+ if excludemin:
+ start += 1
+ else:
+ start = -start - 1
+ if max is _marker:
+ end = len(self._keys)
+ if excludemax:
+ end -= 1
+ else:
+ max = self._to_key(max)
+ end = self._search(max)
+ if end >= 0:
+ if not excludemax:
+ end += 1
+ else:
+ end = -end - 1
+
+ return start, end
+
+ def keys(self, *args, **kw):
+ start, end = self._range(*args, **kw)
+ return self._keys[start:end]
+
+ def iterkeys(self, *args, **kw):
+ if not (args or kw):
+ return iter(self._keys)
+ keys = self._keys
+ return (keys[i] for i in xrange(*self._range(*args, **kw)))
+
+ def __iter__(self):
+ return iter(self._keys)
+
+ def __contains__(self, key):
+ return (self._search(self._to_key(key)) >= 0)
+
+ has_key = __contains__
+
+
+class _SetIteration(object):
+
+ __slots__ = ('to_iterate',
+ 'useValues',
+ '_next',
+ 'active',
+ 'position',
+ 'key',
+ 'value',
+ )
+
+
+ def __init__(self, to_iterate, useValues=False, default=None):
+ if to_iterate is None:
+ to_iterate = ()
+ self.to_iterate = to_iterate
+ if useValues:
+ try:
+ itmeth = to_iterate.iteritems
+ except AttributeError:
+ itmeth = to_iterate.__iter__
+ useValues = False
+ else:
+ self.value = None
+ else:
+ itmeth = to_iterate.__iter__
+
+ self.useValues = useValues
+ self._next = itmeth().next
+ self.active = True
+ self.position = 0
+ self.key = _marker
+ self.value = default
+ self.advance()
+
+ def advance(self):
+ try:
+ if self.useValues:
+ self.key, self.value = self._next()
+ else:
+ self.key = self._next()
+ self.position += 1
+ except StopIteration:
+ self.active = False
+ self.position = -1
+
+ return self
+
+
+class Bucket(_BucketBase):
+
+ __slots__ = ()
+ _value_type = list
+ _to_value = lambda self, x: x
+ VALUE_SAME_CHECK = False
+
+ def setdefault(self, key, value):
+ key, value = self._to_key(key), self._to_value(value)
+ status, value = self._set(key, value, True)
+ return value
+
+ def pop(self, key, default=_marker):
+ try:
+ status, value = self._del(self._to_key(key))
+ except KeyError:
+ if default is _marker:
+ raise
+ return default
+ else:
+ return value
+
+ def update(self, items):
+ if hasattr(items, 'iteritems'):
+ items = items.iteritems()
+ elif hasattr(items, 'items'):
+ items = items.items()
+
+ _si = self.__setitem__
+ try:
+ for key, value in items:
+ _si(key, value)
+ except ValueError:
+ raise TypeError('items must be a sequence of 2-tuples')
+
+ def __setitem__(self, key, value):
+ # Enforce test that key has non-default comparison.
+ if ( getattr(key, '__lt__', None) is None and
+ getattr(key, '__cmp__', None) is None):
+ raise TypeError("Can't use default __cmp__")
+ self._set(self._to_key(key), self._to_value(value))
+
+ def __delitem__(self, key):
+ self._del(self._to_key(key))
+
+ def clear(self):
+ _BucketBase.clear(self)
+ self._values = self._value_type()
+
+ def get(self, key, default=None):
+ index = self._search(self._to_key(key))
+ if index < 0:
+ return default
+ return self._values[index]
+
+ def __getitem__(self, key):
+ index = self._search(self._to_key(key))
+ if index < 0:
+ raise KeyError(key)
+ return self._values[index]
+
+ def _set(self, key, value, ifunset=False):
+ """Set a value
+
+ Return: status, value
+
+ Status is:
+ None if no change
+ 0 if change, but not size change
+ 1 if change and size change
+ """
+ index = self._search(key)
+ if index >= 0:
+ if (ifunset or
+ self.VALUE_SAME_CHECK and value == self._values[index]
+ ):
+ return None, self._values[index]
+ self._p_changed = True
+ self._values[index] = value
+ return 0, value
+ else:
+ self._p_changed = True
+ index = -index - 1
+ self._keys.insert(index, key)
+ self._values.insert(index, value)
+ return 1, value
+
+ def _del(self, key):
+ index = self._search(key)
+ if index >= 0:
+ self._p_changed = True
+ del self._keys[index]
+ return 0, self._values.pop(index)
+ raise KeyError(key)
+
+ def _split(self, index=-1):
+ if index < 0 or index >= len(self._keys):
+ index = len(self._keys) / 2
+ new_instance = self.__class__()
+ new_instance._keys = self._keys[index:]
+ new_instance._values = self._values[index:]
+ del self._keys[index:]
+ del self._values[index:]
+ new_instance._next = self._next
+ self._next = new_instance
+ return new_instance
+
+ def values(self, *args, **kw):
+ start, end = self._range(*args, **kw)
+ return self._values[start:end]
+
+ def itervalues(self, *args, **kw):
+ values = self._values
+ return (values[i] for i in xrange(*self._range(*args, **kw)))
+
+ def items(self, *args, **kw):
+ keys = self._keys
+ values = self._values
+ return [(keys[i], values[i])
+ for i in xrange(*self._range(*args, **kw))]
+
+ def iteritems(self, *args, **kw):
+ keys = self._keys
+ values = self._values
+ return ((keys[i], values[i])
+ for i in xrange(*self._range(*args, **kw)))
+
+ def __getstate__(self):
+ keys = self._keys
+ values = self._values
+ data = []
+ for i in range(len(keys)):
+ data.append(keys[i])
+ data.append(values[i])
+ data = tuple(data)
+
+ if self._next is not None:
+ return data, self._next
+ return (data, )
+
+ def __setstate__(self, state):
+ if not isinstance(state[0], tuple):
+ raise TypeError("tuple required for first state element")
+
+ self.clear()
+ if len(state) == 2:
+ state, self._next = state
+ else:
+ self._next = None
+ state = state[0]
+
+ keys = self._keys
+ values = self._values
+ for i in range(0, len(state), 2):
+ keys.append(state[i])
+ values.append(state[i+1])
+
+ def _p_resolveConflict(self, s_old, s_com, s_new):
+ b_old = self.__class__()
+ if s_old is not None:
+ b_old.__setstate__(s_old)
+ b_com = self.__class__()
+ if s_com is not None:
+ b_com.__setstate__(s_com)
+ b_new = self.__class__()
+ if s_new is not None:
+ b_new.__setstate__(s_new)
+ if (b_com._next != b_old._next or
+ b_new._next != b_old._next):
+ raise BTreesConflictError(-1, -1, -1, 0)
+
+ if not b_com or not b_new:
+ raise BTreesConflictError(-1, -1, -1, 12)
+
+ i_old = _SetIteration(b_old, True)
+ i_com = _SetIteration(b_com, True)
+ i_new = _SetIteration(b_new, True)
+
+ def merge_error(reason):
+ return BTreesConflictError(
+ i_old.position, i_com.position, i_new.position, reason)
+
+ result = self.__class__()
+
+ def merge_output(it):
+ result._keys.append(it.key)
+ result._values.append(it.value)
+ it.advance()
+
+ while i_old.active and i_com.active and i_new.active:
+ cmpOC = cmp(i_old.key, i_com.key)
+ cmpON = cmp(i_old.key, i_new.key)
+ if cmpOC == 0:
+ if cmpON == 0:
+ if i_com.value == i_old.value:
+ result[i_old.key] = i_new.value
+ elif i_new.value == i_old.value:
+ result[i_old.key] = i_com.value
+ else:
+ raise merge_error(1)
+ i_old.advance()
+ i_com.advance()
+ i_new.advance()
+ elif (cmpON > 0): # insert in new
+ merge_output(i_new)
+ elif i_old.value == i_com.value: # deleted new
+ if i_new.position == 1:
+ # Deleted the first item. This will modify the
+ # parent node, so we don't know if merging will be
+ # safe
+ raise merge_error(13)
+ i_old.advance()
+ i_com.advance()
+ else:
+ raise merge_error(2)
+ elif cmpON == 0:
+ if cmpOC > 0: # insert committed
+ merge_output(i_com)
+ elif i_old.value == i_new.value: # delete committed
+ if i_com.position == 1:
+ # Deleted the first item. This will modify the
+ # parent node, so we don't know if merging will be
+ # safe
+ raise merge_error(13)
+ i_old.advance()
+ i_new.advance()
+ else:
+ raise merge_error(3)
+ else: # both keys changed
+ cmpCN = cmp(i_com.key, i_new.key)
+ if cmpCN == 0: # dueling insert
+ raise merge_error(4)
+ if cmpOC > 0: # insert committed
+ if cmpCN > 0: # insert i_new first
+ merge_output(i_new)
+ else:
+ merge_output(i_com)
+ elif cmpON > 0: # insert i_new
+ merge_output(i_new)
+ else:
+ raise merge_error(5) # both deleted same key
+
+ while i_com.active and i_new.active: # new inserts
+ cmpCN = cmp(i_com.key, i_new.key)
+ if cmpCN == 0:
+ raise merge_error(6) # dueling insert
+ if cmpCN > 0: # insert new
+ merge_output(i_new)
+ else: # insert committed
+ merge_output(i_com)
+
+ while i_old.active and i_com.active: # new deletes rest of original
+ cmpOC = cmp(i_old.key, i_com.key)
+ if cmpOC > 0: # insert committed
+ merge_output(i_com)
+ elif cmpOC == 0 and (i_old.value == i_com.value): # del in new
+ i_old.advance()
+ i_com.advance()
+ else: # dueling deletes or delete and change
+ raise merge_error(7)
+
+ while i_old.active and i_new.active:
+ # committed deletes rest of original
+ cmpON = cmp(i_old.key, i_new.key)
+ if cmpON > 0: # insert new
+ merge_output(i_new)
+ elif cmpON == 0 and (i_old.value == i_new.value):
+ # deleted in committed
+ i_old.advance()
+ i_new.advance()
+ else: # dueling deletes or delete and change
+ raise merge_error(8)
+
+ if i_old.active: # dueling deletes
+ raise merge_error(9)
+
+ while i_com.active:
+ merge_output(i_com)
+
+ while i_new.active:
+ merge_output(i_new)
+
+ if len(result._keys) == 0: #pragma NO COVER
+ # If the output bucket is empty, conflict resolution doesn't have
+ # enough info to unlink it from its containing BTree correctly.
+ #
+ # XXX TS, 2012-11-16: I don't think this is possible
+ #
+ raise merge_error(10)
+
+ result._next = b_old._next
+ return result.__getstate__()
+
+
+class Set(_BucketBase):
+
+ __slots__ = ()
+
+ def add(self, key):
+ return self._set(self._to_key(key))[0]
+
+ insert = add
+
+ def remove(self, key):
+ self._del(self._to_key(key))
+
+ def update(self, items):
+ add = self.add
+ for i in items:
+ add(i)
+
+ def __getstate__(self):
+ data = tuple(self._keys)
+ if self._next is not None:
+ return data, self._next
+ return (data, )
+
+ def __setstate__(self, state):
+ if not isinstance(state[0], tuple):
+ raise TypeError('tuple required for first state element')
+
+ self.clear()
+ if len(state) == 2:
+ state, self._next = state
+ else:
+ self._next = None
+ state = state[0]
+
+ self._keys.extend(state)
+
+
+ def _set(self, key, value=None, ifunset=False):
+ index = self._search(key)
+ if index < 0:
+ index = -index - 1
+ self._keys.insert(index, key)
+ return True, None
+ return False, None
+
+ def _del(self, key):
+ index = self._search(key)
+ if index >= 0:
+ self._p_changed = True
+ del self._keys[index]
+ return 0, 0
+ raise KeyError(key)
+
+ def __getitem__(self, i):
+ return self._keys[i]
+
+ def _split(self, index=-1):
+ if index < 0 or index >= len(self._keys):
+ index = len(self._keys) / 2
+ new_instance = self.__class__()
+ new_instance._keys = self._keys[index:]
+ del self._keys[index:]
+ new_instance._next = self._next
+ self._next = new_instance
+ return new_instance
+
+ def _p_resolveConflict(self, s_old, s_com, s_new):
+
+ b_old = self.__class__()
+ if s_old is not None:
+ b_old.__setstate__(s_old)
+ b_com = self.__class__()
+ if s_com is not None:
+ b_com.__setstate__(s_com)
+ b_new = self.__class__()
+ if s_new is not None:
+ b_new.__setstate__(s_new)
+
+ if (b_com._next != b_old._next or
+ b_new._next != b_old._next): # conflict: com or new changed _next
+ raise BTreesConflictError(-1, -1, -1, 0)
+
+ if not b_com or not b_new: # conflict: com or new empty
+ raise BTreesConflictError(-1, -1, -1, 12)
+
+ i_old = _SetIteration(b_old, True)
+ i_com = _SetIteration(b_com, True)
+ i_new = _SetIteration(b_new, True)
+
+ def merge_error(reason):
+ return BTreesConflictError(
+ i_old.position, i_com.position, i_new.position, reason)
+
+ result = self.__class__()
+
+ def merge_output(it):
+ result._keys.append(it.key)
+ it.advance()
+
+ while i_old.active and i_com.active and i_new.active:
+ cmpOC = cmp(i_old.key, i_com.key)
+ cmpON = cmp(i_old.key, i_new.key)
+ if cmpOC == 0:
+ if cmpON == 0: # all match
+ merge_output(i_old)
+ i_com.advance()
+ i_new.advance()
+ elif cmpON > 0: # insert in new
+ merge_output(i_new)
+ else: # deleted new
+ if i_new.position == 1:
+ # Deleted the first item. This will modify the
+ # parent node, so we don't know if merging will be
+ # safe
+ raise merge_error(13)
+ i_old.advance()
+ i_com.advance()
+ elif cmpON == 0:
+ if cmpOC > 0: # insert committed
+ merge_output(i_com)
+ else: # delete committed
+ if i_com.position == 1:
+ # Deleted the first item. This will modify the
+ # parent node, so we don't know if merging will be
+ # safe
+ raise merge_error(13)
+ i_old.advance()
+ i_new.advance()
+ else: # both com and new keys changed
+ cmpCN = cmp(i_com.key, i_new.key)
+ if cmpCN == 0: # both inserted same key
+ raise merge_error(4)
+ if cmpOC > 0: # insert committed
+ if cmpCN > 0: # insert i_new first
+ merge_output(i_new)
+ else:
+ merge_output(i_com)
+ elif cmpON > 0: # insert i_new
+ merge_output(i_new)
+ else: # both com and new deleted same key
+ raise merge_error(5)
+
+ while i_com.active and i_new.active: # new inserts
+ cmpCN = cmp(i_com.key, i_new.key)
+ if cmpCN == 0: # dueling insert
+ raise merge_error(6)
+ if cmpCN > 0: # insert new
+ merge_output(i_new)
+ else: # insert committed
+ merge_output(i_com)
+
+ while i_old.active and i_com.active: # new deletes rest of original
+ cmpOC = cmp(i_old.key, i_com.key)
+ if cmpOC > 0: # insert committed
+ merge_output(i_com)
+ elif cmpOC == 0: # del in new
+ i_old.advance()
+ i_com.advance()
+ else: # dueling deletes or delete and change
+ raise merge_error(7)
+
+ while i_old.active and i_new.active:
+ # committed deletes rest of original
+ cmpON = cmp(i_old.key, i_new.key)
+ if cmpON > 0: # insert new
+ merge_output(i_new)
+ elif cmpON == 0: # deleted in committed
+ i_old.advance()
+ i_new.advance()
+ else: # dueling deletes or delete and change
+ raise merge_error(8)
+
+ if i_old.active: # dueling deletes
+ raise merge_error(9)
+
+ while i_com.active:
+ merge_output(i_com)
+
+ while i_new.active:
+ merge_output(i_new)
+
+ if len(result._keys) == 0: #pragma NO COVER
+ # If the output bucket is empty, conflict resolution doesn't have
+ # enough info to unlink it from its containing BTree correctly.
+ #
+ # XXX TS, 2012-11-16: I don't think this is possible
+ #
+ raise merge_error(10)
+
+ result._next = b_old._next
+ return result.__getstate__()
+
+
+class _TreeItem(object):
+
+ __slots__ = ('key',
+ 'child',
+ )
+
+ def __init__(self, key, child):
+ self.key = key
+ self.child = child
+
+
+class _Tree(_Base):
+
+ __slots__ = ('_data',
+ '_firstbucket',
+ )
+
+ def setdefault(self, key, value):
+ return self._set(self._to_key(key), self._to_value(value), True)[1]
+
+ def pop(self, key, default=_marker):
+ try:
+ return self._del(self._to_key(key))[1]
+ except KeyError:
+ if default is _marker:
+ raise
+ return default
+
+ def update(self, items):
+ if hasattr(items, 'iteritems'):
+ items = items.iteritems()
+ elif hasattr(items, 'items'):
+ items = items.items()
+
+ set = self.__setitem__
+ for i in items:
+ set(*i)
+
+ def __setitem__(self, key, value):
+ # Enforce test that key has non-default comparison.
+ if ( getattr(key, '__lt__', None) is None and
+ getattr(key, '__cmp__', None) is None):
+ raise TypeError("Can't use default __cmp__")
+ self._set(self._to_key(key), self._to_value(value))
+
+ def __delitem__(self, key):
+ self._del(self._to_key(key))
+
+ def clear(self):
+ self._data = []
+ self._firstbucket = None
+
+ def __nonzero__(self):
+ return bool(self._data)
+
+ def __len__(self):
+ l = 0
+ bucket = self._firstbucket
+ while bucket is not None:
+ l += len(bucket._keys)
+ bucket = bucket._next
+ return l
+
+ @property
+ def size(self):
+ return len(self._data)
+
+ def _search(self, key):
+ data = self._data
+ if data:
+ lo = 0
+ hi = len(data)
+ i = hi//2
+ while i > lo:
+ cmp_ = cmp(data[i].key, key)
+ if cmp_ < 0:
+ lo = i
+ elif cmp_ > 0:
+ hi = i
+ else:
+ break
+ i = (lo+hi)//2
+ return i
+ return -1
+
+ def _findbucket(self, key):
+ index = self._search(key)
+ if index >= 0:
+ child = self._data[index].child
+ if isinstance(child, self._bucket_type):
+ return child
+ return child._findbucket(key)
+
+ def __contains__(self, key):
+ return key in (self._findbucket(self._to_key(key)) or ())
+
+ def has_key(self, key):
+ index = self._search(key)
+ if index < 0:
+ return False
+ r = self._data[index].child.has_key(key)
+ return r and r + 1
+
+ def keys(self, min=_marker, max=_marker,
+ excludemin=False, excludemax=False,
+ itertype='iterkeys'):
+ if not self._data:
+ return ()
+
+ if min != _marker:
+ min = self._to_key(min)
+ bucket = self._findbucket(min)
+ else:
+ bucket = self._firstbucket
+
+ iterargs = min, max, excludemin, excludemax
+
+ return _TreeItems(bucket, itertype, iterargs)
+
+ def iterkeys(self, min=_marker, max=_marker,
+ excludemin=False, excludemax=False):
+ return iter(self.keys(min, max, excludemin, excludemax))
+
+ def __iter__(self):
+ return iter(self.keys())
+
+ def minKey(self, min=_marker):
+ if min is _marker:
+ bucket = self._firstbucket
+ else:
+ min = self._to_key(min)
+ bucket = self._findbucket(min)
+ if bucket is not None:
+ return bucket.minKey(min)
+ raise ValueError('empty tree')
+
+ def maxKey(self, max=_marker):
+ data = self._data
+ if not data:
+ raise ValueError('empty tree')
+ if max is _marker:
+ return data[-1].child.maxKey()
+
+ max = self._to_key(max)
+ index = self._search(max)
+ if index and data[index].child.minKey() > max:
+ index -= 1 #pragma NO COVER no idea how to provoke this
+ return data[index].child.maxKey(max)
+
+
+ def _set(self, key, value=None, ifunset=False):
+ if (self._p_jar is not None and
+ self._p_oid is not None and
+ self._p_serial is not None):
+ self._p_jar.readCurrent(self)
+ data = self._data
+ if data:
+ index = self._search(key)
+ child = data[index].child
+ else:
+ index = 0
+ child = self._bucket_type()
+ self._firstbucket = child
+ data.append(_TreeItem(None, child))
+
+ result = child._set(key, value, ifunset)
+ grew = result[0]
+ if grew and child.size > child.MAX_SIZE:
+ self._grow(child, index)
+ elif (grew is not None and
+ child.__class__ is self._bucket_type and
+ len(data) == 1 and
+ child._p_oid is None
+ ):
+ self._p_changed = 1
+ return result
+
+ def _grow(self, child, index):
+ self._p_changed = True
+ new_child = child._split()
+ self._data.insert(index+1, _TreeItem(new_child.minKey(), new_child))
+ if len(self._data) > self.MAX_SIZE * 2:
+ self._split_root()
+
+ def _split_root(self):
+ child = self.__class__()
+ child._data = self._data
+ child._firstbucket = self._firstbucket
+ self._data = [_TreeItem(None, child)]
+ self._grow(child, 0)
+
+ def _split(self, index=None):
+ data = self._data
+ if index is None:
+ index = len(data)//2
+
+ next = self.__class__()
+ next._data = data[index:]
+ first = data[index]
+ del data[index:]
+ if len(data) == 0:
+ self._firstbucket = None # lost our bucket, can't buy no beer
+ if isinstance(first.child, self.__class__):
+ next._firstbucket = first.child._firstbucket
+ else:
+ next._firstbucket = first.child;
+ return next
+
+ def _del(self, key):
+ if (self._p_jar is not None and
+ self._p_oid is not None and
+ self._p_serial is not None):
+ self._p_jar.readCurrent(self)
+
+ data = self._data
+ if not data:
+ raise KeyError(key)
+
+ index = self._search(key)
+ child = data[index].child
+
+ removed_first_bucket, value = child._del(key)
+
+ # fix up the node key, but not for the 0'th one.
+ if index > 0 and child.size and key == data[index].key:
+ self._p_changed = True
+ data[index].key = child.minKey()
+
+ if removed_first_bucket:
+ if index:
+ data[index-1].child._deleteNextBucket()
+ removed_first_bucket = False # clear flag
+ else:
+ self._firstbucket = child._firstbucket
+
+ if not child.size:
+ if child.__class__ is self._bucket_type:
+ if index:
+ data[index-1].child._deleteNextBucket()
+ else:
+ self._firstbucket = child._next
+ removed_first_bucket = True
+ del data[index]
+
+ return removed_first_bucket, value
+
+ def _deleteNextBucket(self):
+ self._data[-1].child._deleteNextBucket()
+
+ def __getstate__(self):
+ data = self._data
+
+ if not data:
+ return None
+
+ if (len(data) == 1 and
+ data[0].child.__class__ is not self.__class__ and
+ data[0].child._p_oid is None
+ ):
+ return ((data[0].child.__getstate__(), ), )
+
+ sdata = []
+ for item in data:
+ if sdata:
+ sdata.append(item.key)
+ sdata.append(item.child)
+ else:
+ sdata.append(item.child)
+
+ return tuple(sdata), self._firstbucket
+
+ def __setstate__(self, state):
+ if state and not isinstance(state[0], tuple):
+ raise TypeError('tuple required for first state element')
+
+ self.clear()
+ if state is None:
+ return
+
+ if len(state) == 1:
+ bucket = self._bucket_type()
+ bucket.__setstate__(state[0][0])
+ state = [bucket], bucket
+
+ data, self._firstbucket = state
+ data = list(reversed(data))
+
+ self._data.append(_TreeItem(None, data.pop()))
+ while data:
+ key = data.pop()
+ child = data.pop()
+ self._data.append(_TreeItem(key, child))
+
+ def _assert(self, condition, message):
+ if not condition:
+ raise AssertionError(message)
+
+ def _check(self, nextbucket=None):
+ data = self._data
+ assert_ = self._assert
+ if not data:
+ assert_(self._firstbucket is None,
+ "Empty BTree has non-NULL firstbucket")
+ return
+ assert_(self._firstbucket is not None,
+ "Non-empty BTree has NULL firstbucket")
+
+ child_class = data[0].child.__class__
+ for i in data:
+ assert_(i.child is not None, "BTree has NULL child")
+ assert_(i.child.__class__ is child_class,
+ "BTree children have different types")
+ assert_(i.child.size, "Bucket length < 1")
+
+ if child_class is self.__class__:
+ assert_(self._firstbucket is data[0].child._firstbucket,
+ "BTree has firstbucket different than "
+ "its first child's firstbucket")
+ for i in range(len(data)-1):
+ data[i].child._check(data[i+1].child._firstbucket)
+ data[-1].child._check(nextbucket)
+ elif child_class is self._bucket_type:
+ assert_(self._firstbucket is data[0].child,
+ "Bottom-level BTree node has inconsistent firstbucket "
+ "belief")
+ for i in range(len(data)-1):
+ assert_(data[i].child._next is data[i+1].child,
+ "Bucket next pointer is damaged")
+ assert_(data[-1].child._next is nextbucket,
+ "Bucket next pointer is damaged")
+ else:
+ assert_(False, "Incorrect child type")
+
+ def _p_resolveConflict(self, old, com, new):
+ s_old = _get_simple_btree_bucket_state(old)
+ s_com = _get_simple_btree_bucket_state(com)
+ s_new = _get_simple_btree_bucket_state(new)
+ return ((
+ self._bucket_type()._p_resolveConflict(s_old, s_com, s_new), ), )
+
+
+def _get_simple_btree_bucket_state(state):
+ if state is None:
+ return state
+ if not isinstance(state, tuple):
+ raise TypeError("_p_resolveConflict: expected tuple or None for state")
+ if len(state) == 2: # non-degenerate BTree, can't resolve
+ raise BTreesConflictError(-1, -1, -1, 11)
+ # Peel away wrapper to get to only-bucket state.
+ if len(state) != 1:
+ raise TypeError("_p_resolveConflict: expected 1- or 2-tuple for state")
+ state = state[0]
+ if not isinstance(state, tuple) or len(state) != 1:
+ raise TypeError("_p_resolveConflict: expected 1-tuple containing "
+ "bucket state")
+ state = state[0]
+ if not isinstance(state, tuple):
+ raise TypeError("_p_resolveConflict: expected tuple for bucket state")
+ return state
+
+
+class _TreeItems(object):
+
+ __slots__ = ('firstbucket',
+ 'itertype',
+ 'iterargs',
+ 'index',
+ 'it',
+ 'v',
+ '_len',
+ )
+
+ def __init__(self, firstbucket, itertype, iterargs):
+ self.firstbucket = firstbucket
+ self.itertype = itertype
+ self.iterargs = iterargs
+ self.index = -1
+ self.it = iter(self)
+ self.v = None
+ self._len = None
+
+ def __getitem__(self, i):
+ if isinstance(i, slice):
+ return list(self)[i]
+ if i < 0:
+ i = len(self) + i
+ if i < 0:
+ raise IndexError(i)
+
+ if i < self.index:
+ self.index = -1
+ self.it = iter(self)
+
+ while i > self.index:
+ try:
+ self.v = self.it.next()
+ except StopIteration:
+ raise IndexError(i)
+ else:
+ self.index += 1
+ return self.v
+
+ def __len__(self):
+ if self._len is None:
+ i = 0
+ for _ in self:
+ i += 1
+ self._len = i
+ return self._len
+
+ def __iter__(self):
+ bucket = self.firstbucket
+ itertype = self.itertype
+ iterargs = self.iterargs
+ done = 0
+ # Note that we don't mind if the first bucket yields no
+ # results due to an idiosyncrasy in how range searches are done.
+ while bucket is not None:
+ for k in getattr(bucket, itertype)(*iterargs):
+ yield k
+ done = 0
+ if done:
+ return
+ bucket = bucket._next
+ done = 1
+
+
+class Tree(_Tree):
+
+ __slots__ = ()
+
+ def get(self, key, default=None):
+ bucket = self._findbucket(key)
+ if bucket:
+ return bucket.get(key, default)
+ return default
+
+ def __getitem__(self, key):
+ bucket = self._findbucket(key)
+ if bucket:
+ return bucket[key]
+ raise KeyError(key)
+
+ def values(self, min=_marker, max=_marker,
+ excludemin=False, excludemax=False):
+ return self.keys(min, max, excludemin, excludemax, 'itervalues')
+
+ def itervalues(self, min=_marker, max=_marker,
+ excludemin=False, excludemax=False):
+ return iter(self.values(min, max, excludemin, excludemax))
+
+ def items(self, min=_marker, max=_marker,
+ excludemin=False, excludemax=False):
+ return self.keys(min, max, excludemin, excludemax, 'iteritems')
+
+ def iteritems(self, min=_marker, max=_marker,
+ excludemin=False, excludemax=False):
+ return iter(self.items(min, max, excludemin, excludemax))
+
+ def byValue(self, min):
+ return sorted((v, k) for (k, v) in self.iteritems() if v >= min)
+
+ def insert(self, key, value):
+ return bool(self._set(key, value, True)[0])
+
+
+class TreeSet(_Tree):
+
+ __slots__ = ()
+
+ #_next = None
+ def add(self, key):
+ return self._set(self._to_key(key))[0]
+
+ insert = add
+
+ def remove(self, key):
+ self._del(self._to_key(key))
+
+ def update(self, items):
+ add = self.add
+ for i in items:
+ add(i)
+
+ _p_resolveConflict = _Tree._p_resolveConflict
+
+
+class set_operation(object):
+
+ __slots__ = ('func',
+ 'set_type',
+ )
+
+ def __init__(self, func, set_type):
+ self.func = func
+ self.set_type = set_type
+
+ def __call__(self, *a, **k):
+ return self.func(self.set_type, *a, **k)
+
+
+def difference(set_type, o1, o2):
+ if o1 is None or o2 is None:
+ return o1
+ i1 = _SetIteration(o1, True, 0)
+ i2 = _SetIteration(o2, False, 0)
+ if i1.useValues:
+ result = o1._mapping_type()
+ def copy(i):
+ result._keys.append(i.key)
+ result._values.append(i.value)
+ else:
+ result = o1._set_type()
+ def copy(i):
+ result._keys.append(i.key)
+ while i1.active and i2.active:
+ cmp_ = cmp(i1.key, i2.key)
+ if cmp_ < 0:
+ copy(i1)
+ i1.advance()
+ elif cmp_ == 0:
+ i1.advance()
+ i2.advance()
+ else:
+ i2.advance()
+ while i1.active:
+ copy(i1)
+ i1.advance()
+ return result
+
+def union(set_type, o1, o2):
+ if o1 is None:
+ return o2
+ if o2 is None:
+ return o1
+ i1 = _SetIteration(o1, False, 0)
+ i2 = _SetIteration(o2, False, 0)
+ result = o1._set_type()
+ def copy(i):
+ result._keys.append(i.key)
+ while i1.active and i2.active:
+ cmp_ = cmp(i1.key, i2.key)
+ if cmp_ < 0:
+ copy(i1)
+ i1.advance()
+ elif cmp_ == 0:
+ copy(i1)
+ i1.advance()
+ i2.advance()
+ else:
+ copy(i2)
+ i2.advance()
+ while i1.active:
+ copy(i1)
+ i1.advance()
+ while i2.active:
+ copy(i2)
+ i2.advance()
+ return result
+
+def intersection(set_type, o1, o2):
+ if o1 is None:
+ return o2
+ if o2 is None:
+ return o1
+ i1 = _SetIteration(o1, False, 0)
+ i2 = _SetIteration(o2, False, 0)
+ result = o1._set_type()
+ def copy(i):
+ result._keys.append(i.key)
+ while i1.active and i2.active:
+ cmp_ = cmp(i1.key, i2.key)
+ if cmp_ < 0:
+ i1.advance()
+ elif cmp_ == 0:
+ copy(i1)
+ i1.advance()
+ i2.advance()
+ else:
+ i2.advance()
+ return result
+
+def weightedUnion(set_type, o1, o2, w1=1, w2=1):
+ if o1 is None:
+ if o2 is None:
+ return 0, None
+ return w2, o2
+ if o2 is None:
+ return w1, o1
+ MERGE_DEFAULT = getattr(o1, 'MERGE_DEFAULT', None)
+ i1 = _SetIteration(o1, True, MERGE_DEFAULT)
+ i2 = _SetIteration(o2, True, MERGE_DEFAULT)
+ MERGE = getattr(o1, 'MERGE', None)
+ if MERGE is None and i1.useValues and i2.useValues:
+ raise TypeError("invalid set operation")
+ MERGE_WEIGHT = getattr(o1, 'MERGE_WEIGHT')
+ if (not i1.useValues) and i2.useValues:
+ i1, i2 = i2, i1
+ w1, w2 = w2, w1
+ if MERGE_DEFAULT is None:
+ if i1.useValues:
+ if (not i2.useValues):
+ raise TypeError("invalid set operation")
+ else:
+ raise TypeError("invalid set operation")
+ _merging = i1.useValues or i2.useValues
+ if _merging:
+ result = o1._mapping_type()
+ def copy(i, w):
+ result._keys.append(i.key)
+ result._values.append(MERGE_WEIGHT(i.value, w))
+ else:
+ result = o1._set_type()
+ def copy(i, w):
+ result._keys.append(i.key)
+
+ while i1.active and i2.active:
+ cmp_ = cmp(i1.key, i2.key)
+ if cmp_ < 0:
+ copy(i1, w1)
+ i1.advance()
+ elif cmp_ == 0:
+ result._keys.append(i1.key)
+ if _merging:
+ result._values.append(MERGE(i1.value, w1, i2.value, w2))
+ i1.advance()
+ i2.advance()
+ else:
+ copy(i2, w2)
+ i2.advance()
+ while i1.active:
+ copy(i1, w1)
+ i1.advance()
+ while i2.active:
+ copy(i2, w2)
+ i2.advance()
+ return 1, result
+
+def weightedIntersection(set_type, o1, o2, w1=1, w2=1):
+ if o1 is None:
+ if o2 is None:
+ return 0, None
+ return w2, o2
+ if o2 is None:
+ return w1, o1
+ MERGE_DEFAULT = getattr(o1, 'MERGE_DEFAULT', None)
+ i1 = _SetIteration(o1, True, MERGE_DEFAULT)
+ i2 = _SetIteration(o2, True, MERGE_DEFAULT)
+ MERGE = getattr(o1, 'MERGE', None)
+ if MERGE is None and i1.useValues and i2.useValues:
+ raise TypeError("invalid set operation")
+ MERGE_WEIGHT = getattr(o1, 'MERGE_WEIGHT')
+ if (not i1.useValues) and i2.useValues:
+ i1, i2 = i2, i1
+ w1, w2 = w2, w1
+ if MERGE_DEFAULT is None:
+ if i1.useValues:
+ if (not i2.useValues):
+ raise TypeError("invalid set operation")
+ else:
+ raise TypeError("invalid set operation")
+ _merging = i1.useValues or i2.useValues
+ if _merging:
+ result = o1._mapping_type()
+ else:
+ result = o1._set_type()
+ while i1.active and i2.active:
+ cmp_ = cmp(i1.key, i2.key)
+ if cmp_ < 0:
+ i1.advance()
+ elif cmp_ == 0:
+ result._keys.append(i1.key)
+ if _merging:
+ result._values.append(MERGE(i1.value, w1, i2.value, w2))
+ i1.advance()
+ i2.advance()
+ else:
+ i2.advance()
+ if isinstance(result, (Set, TreeSet)):
+ return w1 + w2, result
+ return 1, result
+
+def multiunion(set_type, seqs):
+ # XXX simple/slow implementation. Goal is just to get tests to pass.
+ result = set_type()
+ for s in seqs:
+ try:
+ iter(s)
+ except TypeError:
+ s = set_type((s, ))
+ result.update(s)
+ return result
+
+def to_ob(self, v):
+ return v
+
+int_types = int, long
+def to_int(self, v):
+ try:
+ # XXX Python 2.6 doesn't truncate, it spews a warning.
+ if not unpack("i", pack("i", v))[0] == v: #pragma NO COVER
+ raise TypeError('32-bit integer expected')
+ except (struct_error,
+ OverflowError, #PyPy
+ ):
+ raise TypeError('32-bit integer expected')
+
+ return int(v)
+
+def to_float(self, v):
+ try:
+ pack("f", v)
+ except struct_error:
+ raise TypeError('float expected')
+ return float(v)
+
+def to_long(self, v):
+ try:
+ # XXX Python 2.6 doesn't truncate, it spews a warning.
+ if not unpack("q", pack("q", v))[0] == v: #pragma NO COVER
+ if isinstance(v, int_types):
+ raise ValueError("Value out of range", v)
+ raise TypeError('64-bit integer expected')
+ except (struct_error,
+ OverflowError, #PyPy
+ ):
+ if isinstance(v, int_types):
+ raise ValueError("Value out of range", v)
+ raise TypeError('64-bit integer expected')
+
+ return int(v)
+
+def to_str(l):
+ def to(self, v):
+ if not (isinstance(v, str) and len(v) == l):
+ raise TypeError("%s-character string expected" % l)
+ return v
+ return to
+
+tos = dict(I=to_int, L=to_long, F=to_float, O=to_ob)
+
+MERGE_DEFAULT_int = 1
+MERGE_DEFAULT_float = 1.0
+
+def MERGE(self, value1, weight1, value2, weight2):
+ return (value1 * weight1) + (value2 * weight2)
+
+def MERGE_WEIGHT_default(self, value, weight):
+ return value
+
+def MERGE_WEIGHT_numeric(self, value, weight):
+ return value * weight
Modified: BTrees/trunk/BTrees/check.py
===================================================================
--- BTrees/trunk/BTrees/check.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/check.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -32,15 +32,24 @@
that doesn't exist in the actual BTree).
"""
-from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
+from BTrees.IFBTree import IFBTree, IFBucket, IFSet, IFTreeSet
+from BTrees.IFBTree import IFBTreePy, IFBucketPy, IFSetPy, IFTreeSetPy
+from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
+from BTrees.IIBTree import IIBTreePy, IIBucketPy, IISetPy, IITreeSetPy
+from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
+from BTrees.IOBTree import IOBTreePy, IOBucketPy, IOSetPy, IOTreeSetPy
+from BTrees.LFBTree import LFBTree, LFBucket, LFSet, LFTreeSet
+from BTrees.LFBTree import LFBTreePy, LFBucketPy, LFSetPy, LFTreeSetPy
+from BTrees.LLBTree import LLBTree, LLBucket, LLSet, LLTreeSet
+from BTrees.LLBTree import LLBTreePy, LLBucketPy, LLSetPy, LLTreeSetPy
+from BTrees.LOBTree import LOBTree, LOBucket, LOSet, LOTreeSet
+from BTrees.LOBTree import LOBTreePy, LOBucketPy, LOSetPy, LOTreeSetPy
from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
-from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
-from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
-from BTrees.IFBTree import IFBTree, IFBucket, IFSet, IFTreeSet
+from BTrees.OIBTree import OIBTreePy, OIBucketPy, OISetPy, OITreeSetPy
from BTrees.OLBTree import OLBTree, OLBucket, OLSet, OLTreeSet
-from BTrees.LOBTree import LOBTree, LOBucket, LOSet, LOTreeSet
-from BTrees.LLBTree import LLBTree, LLBucket, LLSet, LLTreeSet
-from BTrees.LFBTree import LFBTree, LFBucket, LFSet, LFTreeSet
+from BTrees.OLBTree import OLBTreePy, OLBucketPy, OLSetPy, OLTreeSetPy
+from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
+from BTrees.OOBTree import OOBTreePy, OOBucketPy, OOSetPy, OOTreeSetPy
from BTrees.utils import positive_id
from BTrees.utils import oid_repr
@@ -59,6 +68,9 @@
('Set', (TYPE_BUCKET, False)),
):
_type2kind[globals()[kv+name]] = kind
+ py = kv + name + 'Py'
+ if py in globals():
+ _type2kind[globals()[py]] = kind
# Return pair
#
@@ -114,8 +126,15 @@
'LL', 'LO', 'OL', 'LF',
):
_btree2bucket[globals()[kv+'BTree']] = globals()[kv+'Bucket']
+ py = kv + 'BTreePy'
+ if py in globals():
+ _btree2bucket[globals()[py]] = globals()[kv+'BucketPy']
_btree2bucket[globals()[kv+'TreeSet']] = globals()[kv+'Set']
+ py = kv + 'TreeSetPy'
+ if py in globals():
+ _btree2bucket[globals()[kv+'TreeSetPy']] = globals()[kv+'SetPy']
+
def crack_btree(t, is_mapping):
state = t.__getstate__()
if state is None:
@@ -349,7 +368,7 @@
".".join(map(str, path)))
self.errors.append(s)
-class Printer(Walker):
+class Printer(Walker): #pragma NO COVER
def __init__(self, obj):
Walker.__init__(self, obj)
@@ -403,6 +422,6 @@
Checker(btree).check()
-def display(btree):
+def display(btree): #pragma NO COVER
"Display the internal structure of a BTree, Bucket, TreeSet or Set."
Printer(btree).display()
Modified: BTrees/trunk/BTrees/fsBTree.py
===================================================================
--- BTrees/trunk/BTrees/fsBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/fsBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,6 +1,6 @@
##############################################################################
#
-# Copyright (c) 2001, 2002 Zope Foundation and Contributors.
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
@@ -15,5 +15,119 @@
# fsBTrees are data structures used for ZODB FileStorage. They are not
# expected to be "public" excpect to FileStorage.
-# hack to overcome dynamic-linking headache.
-from _fsBTree import *
+__all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
+ 'fsBucket', 'fsSet', 'fsBTree', 'fsTreeSet',
+ 'union', 'intersection', 'difference', 'multiunion',
+ )
+
+
+from zope.interface import moduleProvides
+
+from .Interfaces import IIntegerObjectBTreeModule
+from ._base import Bucket
+from ._base import Set
+from ._base import Tree as BTree
+from ._base import TreeSet
+from ._base import difference as _difference
+from ._base import intersection as _intersection
+from ._base import multiunion as _multiunion
+from ._base import set_operation as _set_operation
+from ._base import to_str as _to_str
+from ._base import union as _union
+
+_BUCKET_SIZE = 500
+_TREE_SIZE = 500
+using64bits = False
+_to_key = _to_str(2)
+_to_value = _to_str(6)
+
+
+class fsBucketPy(Bucket):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+
+ def MERGE_WEIGHT(self, value, weight):
+ return value
+
+ def toString(self):
+ return ''.join(self._keys) + ''.join(self._values)
+
+ def fromString(self, v):
+ length = len(v)
+ if length % 8 != 0:
+ raise ValueError()
+ count = length // 8
+ keys, values = v[:count*2], v[count*2:]
+ self.clear()
+ while keys and values:
+ key, keys = keys[:2], keys[2:]
+ value, values = values[:6], values[6:]
+ self._keys.append(key)
+ self._values.append(value)
+ return self
+
+
+class fsSetPy(Set):
+ MAX_SIZE = _BUCKET_SIZE
+ _to_key = _to_key
+
+
+class fsBTreePy(BTree):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+ _to_value = _to_value
+ def MERGE_WEIGHT(self, value, weight):
+ return value
+
+
+class fsTreeSetPy(TreeSet):
+ MAX_SIZE = _TREE_SIZE
+ _to_key = _to_key
+
+
+# Can't declare forward refs, so fix up afterwards:
+
+fsBucketPy._mapping_type = fsBucketPy._bucket_type = fsBucketPy
+fsBucketPy._set_type = fsSetPy
+
+fsSetPy._mapping_type = fsBucketPy
+fsSetPy._set_type = fsSetPy._bucket_type = fsSetPy
+
+fsBTreePy._mapping_type = fsBTreePy._bucket_type = fsBucketPy
+fsBTreePy._set_type = fsSetPy
+
+fsTreeSetPy._mapping_type = fsBucketPy
+fsTreeSetPy._set_type = fsTreeSetPy._bucket_type = fsSetPy
+
+
+differencePy = _set_operation(_difference, fsSetPy)
+unionPy = _set_operation(_union, fsSetPy)
+intersectionPy = _set_operation(_intersection, fsSetPy)
+multiunionPy = _set_operation(_multiunion, fsSetPy)
+
+try:
+ from _fsBTree import fsBucket
+ from _fsBTree import fsSet
+ from _fsBTree import fsBTree
+ from _fsBTree import fsTreeSet
+ from _fsBTree import difference
+ from _fsBTree import union
+ from _fsBTree import intersection
+ from _fsBTree import multiunion
+except ImportError: #pragma NO COVER
+ fsBucket = fsBucketPy
+ fsSet = fsSetPy
+ fsBTree = fsBTreePy
+ fsTreeSet = fsTreeSetPy
+ difference = differencePy
+ union = unionPy
+ intersection = intersectionPy
+ multiunion = multiunionPy
+
+Bucket = fsBucket
+Set = fsSet
+BTree = fsBTree
+TreeSet = fsTreeSet
+
+moduleProvides(IIntegerObjectBTreeModule)
Copied: BTrees/trunk/BTrees/tests/common.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/common.py)
===================================================================
--- BTrees/trunk/BTrees/tests/common.py (rev 0)
+++ BTrees/trunk/BTrees/tests/common.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,2165 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+
+def _skip_wo_ZODB(test_method): #pragma NO COVER
+ try:
+ import ZODB
+ except ImportError: # skip this test if ZODB is not available
+ def _dummy(*args):
+ pass
+ return _dummy
+ else:
+ return test_method
+
+
+class Base(object):
+ # Tests common to all types: sets, buckets, and BTrees
+
+ db = None
+
+ def _makeOne(self):
+ return self._getTargetClass()()
+
+
+ def tearDown(self):
+ if self.db is not None:
+ self.db.close()
+
+ def _getRoot(self):
+ from ZODB import DB
+ from ZODB.MappingStorage import MappingStorage
+ if self.db is None:
+ # Unclear: On the next line, the ZODB4 flavor of this routine
+ # [asses a cache_size argument:
+ # self.db = DB(MappingStorage(), cache_size=1)
+ # If that's done here, though, testLoadAndStore() and
+ # testGhostUnghost() both nail the CPU and seemingly
+ # never finish.
+ self.db = DB(MappingStorage())
+ return self.db.open().root()
+
+ def _closeRoot(self, root):
+ root._p_jar.close()
+
+ @_skip_wo_ZODB
+ def testLoadAndStore(self):
+ import transaction
+ for i in 0, 10, 1000:
+ t = self._makeOne()
+ self._populate(t, i)
+ root = None
+ root = self._getRoot()
+ root[i] = t
+ transaction.commit()
+
+ root2 = self._getRoot()
+ if hasattr(t, 'items'):
+ self.assertEqual(list(root2[i].items()) , list(t.items()))
+ else:
+ self.assertEqual(list(root2[i].keys()) , list(t.keys()))
+
+ self._closeRoot(root)
+ self._closeRoot(root2)
+
+ def testSetstateArgumentChecking(self):
+ try:
+ self._makeOne().__setstate__(('',))
+ except TypeError, v:
+ self.assertEqual(str(v), 'tuple required for first state element')
+ else:
+ raise AssertionError("Expected exception")
+
+ @_skip_wo_ZODB
+ def testGhostUnghost(self):
+ import transaction
+ for i in 0, 10, 1000:
+ t = self._makeOne()
+ self._populate(t, i)
+ root = self._getRoot()
+ root[i] = t
+ transaction.commit()
+
+ root2 = self._getRoot()
+ root2[i]._p_deactivate()
+ transaction.commit()
+ if hasattr(t, 'items'):
+ self.assertEqual(list(root2[i].items()) , list(t.items()))
+ else:
+ self.assertEqual(list(root2[i].keys()) , list(t.keys()))
+
+ self._closeRoot(root)
+ self._closeRoot(root2)
+
+ def testSimpleExclusiveKeyRange(self):
+ t = self._makeOne()
+ self.assertEqual(list(t.keys()), [])
+ self.assertEqual(list(t.keys(excludemin=True)), [])
+ self.assertEqual(list(t.keys(excludemax=True)), [])
+ self.assertEqual(list(t.keys(excludemin=True, excludemax=True)), [])
+
+ self._populate(t, 1)
+ self.assertEqual(list(t.keys()), [0])
+ self.assertEqual(list(t.keys(excludemin=True)), [])
+ self.assertEqual(list(t.keys(excludemax=True)), [])
+ self.assertEqual(list(t.keys(excludemin=True, excludemax=True)), [])
+
+ t.clear()
+ self._populate(t, 2)
+ self.assertEqual(list(t.keys()), [0, 1])
+ self.assertEqual(list(t.keys(excludemin=True)), [1])
+ self.assertEqual(list(t.keys(excludemax=True)), [0])
+ self.assertEqual(list(t.keys(excludemin=True, excludemax=True)), [])
+
+ t.clear()
+ self._populate(t, 3)
+ self.assertEqual(list(t.keys()), [0, 1, 2])
+ self.assertEqual(list(t.keys(excludemin=True)), [1, 2])
+ self.assertEqual(list(t.keys(excludemax=True)), [0, 1])
+ self.assertEqual(list(t.keys(excludemin=True, excludemax=True)), [1])
+
+ self.assertEqual(list(t.keys(-1, 3, excludemin=True, excludemax=True)),
+ [0, 1, 2])
+ self.assertEqual(list(t.keys(0, 3, excludemin=True, excludemax=True)),
+ [1, 2])
+ self.assertEqual(list(t.keys(-1, 2, excludemin=True, excludemax=True)),
+ [0, 1])
+ self.assertEqual(list(t.keys(0, 2, excludemin=True, excludemax=True)),
+ [1])
+
+ @_skip_wo_ZODB
+ def test_UpdatesDoReadChecksOnInternalNodes(self):
+ import transaction
+ from ZODB import DB
+ from ZODB.MappingStorage import MappingStorage
+ t = self._makeOne()
+ if not hasattr(t, '_firstbucket'):
+ return
+ self._populate(t, 1000)
+ store = MappingStorage()
+ db = DB(store)
+ conn = db.open()
+ conn.root.t = t
+ transaction.commit()
+
+ read = []
+ def readCurrent(ob):
+ read.append(ob)
+ conn.__class__.readCurrent(conn, ob)
+ return 1
+
+ conn.readCurrent = readCurrent
+
+ try:
+ add = t.add
+ remove = t.remove
+ except AttributeError:
+ def add(i):
+ t[i] = i
+ def remove(i):
+ del t[i]
+
+ # Modifying a thing
+ remove(100)
+ self.assert_(t in read)
+ del read[:]
+ add(100)
+ self.assert_(t in read)
+ del read[:]
+
+ transaction.abort()
+ conn.cacheMinimize()
+ list(t)
+ self.assert_(100 in t)
+ self.assert_(not read)
+
+
+class MappingBase(Base):
+ # Tests common to mappings (buckets, btrees)
+
+ def _populate(self, t, l):
+ # Make some data
+ for i in range(l): t[i]=i
+
+ def testRepr(self):
+ # test the repr because buckets have a complex repr implementation
+ # internally the cutoff from a stack allocated buffer to a heap
+ # allocated buffer is 10000.
+ t = self._makeOne()
+ for i in range(1000):
+ t[i] = i
+ r = repr(t)
+ # Make sure the repr is 10000 bytes long for a bucket.
+ # But since the test is also run for btrees, skip the length
+ # check if the repr starts with '<'
+ if not r.startswith('<'):
+ self.assert_(len(r) > 10000)
+
+ def testGetItemFails(self):
+ self.assertRaises(KeyError, self._getitemfail)
+
+ def _getitemfail(self):
+ return self._makeOne()[1]
+
+ def testGetReturnsDefault(self):
+ self.assertEqual(self._makeOne().get(1) , None)
+ self.assertEqual(self._makeOne().get(1, 'foo') , 'foo')
+
+ def testSetItemGetItemWorks(self):
+ t = self._makeOne()
+ t[1] = 1
+ a = t[1]
+ self.assertEqual(a , 1, `a`)
+
+ def testReplaceWorks(self):
+ t = self._makeOne()
+ t[1] = 1
+ self.assertEqual(t[1] , 1, t[1])
+ t[1] = 2
+ self.assertEqual(t[1] , 2, t[1])
+
+ def testLen(self):
+ import random
+ t = self._makeOne()
+ added = {}
+ r = range(1000)
+ for x in r:
+ k = random.choice(r)
+ t[k] = x
+ added[k] = x
+ addl = added.keys()
+ self.assertEqual(len(t) , len(addl), len(t))
+
+ def testHasKeyWorks(self):
+ t = self._makeOne()
+ t[1] = 1
+ self.assert_(t.has_key(1))
+ self.assert_(1 in t)
+ self.assert_(0 not in t)
+ self.assert_(2 not in t)
+
+ def testValuesWorks(self):
+ t = self._makeOne()
+ for x in range(100):
+ t[x] = x*x
+ v = t.values()
+ for i in range(100):
+ self.assertEqual(v[i], i*i)
+ self.assertRaises(IndexError, lambda: v[i+1])
+ i = 0
+ for value in t.itervalues():
+ self.assertEqual(value, i*i)
+ i += 1
+
+ def testValuesWorks1(self):
+ t = self._makeOne()
+ for x in range(100):
+ t[99-x] = x
+
+ for x in range(40):
+ lst = list(t.values(0+x,99-x))
+ lst.sort()
+ self.assertEqual(lst,range(0+x,99-x+1))
+
+ lst = list(t.values(max=99-x, min=0+x))
+ lst.sort()
+ self.assertEqual(lst,range(0+x,99-x+1))
+
+ def testValuesNegativeIndex(self):
+ t = self._makeOne()
+ L = [-3, 6, -11, 4]
+ for i in L:
+ t[i] = i
+ L.sort()
+ vals = t.values()
+ for i in range(-1, -5, -1):
+ self.assertEqual(vals[i], L[i])
+ self.assertRaises(IndexError, lambda: vals[-5])
+
+ def testKeysWorks(self):
+ t = self._makeOne()
+ for x in range(100):
+ t[x] = x
+ v = t.keys()
+ i = 0
+ for x in v:
+ self.assertEqual(x,i)
+ i = i + 1
+ self.assertRaises(IndexError, lambda: v[i])
+
+ for x in range(40):
+ lst = t.keys(0+x,99-x)
+ self.assertEqual(list(lst), range(0+x, 99-x+1))
+
+ lst = t.keys(max=99-x, min=0+x)
+ self.assertEqual(list(lst), range(0+x, 99-x+1))
+
+ self.assertEqual(len(v), 100)
+
+ def testKeysNegativeIndex(self):
+ t = self._makeOne()
+ L = [-3, 6, -11, 4]
+ for i in L:
+ t[i] = i
+ L.sort()
+ keys = t.keys()
+ for i in range(-1, -5, -1):
+ self.assertEqual(keys[i], L[i])
+ self.assertRaises(IndexError, lambda: keys[-5])
+
+ def testItemsWorks(self):
+ t = self._makeOne()
+ for x in range(100):
+ t[x] = 2*x
+ v = t.items()
+ i = 0
+ for x in v:
+ self.assertEqual(x[0], i)
+ self.assertEqual(x[1], 2*i)
+ i += 1
+ self.assertRaises(IndexError, lambda: v[i+1])
+
+ i = 0
+ for x in t.iteritems():
+ self.assertEqual(x, (i, 2*i))
+ i += 1
+
+ items = list(t.items(min=12, max=20))
+ self.assertEqual(items, zip(range(12, 21), range(24, 43, 2)))
+
+ items = list(t.iteritems(min=12, max=20))
+ self.assertEqual(items, zip(range(12, 21), range(24, 43, 2)))
+
+ def testItemsNegativeIndex(self):
+ t = self._makeOne()
+ L = [-3, 6, -11, 4]
+ for i in L:
+ t[i] = i
+ L.sort()
+ items = t.items()
+ for i in range(-1, -5, -1):
+ self.assertEqual(items[i], (L[i], L[i]))
+ self.assertRaises(IndexError, lambda: items[-5])
+
+ def testDeleteInvalidKeyRaisesKeyError(self):
+ self.assertRaises(KeyError, self._deletefail)
+
+ def _deletefail(self):
+ t = self._makeOne()
+ del t[1]
+
+ def testMaxKeyMinKey(self):
+ t = self._makeOne()
+ t[7] = 6
+ t[3] = 10
+ t[8] = 12
+ t[1] = 100
+ t[5] = 200
+ t[10] = 500
+ t[6] = 99
+ t[4] = 150
+ del t[7]
+ self.assertEqual(t.maxKey(), 10)
+ self.assertEqual(t.maxKey(6), 6)
+ self.assertEqual(t.maxKey(9), 8)
+ self.assertEqual(t.minKey(), 1)
+ self.assertEqual(t.minKey(3), 3)
+ self.assertEqual(t.minKey(9), 10)
+
+ try:
+ t.maxKey(t.minKey() - 1)
+ except ValueError, err:
+ self.assertEqual(str(err), "no key satisfies the conditions")
+ else:
+ self.fail("expected ValueError")
+
+ try:
+ t.minKey(t.maxKey() + 1)
+ except ValueError, err:
+ self.assertEqual(str(err), "no key satisfies the conditions")
+ else:
+ self.fail("expected ValueError")
+
+ def testClear(self):
+ import random
+ t = self._makeOne()
+ r = range(100)
+ for x in r:
+ rnd = random.choice(r)
+ t[rnd] = 0
+ t.clear()
+ diff = lsubtract(list(t.keys()), [])
+ self.assertEqual(diff, [])
+
+ def testUpdate(self):
+ import random
+ t = self._makeOne()
+ d={}
+ l=[]
+ for i in range(10000):
+ k=random.randrange(-2000, 2001)
+ d[k]=i
+ l.append((k, i))
+
+ items=d.items()
+ items.sort()
+
+ t.update(d)
+ self.assertEqual(list(t.items()), items)
+
+ t.clear()
+ self.assertEqual(list(t.items()), [])
+
+ t.update(l)
+ self.assertEqual(list(t.items()), items)
+
+ # Before ZODB 3.4.2, update/construction from PersistentMapping failed.
+ def testUpdateFromPersistentMapping(self):
+ from persistent.mapping import PersistentMapping
+ t = self._makeOne()
+ pm = PersistentMapping({1: 2})
+ t.update(pm)
+ self.assertEqual(list(t.items()), [(1, 2)])
+
+ # Construction goes thru the same internals as .update().
+ t = t.__class__(pm)
+ self.assertEqual(list(t.items()), [(1, 2)])
+
+ def testEmptyRangeSearches(self):
+ t = self._makeOne()
+ t.update([(1,1), (5,5), (9,9)])
+ self.assertEqual(list(t.keys(-6,-4)), [], list(t.keys(-6,-4)))
+ self.assertEqual(list(t.keys(2,4)), [], list(t.keys(2,4)))
+ self.assertEqual(list(t.keys(6,8)), [], list(t.keys(6,8)))
+ self.assertEqual(list(t.keys(10,12)), [], list(t.keys(10,12)))
+ self.assertEqual(list(t.keys(9, 1)), [], list(t.keys(9, 1)))
+
+ # For IITreeSets, this one was returning 31 for len(keys), and
+ # list(keys) produced a list with 100 elements.
+ t.clear()
+ t.update(zip(range(300), range(300)))
+ keys = t.keys(200, 50)
+ self.assertEqual(len(keys), 0)
+ self.assertEqual(list(keys), [])
+ self.assertEqual(list(t.iterkeys(200, 50)), [])
+
+ keys = t.keys(max=50, min=200)
+ self.assertEqual(len(keys), 0)
+ self.assertEqual(list(keys), [])
+ self.assertEqual(list(t.iterkeys(max=50, min=200)), [])
+
+ def testSlicing(self):
+ # Test that slicing of .keys()/.values()/.items() works exactly the
+ # same way as slicing a Python list with the same contents.
+ # This tests fixes to several bugs in this area, starting with
+ # http://collector.zope.org/Zope/419,
+ # "BTreeItems slice contains 1 too many elements".
+ t = self._makeOne()
+ for n in range(10):
+ t.clear()
+ self.assertEqual(len(t), 0)
+
+ keys = []
+ values = []
+ items = []
+ for key in range(n):
+ value = -2 * key
+ t[key] = value
+ keys.append(key)
+ values.append(value)
+ items.append((key, value))
+ self.assertEqual(len(t), n)
+
+ kslice = t.keys()
+ vslice = t.values()
+ islice = t.items()
+ self.assertEqual(len(kslice), n)
+ self.assertEqual(len(vslice), n)
+ self.assertEqual(len(islice), n)
+
+ # Test whole-structure slices.
+ x = kslice[:]
+ self.assertEqual(list(x), keys[:])
+
+ x = vslice[:]
+ self.assertEqual(list(x), values[:])
+
+ x = islice[:]
+ self.assertEqual(list(x), items[:])
+
+ for lo in range(-2*n, 2*n+1):
+ # Test one-sided slices.
+ x = kslice[:lo]
+ self.assertEqual(list(x), keys[:lo])
+ x = kslice[lo:]
+ self.assertEqual(list(x), keys[lo:])
+
+ x = vslice[:lo]
+ self.assertEqual(list(x), values[:lo])
+ x = vslice[lo:]
+ self.assertEqual(list(x), values[lo:])
+
+ x = islice[:lo]
+ self.assertEqual(list(x), items[:lo])
+ x = islice[lo:]
+ self.assertEqual(list(x), items[lo:])
+
+ for hi in range(-2*n, 2*n+1):
+ # Test two-sided slices.
+ x = kslice[lo:hi]
+ self.assertEqual(list(x), keys[lo:hi])
+
+ x = vslice[lo:hi]
+ self.assertEqual(list(x), values[lo:hi])
+
+ x = islice[lo:hi]
+ self.assertEqual(list(x), items[lo:hi])
+
+ # The specific test case from Zope collector 419.
+ t.clear()
+ for i in xrange(100):
+ t[i] = 1
+ tslice = t.items()[20:80]
+ self.assertEqual(len(tslice), 60)
+ self.assertEqual(list(tslice), zip(range(20, 80), [1]*60))
+
+ def testIterators(self):
+ t = self._makeOne()
+
+ for keys in [], [-2], [1, 4], range(-170, 2000, 6):
+ t.clear()
+ for k in keys:
+ t[k] = -3 * k
+
+ self.assertEqual(list(t), keys)
+
+ x = []
+ for k in t:
+ x.append(k)
+ self.assertEqual(x, keys)
+
+ it = iter(t)
+ self.assert_(it is iter(it))
+ x = []
+ try:
+ while 1:
+ x.append(it.next())
+ except StopIteration:
+ pass
+ self.assertEqual(x, keys)
+
+ self.assertEqual(list(t.iterkeys()), keys)
+ self.assertEqual(list(t.itervalues()), list(t.values()))
+ self.assertEqual(list(t.iteritems()), list(t.items()))
+
+ def testRangedIterators(self):
+ t = self._makeOne()
+
+ for keys in [], [-2], [1, 4], range(-170, 2000, 13):
+ t.clear()
+ values = []
+ for k in keys:
+ value = -3 * k
+ t[k] = value
+ values.append(value)
+ items = zip(keys, values)
+
+ self.assertEqual(list(t.iterkeys()), keys)
+ self.assertEqual(list(t.itervalues()), values)
+ self.assertEqual(list(t.iteritems()), items)
+
+ if not keys:
+ continue
+
+ min_mid_max = (keys[0], keys[len(keys) >> 1], keys[-1])
+ for key1 in min_mid_max:
+ for lo in range(key1 - 1, key1 + 2):
+ # Test one-sided range iterators.
+ goodkeys = [k for k in keys if lo <= k]
+ got = t.iterkeys(lo)
+ self.assertEqual(goodkeys, list(got))
+
+ goodvalues = [t[k] for k in goodkeys]
+ got = t.itervalues(lo)
+ self.assertEqual(goodvalues, list(got))
+
+ gooditems = zip(goodkeys, goodvalues)
+ got = t.iteritems(lo)
+ self.assertEqual(gooditems, list(got))
+
+ for key2 in min_mid_max:
+ for hi in range(key2 - 1, key2 + 2):
+ goodkeys = [k for k in keys if lo <= k <= hi]
+ got = t.iterkeys(min=lo, max=hi)
+ self.assertEqual(goodkeys, list(got))
+
+ goodvalues = [t[k] for k in goodkeys]
+ got = t.itervalues(lo, max=hi)
+ self.assertEqual(goodvalues, list(got))
+
+ gooditems = zip(goodkeys, goodvalues)
+ got = t.iteritems(max=hi, min=lo)
+ self.assertEqual(gooditems, list(got))
+
+ def testBadUpdateTupleSize(self):
+ # This one silently ignored the excess in Zope3.
+ t = self._makeOne()
+ self.assertRaises(TypeError, t.update, [(1, 2, 3)])
+
+ # This one dumped core in Zope3.
+ self.assertRaises(TypeError, t.update, [(1,)])
+
+ # This one should simply succeed.
+ t.update([(1, 2)])
+ self.assertEqual(list(t.items()), [(1, 2)])
+
+ def testSimpleExclusivRanges(self):
+ def identity(x):
+ return x
+ def dup(x):
+ return [(y, y) for y in x]
+
+ for methodname, f in (("keys", identity),
+ ("values", identity),
+ ("items", dup),
+ ("iterkeys", identity),
+ ("itervalues", identity),
+ ("iteritems", dup)):
+
+ t = self._makeOne()
+ meth = getattr(t, methodname, None)
+ if meth is None:
+ continue
+
+ self.assertEqual(list(meth()), [])
+ self.assertEqual(list(meth(excludemin=True)), [])
+ self.assertEqual(list(meth(excludemax=True)), [])
+ self.assertEqual(list(meth(excludemin=True, excludemax=True)), [])
+
+ self._populate(t, 1)
+ self.assertEqual(list(meth()), f([0]))
+ self.assertEqual(list(meth(excludemin=True)), [])
+ self.assertEqual(list(meth(excludemax=True)), [])
+ self.assertEqual(list(meth(excludemin=True, excludemax=True)), [])
+
+ t.clear()
+ self._populate(t, 2)
+ self.assertEqual(list(meth()), f([0, 1]))
+ self.assertEqual(list(meth(excludemin=True)), f([1]))
+ self.assertEqual(list(meth(excludemax=True)), f([0]))
+ self.assertEqual(list(meth(excludemin=True, excludemax=True)), [])
+
+ t.clear()
+ self._populate(t, 3)
+ self.assertEqual(list(meth()), f([0, 1, 2]))
+ self.assertEqual(list(meth(excludemin=True)), f([1, 2]))
+ self.assertEqual(list(meth(excludemax=True)), f([0, 1]))
+ self.assertEqual(list(meth(excludemin=True, excludemax=True)),
+ f([1]))
+ self.assertEqual(list(meth(-1, 3, excludemin=True,
+ excludemax=True)),
+ f([0, 1, 2]))
+ self.assertEqual(list(meth(0, 3, excludemin=True,
+ excludemax=True)),
+ f([1, 2]))
+ self.assertEqual(list(meth(-1, 2, excludemin=True,
+ excludemax=True)),
+ f([0, 1]))
+ self.assertEqual(list(meth(0, 2, excludemin=True,
+ excludemax=True)),
+ f([1]))
+
+ def testSetdefault(self):
+ t = self._makeOne()
+
+ self.assertEqual(t.setdefault(1, 2), 2)
+ # That should also have associated 1 with 2 in the tree.
+ self.assert_(1 in t)
+ self.assertEqual(t[1], 2)
+ # And trying to change it again should have no effect.
+ self.assertEqual(t.setdefault(1, 666), 2)
+ self.assertEqual(t[1], 2)
+
+ # Not enough arguments.
+ self.assertRaises(TypeError, t.setdefault)
+ self.assertRaises(TypeError, t.setdefault, 1)
+ # Too many arguments.
+ self.assertRaises(TypeError, t.setdefault, 1, 2, 3)
+
+
+ def testPop(self):
+ t = self._makeOne()
+
+ # Empty container.
+ # If no default given, raises KeyError.
+ self.assertRaises(KeyError, t.pop, 1)
+ # But if default given, returns that instead.
+ self.assertEqual(t.pop(1, 42), 42)
+
+ t[1] = 3
+ # KeyError when key is not in container and default is not passed.
+ self.assertRaises(KeyError, t.pop, 5)
+ self.assertEqual(list(t.items()), [(1, 3)])
+ # If key is in container, returns the value and deletes the key.
+ self.assertEqual(t.pop(1), 3)
+ self.assertEqual(len(t), 0)
+
+ # If key is present, return value bypassing default.
+ t[1] = 3
+ self.assertEqual(t.pop(1, 7), 3)
+ self.assertEqual(len(t), 0)
+
+ # Pop only one item.
+ t[1] = 3
+ t[2] = 4
+ self.assertEqual(len(t), 2)
+ self.assertEqual(t.pop(1), 3)
+ self.assertEqual(len(t), 1)
+ self.assertEqual(t[2], 4)
+ self.assertEqual(t.pop(1, 3), 3)
+
+ # Too few arguments.
+ self.assertRaises(TypeError, t.pop)
+ # Too many arguments.
+ self.assertRaises(TypeError, t.pop, 1, 2, 3)
+
+
+class BTreeTests(MappingBase):
+ # Tests common to all BTrees
+
+ def _checkIt(self, t):
+ from BTrees.check import check
+ t._check()
+ check(t)
+
+ def testDeleteNoChildrenWorks(self):
+ t = self._makeOne()
+ t[5] = 6
+ t[2] = 10
+ t[6] = 12
+ t[1] = 100
+ t[3] = 200
+ t[10] = 500
+ t[4] = 99
+ del t[4]
+ diff = lsubtract(t.keys(), [1,2,3,5,6,10])
+ self.assertEqual(diff , [], diff)
+ self._checkIt(t)
+
+ def testDeleteOneChildWorks(self):
+ t = self._makeOne()
+ t[5] = 6
+ t[2] = 10
+ t[6] = 12
+ t[1] = 100
+ t[3] = 200
+ t[10] = 500
+ t[4] = 99
+ del t[3]
+ diff = lsubtract(t.keys(), [1,2,4,5,6,10])
+ self.assertEqual(diff , [], diff)
+ self._checkIt(t)
+
+ def testDeleteTwoChildrenNoInorderSuccessorWorks(self):
+ t = self._makeOne()
+ t[5] = 6
+ t[2] = 10
+ t[6] = 12
+ t[1] = 100
+ t[3] = 200
+ t[10] = 500
+ t[4] = 99
+ del t[2]
+ diff = lsubtract(t.keys(), [1,3,4,5,6,10])
+ self.assertEqual(diff , [], diff)
+ self._checkIt(t)
+
+ def testDeleteTwoChildrenInorderSuccessorWorks(self):
+ # 7, 3, 8, 1, 5, 10, 6, 4 -- del 3
+ t = self._makeOne()
+ t[7] = 6
+ t[3] = 10
+ t[8] = 12
+ t[1] = 100
+ t[5] = 200
+ t[10] = 500
+ t[6] = 99
+ t[4] = 150
+ del t[3]
+ diff = lsubtract(t.keys(), [1,4,5,6,7,8,10])
+ self.assertEqual(diff , [], diff)
+ self._checkIt(t)
+
+ def testDeleteRootWorks(self):
+ # 7, 3, 8, 1, 5, 10, 6, 4 -- del 7
+ t = self._makeOne()
+ t[7] = 6
+ t[3] = 10
+ t[8] = 12
+ t[1] = 100
+ t[5] = 200
+ t[10] = 500
+ t[6] = 99
+ t[4] = 150
+ del t[7]
+ diff = lsubtract(t.keys(), [1,3,4,5,6,8,10])
+ self.assertEqual(diff , [], diff)
+ self._checkIt(t)
+
+ def testRandomNonOverlappingInserts(self):
+ import random
+ t = self._makeOne()
+ added = {}
+ r = range(100)
+ for x in r:
+ k = random.choice(r)
+ if not added.has_key(k):
+ t[k] = x
+ added[k] = 1
+ addl = added.keys()
+ addl.sort()
+ diff = lsubtract(list(t.keys()), addl)
+ self.assertEqual(diff , [], (diff, addl, list(t.keys())))
+ self._checkIt(t)
+
+ def testRandomOverlappingInserts(self):
+ import random
+ t = self._makeOne()
+ added = {}
+ r = range(100)
+ for x in r:
+ k = random.choice(r)
+ t[k] = x
+ added[k] = 1
+ addl = added.keys()
+ addl.sort()
+ diff = lsubtract(t.keys(), addl)
+ self.assertEqual(diff , [], diff)
+ self._checkIt(t)
+
+ def testRandomDeletes(self):
+ import random
+ t = self._makeOne()
+ r = range(1000)
+ added = []
+ for x in r:
+ k = random.choice(r)
+ t[k] = x
+ added.append(k)
+ deleted = []
+ for x in r:
+ k = random.choice(r)
+ if t.has_key(k):
+ self.assert_(k in t)
+ del t[k]
+ deleted.append(k)
+ if t.has_key(k):
+ self.fail( "had problems deleting %s" % k )
+ badones = []
+ for x in deleted:
+ if t.has_key(x):
+ badones.append(x)
+ self.assertEqual(badones , [], (badones, added, deleted))
+ self._checkIt(t)
+
+ def testTargetedDeletes(self):
+ import random
+ t = self._makeOne()
+ r = range(1000)
+ for x in r:
+ k = random.choice(r)
+ t[k] = x
+ for x in r:
+ try:
+ del t[x]
+ except KeyError:
+ pass
+ self.assertEqual(realseq(t.keys()) , [], realseq(t.keys()))
+ self._checkIt(t)
+
+ def testPathologicalRightBranching(self):
+ t = self._makeOne()
+ r = range(1000)
+ for x in r:
+ t[x] = 1
+ self.assertEqual(realseq(t.keys()) , r, realseq(t.keys()))
+ for x in r:
+ del t[x]
+ self.assertEqual(realseq(t.keys()) , [], realseq(t.keys()))
+ self._checkIt(t)
+
+ def testPathologicalLeftBranching(self):
+ t = self._makeOne()
+ r = range(1000)
+ revr = r[:]
+ revr.reverse()
+ for x in revr:
+ t[x] = 1
+ self.assertEqual(realseq(t.keys()) , r, realseq(t.keys()))
+
+ for x in revr:
+ del t[x]
+ self.assertEqual(realseq(t.keys()) , [], realseq(t.keys()))
+ self._checkIt(t)
+
+ def testSuccessorChildParentRewriteExerciseCase(self):
+ t = self._makeOne()
+ add_order = [
+ 85, 73, 165, 273, 215, 142, 233, 67, 86, 166, 235, 225, 255,
+ 73, 175, 171, 285, 162, 108, 28, 283, 258, 232, 199, 260,
+ 298, 275, 44, 261, 291, 4, 181, 285, 289, 216, 212, 129,
+ 243, 97, 48, 48, 159, 22, 285, 92, 110, 27, 55, 202, 294,
+ 113, 251, 193, 290, 55, 58, 239, 71, 4, 75, 129, 91, 111,
+ 271, 101, 289, 194, 218, 77, 142, 94, 100, 115, 101, 226,
+ 17, 94, 56, 18, 163, 93, 199, 286, 213, 126, 240, 245, 190,
+ 195, 204, 100, 199, 161, 292, 202, 48, 165, 6, 173, 40, 218,
+ 271, 228, 7, 166, 173, 138, 93, 22, 140, 41, 234, 17, 249,
+ 215, 12, 292, 246, 272, 260, 140, 58, 2, 91, 246, 189, 116,
+ 72, 259, 34, 120, 263, 168, 298, 118, 18, 28, 299, 192, 252,
+ 112, 60, 277, 273, 286, 15, 263, 141, 241, 172, 255, 52, 89,
+ 127, 119, 255, 184, 213, 44, 116, 231, 173, 298, 178, 196,
+ 89, 184, 289, 98, 216, 115, 35, 132, 278, 238, 20, 241, 128,
+ 179, 159, 107, 206, 194, 31, 260, 122, 56, 144, 118, 283,
+ 183, 215, 214, 87, 33, 205, 183, 212, 221, 216, 296, 40,
+ 108, 45, 188, 139, 38, 256, 276, 114, 270, 112, 214, 191,
+ 147, 111, 299, 107, 101, 43, 84, 127, 67, 205, 251, 38, 91,
+ 297, 26, 165, 187, 19, 6, 73, 4, 176, 195, 90, 71, 30, 82,
+ 139, 210, 8, 41, 253, 127, 190, 102, 280, 26, 233, 32, 257,
+ 194, 263, 203, 190, 111, 218, 199, 29, 81, 207, 18, 180,
+ 157, 172, 192, 135, 163, 275, 74, 296, 298, 265, 105, 191,
+ 282, 277, 83, 188, 144, 259, 6, 173, 81, 107, 292, 231,
+ 129, 65, 161, 113, 103, 136, 255, 285, 289, 1
+ ]
+ delete_order = [
+ 276, 273, 12, 275, 2, 286, 127, 83, 92, 33, 101, 195,
+ 299, 191, 22, 232, 291, 226, 110, 94, 257, 233, 215, 184,
+ 35, 178, 18, 74, 296, 210, 298, 81, 265, 175, 116, 261,
+ 212, 277, 260, 234, 6, 129, 31, 4, 235, 249, 34, 289, 105,
+ 259, 91, 93, 119, 7, 183, 240, 41, 253, 290, 136, 75, 292,
+ 67, 112, 111, 256, 163, 38, 126, 139, 98, 56, 282, 60, 26,
+ 55, 245, 225, 32, 52, 40, 271, 29, 252, 239, 89, 87, 205,
+ 213, 180, 97, 108, 120, 218, 44, 187, 196, 251, 202, 203,
+ 172, 28, 188, 77, 90, 199, 297, 282, 141, 100, 161, 216,
+ 73, 19, 17, 189, 30, 258
+ ]
+ for x in add_order:
+ t[x] = 1
+ for x in delete_order:
+ try: del t[x]
+ except KeyError:
+ if t.has_key(x):
+ self.assertEqual(1,2,"failed to delete %s" % x)
+ self._checkIt(t)
+
+ def testRangeSearchAfterSequentialInsert(self):
+ t = self._makeOne()
+ r = range(100)
+ for x in r:
+ t[x] = 0
+ diff = lsubtract(list(t.keys(0, 100)), r)
+ self.assertEqual(diff , [], diff)
+ self._checkIt(t)
+
+ def testRangeSearchAfterRandomInsert(self):
+ import random
+ t = self._makeOne()
+ r = range(100)
+ a = {}
+ for x in r:
+ rnd = random.choice(r)
+ t[rnd] = 0
+ a[rnd] = 0
+ diff = lsubtract(list(t.keys(0, 100)), a.keys())
+ self.assertEqual(diff, [], diff)
+ self._checkIt(t)
+
+ def testPathologicalRangeSearch(self):
+ t = self._makeOne()
+ # Build a 2-level tree with at least two buckets.
+ for i in range(200):
+ t[i] = i
+ items, dummy = t.__getstate__()
+ self.assert_(len(items) > 2) # at least two buckets and a key
+ # All values in the first bucket are < firstkey. All in the
+ # second bucket are >= firstkey, and firstkey is the first key in
+ # the second bucket.
+ firstkey = items[1]
+ therange = t.keys(-1, firstkey)
+ self.assertEqual(len(therange), firstkey + 1)
+ self.assertEqual(list(therange), range(firstkey + 1))
+ # Now for the tricky part. If we delete firstkey, the second bucket
+ # loses its smallest key, but firstkey remains in the BTree node.
+ # If we then do a high-end range search on firstkey, the BTree node
+ # directs us to look in the second bucket, but there's no longer any
+ # key <= firstkey in that bucket. The correct answer points to the
+ # end of the *first* bucket. The algorithm has to be smart enough
+ # to "go backwards" in the BTree then; if it doesn't, it will
+ # erroneously claim that the range is empty.
+ del t[firstkey]
+ therange = t.keys(min=-1, max=firstkey)
+ self.assertEqual(len(therange), firstkey)
+ self.assertEqual(list(therange), range(firstkey))
+ self._checkIt(t)
+
+ def testInsertMethod(self):
+ t = self._makeOne()
+ t[0] = 1
+ self.assertEqual(t.insert(0, 1) , 0)
+ self.assertEqual(t.insert(1, 1) , 1)
+ self.assertEqual(lsubtract(list(t.keys()), [0,1]) , [])
+ self._checkIt(t)
+
+ def testDamagedIterator(self):
+ # A cute one from Steve Alexander. This caused the BTreeItems
+ # object to go insane, accessing memory beyond the allocated part
+ # of the bucket. If it fails, the symptom is either a C-level
+ # assertion error (if the BTree code was compiled without NDEBUG),
+ # or most likely a segfault (if the BTree code was compiled with
+ # NDEBUG).
+ t = self._makeOne()
+ self._populate(t, 10)
+ # In order for this to fail, it's important that k be a "lazy"
+ # iterator, referring to the BTree by indirect position (index)
+ # instead of a fully materialized list. Then the position can
+ # end up pointing into trash memory, if the bucket pointed to
+ # shrinks.
+ k = t.keys()
+ for dummy in range(20):
+ try:
+ del t[k[0]]
+ except RuntimeError, detail:
+ self.assertEqual(str(detail), "the bucket being iterated "
+ "changed size")
+ break
+ except KeyError, v:
+ # The Python implementation behaves very differently and
+ # gives a key error in this situation. It can't mess up
+ # memory and can't readily detect changes to underlying buckets
+ # in any sane way.
+ self.assertEqual(str(v), str(k[0]))
+ self._checkIt(t)
+
+
+class NormalSetTests(Base):
+ # Test common to all set types
+
+ def _populate(self, t, l):
+ # Make some data
+ t.update(range(l))
+
+ def testInsertReturnsValue(self):
+ t = self._makeOne()
+ self.assertEqual(t.insert(5) , 1)
+ self.assertEqual(t.add(4) , 1)
+
+ def testDuplicateInsert(self):
+ t = self._makeOne()
+ t.insert(5)
+ self.assertEqual(t.insert(5) , 0)
+ self.assertEqual(t.add(5) , 0)
+
+ def testInsert(self):
+ t = self._makeOne()
+ t.insert(1)
+ self.assert_(t.has_key(1))
+ self.assert_(1 in t)
+ self.assert_(2 not in t)
+
+ def testBigInsert(self):
+ t = self._makeOne()
+ r = xrange(10000)
+ for x in r:
+ t.insert(x)
+ for x in r:
+ self.assert_(t.has_key(x))
+ self.assert_(x in t)
+
+ def testRemoveSucceeds(self):
+ t = self._makeOne()
+ r = xrange(10000)
+ for x in r: t.insert(x)
+ for x in r: t.remove(x)
+
+ def testRemoveFails(self):
+ self.assertRaises(KeyError, self._removenonexistent)
+
+ def _removenonexistent(self):
+ self._makeOne().remove(1)
+
+ def testHasKeyFails(self):
+ t = self._makeOne()
+ self.assert_(not t.has_key(1))
+ self.assert_(1 not in t)
+
+ def testKeys(self):
+ t = self._makeOne()
+ r = xrange(1000)
+ for x in r:
+ t.insert(x)
+ diff = lsubtract(t.keys(), r)
+ self.assertEqual(diff, [])
+
+
+ def testClear(self):
+ t = self._makeOne()
+ r = xrange(1000)
+ for x in r: t.insert(x)
+ t.clear()
+ diff = lsubtract(t.keys(), [])
+ self.assertEqual(diff , [], diff)
+
+ def testMaxKeyMinKey(self):
+ t = self._makeOne()
+ t.insert(1)
+ t.insert(2)
+ t.insert(3)
+ t.insert(8)
+ t.insert(5)
+ t.insert(10)
+ t.insert(6)
+ t.insert(4)
+ self.assertEqual(t.maxKey() , 10)
+ self.assertEqual(t.maxKey(6) , 6)
+ self.assertEqual(t.maxKey(9) , 8)
+ self.assertEqual(t.minKey() , 1)
+ self.assertEqual(t.minKey(3) , 3)
+ self.assertEqual(t.minKey(9) , 10)
+ self.assert_(t.minKey() in t)
+ self.assert_(t.minKey()-1 not in t)
+ self.assert_(t.maxKey() in t)
+ self.assert_(t.maxKey()+1 not in t)
+
+ try:
+ t.maxKey(t.minKey() - 1)
+ except ValueError, err:
+ self.assertEqual(str(err), "no key satisfies the conditions")
+ else:
+ self.fail("expected ValueError")
+
+ try:
+ t.minKey(t.maxKey() + 1)
+ except ValueError, err:
+ self.assertEqual(str(err), "no key satisfies the conditions")
+ else:
+ self.fail("expected ValueError")
+
+ def testUpdate(self):
+ import random
+ t = self._makeOne()
+ d={}
+ l=[]
+ for i in range(10000):
+ k=random.randrange(-2000, 2001)
+ d[k]=i
+ l.append(k)
+
+ items = d.keys()
+ items.sort()
+
+ t.update(l)
+ self.assertEqual(list(t.keys()), items)
+
+ def testEmptyRangeSearches(self):
+ t = self._makeOne()
+ t.update([1, 5, 9])
+ self.assertEqual(list(t.keys(-6,-4)), [], list(t.keys(-6,-4)))
+ self.assertEqual(list(t.keys(2,4)), [], list(t.keys(2,4)))
+ self.assertEqual(list(t.keys(6,8)), [], list(t.keys(6,8)))
+ self.assertEqual(list(t.keys(10,12)), [], list(t.keys(10,12)))
+ self.assertEqual(list(t.keys(9,1)), [], list(t.keys(9,1)))
+
+ # For IITreeSets, this one was returning 31 for len(keys), and
+ # list(keys) produced a list with 100 elements.
+ t.clear()
+ t.update(range(300))
+ keys = t.keys(200, 50)
+ self.assertEqual(len(keys), 0)
+ self.assertEqual(list(keys), [])
+
+ keys = t.keys(max=50, min=200)
+ self.assertEqual(len(keys), 0)
+ self.assertEqual(list(keys), [])
+
+ def testSlicing(self):
+ # Test that slicing of .keys() works exactly the same way as slicing
+ # a Python list with the same contents.
+ t = self._makeOne()
+ for n in range(10):
+ t.clear()
+ self.assertEqual(len(t), 0)
+
+ keys = range(10*n, 11*n)
+ t.update(keys)
+ self.assertEqual(len(t), n)
+
+ kslice = t.keys()
+ self.assertEqual(len(kslice), n)
+
+ # Test whole-structure slices.
+ x = kslice[:]
+ self.assertEqual(list(x), keys[:])
+
+ for lo in range(-2*n, 2*n+1):
+ # Test one-sided slices.
+ x = kslice[:lo]
+ self.assertEqual(list(x), keys[:lo])
+ x = kslice[lo:]
+ self.assertEqual(list(x), keys[lo:])
+
+ for hi in range(-2*n, 2*n+1):
+ # Test two-sided slices.
+ x = kslice[lo:hi]
+ self.assertEqual(list(x), keys[lo:hi])
+
+ def testIterator(self):
+ t = self._makeOne()
+
+ for keys in [], [-2], [1, 4], range(-170, 2000, 6):
+ t.clear()
+ t.update(keys)
+
+ self.assertEqual(list(t), keys)
+
+ x = []
+ for k in t:
+ x.append(k)
+ self.assertEqual(x, keys)
+
+ it = iter(t)
+ self.assert_(it is iter(it))
+ x = []
+ try:
+ while 1:
+ x.append(it.next())
+ except StopIteration:
+ pass
+ self.assertEqual(x, keys)
+
+class ExtendedSetTests(NormalSetTests):
+
+ def testLen(self):
+ t = self._makeOne()
+ r = xrange(10000)
+ for x in r: t.insert(x)
+ self.assertEqual(len(t) , 10000, len(t))
+
+ def testGetItem(self):
+ t = self._makeOne()
+ r = xrange(10000)
+ for x in r: t.insert(x)
+ for x in r:
+ self.assertEqual(t[x] , x)
+
+
+class InternalKeysMappingTest(object):
+ # There must not be any internal keys not in the BTree
+
+ def _makeOne(self):
+ return self._getTargetClass()()
+
+ def add_key(self, tree, key):
+ tree[key] = key
+
+ @_skip_wo_ZODB
+ def test_internal_keys_after_deletion(self):
+ # Make sure when a key's deleted, it's not an internal key
+ #
+ # We'll leverage __getstate__ to introspect the internal structures.
+ #
+ # We need to check BTrees with BTree children as well as BTrees
+ # with bucket children.
+ import transaction
+ from ZODB.MappingStorage import DB
+ db = DB()
+ conn = db.open()
+
+ tree = conn.root.tree = self._makeOne()
+ i = 0
+
+ # Grow the btree until we have multiple buckets
+ while 1:
+ i += 1
+ self.add_key(tree, i)
+ data = tree.__getstate__()[0]
+ if len(data) >= 3:
+ break
+
+ transaction.commit()
+
+ # Now, delete the internal key and make sure it's really gone
+ key = data[1]
+ del tree[key]
+ data = tree.__getstate__()[0]
+ self.assert_(data[1] != key)
+
+ # The tree should have changed:
+ self.assert_(tree._p_changed)
+
+ # Grow the btree until we have multiple levels
+ while 1:
+ i += 1
+ self.add_key(tree, i)
+ data = tree.__getstate__()[0]
+ if data[0].__class__ == tree.__class__:
+ assert len(data[2].__getstate__()[0]) >= 3
+ break
+
+ # Now, delete the internal key and make sure it's really gone
+ key = data[1]
+ del tree[key]
+ data = tree.__getstate__()[0]
+ self.assert_(data[1] != key)
+
+ transaction.abort()
+ db.close()
+
+
+class InternalKeysSetTest(object):
+ # There must not be any internal keys not in the TreeSet
+
+ def add_key(self, tree, key):
+ tree.add(key)
+
+
+class ModuleTest(object):
+ # test for presence of generic names in module
+ prefix = None
+ def _getModule(self):
+ pass
+ def testNames(self):
+ for name in ('Bucket', 'BTree', 'Set', 'TreeSet'):
+ klass = getattr(self._getModule(), name)
+ self.assertEqual(klass.__module__, self._getModule().__name__)
+ self.assert_(klass is getattr(self._getModule(),
+ self.prefix + name))
+
+ def testModuleProvides(self):
+ from zope.interface.verify import verifyObject
+ verifyObject(self._getInterface(), self._getModule())
+
+ def testFamily(self):
+ import BTrees
+ if self.prefix == 'OO':
+ self.assert_(
+ getattr(self._getModule(), 'family', self) is self)
+ elif 'L' in self.prefix:
+ self.assert_(self._getModule().family is BTrees.family64)
+ elif 'I' in self.prefix:
+ self.assert_(self._getModule().family is BTrees.family32)
+
+
+class TypeTest(object):
+ # tests of various type errors
+
+ def testBadTypeRaises(self):
+ self.assertRaises(TypeError, self._stringraises)
+ self.assertRaises(TypeError, self._floatraises)
+ self.assertRaises(TypeError, self._noneraises)
+
+
+class I_SetsBase(object):
+
+ def testBadBadKeyAfterFirst(self):
+ t = self._makeOne()
+ self.assertRaises(TypeError, t.__class__, [1, ''])
+ self.assertRaises(TypeError, t.update, [1, ''])
+
+ def testNonIntegerInsertRaises(self):
+ self.assertRaises(TypeError,self._insertstringraises)
+ self.assertRaises(TypeError,self._insertfloatraises)
+ self.assertRaises(TypeError,self._insertnoneraises)
+
+ def _insertstringraises(self):
+ self._makeOne().insert('a')
+
+ def _insertfloatraises(self):
+ self._makeOne().insert(1.4)
+
+ def _insertnoneraises(self):
+ self._makeOne().insert(None)
+
+
+LARGEST_32_BITS = 2147483647
+SMALLEST_32_BITS = -LARGEST_32_BITS - 1
+
+SMALLEST_POSITIVE_33_BITS = LARGEST_32_BITS + 1
+LARGEST_NEGATIVE_33_BITS = SMALLEST_32_BITS - 1
+
+LARGEST_64_BITS = 0x7fffffffffffffff
+SMALLEST_64_BITS = -LARGEST_64_BITS - 1
+
+SMALLEST_POSITIVE_65_BITS = LARGEST_64_BITS + 1
+LARGEST_NEGATIVE_65_BITS = SMALLEST_64_BITS - 1
+
+
+class TestLongIntSupport:
+
+ def getTwoValues(self):
+ # Return two distinct values; these must compare as un-equal.
+ #
+ # These values must be usable as values.
+ return object(), object()
+
+ def getTwoKeys(self):
+ # Return two distinct values, these must compare as un-equal.
+ #
+ #These values must be usable as keys.
+ return 0, 1
+
+ def _set_value(self, key, value):
+ t = self._makeOne()
+ t[key] = value
+
+
+class TestLongIntKeys(TestLongIntSupport):
+
+ def testLongIntKeysWork(self):
+ from BTrees.IIBTree import using64bits
+ if not using64bits:
+ return
+ t = self._makeOne()
+ o1, o2 = self.getTwoValues()
+ assert o1 != o2
+
+ # Test some small key values first:
+ t[0L] = o1
+ self.assertEqual(t[0], o1)
+ t[0] = o2
+ self.assertEqual(t[0L], o2)
+ self.assertEqual(list(t.keys()), [0])
+
+ # Test some large key values too:
+ k1 = SMALLEST_POSITIVE_33_BITS
+ k2 = LARGEST_64_BITS
+ k3 = SMALLEST_64_BITS
+ t[k1] = o1
+ t[k2] = o2
+ t[k3] = o1
+ self.assertEqual(t[k1], o1)
+ self.assertEqual(t[k2], o2)
+ self.assertEqual(t[k3], o1)
+ self.assertEqual(list(t.keys()), [k3, 0, k1, k2])
+
+ def testLongIntKeysOutOfRange(self):
+ from BTrees.IIBTree import using64bits
+ if not using64bits:
+ return
+ o1, o2 = self.getTwoValues()
+ self.assertRaises(
+ ValueError,
+ self._set_value, SMALLEST_POSITIVE_65_BITS, o1)
+ self.assertRaises(
+ ValueError,
+ self._set_value, LARGEST_NEGATIVE_65_BITS, o1)
+
+class TestLongIntValues(TestLongIntSupport):
+
+ def testLongIntValuesWork(self):
+ from BTrees.IIBTree import using64bits
+ if not using64bits:
+ return
+ t = self._makeOne()
+ keys = list(self.getTwoKeys())
+ keys.sort()
+ k1, k2 = keys
+ assert k1 != k2
+
+ # This is the smallest positive integer that requires 33 bits:
+ v1 = SMALLEST_POSITIVE_33_BITS
+ v2 = v1 + 1
+
+ t[k1] = v1
+ t[k2] = v2
+ self.assertEqual(t[k1], v1)
+ self.assertEqual(t[k2], v2)
+ self.assertEqual(list(t.values()), [v1, v2])
+
+ def testLongIntValuesOutOfRange(self):
+ from BTrees.IIBTree import using64bits
+ if not using64bits:
+ return
+ k1, k2 = self.getTwoKeys()
+ self.assertRaises(
+ ValueError,
+ self._set_value, k1, SMALLEST_POSITIVE_65_BITS)
+ self.assertRaises(
+ ValueError,
+ self._set_value, k1, LARGEST_NEGATIVE_65_BITS)
+
+# Given a mapping builder (IIBTree, OOBucket, etc), return a function
+# that builds an object of that type given only a list of keys.
+def makeBuilder(mapbuilder):
+ def result(keys=[], mapbuilder=mapbuilder):
+ return mapbuilder(zip(keys, keys))
+ return result
+
+# Subclasses have to set up:
+# builders() - function returning functions to build inputs,
+# each returned callable tkes an optional keys arg
+# intersection, union, difference - set to the type-correct versions
+class SetResult(object):
+ def setUp(self):
+ self.Akeys = [1, 3, 5, 6 ]
+ self.Bkeys = [ 2, 3, 4, 6, 7]
+ self.As = [makeset(self.Akeys) for makeset in self.builders()]
+ self.Bs = [makeset(self.Bkeys) for makeset in self.builders()]
+ self.emptys = [makeset() for makeset in self.builders()]
+
+ # Slow but obviously correct Python implementations of basic ops.
+ def _union(self, x, y):
+ result = list(x)
+ for e in y:
+ if e not in result:
+ result.append(e)
+ result.sort()
+ return result
+
+ def _intersection(self, x, y):
+ result = []
+ for e in x:
+ if e in y:
+ result.append(e)
+ return result
+
+ def _difference(self, x, y):
+ result = list(x)
+ for e in y:
+ if e in result:
+ result.remove(e)
+ # Difference preserves LHS values.
+ if hasattr(x, "values"):
+ result = [(k, x[k]) for k in result]
+ return result
+
+ def testNone(self):
+ for op in self.union, self.intersection, self.difference:
+ C = op(None, None)
+ self.assert_(C is None)
+
+ for op in self.union, self.intersection, self.difference:
+ for A in self.As:
+ C = op(A, None)
+ self.assert_(C is A)
+
+ C = op(None, A)
+ if op == self.difference:
+ self.assert_(C is None)
+ else:
+ self.assert_(C is A)
+
+ def testEmptyUnion(self):
+ for A in self.As:
+ for E in self.emptys:
+ C = self.union(A, E)
+ self.assert_(not hasattr(C, "values"))
+ self.assertEqual(list(C), self.Akeys)
+
+ C = self.union(E, A)
+ self.assert_(not hasattr(C, "values"))
+ self.assertEqual(list(C), self.Akeys)
+
+ def testEmptyIntersection(self):
+ for A in self.As:
+ for E in self.emptys:
+ C = self.intersection(A, E)
+ self.assert_(not hasattr(C, "values"))
+ self.assertEqual(list(C), [])
+
+ C = self.intersection(E, A)
+ self.assert_(not hasattr(C, "values"))
+ self.assertEqual(list(C), [])
+
+ def testEmptyDifference(self):
+ for A in self.As:
+ for E in self.emptys:
+ C = self.difference(A, E)
+ # Difference preserves LHS values.
+ self.assertEqual(hasattr(C, "values"), hasattr(A, "values"))
+ if hasattr(A, "values"):
+ self.assertEqual(list(C.items()), list(A.items()))
+ else:
+ self.assertEqual(list(C), self.Akeys)
+
+ C = self.difference(E, A)
+ self.assertEqual(hasattr(C, "values"), hasattr(E, "values"))
+ self.assertEqual(list(C), [])
+
+ def testUnion(self):
+ inputs = self.As + self.Bs
+ for A in inputs:
+ for B in inputs:
+ C = self.union(A, B)
+ self.assert_(not hasattr(C, "values"))
+ self.assertEqual(list(C), self._union(A, B))
+
+ def testIntersection(self):
+ inputs = self.As + self.Bs
+ for A in inputs:
+ for B in inputs:
+ C = self.intersection(A, B)
+ self.assert_(not hasattr(C, "values"))
+ self.assertEqual(list(C), self._intersection(A, B))
+
+ def testDifference(self):
+ inputs = self.As + self.Bs
+ for A in inputs:
+ for B in inputs:
+ C = self.difference(A, B)
+ # Difference preserves LHS values.
+ self.assertEqual(hasattr(C, "values"), hasattr(A, "values"))
+ want = self._difference(A, B)
+ if hasattr(A, "values"):
+ self.assertEqual(list(C.items()), want)
+ else:
+ self.assertEqual(list(C), want)
+
+ def testLargerInputs(self):
+ from BTrees.IIBTree import IISet
+ from random import randint
+ MAXSIZE = 200
+ MAXVAL = 400
+ for i in range(3):
+ n = randint(0, MAXSIZE)
+ Akeys = [randint(1, MAXVAL) for j in range(n)]
+ As = [makeset(Akeys) for makeset in self.builders()]
+ Akeys = IISet(Akeys)
+
+ n = randint(0, MAXSIZE)
+ Bkeys = [randint(1, MAXVAL) for j in range(n)]
+ Bs = [makeset(Bkeys) for makeset in self.builders()]
+ Bkeys = IISet(Bkeys)
+
+ for op, simulator in ((self.union, self._union),
+ (self.intersection, self._intersection),
+ (self.difference, self._difference)):
+ for A in As:
+ for B in Bs:
+ got = op(A, B)
+ want = simulator(Akeys, Bkeys)
+ self.assertEqual(list(got), want,
+ (A, B, Akeys, Bkeys, list(got), want))
+
+# Subclasses must set up (as class variables):
+# weightedUnion, weightedIntersection
+# builders -- sequence of constructors, taking items
+# union, intersection -- the module routines of those names
+# mkbucket -- the module bucket builder
+class Weighted(object):
+
+ def setUp(self):
+ self.Aitems = [(1, 10), (3, 30), (5, 50), (6, 60)]
+ self.Bitems = [(2, 21), (3, 31), (4, 41), (6, 61), (7, 71)]
+
+ self.As = [make(self.Aitems) for make in self.builders()]
+ self.Bs = [make(self.Bitems) for make in self.builders()]
+ self.emptys = [make([]) for make in self.builders()]
+
+ weights = []
+ for w1 in -3, -1, 0, 1, 7:
+ for w2 in -3, -1, 0, 1, 7:
+ weights.append((w1, w2))
+ self.weights = weights
+
+ def testBothNone(self):
+ for op in self.weightedUnion(), self.weightedIntersection():
+ w, C = op(None, None)
+ self.assert_(C is None)
+ self.assertEqual(w, 0)
+
+ w, C = op(None, None, 42, 666)
+ self.assert_(C is None)
+ self.assertEqual(w, 0)
+
+ def testLeftNone(self):
+ for op in self.weightedUnion(), self.weightedIntersection():
+ for A in self.As + self.emptys:
+ w, C = op(None, A)
+ self.assert_(C is A)
+ self.assertEqual(w, 1)
+
+ w, C = op(None, A, 42, 666)
+ self.assert_(C is A)
+ self.assertEqual(w, 666)
+
+ def testRightNone(self):
+ for op in self.weightedUnion(), self.weightedIntersection():
+ for A in self.As + self.emptys:
+ w, C = op(A, None)
+ self.assert_(C is A)
+ self.assertEqual(w, 1)
+
+ w, C = op(A, None, 42, 666)
+ self.assert_(C is A)
+ self.assertEqual(w, 42)
+
+ # If obj is a set, return a bucket with values all 1; else return obj.
+ def _normalize(self, obj):
+ if isaset(obj):
+ obj = self.mkbucket(zip(obj, [1] * len(obj)))
+ return obj
+
+ # Python simulation of weightedUnion.
+ def _wunion(self, A, B, w1=1, w2=1):
+ if isaset(A) and isaset(B):
+ return 1, self.union()(A, B).keys()
+ A = self._normalize(A)
+ B = self._normalize(B)
+ result = []
+ for key in self.union()(A, B):
+ v1 = A.get(key, 0)
+ v2 = B.get(key, 0)
+ result.append((key, v1*w1 + v2*w2))
+ return 1, result
+
+ def testUnion(self):
+ inputs = self.As + self.Bs + self.emptys
+ for A in inputs:
+ for B in inputs:
+ want_w, want_s = self._wunion(A, B)
+ got_w, got_s = self.weightedUnion()(A, B)
+ self.assertEqual(got_w, want_w)
+ if isaset(got_s):
+ self.assertEqual(got_s.keys(), want_s)
+ else:
+ self.assertEqual(got_s.items(), want_s)
+
+ for w1, w2 in self.weights:
+ want_w, want_s = self._wunion(A, B, w1, w2)
+ got_w, got_s = self.weightedUnion()(A, B, w1, w2)
+ self.assertEqual(got_w, want_w)
+ if isaset(got_s):
+ self.assertEqual(got_s.keys(), want_s)
+ else:
+ self.assertEqual(got_s.items(), want_s)
+
+ # Python simulation weightedIntersection.
+ def _wintersection(self, A, B, w1=1, w2=1):
+ if isaset(A) and isaset(B):
+ return w1 + w2, self.intersection()(A, B).keys()
+ A = self._normalize(A)
+ B = self._normalize(B)
+ result = []
+ for key in self.intersection()(A, B):
+ result.append((key, A[key]*w1 + B[key]*w2))
+ return 1, result
+
+ def testIntersection(self):
+ inputs = self.As + self.Bs + self.emptys
+ for A in inputs:
+ for B in inputs:
+ want_w, want_s = self._wintersection(A, B)
+ got_w, got_s = self.weightedIntersection()(A, B)
+ self.assertEqual(got_w, want_w)
+ if isaset(got_s):
+ self.assertEqual(got_s.keys(), want_s)
+ else:
+ self.assertEqual(got_s.items(), want_s)
+
+ for w1, w2 in self.weights:
+ want_w, want_s = self._wintersection(A, B, w1, w2)
+ got_w, got_s = self.weightedIntersection()(A, B, w1, w2)
+ self.assertEqual(got_w, want_w)
+ if isaset(got_s):
+ self.assertEqual(got_s.keys(), want_s)
+ else:
+ self.assertEqual(got_s.items(), want_s)
+
+# Given a set builder (like OITreeSet or OISet), return a function that
+# takes a list of (key, value) pairs and builds a set out of the keys.
+def itemsToSet(setbuilder):
+ def result(items, setbuilder=setbuilder):
+ return setbuilder([key for key, value in items])
+ return result
+
+# 'thing' is a bucket, btree, set or treeset. Return true iff it's one of the
+# latter two.
+def isaset(thing):
+ return not hasattr(thing, 'values')
+
+# Subclasses must set up (as class variables):
+# multiunion, union
+# mkset, mktreeset
+# mkbucket, mkbtree
+class MultiUnion(object):
+
+ def testEmpty(self):
+ self.assertEqual(len(self.multiunion([])), 0)
+
+ def testOne(self):
+ for sequence in [3], range(20), range(-10, 0, 2) + range(1, 10, 2):
+ seq1 = sequence[:]
+ seq2 = sequence[:]
+ seq2.reverse()
+ seqsorted = sequence[:]
+ seqsorted.sort()
+ for seq in seq1, seq2, seqsorted:
+ for builder in self.mkset, self.mktreeset:
+ input = builder(seq)
+ output = self.multiunion([input])
+ self.assertEqual(len(seq), len(output))
+ self.assertEqual(seqsorted, list(output))
+
+ def testValuesIgnored(self):
+ for builder in self.mkbucket, self.mkbtree:
+ input = builder([(1, 2), (3, 4), (5, 6)])
+ output = self.multiunion([input])
+ self.assertEqual([1, 3, 5], list(output))
+
+ def testBigInput(self):
+ N = 100000
+ input = self.mkset(range(N))
+ output = self.multiunion([input] * 10)
+ self.assertEqual(len(output), N)
+ self.assertEqual(output.minKey(), 0)
+ self.assertEqual(output.maxKey(), N-1)
+ self.assertEqual(list(output), range(N))
+
+ def testLotsOfLittleOnes(self):
+ from random import shuffle
+ N = 5000
+ inputs = []
+ mkset, mktreeset = self.mkset, self.mktreeset
+ for i in range(N):
+ base = i * 4 - N
+ inputs.append(mkset([base, base+1]))
+ inputs.append(mktreeset([base+2, base+3]))
+ shuffle(inputs)
+ output = self.multiunion(inputs)
+ self.assertEqual(len(output), N*4)
+ self.assertEqual(list(output), range(-N, 3*N))
+
+ def testFunkyKeyIteration(self):
+ # The internal set iteration protocol allows "iterating over" a
+ # a single key as if it were a set.
+ N = 100
+ union, mkset = self.union, self.mkset
+ slow = mkset()
+ for i in range(N):
+ slow = union(slow, mkset([i]))
+ fast = self.multiunion(range(N)) # acts like N distinct singleton sets
+ self.assertEqual(len(slow), N)
+ self.assertEqual(len(fast), N)
+ self.assertEqual(list(slow), list(fast))
+ self.assertEqual(list(fast), range(N))
+
+
+class ConflictTestBase(object):
+ # Tests common to all types: sets, buckets, and BTrees
+
+ storage = None
+
+ def tearDown(self):
+ import transaction
+ transaction.abort()
+ if self.storage is not None:
+ self.storage.close()
+ self.storage.cleanup()
+
+ def _makeOne(self):
+ return self._getTargetClass()()
+
+ def openDB(self):
+ import os
+ from ZODB.FileStorage import FileStorage
+ from ZODB.DB import DB
+ n = 'fs_tmp__%s' % os.getpid()
+ self.storage = FileStorage(n)
+ self.db = DB(self.storage)
+ return self.db
+
+
+def _test_merge(o1, o2, o3, expect, message='failed to merge', should_fail=0):
+ from BTrees.Interfaces import BTreesConflictError
+ s1 = o1.__getstate__()
+ s2 = o2.__getstate__()
+ s3 = o3.__getstate__()
+ expected = expect.__getstate__()
+ if expected is None:
+ expected = ((((),),),)
+
+ if should_fail:
+ try:
+ merged = o1._p_resolveConflict(s1, s2, s3)
+ except BTreesConflictError, err:
+ pass
+ else:
+ assert 0, message
+ else:
+ merged = o1._p_resolveConflict(s1, s2, s3)
+ assert merged == expected, message
+
+
+class MappingConflictTestBase(ConflictTestBase):
+ # Tests common to mappings (buckets, btrees).
+
+ def _deletefail(self):
+ t = self._makeOne()
+ del t[1]
+
+ def _setupConflict(self):
+
+ l=[ -5124, -7377, 2274, 8801, -9901, 7327, 1565, 17, -679,
+ 3686, -3607, 14, 6419, -5637, 6040, -4556, -8622, 3847, 7191,
+ -4067]
+
+
+ e1=[(-1704, 0), (5420, 1), (-239, 2), (4024, 3), (-6984, 4)]
+ e2=[(7745, 0), (4868, 1), (-2548, 2), (-2711, 3), (-3154, 4)]
+
+
+ base = self._makeOne()
+ base.update([(i, i*i) for i in l[:20]])
+ b1=base.__class__(base)
+ b2=base.__class__(base)
+ bm=base.__class__(base)
+
+ items=base.items()
+
+ return base, b1, b2, bm, e1, e2, items
+
+ def testMergeDelete(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ del b1[items[1][0]]
+ del b2[items[5][0]]
+ del b1[items[-1][0]]
+ del b2[items[-2][0]]
+ del bm[items[1][0]]
+ del bm[items[5][0]]
+ del bm[items[-1][0]]
+ del bm[items[-2][0]]
+ _test_merge(base, b1, b2, bm, 'merge delete')
+
+ def testMergeDeleteAndUpdate(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ del b1[items[1][0]]
+ b2[items[5][0]]=1
+ del b1[items[-1][0]]
+ b2[items[-2][0]]=2
+ del bm[items[1][0]]
+ bm[items[5][0]]=1
+ del bm[items[-1][0]]
+ bm[items[-2][0]]=2
+ _test_merge(base, b1, b2, bm, 'merge update and delete')
+
+ def testMergeUpdate(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1[items[0][0]]=1
+ b2[items[5][0]]=2
+ b1[items[-1][0]]=3
+ b2[items[-2][0]]=4
+ bm[items[0][0]]=1
+ bm[items[5][0]]=2
+ bm[items[-1][0]]=3
+ bm[items[-2][0]]=4
+ _test_merge(base, b1, b2, bm, 'merge update')
+
+ def testFailMergeDelete(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ del b1[items[0][0]]
+ del b2[items[0][0]]
+ _test_merge(base, b1, b2, bm, 'merge conflicting delete',
+ should_fail=1)
+
+ def testFailMergeUpdate(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1[items[0][0]]=1
+ b2[items[0][0]]=2
+ _test_merge(base, b1, b2, bm, 'merge conflicting update',
+ should_fail=1)
+
+ def testFailMergeDeleteAndUpdate(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ del b1[items[0][0]]
+ b2[items[0][0]]=-9
+ _test_merge(base, b1, b2, bm, 'merge conflicting update and delete',
+ should_fail=1)
+
+ def testMergeInserts(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1[-99999]=-99999
+ b1[e1[0][0]]=e1[0][1]
+ b2[99999]=99999
+ b2[e1[2][0]]=e1[2][1]
+
+ bm[-99999]=-99999
+ bm[e1[0][0]]=e1[0][1]
+ bm[99999]=99999
+ bm[e1[2][0]]=e1[2][1]
+ _test_merge(base, b1, b2, bm, 'merge insert')
+
+ def testMergeInsertsFromEmpty(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ base.clear()
+ b1.clear()
+ b2.clear()
+ bm.clear()
+
+ b1.update(e1)
+ bm.update(e1)
+ b2.update(e2)
+ bm.update(e2)
+
+ _test_merge(base, b1, b2, bm, 'merge insert from empty')
+
+ def testFailMergeEmptyAndFill(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.clear()
+ bm.clear()
+ b2.update(e2)
+ bm.update(e2)
+
+ _test_merge(base, b1, b2, bm, 'merge insert from empty', should_fail=1)
+
+ def testMergeEmpty(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.clear()
+ bm.clear()
+
+ _test_merge(base, b1, b2, bm, 'empty one and not other', should_fail=1)
+
+ def testFailMergeInsert(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1[-99999]=-99999
+ b1[e1[0][0]]=e1[0][1]
+ b2[99999]=99999
+ b2[e1[0][0]]=e1[0][1]
+ _test_merge(base, b1, b2, bm, 'merge conflicting inserts',
+ should_fail=1)
+
+class SetConflictTestBase(ConflictTestBase):
+ "Set (as opposed to TreeSet) specific tests."
+
+ def _setupConflict(self):
+ l=[ -5124, -7377, 2274, 8801, -9901, 7327, 1565, 17, -679,
+ 3686, -3607, 14, 6419, -5637, 6040, -4556, -8622, 3847, 7191,
+ -4067]
+
+ e1=[-1704, 5420, -239, 4024, -6984]
+ e2=[7745, 4868, -2548, -2711, -3154]
+
+
+ base = self._makeOne()
+ base.update(l)
+ b1=base.__class__(base)
+ b2=base.__class__(base)
+ bm=base.__class__(base)
+
+ items=base.keys()
+
+ return base, b1, b2, bm, e1, e2, items
+
+ def testMergeDelete(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1.remove(items[1])
+ b2.remove(items[5])
+ b1.remove(items[-1])
+ b2.remove(items[-2])
+ bm.remove(items[1])
+ bm.remove(items[5])
+ bm.remove(items[-1])
+ bm.remove(items[-2])
+ _test_merge(base, b1, b2, bm, 'merge delete')
+
+ def testFailMergeDelete(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1.remove(items[0])
+ b2.remove(items[0])
+ _test_merge(base, b1, b2, bm, 'merge conflicting delete',
+ should_fail=1)
+
+ def testMergeInserts(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.insert(-99999)
+ b1.insert(e1[0])
+ b2.insert(99999)
+ b2.insert(e1[2])
+
+ bm.insert(-99999)
+ bm.insert(e1[0])
+ bm.insert(99999)
+ bm.insert(e1[2])
+ _test_merge(base, b1, b2, bm, 'merge insert')
+
+ def testMergeInsertsFromEmpty(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ base.clear()
+ b1.clear()
+ b2.clear()
+ bm.clear()
+
+ b1.update(e1)
+ bm.update(e1)
+ b2.update(e2)
+ bm.update(e2)
+
+ _test_merge(base, b1, b2, bm, 'merge insert from empty')
+
+ def testFailMergeEmptyAndFill(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.clear()
+ bm.clear()
+ b2.update(e2)
+ bm.update(e2)
+
+ _test_merge(base, b1, b2, bm, 'merge insert from empty', should_fail=1)
+
+ def testMergeEmpty(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+
+ b1.clear()
+ bm.clear()
+
+ _test_merge(base, b1, b2, bm, 'empty one and not other', should_fail=1)
+
+ def testFailMergeInsert(self):
+ base, b1, b2, bm, e1, e2, items = self._setupConflict()
+ b1.insert(-99999)
+ b1.insert(e1[0])
+ b2.insert(99999)
+ b2.insert(e1[0])
+ _test_merge(base, b1, b2, bm, 'merge conflicting inserts',
+ should_fail=1)
+
+
+## utility functions
+
+def lsubtract(l1, l2):
+ l1 = list(l1)
+ l2 = list(l2)
+ l = filter(lambda x, l1=l1: x not in l1, l2)
+ l = l + filter(lambda x, l2=l2: x not in l2, l1)
+ return l
+
+def realseq(itemsob):
+ return [x for x in itemsob]
+
+def permutations(x):
+ # Return a list of all permutations of list x.
+ n = len(x)
+ if n <= 1:
+ return [x]
+ result = []
+ x0 = x[0]
+ for i in range(n):
+ # Build the (n-1)! permutations with x[i] in the first position.
+ xcopy = x[:]
+ first, xcopy[i] = xcopy[i], x0
+ result.extend([[first] + p for p in permutations(xcopy[1:])])
+ return result
Modified: BTrees/trunk/BTrees/tests/testBTrees.py
===================================================================
--- BTrees/trunk/BTrees/tests/testBTrees.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/tests/testBTrees.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -13,1229 +13,9 @@
##############################################################################
import unittest
-def _skip_wo_ZODB(test_method): #pragma NO COVER
- try:
- import ZODB
- except ImportError: # skip this test if ZODB is not available
- def _dummy(*args):
- pass
- return _dummy
- else:
- return test_method
+from BTrees.tests.common import permutations
-class Base(object):
- # Tests common to all types: sets, buckets, and BTrees
-
- db = None
-
- def _makeOne(self):
- return self._getTargetClass()()
-
-
- def tearDown(self):
- if self.db is not None:
- self.db.close()
-
- def _getRoot(self):
- from ZODB import DB
- from ZODB.MappingStorage import MappingStorage
- if self.db is None:
- # Unclear: On the next line, the ZODB4 flavor of this routine
- # [asses a cache_size argument:
- # self.db = DB(MappingStorage(), cache_size=1)
- # If that's done here, though, testLoadAndStore() and
- # testGhostUnghost() both nail the CPU and seemingly
- # never finish.
- self.db = DB(MappingStorage())
- return self.db.open().root()
-
- def _closeRoot(self, root):
- root._p_jar.close()
-
- @_skip_wo_ZODB
- def testLoadAndStore(self):
- import transaction
- for i in 0, 10, 1000:
- t = self._makeOne()
- self._populate(t, i)
- root = None
- root = self._getRoot()
- root[i] = t
- transaction.commit()
-
- root2 = self._getRoot()
- if hasattr(t, 'items'):
- self.assertEqual(list(root2[i].items()) , list(t.items()))
- else:
- self.assertEqual(list(root2[i].keys()) , list(t.keys()))
-
- self._closeRoot(root)
- self._closeRoot(root2)
-
- def testSetstateArgumentChecking(self):
- try:
- self._makeOne().__setstate__(('',))
- except TypeError, v:
- self.assertEqual(str(v), 'tuple required for first state element')
- else:
- raise AssertionError("Expected exception")
-
- @_skip_wo_ZODB
- def testGhostUnghost(self):
- import transaction
- for i in 0, 10, 1000:
- t = self._makeOne()
- self._populate(t, i)
- root = self._getRoot()
- root[i] = t
- transaction.commit()
-
- root2 = self._getRoot()
- root2[i]._p_deactivate()
- transaction.commit()
- if hasattr(t, 'items'):
- self.assertEqual(list(root2[i].items()) , list(t.items()))
- else:
- self.assertEqual(list(root2[i].keys()) , list(t.keys()))
-
- self._closeRoot(root)
- self._closeRoot(root2)
-
- def testSimpleExclusiveKeyRange(self):
- t = self._makeOne()
- self.assertEqual(list(t.keys()), [])
- self.assertEqual(list(t.keys(excludemin=True)), [])
- self.assertEqual(list(t.keys(excludemax=True)), [])
- self.assertEqual(list(t.keys(excludemin=True, excludemax=True)), [])
-
- self._populate(t, 1)
- self.assertEqual(list(t.keys()), [0])
- self.assertEqual(list(t.keys(excludemin=True)), [])
- self.assertEqual(list(t.keys(excludemax=True)), [])
- self.assertEqual(list(t.keys(excludemin=True, excludemax=True)), [])
-
- t.clear()
- self._populate(t, 2)
- self.assertEqual(list(t.keys()), [0, 1])
- self.assertEqual(list(t.keys(excludemin=True)), [1])
- self.assertEqual(list(t.keys(excludemax=True)), [0])
- self.assertEqual(list(t.keys(excludemin=True, excludemax=True)), [])
-
- t.clear()
- self._populate(t, 3)
- self.assertEqual(list(t.keys()), [0, 1, 2])
- self.assertEqual(list(t.keys(excludemin=True)), [1, 2])
- self.assertEqual(list(t.keys(excludemax=True)), [0, 1])
- self.assertEqual(list(t.keys(excludemin=True, excludemax=True)), [1])
-
- self.assertEqual(list(t.keys(-1, 3, excludemin=True, excludemax=True)),
- [0, 1, 2])
- self.assertEqual(list(t.keys(0, 3, excludemin=True, excludemax=True)),
- [1, 2])
- self.assertEqual(list(t.keys(-1, 2, excludemin=True, excludemax=True)),
- [0, 1])
- self.assertEqual(list(t.keys(0, 2, excludemin=True, excludemax=True)),
- [1])
-
- @_skip_wo_ZODB
- def test_UpdatesDoReadChecksOnInternalNodes(self):
- import transaction
- from ZODB import DB
- from ZODB.MappingStorage import MappingStorage
- t = self._makeOne()
- if not hasattr(t, '_firstbucket'):
- return
- self._populate(t, 1000)
- store = MappingStorage()
- db = DB(store)
- conn = db.open()
- conn.root.t = t
- transaction.commit()
-
- read = []
- def readCurrent(ob):
- read.append(ob)
- conn.__class__.readCurrent(conn, ob)
- return 1
-
- conn.readCurrent = readCurrent
-
- try:
- add = t.add
- remove = t.remove
- except AttributeError:
- def add(i):
- t[i] = i
- def remove(i):
- del t[i]
-
- # Modifying a thing
- remove(100)
- self.assert_(t in read)
- del read[:]
- add(100)
- self.assert_(t in read)
- del read[:]
-
- transaction.abort()
- conn.cacheMinimize()
- list(t)
- self.assert_(100 in t)
- self.assert_(not read)
-
-
-class MappingBase(Base):
- # Tests common to mappings (buckets, btrees)
-
- def _populate(self, t, l):
- # Make some data
- for i in range(l): t[i]=i
-
- def testRepr(self):
- # test the repr because buckets have a complex repr implementation
- # internally the cutoff from a stack allocated buffer to a heap
- # allocated buffer is 10000.
- t = self._makeOne()
- for i in range(1000):
- t[i] = i
- r = repr(t)
- # Make sure the repr is 10000 bytes long for a bucket.
- # But since the test is also run for btrees, skip the length
- # check if the repr starts with '<'
- if not r.startswith('<'):
- self.assert_(len(r) > 10000)
-
- def testGetItemFails(self):
- self.assertRaises(KeyError, self._getitemfail)
-
- def _getitemfail(self):
- return self._makeOne()[1]
-
- def testGetReturnsDefault(self):
- self.assertEqual(self._makeOne().get(1) , None)
- self.assertEqual(self._makeOne().get(1, 'foo') , 'foo')
-
- def testSetItemGetItemWorks(self):
- t = self._makeOne()
- t[1] = 1
- a = t[1]
- self.assertEqual(a , 1, `a`)
-
- def testReplaceWorks(self):
- t = self._makeOne()
- t[1] = 1
- self.assertEqual(t[1] , 1, t[1])
- t[1] = 2
- self.assertEqual(t[1] , 2, t[1])
-
- def testLen(self):
- import random
- t = self._makeOne()
- added = {}
- r = range(1000)
- for x in r:
- k = random.choice(r)
- t[k] = x
- added[k] = x
- addl = added.keys()
- self.assertEqual(len(t) , len(addl), len(t))
-
- def testHasKeyWorks(self):
- t = self._makeOne()
- t[1] = 1
- self.assert_(t.has_key(1))
- self.assert_(1 in t)
- self.assert_(0 not in t)
- self.assert_(2 not in t)
-
- def testValuesWorks(self):
- t = self._makeOne()
- for x in range(100):
- t[x] = x*x
- v = t.values()
- for i in range(100):
- self.assertEqual(v[i], i*i)
- self.assertRaises(IndexError, lambda: v[i+1])
- i = 0
- for value in t.itervalues():
- self.assertEqual(value, i*i)
- i += 1
-
- def testValuesWorks1(self):
- t = self._makeOne()
- for x in range(100):
- t[99-x] = x
-
- for x in range(40):
- lst = list(t.values(0+x,99-x))
- lst.sort()
- self.assertEqual(lst,range(0+x,99-x+1))
-
- lst = list(t.values(max=99-x, min=0+x))
- lst.sort()
- self.assertEqual(lst,range(0+x,99-x+1))
-
- def testValuesNegativeIndex(self):
- t = self._makeOne()
- L = [-3, 6, -11, 4]
- for i in L:
- t[i] = i
- L.sort()
- vals = t.values()
- for i in range(-1, -5, -1):
- self.assertEqual(vals[i], L[i])
- self.assertRaises(IndexError, lambda: vals[-5])
-
- def testKeysWorks(self):
- t = self._makeOne()
- for x in range(100):
- t[x] = x
- v = t.keys()
- i = 0
- for x in v:
- self.assertEqual(x,i)
- i = i + 1
- self.assertRaises(IndexError, lambda: v[i])
-
- for x in range(40):
- lst = t.keys(0+x,99-x)
- self.assertEqual(list(lst), range(0+x, 99-x+1))
-
- lst = t.keys(max=99-x, min=0+x)
- self.assertEqual(list(lst), range(0+x, 99-x+1))
-
- self.assertEqual(len(v), 100)
-
- def testKeysNegativeIndex(self):
- t = self._makeOne()
- L = [-3, 6, -11, 4]
- for i in L:
- t[i] = i
- L.sort()
- keys = t.keys()
- for i in range(-1, -5, -1):
- self.assertEqual(keys[i], L[i])
- self.assertRaises(IndexError, lambda: keys[-5])
-
- def testItemsWorks(self):
- t = self._makeOne()
- for x in range(100):
- t[x] = 2*x
- v = t.items()
- i = 0
- for x in v:
- self.assertEqual(x[0], i)
- self.assertEqual(x[1], 2*i)
- i += 1
- self.assertRaises(IndexError, lambda: v[i+1])
-
- i = 0
- for x in t.iteritems():
- self.assertEqual(x, (i, 2*i))
- i += 1
-
- items = list(t.items(min=12, max=20))
- self.assertEqual(items, zip(range(12, 21), range(24, 43, 2)))
-
- items = list(t.iteritems(min=12, max=20))
- self.assertEqual(items, zip(range(12, 21), range(24, 43, 2)))
-
- def testItemsNegativeIndex(self):
- t = self._makeOne()
- L = [-3, 6, -11, 4]
- for i in L:
- t[i] = i
- L.sort()
- items = t.items()
- for i in range(-1, -5, -1):
- self.assertEqual(items[i], (L[i], L[i]))
- self.assertRaises(IndexError, lambda: items[-5])
-
- def testDeleteInvalidKeyRaisesKeyError(self):
- self.assertRaises(KeyError, self._deletefail)
-
- def _deletefail(self):
- t = self._makeOne()
- del t[1]
-
- def testMaxKeyMinKey(self):
- t = self._makeOne()
- t[7] = 6
- t[3] = 10
- t[8] = 12
- t[1] = 100
- t[5] = 200
- t[10] = 500
- t[6] = 99
- t[4] = 150
- del t[7]
- self.assertEqual(t.maxKey(), 10)
- self.assertEqual(t.maxKey(6), 6)
- self.assertEqual(t.maxKey(9), 8)
- self.assertEqual(t.minKey(), 1)
- self.assertEqual(t.minKey(3), 3)
- self.assertEqual(t.minKey(9), 10)
-
- try:
- t.maxKey(t.minKey() - 1)
- except ValueError, err:
- self.assertEqual(str(err), "no key satisfies the conditions")
- else:
- self.fail("expected ValueError")
-
- try:
- t.minKey(t.maxKey() + 1)
- except ValueError, err:
- self.assertEqual(str(err), "no key satisfies the conditions")
- else:
- self.fail("expected ValueError")
-
- def testClear(self):
- import random
- t = self._makeOne()
- r = range(100)
- for x in r:
- rnd = random.choice(r)
- t[rnd] = 0
- t.clear()
- diff = lsubtract(list(t.keys()), [])
- self.assertEqual(diff, [])
-
- def testUpdate(self):
- import random
- t = self._makeOne()
- d={}
- l=[]
- for i in range(10000):
- k=random.randrange(-2000, 2001)
- d[k]=i
- l.append((k, i))
-
- items=d.items()
- items.sort()
-
- t.update(d)
- self.assertEqual(list(t.items()), items)
-
- t.clear()
- self.assertEqual(list(t.items()), [])
-
- t.update(l)
- self.assertEqual(list(t.items()), items)
-
- # Before ZODB 3.4.2, update/construction from PersistentMapping failed.
- def testUpdateFromPersistentMapping(self):
- from persistent.mapping import PersistentMapping
- t = self._makeOne()
- pm = PersistentMapping({1: 2})
- t.update(pm)
- self.assertEqual(list(t.items()), [(1, 2)])
-
- # Construction goes thru the same internals as .update().
- t = t.__class__(pm)
- self.assertEqual(list(t.items()), [(1, 2)])
-
- def testEmptyRangeSearches(self):
- t = self._makeOne()
- t.update([(1,1), (5,5), (9,9)])
- self.assertEqual(list(t.keys(-6,-4)), [], list(t.keys(-6,-4)))
- self.assertEqual(list(t.keys(2,4)), [], list(t.keys(2,4)))
- self.assertEqual(list(t.keys(6,8)), [], list(t.keys(6,8)))
- self.assertEqual(list(t.keys(10,12)), [], list(t.keys(10,12)))
- self.assertEqual(list(t.keys(9, 1)), [], list(t.keys(9, 1)))
-
- # For IITreeSets, this one was returning 31 for len(keys), and
- # list(keys) produced a list with 100 elements.
- t.clear()
- t.update(zip(range(300), range(300)))
- keys = t.keys(200, 50)
- self.assertEqual(len(keys), 0)
- self.assertEqual(list(keys), [])
- self.assertEqual(list(t.iterkeys(200, 50)), [])
-
- keys = t.keys(max=50, min=200)
- self.assertEqual(len(keys), 0)
- self.assertEqual(list(keys), [])
- self.assertEqual(list(t.iterkeys(max=50, min=200)), [])
-
- def testSlicing(self):
- # Test that slicing of .keys()/.values()/.items() works exactly the
- # same way as slicing a Python list with the same contents.
- # This tests fixes to several bugs in this area, starting with
- # http://collector.zope.org/Zope/419,
- # "BTreeItems slice contains 1 too many elements".
- t = self._makeOne()
- for n in range(10):
- t.clear()
- self.assertEqual(len(t), 0)
-
- keys = []
- values = []
- items = []
- for key in range(n):
- value = -2 * key
- t[key] = value
- keys.append(key)
- values.append(value)
- items.append((key, value))
- self.assertEqual(len(t), n)
-
- kslice = t.keys()
- vslice = t.values()
- islice = t.items()
- self.assertEqual(len(kslice), n)
- self.assertEqual(len(vslice), n)
- self.assertEqual(len(islice), n)
-
- # Test whole-structure slices.
- x = kslice[:]
- self.assertEqual(list(x), keys[:])
-
- x = vslice[:]
- self.assertEqual(list(x), values[:])
-
- x = islice[:]
- self.assertEqual(list(x), items[:])
-
- for lo in range(-2*n, 2*n+1):
- # Test one-sided slices.
- x = kslice[:lo]
- self.assertEqual(list(x), keys[:lo])
- x = kslice[lo:]
- self.assertEqual(list(x), keys[lo:])
-
- x = vslice[:lo]
- self.assertEqual(list(x), values[:lo])
- x = vslice[lo:]
- self.assertEqual(list(x), values[lo:])
-
- x = islice[:lo]
- self.assertEqual(list(x), items[:lo])
- x = islice[lo:]
- self.assertEqual(list(x), items[lo:])
-
- for hi in range(-2*n, 2*n+1):
- # Test two-sided slices.
- x = kslice[lo:hi]
- self.assertEqual(list(x), keys[lo:hi])
-
- x = vslice[lo:hi]
- self.assertEqual(list(x), values[lo:hi])
-
- x = islice[lo:hi]
- self.assertEqual(list(x), items[lo:hi])
-
- # The specific test case from Zope collector 419.
- t.clear()
- for i in xrange(100):
- t[i] = 1
- tslice = t.items()[20:80]
- self.assertEqual(len(tslice), 60)
- self.assertEqual(list(tslice), zip(range(20, 80), [1]*60))
-
- def testIterators(self):
- t = self._makeOne()
-
- for keys in [], [-2], [1, 4], range(-170, 2000, 6):
- t.clear()
- for k in keys:
- t[k] = -3 * k
-
- self.assertEqual(list(t), keys)
-
- x = []
- for k in t:
- x.append(k)
- self.assertEqual(x, keys)
-
- it = iter(t)
- self.assert_(it is iter(it))
- x = []
- try:
- while 1:
- x.append(it.next())
- except StopIteration:
- pass
- self.assertEqual(x, keys)
-
- self.assertEqual(list(t.iterkeys()), keys)
- self.assertEqual(list(t.itervalues()), list(t.values()))
- self.assertEqual(list(t.iteritems()), list(t.items()))
-
- def testRangedIterators(self):
- t = self._makeOne()
-
- for keys in [], [-2], [1, 4], range(-170, 2000, 13):
- t.clear()
- values = []
- for k in keys:
- value = -3 * k
- t[k] = value
- values.append(value)
- items = zip(keys, values)
-
- self.assertEqual(list(t.iterkeys()), keys)
- self.assertEqual(list(t.itervalues()), values)
- self.assertEqual(list(t.iteritems()), items)
-
- if not keys:
- continue
-
- min_mid_max = (keys[0], keys[len(keys) >> 1], keys[-1])
- for key1 in min_mid_max:
- for lo in range(key1 - 1, key1 + 2):
- # Test one-sided range iterators.
- goodkeys = [k for k in keys if lo <= k]
- got = t.iterkeys(lo)
- self.assertEqual(goodkeys, list(got))
-
- goodvalues = [t[k] for k in goodkeys]
- got = t.itervalues(lo)
- self.assertEqual(goodvalues, list(got))
-
- gooditems = zip(goodkeys, goodvalues)
- got = t.iteritems(lo)
- self.assertEqual(gooditems, list(got))
-
- for key2 in min_mid_max:
- for hi in range(key2 - 1, key2 + 2):
- goodkeys = [k for k in keys if lo <= k <= hi]
- got = t.iterkeys(min=lo, max=hi)
- self.assertEqual(goodkeys, list(got))
-
- goodvalues = [t[k] for k in goodkeys]
- got = t.itervalues(lo, max=hi)
- self.assertEqual(goodvalues, list(got))
-
- gooditems = zip(goodkeys, goodvalues)
- got = t.iteritems(max=hi, min=lo)
- self.assertEqual(gooditems, list(got))
-
- def testBadUpdateTupleSize(self):
- # This one silently ignored the excess in Zope3.
- t = self._makeOne()
- self.assertRaises(TypeError, t.update, [(1, 2, 3)])
-
- # This one dumped core in Zope3.
- self.assertRaises(TypeError, t.update, [(1,)])
-
- # This one should simply succeed.
- t.update([(1, 2)])
- self.assertEqual(list(t.items()), [(1, 2)])
-
- def testSimpleExclusivRanges(self):
- def identity(x):
- return x
- def dup(x):
- return [(y, y) for y in x]
-
- for methodname, f in (("keys", identity),
- ("values", identity),
- ("items", dup),
- ("iterkeys", identity),
- ("itervalues", identity),
- ("iteritems", dup)):
-
- t = self._makeOne()
- meth = getattr(t, methodname, None)
- if meth is None:
- continue
-
- self.assertEqual(list(meth()), [])
- self.assertEqual(list(meth(excludemin=True)), [])
- self.assertEqual(list(meth(excludemax=True)), [])
- self.assertEqual(list(meth(excludemin=True, excludemax=True)), [])
-
- self._populate(t, 1)
- self.assertEqual(list(meth()), f([0]))
- self.assertEqual(list(meth(excludemin=True)), [])
- self.assertEqual(list(meth(excludemax=True)), [])
- self.assertEqual(list(meth(excludemin=True, excludemax=True)), [])
-
- t.clear()
- self._populate(t, 2)
- self.assertEqual(list(meth()), f([0, 1]))
- self.assertEqual(list(meth(excludemin=True)), f([1]))
- self.assertEqual(list(meth(excludemax=True)), f([0]))
- self.assertEqual(list(meth(excludemin=True, excludemax=True)), [])
-
- t.clear()
- self._populate(t, 3)
- self.assertEqual(list(meth()), f([0, 1, 2]))
- self.assertEqual(list(meth(excludemin=True)), f([1, 2]))
- self.assertEqual(list(meth(excludemax=True)), f([0, 1]))
- self.assertEqual(list(meth(excludemin=True, excludemax=True)),
- f([1]))
- self.assertEqual(list(meth(-1, 3, excludemin=True,
- excludemax=True)),
- f([0, 1, 2]))
- self.assertEqual(list(meth(0, 3, excludemin=True,
- excludemax=True)),
- f([1, 2]))
- self.assertEqual(list(meth(-1, 2, excludemin=True,
- excludemax=True)),
- f([0, 1]))
- self.assertEqual(list(meth(0, 2, excludemin=True,
- excludemax=True)),
- f([1]))
-
- def testSetdefault(self):
- t = self._makeOne()
-
- self.assertEqual(t.setdefault(1, 2), 2)
- # That should also have associated 1 with 2 in the tree.
- self.assert_(1 in t)
- self.assertEqual(t[1], 2)
- # And trying to change it again should have no effect.
- self.assertEqual(t.setdefault(1, 666), 2)
- self.assertEqual(t[1], 2)
-
- # Not enough arguments.
- self.assertRaises(TypeError, t.setdefault)
- self.assertRaises(TypeError, t.setdefault, 1)
- # Too many arguments.
- self.assertRaises(TypeError, t.setdefault, 1, 2, 3)
-
-
- def testPop(self):
- t = self._makeOne()
-
- # Empty container.
- # If no default given, raises KeyError.
- self.assertRaises(KeyError, t.pop, 1)
- # But if default given, returns that instead.
- self.assertEqual(t.pop(1, 42), 42)
-
- t[1] = 3
- # KeyError when key is not in container and default is not passed.
- self.assertRaises(KeyError, t.pop, 5)
- self.assertEqual(list(t.items()), [(1, 3)])
- # If key is in container, returns the value and deletes the key.
- self.assertEqual(t.pop(1), 3)
- self.assertEqual(len(t), 0)
-
- # If key is present, return value bypassing default.
- t[1] = 3
- self.assertEqual(t.pop(1, 7), 3)
- self.assertEqual(len(t), 0)
-
- # Pop only one item.
- t[1] = 3
- t[2] = 4
- self.assertEqual(len(t), 2)
- self.assertEqual(t.pop(1), 3)
- self.assertEqual(len(t), 1)
- self.assertEqual(t[2], 4)
- self.assertEqual(t.pop(1, 3), 3)
-
- # Too few arguments.
- self.assertRaises(TypeError, t.pop)
- # Too many arguments.
- self.assertRaises(TypeError, t.pop, 1, 2, 3)
-
-
-class NormalSetTests(Base):
- # Test common to all set types
-
- def _populate(self, t, l):
- # Make some data
- t.update(range(l))
-
- def testInsertReturnsValue(self):
- t = self._makeOne()
- self.assertEqual(t.insert(5) , 1)
- self.assertEqual(t.add(4) , 1)
-
- def testDuplicateInsert(self):
- t = self._makeOne()
- t.insert(5)
- self.assertEqual(t.insert(5) , 0)
- self.assertEqual(t.add(5) , 0)
-
- def testInsert(self):
- t = self._makeOne()
- t.insert(1)
- self.assert_(t.has_key(1))
- self.assert_(1 in t)
- self.assert_(2 not in t)
-
- def testBigInsert(self):
- t = self._makeOne()
- r = xrange(10000)
- for x in r:
- t.insert(x)
- for x in r:
- self.assert_(t.has_key(x))
- self.assert_(x in t)
-
- def testRemoveSucceeds(self):
- t = self._makeOne()
- r = xrange(10000)
- for x in r: t.insert(x)
- for x in r: t.remove(x)
-
- def testRemoveFails(self):
- self.assertRaises(KeyError, self._removenonexistent)
-
- def _removenonexistent(self):
- self._makeOne().remove(1)
-
- def testHasKeyFails(self):
- t = self._makeOne()
- self.assert_(not t.has_key(1))
- self.assert_(1 not in t)
-
- def testKeys(self):
- t = self._makeOne()
- r = xrange(1000)
- for x in r:
- t.insert(x)
- diff = lsubtract(t.keys(), r)
- self.assertEqual(diff, [])
-
-
- def testClear(self):
- t = self._makeOne()
- r = xrange(1000)
- for x in r: t.insert(x)
- t.clear()
- diff = lsubtract(t.keys(), [])
- self.assertEqual(diff , [], diff)
-
- def testMaxKeyMinKey(self):
- t = self._makeOne()
- t.insert(1)
- t.insert(2)
- t.insert(3)
- t.insert(8)
- t.insert(5)
- t.insert(10)
- t.insert(6)
- t.insert(4)
- self.assertEqual(t.maxKey() , 10)
- self.assertEqual(t.maxKey(6) , 6)
- self.assertEqual(t.maxKey(9) , 8)
- self.assertEqual(t.minKey() , 1)
- self.assertEqual(t.minKey(3) , 3)
- self.assertEqual(t.minKey(9) , 10)
- self.assert_(t.minKey() in t)
- self.assert_(t.minKey()-1 not in t)
- self.assert_(t.maxKey() in t)
- self.assert_(t.maxKey()+1 not in t)
-
- try:
- t.maxKey(t.minKey() - 1)
- except ValueError, err:
- self.assertEqual(str(err), "no key satisfies the conditions")
- else:
- self.fail("expected ValueError")
-
- try:
- t.minKey(t.maxKey() + 1)
- except ValueError, err:
- self.assertEqual(str(err), "no key satisfies the conditions")
- else:
- self.fail("expected ValueError")
-
- def testUpdate(self):
- import random
- t = self._makeOne()
- d={}
- l=[]
- for i in range(10000):
- k=random.randrange(-2000, 2001)
- d[k]=i
- l.append(k)
-
- items = d.keys()
- items.sort()
-
- t.update(l)
- self.assertEqual(list(t.keys()), items)
-
- def testEmptyRangeSearches(self):
- t = self._makeOne()
- t.update([1, 5, 9])
- self.assertEqual(list(t.keys(-6,-4)), [], list(t.keys(-6,-4)))
- self.assertEqual(list(t.keys(2,4)), [], list(t.keys(2,4)))
- self.assertEqual(list(t.keys(6,8)), [], list(t.keys(6,8)))
- self.assertEqual(list(t.keys(10,12)), [], list(t.keys(10,12)))
- self.assertEqual(list(t.keys(9,1)), [], list(t.keys(9,1)))
-
- # For IITreeSets, this one was returning 31 for len(keys), and
- # list(keys) produced a list with 100 elements.
- t.clear()
- t.update(range(300))
- keys = t.keys(200, 50)
- self.assertEqual(len(keys), 0)
- self.assertEqual(list(keys), [])
-
- keys = t.keys(max=50, min=200)
- self.assertEqual(len(keys), 0)
- self.assertEqual(list(keys), [])
-
- def testSlicing(self):
- # Test that slicing of .keys() works exactly the same way as slicing
- # a Python list with the same contents.
- t = self._makeOne()
- for n in range(10):
- t.clear()
- self.assertEqual(len(t), 0)
-
- keys = range(10*n, 11*n)
- t.update(keys)
- self.assertEqual(len(t), n)
-
- kslice = t.keys()
- self.assertEqual(len(kslice), n)
-
- # Test whole-structure slices.
- x = kslice[:]
- self.assertEqual(list(x), keys[:])
-
- for lo in range(-2*n, 2*n+1):
- # Test one-sided slices.
- x = kslice[:lo]
- self.assertEqual(list(x), keys[:lo])
- x = kslice[lo:]
- self.assertEqual(list(x), keys[lo:])
-
- for hi in range(-2*n, 2*n+1):
- # Test two-sided slices.
- x = kslice[lo:hi]
- self.assertEqual(list(x), keys[lo:hi])
-
- def testIterator(self):
- t = self._makeOne()
-
- for keys in [], [-2], [1, 4], range(-170, 2000, 6):
- t.clear()
- t.update(keys)
-
- self.assertEqual(list(t), keys)
-
- x = []
- for k in t:
- x.append(k)
- self.assertEqual(x, keys)
-
- it = iter(t)
- self.assert_(it is iter(it))
- x = []
- try:
- while 1:
- x.append(it.next())
- except StopIteration:
- pass
- self.assertEqual(x, keys)
-
-class ExtendedSetTests(NormalSetTests):
-
- def testLen(self):
- t = self._makeOne()
- r = xrange(10000)
- for x in r: t.insert(x)
- self.assertEqual(len(t) , 10000, len(t))
-
- def testGetItem(self):
- t = self._makeOne()
- r = xrange(10000)
- for x in r: t.insert(x)
- for x in r:
- self.assertEqual(t[x] , x)
-
-
-LARGEST_32_BITS = 2147483647
-SMALLEST_32_BITS = -LARGEST_32_BITS - 1
-
-SMALLEST_POSITIVE_33_BITS = LARGEST_32_BITS + 1
-LARGEST_NEGATIVE_33_BITS = SMALLEST_32_BITS - 1
-
-LARGEST_64_BITS = 0x7fffffffffffffff
-SMALLEST_64_BITS = -LARGEST_64_BITS - 1
-
-SMALLEST_POSITIVE_65_BITS = LARGEST_64_BITS + 1
-LARGEST_NEGATIVE_65_BITS = SMALLEST_64_BITS - 1
-
-class TestLongIntSupport:
-
- def getTwoValues(self):
- # Return two distinct values; these must compare as un-equal.
- #
- # These values must be usable as values.
- return object(), object()
-
- def getTwoKeys(self):
- # Return two distinct values, these must compare as un-equal.
- #
- #These values must be usable as keys.
- return 0, 1
-
- def _set_value(self, key, value):
- t = self._makeOne()
- t[key] = value
-
-class TestLongIntKeys(TestLongIntSupport):
-
- def testLongIntKeysWork(self):
- from BTrees.IIBTree import using64bits
- if not using64bits:
- return
- t = self._makeOne()
- o1, o2 = self.getTwoValues()
- assert o1 != o2
-
- # Test some small key values first:
- t[0L] = o1
- self.assertEqual(t[0], o1)
- t[0] = o2
- self.assertEqual(t[0L], o2)
- self.assertEqual(list(t.keys()), [0])
-
- # Test some large key values too:
- k1 = SMALLEST_POSITIVE_33_BITS
- k2 = LARGEST_64_BITS
- k3 = SMALLEST_64_BITS
- t[k1] = o1
- t[k2] = o2
- t[k3] = o1
- self.assertEqual(t[k1], o1)
- self.assertEqual(t[k2], o2)
- self.assertEqual(t[k3], o1)
- self.assertEqual(list(t.keys()), [k3, 0, k1, k2])
-
- def testLongIntKeysOutOfRange(self):
- from BTrees.IIBTree import using64bits
- if not using64bits:
- return
- o1, o2 = self.getTwoValues()
- self.assertRaises(
- ValueError,
- self._set_value, SMALLEST_POSITIVE_65_BITS, o1)
- self.assertRaises(
- ValueError,
- self._set_value, LARGEST_NEGATIVE_65_BITS, o1)
-
-class TestLongIntValues(TestLongIntSupport):
-
- def testLongIntValuesWork(self):
- from BTrees.IIBTree import using64bits
- if not using64bits:
- return
- t = self._makeOne()
- keys = list(self.getTwoKeys())
- keys.sort()
- k1, k2 = keys
- assert k1 != k2
-
- # This is the smallest positive integer that requires 33 bits:
- v1 = SMALLEST_POSITIVE_33_BITS
- v2 = v1 + 1
-
- t[k1] = v1
- t[k2] = v2
- self.assertEqual(t[k1], v1)
- self.assertEqual(t[k2], v2)
- self.assertEqual(list(t.values()), [v1, v2])
-
- def testLongIntValuesOutOfRange(self):
- from BTrees.IIBTree import using64bits
- if not using64bits:
- return
- k1, k2 = self.getTwoKeys()
- self.assertRaises(
- ValueError,
- self._set_value, k1, SMALLEST_POSITIVE_65_BITS)
- self.assertRaises(
- ValueError,
- self._set_value, k1, LARGEST_NEGATIVE_65_BITS)
-
-
-# tests of various type errors
-
-class TypeTest(object):
-
- def testBadTypeRaises(self):
- self.assertRaises(TypeError, self._stringraises)
- self.assertRaises(TypeError, self._floatraises)
- self.assertRaises(TypeError, self._noneraises)
-
-class TestIOBTrees(TypeTest, unittest.TestCase):
- def _makeOne(self):
- from BTrees.IOBTree import IOBTree
- return IOBTree()
-
- def _stringraises(self):
- self._makeOne()['c'] = 1
-
- def _floatraises(self):
- self._makeOne()[2.5] = 1
-
- def _noneraises(self):
- self._makeOne()[None] = 1
-
-class TestOIBTrees(TypeTest, unittest.TestCase):
- def _makeOne(self):
- from BTrees.OIBTree import OIBTree
- return OIBTree()
-
- def _stringraises(self):
- self._makeOne()[1] = 'c'
-
- def _floatraises(self):
- self._makeOne()[1] = 1.4
-
- def _noneraises(self):
- self._makeOne()[1] = None
-
- def testEmptyFirstBucketReportedByGuido(self):
- b = self._makeOne()
- for i in xrange(29972): # reduce to 29971 and it works
- b[i] = i
- for i in xrange(30): # reduce to 29 and it works
- del b[i]
- b[i+40000] = i
-
- self.assertEqual(b.keys()[0], 30)
-
-class TestIIBTrees(unittest.TestCase):
- def _makeOne(self):
- from BTrees.IIBTree import IIBTree
- return IIBTree()
-
- def testNonIntegerKeyRaises(self):
- self.assertRaises(TypeError, self._stringraiseskey)
- self.assertRaises(TypeError, self._floatraiseskey)
- self.assertRaises(TypeError, self._noneraiseskey)
-
- def testNonIntegerValueRaises(self):
- self.assertRaises(TypeError, self._stringraisesvalue)
- self.assertRaises(TypeError, self._floatraisesvalue)
- self.assertRaises(TypeError, self._noneraisesvalue)
-
- def _stringraiseskey(self):
- self._makeOne()['c'] = 1
-
- def _floatraiseskey(self):
- self._makeOne()[2.5] = 1
-
- def _noneraiseskey(self):
- self._makeOne()[None] = 1
-
- def _stringraisesvalue(self):
- self._makeOne()[1] = 'c'
-
- def _floatraisesvalue(self):
- self._makeOne()[1] = 1.4
-
- def _noneraisesvalue(self):
- self._makeOne()[1] = None
-
-class TestIFBTrees(unittest.TestCase):
- def _makeOne(self):
- from BTrees.IFBTree import IFBTree
- return IFBTree()
-
- def testNonIntegerKeyRaises(self):
- self.assertRaises(TypeError, self._stringraiseskey)
- self.assertRaises(TypeError, self._floatraiseskey)
- self.assertRaises(TypeError, self._noneraiseskey)
-
- def testNonNumericValueRaises(self):
- self.assertRaises(TypeError, self._stringraisesvalue)
- self.assertRaises(TypeError, self._noneraisesvalue)
- self._makeOne()[1] = 1
- self._makeOne()[1] = 1.0
-
- def _stringraiseskey(self):
- self._makeOne()['c'] = 1
-
- def _floatraiseskey(self):
- self._makeOne()[2.5] = 1
-
- def _noneraiseskey(self):
- self._makeOne()[None] = 1
-
- def _stringraisesvalue(self):
- self._makeOne()[1] = 'c'
-
- def _floatraisesvalue(self):
- self._makeOne()[1] = 1.4
-
- def _noneraisesvalue(self):
- self._makeOne()[1] = None
-
-class I_SetsBase(object):
-
- def testBadBadKeyAfterFirst(self):
- t = self._makeOne()
- self.assertRaises(TypeError, t.__class__, [1, ''])
- self.assertRaises(TypeError, t.update, [1, ''])
-
- def testNonIntegerInsertRaises(self):
- self.assertRaises(TypeError,self._insertstringraises)
- self.assertRaises(TypeError,self._insertfloatraises)
- self.assertRaises(TypeError,self._insertnoneraises)
-
- def _insertstringraises(self):
- self._makeOne().insert('a')
-
- def _insertfloatraises(self):
- self._makeOne().insert(1.4)
-
- def _insertnoneraises(self):
- self._makeOne().insert(None)
-
-class TestIOSets(I_SetsBase, unittest.TestCase):
-
- def _makeOne(self):
- from BTrees.IOBTree import IOSet
- return IOSet()
-
-class TestIOTreeSets(I_SetsBase, unittest.TestCase):
-
- def _makeOne(self):
- from BTrees.IOBTree import IOTreeSet
- return IOTreeSet()
-
-class TestIISets(I_SetsBase, unittest.TestCase):
-
- def _makeOne(self):
- from BTrees.IIBTree import IISet
- return IISet()
-
-class TestIITreeSets(I_SetsBase, unittest.TestCase):
-
- def _makeOne(self):
- from BTrees.IIBTree import IITreeSet
- return IITreeSet()
-
-class TestLOSets(I_SetsBase, unittest.TestCase):
-
- def _makeOne(self):
- from BTrees.LOBTree import LOSet
- return LOSet()
-
-class TestLOTreeSets(I_SetsBase, unittest.TestCase):
-
- def _makeOne(self):
- from BTrees.LOBTree import LOTreeSet
- return LOTreeSet()
-
-class TestLLSets(I_SetsBase, unittest.TestCase):
-
- def _makeOne(self):
- from BTrees.LLBTree import LLSet
- return LLSet()
-
-class TestLLTreeSets(I_SetsBase, unittest.TestCase):
-
- def _makeOne(self):
- from BTrees.LLBTree import LLTreeSet
- return LLTreeSet()
-
-
class DegenerateBTree(unittest.TestCase):
# Build a degenerate tree (set). Boxes are BTree nodes. There are
# 5 leaf buckets, each containing a single int. Keys in the BTree
@@ -1407,8 +187,10 @@
# at some unrelated line.
del t # trigger destructor
+
LP294788_ids = {}
+
class ToBeDeleted(object):
def __init__(self, id):
assert type(id) is int #we don't want to store any object ref here
@@ -1427,6 +209,7 @@
def __hash__(self):
return hash(self.id)
+
class BugFixes(unittest.TestCase):
# Collector 1843. Error returns were effectively ignored in
@@ -1596,461 +379,18 @@
self.assertEqual(len(t), 0)
self.assertEqual(len(LP294788_ids), 0)
-class BTreeTests(MappingBase):
- # Tests common to all BTrees
- def _checkIt(self, t):
- from BTrees.check import check
- t._check()
- check(t)
-
- def testDeleteNoChildrenWorks(self):
- t = self._makeOne()
- t[5] = 6
- t[2] = 10
- t[6] = 12
- t[1] = 100
- t[3] = 200
- t[10] = 500
- t[4] = 99
- del t[4]
- diff = lsubtract(t.keys(), [1,2,3,5,6,10])
- self.assertEqual(diff , [], diff)
- self._checkIt(t)
-
- def testDeleteOneChildWorks(self):
- t = self._makeOne()
- t[5] = 6
- t[2] = 10
- t[6] = 12
- t[1] = 100
- t[3] = 200
- t[10] = 500
- t[4] = 99
- del t[3]
- diff = lsubtract(t.keys(), [1,2,4,5,6,10])
- self.assertEqual(diff , [], diff)
- self._checkIt(t)
-
- def testDeleteTwoChildrenNoInorderSuccessorWorks(self):
- t = self._makeOne()
- t[5] = 6
- t[2] = 10
- t[6] = 12
- t[1] = 100
- t[3] = 200
- t[10] = 500
- t[4] = 99
- del t[2]
- diff = lsubtract(t.keys(), [1,3,4,5,6,10])
- self.assertEqual(diff , [], diff)
- self._checkIt(t)
-
- def testDeleteTwoChildrenInorderSuccessorWorks(self):
- # 7, 3, 8, 1, 5, 10, 6, 4 -- del 3
- t = self._makeOne()
- t[7] = 6
- t[3] = 10
- t[8] = 12
- t[1] = 100
- t[5] = 200
- t[10] = 500
- t[6] = 99
- t[4] = 150
- del t[3]
- diff = lsubtract(t.keys(), [1,4,5,6,7,8,10])
- self.assertEqual(diff , [], diff)
- self._checkIt(t)
-
- def testDeleteRootWorks(self):
- # 7, 3, 8, 1, 5, 10, 6, 4 -- del 7
- t = self._makeOne()
- t[7] = 6
- t[3] = 10
- t[8] = 12
- t[1] = 100
- t[5] = 200
- t[10] = 500
- t[6] = 99
- t[4] = 150
- del t[7]
- diff = lsubtract(t.keys(), [1,3,4,5,6,8,10])
- self.assertEqual(diff , [], diff)
- self._checkIt(t)
-
- def testRandomNonOverlappingInserts(self):
- import random
- t = self._makeOne()
- added = {}
- r = range(100)
- for x in r:
- k = random.choice(r)
- if not added.has_key(k):
- t[k] = x
- added[k] = 1
- addl = added.keys()
- addl.sort()
- diff = lsubtract(list(t.keys()), addl)
- self.assertEqual(diff , [], (diff, addl, list(t.keys())))
- self._checkIt(t)
-
- def testRandomOverlappingInserts(self):
- import random
- t = self._makeOne()
- added = {}
- r = range(100)
- for x in r:
- k = random.choice(r)
- t[k] = x
- added[k] = 1
- addl = added.keys()
- addl.sort()
- diff = lsubtract(t.keys(), addl)
- self.assertEqual(diff , [], diff)
- self._checkIt(t)
-
- def testRandomDeletes(self):
- import random
- t = self._makeOne()
- r = range(1000)
- added = []
- for x in r:
- k = random.choice(r)
- t[k] = x
- added.append(k)
- deleted = []
- for x in r:
- k = random.choice(r)
- if t.has_key(k):
- self.assert_(k in t)
- del t[k]
- deleted.append(k)
- if t.has_key(k):
- self.fail( "had problems deleting %s" % k )
- badones = []
- for x in deleted:
- if t.has_key(x):
- badones.append(x)
- self.assertEqual(badones , [], (badones, added, deleted))
- self._checkIt(t)
-
- def testTargetedDeletes(self):
- import random
- t = self._makeOne()
- r = range(1000)
- for x in r:
- k = random.choice(r)
- t[k] = x
- for x in r:
- try:
- del t[x]
- except KeyError:
- pass
- self.assertEqual(realseq(t.keys()) , [], realseq(t.keys()))
- self._checkIt(t)
-
- def testPathologicalRightBranching(self):
- t = self._makeOne()
- r = range(1000)
- for x in r:
- t[x] = 1
- self.assertEqual(realseq(t.keys()) , r, realseq(t.keys()))
- for x in r:
- del t[x]
- self.assertEqual(realseq(t.keys()) , [], realseq(t.keys()))
- self._checkIt(t)
-
- def testPathologicalLeftBranching(self):
- t = self._makeOne()
- r = range(1000)
- revr = r[:]
- revr.reverse()
- for x in revr:
- t[x] = 1
- self.assertEqual(realseq(t.keys()) , r, realseq(t.keys()))
-
- for x in revr:
- del t[x]
- self.assertEqual(realseq(t.keys()) , [], realseq(t.keys()))
- self._checkIt(t)
-
- def testSuccessorChildParentRewriteExerciseCase(self):
- t = self._makeOne()
- add_order = [
- 85, 73, 165, 273, 215, 142, 233, 67, 86, 166, 235, 225, 255,
- 73, 175, 171, 285, 162, 108, 28, 283, 258, 232, 199, 260,
- 298, 275, 44, 261, 291, 4, 181, 285, 289, 216, 212, 129,
- 243, 97, 48, 48, 159, 22, 285, 92, 110, 27, 55, 202, 294,
- 113, 251, 193, 290, 55, 58, 239, 71, 4, 75, 129, 91, 111,
- 271, 101, 289, 194, 218, 77, 142, 94, 100, 115, 101, 226,
- 17, 94, 56, 18, 163, 93, 199, 286, 213, 126, 240, 245, 190,
- 195, 204, 100, 199, 161, 292, 202, 48, 165, 6, 173, 40, 218,
- 271, 228, 7, 166, 173, 138, 93, 22, 140, 41, 234, 17, 249,
- 215, 12, 292, 246, 272, 260, 140, 58, 2, 91, 246, 189, 116,
- 72, 259, 34, 120, 263, 168, 298, 118, 18, 28, 299, 192, 252,
- 112, 60, 277, 273, 286, 15, 263, 141, 241, 172, 255, 52, 89,
- 127, 119, 255, 184, 213, 44, 116, 231, 173, 298, 178, 196,
- 89, 184, 289, 98, 216, 115, 35, 132, 278, 238, 20, 241, 128,
- 179, 159, 107, 206, 194, 31, 260, 122, 56, 144, 118, 283,
- 183, 215, 214, 87, 33, 205, 183, 212, 221, 216, 296, 40,
- 108, 45, 188, 139, 38, 256, 276, 114, 270, 112, 214, 191,
- 147, 111, 299, 107, 101, 43, 84, 127, 67, 205, 251, 38, 91,
- 297, 26, 165, 187, 19, 6, 73, 4, 176, 195, 90, 71, 30, 82,
- 139, 210, 8, 41, 253, 127, 190, 102, 280, 26, 233, 32, 257,
- 194, 263, 203, 190, 111, 218, 199, 29, 81, 207, 18, 180,
- 157, 172, 192, 135, 163, 275, 74, 296, 298, 265, 105, 191,
- 282, 277, 83, 188, 144, 259, 6, 173, 81, 107, 292, 231,
- 129, 65, 161, 113, 103, 136, 255, 285, 289, 1
- ]
- delete_order = [
- 276, 273, 12, 275, 2, 286, 127, 83, 92, 33, 101, 195,
- 299, 191, 22, 232, 291, 226, 110, 94, 257, 233, 215, 184,
- 35, 178, 18, 74, 296, 210, 298, 81, 265, 175, 116, 261,
- 212, 277, 260, 234, 6, 129, 31, 4, 235, 249, 34, 289, 105,
- 259, 91, 93, 119, 7, 183, 240, 41, 253, 290, 136, 75, 292,
- 67, 112, 111, 256, 163, 38, 126, 139, 98, 56, 282, 60, 26,
- 55, 245, 225, 32, 52, 40, 271, 29, 252, 239, 89, 87, 205,
- 213, 180, 97, 108, 120, 218, 44, 187, 196, 251, 202, 203,
- 172, 28, 188, 77, 90, 199, 297, 282, 141, 100, 161, 216,
- 73, 19, 17, 189, 30, 258
- ]
- for x in add_order:
- t[x] = 1
- for x in delete_order:
- try: del t[x]
- except KeyError:
- if t.has_key(x):
- self.assertEqual(1,2,"failed to delete %s" % x)
- self._checkIt(t)
-
- def testRangeSearchAfterSequentialInsert(self):
- t = self._makeOne()
- r = range(100)
- for x in r:
- t[x] = 0
- diff = lsubtract(list(t.keys(0, 100)), r)
- self.assertEqual(diff , [], diff)
- self._checkIt(t)
-
- def testRangeSearchAfterRandomInsert(self):
- import random
- t = self._makeOne()
- r = range(100)
- a = {}
- for x in r:
- rnd = random.choice(r)
- t[rnd] = 0
- a[rnd] = 0
- diff = lsubtract(list(t.keys(0, 100)), a.keys())
- self.assertEqual(diff, [], diff)
- self._checkIt(t)
-
- def testPathologicalRangeSearch(self):
- t = self._makeOne()
- # Build a 2-level tree with at least two buckets.
- for i in range(200):
- t[i] = i
- items, dummy = t.__getstate__()
- self.assert_(len(items) > 2) # at least two buckets and a key
- # All values in the first bucket are < firstkey. All in the
- # second bucket are >= firstkey, and firstkey is the first key in
- # the second bucket.
- firstkey = items[1]
- therange = t.keys(-1, firstkey)
- self.assertEqual(len(therange), firstkey + 1)
- self.assertEqual(list(therange), range(firstkey + 1))
- # Now for the tricky part. If we delete firstkey, the second bucket
- # loses its smallest key, but firstkey remains in the BTree node.
- # If we then do a high-end range search on firstkey, the BTree node
- # directs us to look in the second bucket, but there's no longer any
- # key <= firstkey in that bucket. The correct answer points to the
- # end of the *first* bucket. The algorithm has to be smart enough
- # to "go backwards" in the BTree then; if it doesn't, it will
- # erroneously claim that the range is empty.
- del t[firstkey]
- therange = t.keys(min=-1, max=firstkey)
- self.assertEqual(len(therange), firstkey)
- self.assertEqual(list(therange), range(firstkey))
- self._checkIt(t)
-
- def testInsertMethod(self):
- t = self._makeOne()
- t[0] = 1
- self.assertEqual(t.insert(0, 1) , 0)
- self.assertEqual(t.insert(1, 1) , 1)
- self.assertEqual(lsubtract(list(t.keys()), [0,1]) , [])
- self._checkIt(t)
-
- def testDamagedIterator(self):
- # A cute one from Steve Alexander. This caused the BTreeItems
- # object to go insane, accessing memory beyond the allocated part
- # of the bucket. If it fails, the symptom is either a C-level
- # assertion error (if the BTree code was compiled without NDEBUG),
- # or most likely a segfault (if the BTree code was compiled with
- # NDEBUG).
- t = self._makeOne()
- self._populate(t, 10)
- # In order for this to fail, it's important that k be a "lazy"
- # iterator, referring to the BTree by indirect position (index)
- # instead of a fully materialized list. Then the position can
- # end up pointing into trash memory, if the bucket pointed to
- # shrinks.
- k = t.keys()
- for dummy in range(20):
- try:
- del t[k[0]]
- except RuntimeError, detail:
- self.assertEqual(str(detail), "the bucket being iterated "
- "changed size")
- break
- self._checkIt(t)
-
-class IIBTreeTest(BTreeTests, unittest.TestCase):
- def _makeOne(self):
- from BTrees.IIBTree import IIBTree
- return IIBTree()
-
- def testIIBTreeOverflow(self):
- good = set()
- b = self._makeOne()
-
- def trial(i):
- i = int(i)
- try:
- b[i] = 0
- except TypeError:
- self.assertRaises(TypeError, b.__setitem__, 0, i)
- else:
- good.add(i)
- b[0] = i
- self.assertEqual(b[0], i)
-
- for i in range((1<<31) - 3, (1<<31) + 3):
- trial(i)
- trial(-i)
-
- del b[0]
- self.assertEqual(sorted(good), sorted(b))
-
-class IFBTreeTest(BTreeTests, unittest.TestCase):
- def _makeOne(self):
- from BTrees.IFBTree import IFBTree
- return IFBTree()
-
-class IOBTreeTest(BTreeTests, unittest.TestCase):
- def _makeOne(self):
- from BTrees.IOBTree import IOBTree
- return IOBTree()
-
-class OIBTreeTest(BTreeTests, unittest.TestCase):
- def _makeOne(self):
- from BTrees.OIBTree import OIBTree
- return OIBTree()
-
-class OOBTreeTest(BTreeTests, unittest.TestCase):
- def _makeOne(self):
- from BTrees.OOBTree import OOBTree
- return OOBTree()
-
- def testRejectDefaultComparison(self):
- # Check that passing int keys w default comparison fails.
- # Only applies to new-style class instances. Old-style
- # instances are too hard to introspect.
-
- # This is white box because we know that the check is being
- # used in a function that's used in lots of places.
- # Otherwise, there are many permutations that would have to be
- # checked.
- t = self._makeOne()
-
- class C(object):
- pass
-
- self.assertRaises(TypeError, lambda : t.__setitem__(C(), 1))
-
- class C(object):
- def __cmp__(*args):
- return 1
-
- c = C()
- t[c] = 1
-
- t.clear()
-
- class C(object):
- def __lt__(*args):
- return 1
-
- c = C()
- t[c] = 1
-
- t.clear()
-
-from BTrees.IIBTree import using64bits
-if using64bits:
-
- class IIBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues,
- unittest.TestCase):
- def _makeOne(self):
- from BTrees.IIBTree import IIBTree
- return IIBTree()
- def getTwoValues(self):
- return 1, 2
-
- class IFBTreeTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
- def _makeOne(self):
- from BTrees.IFBTree import IFBTree
- return IFBTree()
- def getTwoValues(self):
- return 0.5, 1.5
-
- class IOBTreeTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
- def _makeOne(self):
- from BTrees.IOBTree import IOBTree
- return IOBTree()
-
- class OIBTreeTest(BTreeTests, TestLongIntValues, unittest.TestCase):
- def _makeOne(self):
- from BTrees.OIBTree import OIBTree
- return OIBTree()
- def getTwoKeys(self):
- return object(), object()
-
-class LLBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues,
- unittest.TestCase):
- def _makeOne(self):
- from BTrees.LLBTree import LLBTree
- return LLBTree()
- def getTwoValues(self):
- return 1, 2
-
-class LFBTreeTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
- def _makeOne(self):
- from BTrees.LFBTree import LFBTree
- return LFBTree()
- def getTwoValues(self):
- return 0.5, 1.5
-
-class LOBTreeTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
- def _makeOne(self):
- from BTrees.LOBTree import LOBTree
- return LOBTree()
-
-class OLBTreeTest(BTreeTests, TestLongIntValues, unittest.TestCase):
- def _makeOne(self):
- from BTrees.OLBTree import OLBTree
- return OLBTree()
- def getTwoKeys(self):
- return object(), object()
-
-
# cmp error propagation tests
+
class DoesntLikeBeingCompared:
+
def __cmp__(self,other):
raise ValueError('incomparable')
+
class TestCmpError(unittest.TestCase):
+
def testFoo(self):
from BTrees.OOBTree import OOBTree
t = OOBTree()
@@ -2063,33 +403,7 @@
self.fail('incomarable objects should not be allowed into '
'the tree')
-# test for presence of generic names in module
-class ModuleTest(object):
- prefix = None
- def _getModule(self):
- pass
- def testNames(self):
- for name in ('Bucket', 'BTree', 'Set', 'TreeSet'):
- klass = getattr(self._getModule(), name)
- self.assertEqual(klass.__module__, self._getModule().__name__)
- self.assert_(klass is getattr(self._getModule(),
- self.prefix + name))
-
- def testModuleProvides(self):
- from zope.interface.verify import verifyObject
- verifyObject(self._getInterface(), self._getModule())
-
- def testFamily(self):
- import BTrees
- if self.prefix == 'OO':
- self.assert_(
- getattr(self._getModule(), 'family', self) is self)
- elif 'L' in self.prefix:
- self.assert_(self._getModule().family is BTrees.family64)
- elif 'I' in self.prefix:
- self.assert_(self._getModule().family is BTrees.family32)
-
class FamilyTest(unittest.TestCase):
def test32(self):
from zope.interface.verify import verifyObject
@@ -2143,6 +457,7 @@
s.insert(BTrees.family64.minint)
self.assert_(BTrees.family64.minint in s)
s = LOTreeSet()
+ # XXX why oh why do we expect ValueError here, but TypeError in test32?
self.assertRaises(ValueError, s.insert, BTrees.family64.maxint + 1)
self.assertRaises(ValueError, s.insert, BTrees.family64.minint - 1)
self.check_pickling(BTrees.family64)
@@ -2183,448 +498,11 @@
self.failUnless(f1 is family)
self.failUnless(f2 is family)
-class InternalKeysMappingTest(object):
- # There must not be any internal keys not in the BTree
- def _makeOne(self):
- return self._getTargetClass()()
-
- def add_key(self, tree, key):
- tree[key] = key
-
- @_skip_wo_ZODB
- def test_internal_keys_after_deletion(self):
- # Make sure when a key's deleted, it's not an internal key
- #
- # We'll leverage __getstate__ to introspect the internal structures.
- #
- # We need to check BTrees with BTree children as well as BTrees
- # with bucket children.
- import transaction
- from ZODB.MappingStorage import DB
- db = DB()
- conn = db.open()
-
- tree = conn.root.tree = self._makeOne()
- i = 0
-
- # Grow the btree until we have multiple buckets
- while 1:
- i += 1
- self.add_key(tree, i)
- data = tree.__getstate__()[0]
- if len(data) >= 3:
- break
-
- transaction.commit()
-
- # Now, delete the internal key and make sure it's really gone
- key = data[1]
- del tree[key]
- data = tree.__getstate__()[0]
- self.assert_(data[1] != key)
-
- # The tree should have changed:
- self.assert_(tree._p_changed)
-
- # Grow the btree until we have multiple levels
- while 1:
- i += 1
- self.add_key(tree, i)
- data = tree.__getstate__()[0]
- if data[0].__class__ == tree.__class__:
- assert len(data[2].__getstate__()[0]) >= 3
- break
-
- # Now, delete the internal key and make sure it's really gone
- key = data[1]
- del tree[key]
- data = tree.__getstate__()[0]
- self.assert_(data[1] != key)
-
- transaction.abort()
- db.close()
-
-class InternalKeysSetTest(object):
- # There must not be any internal keys not in the TreeSet
-
- def add_key(self, tree, key):
- tree.add(key)
-
-## utility functions
-
-def lsubtract(l1, l2):
- l1 = list(l1)
- l2 = list(l2)
- l = filter(lambda x, l1=l1: x not in l1, l2)
- l = l + filter(lambda x, l2=l2: x not in l2, l1)
- return l
-
-def realseq(itemsob):
- return [x for x in itemsob]
-
-def permutations(x):
- # Return a list of all permutations of list x.
- n = len(x)
- if n <= 1:
- return [x]
- result = []
- x0 = x[0]
- for i in range(n):
- # Build the (n-1)! permutations with x[i] in the first position.
- xcopy = x[:]
- first, xcopy[i] = xcopy[i], x0
- result.extend([[first] + p for p in permutations(xcopy[1:])])
- return result
-
-# Unroll stuff in 'test_suite'
-
-
-class OOBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OOBTree import OOBTree
- return OOBTree
-class OOTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OOBTree import OOTreeSet
- return OOTreeSet
-class OOBucketTest(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OOBTree import OOBucket
- return OOBucket
-class OOTreeSetTest(NormalSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OOBTree import OOTreeSet
- return OOTreeSet
-class OOSetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OOBTree import OOSet
- return OOSet
-class OOModuleTest(ModuleTest, unittest.TestCase):
- prefix = 'OO'
- def _getModule(self):
- import BTrees
- return BTrees.OOBTree
- def _getInterface(self):
- import BTrees.Interfaces
- return BTrees.Interfaces.IObjectObjectBTreeModule
-
-class IIBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IIBTree import IIBTree
- return IIBTree
-class IITreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IIBTree import IITreeSet
- return IITreeSet
-class IIBucketTest(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IIBTree import IIBucket
- return IIBucket
-class IITreeSetTest(NormalSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IIBTree import IITreeSet
- return IITreeSet
-class IISetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IIBTree import IISet
- return IISet
-class IIModuleTest(ModuleTest, unittest.TestCase):
- prefix = 'II'
- def _getModule(self):
- import BTrees
- return BTrees.IIBTree
- def _getInterface(self):
- import BTrees.Interfaces
- return BTrees.Interfaces.IIntegerIntegerBTreeModule
-
-class IOBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IOBTree import IOBTree
- return IOBTree
-class IOTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IOBTree import IOTreeSet
- return IOTreeSet
-class IOBucketTest(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IOBTree import IOBucket
- return IOBucket
-class IOTreeSetTest(NormalSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IOBTree import IOTreeSet
- return IOTreeSet
-class IOSetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IOBTree import IOSet
- return IOSet
-class IOModuleTest(ModuleTest, unittest.TestCase):
- prefix = 'IO'
- def _getModule(self):
- import BTrees
- return BTrees.IOBTree
- def _getInterface(self):
- import BTrees.Interfaces
- return BTrees.Interfaces.IIntegerObjectBTreeModule
-
-class OIBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OIBTree import OIBTree
- return OIBTree
-class OITreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OIBTree import OITreeSet
- return OITreeSet
-class OIBucketTest(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OIBTree import OIBucket
- return OIBucket
-class OITreeSetTest(NormalSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OIBTree import OITreeSet
- return OITreeSet
-class OISetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OIBTree import OISet
- return OISet
-class OIModuleTest(ModuleTest, unittest.TestCase):
- prefix = 'OI'
- def _getModule(self):
- import BTrees
- return BTrees.OIBTree
- def _getInterface(self):
- import BTrees.Interfaces
- return BTrees.Interfaces.IObjectIntegerBTreeModule
-
-class IFBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IFBTree import IFBTree
- return IFBTree
-class IFTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IFBTree import IFTreeSet
- return IFTreeSet
-class IFBucketTest(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IFBTree import IFBucket
- return IFBucket
-class IFTreeSetTest(NormalSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IFBTree import IFTreeSet
- return IFTreeSet
-class IFSetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IFBTree import IFSet
- return IFSet
-class IFModuleTest(ModuleTest, unittest.TestCase):
- prefix = 'IF'
- def _getModule(self):
- import BTrees
- return BTrees.IFBTree
- def _getInterface(self):
- import BTrees.Interfaces
- return BTrees.Interfaces.IIntegerFloatBTreeModule
-
-class LLBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLBTree
- return LLBTree
-class LLTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLTreeSet
- return LLTreeSet
-class LLBucketTest(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLBucket
- return LLBucket
-class LLTreeSetTest(NormalSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLTreeSet
- return LLTreeSet
-class LLSetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLSet
- return LLSet
-class LLSetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLSet
- return LLSet
-class LLModuleTest(ModuleTest, unittest.TestCase):
- prefix = 'LL'
- def _getModule(self):
- import BTrees
- return BTrees.LLBTree
- def _getInterface(self):
- import BTrees.Interfaces
- return BTrees.Interfaces.IIntegerIntegerBTreeModule
-
-class LOBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LOBTree import LOBTree
- return LOBTree
-class LOTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LOBTree import LOTreeSet
- return LOTreeSet
-class LOBucketTest(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LOBTree import LOBucket
- return LOBucket
-class LOTreeSetTest(NormalSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LOBTree import LOTreeSet
- return LOTreeSet
-class LOSetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LOBTree import LOSet
- return LOSet
-class LOModuleTest(ModuleTest, unittest.TestCase):
- prefix = 'LO'
- def _getModule(self):
- import BTrees
- return BTrees.LOBTree
- def _getInterface(self):
- import BTrees.Interfaces
- return BTrees.Interfaces.IIntegerObjectBTreeModule
-
-class OLBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OLBTree import OLBTree
- return OLBTree
-class OLTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OLBTree import OLTreeSet
- return OLTreeSet
-class OLBucketTest(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OLBTree import OLBucket
- return OLBucket
-class OLTreeSetTest(NormalSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OLBTree import OLTreeSet
- return OLTreeSet
-class OLSetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OLBTree import OLSet
- return OLSet
-class OLModuleTest(ModuleTest, unittest.TestCase):
- prefix = 'OL'
- def _getModule(self):
- import BTrees
- return BTrees.OLBTree
- def _getInterface(self):
- import BTrees.Interfaces
- return BTrees.Interfaces.IObjectIntegerBTreeModule
-
-class LFBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LFBTree import LFBTree
- return LFBTree
-class LFTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LFBTree import LFTreeSet
- return LFTreeSet
-class LFBucketTest(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LFBTree import LFBucket
- return LFBucket
-class LFTreeSetTest(NormalSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LFBTree import LFTreeSet
- return LFTreeSet
-class LFSetTest(ExtendedSetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LFBTree import LFSet
- return LFSet
-class LFModuleTest(ModuleTest, unittest.TestCase):
- prefix = 'LF'
- def _getModule(self):
- import BTrees
- return BTrees.LFBTree
- def _getInterface(self):
- import BTrees.Interfaces
- return BTrees.Interfaces.IIntegerFloatBTreeModule
-
-
def test_suite():
return unittest.TestSuite((
- unittest.makeSuite(OOBTreeInternalKeyTest),
- unittest.makeSuite(OOTreeSetInternalKeyTest),
- unittest.makeSuite(OOBucketTest),
- unittest.makeSuite(OOTreeSetTest),
- unittest.makeSuite(OOSetTest),
- unittest.makeSuite(OOModuleTest),
- unittest.makeSuite(IIBTreeInternalKeyTest),
- unittest.makeSuite(IITreeSetInternalKeyTest),
- unittest.makeSuite(IIBucketTest),
- unittest.makeSuite(IITreeSetTest),
- unittest.makeSuite(IISetTest),
- unittest.makeSuite(IIModuleTest),
- unittest.makeSuite(IOBTreeInternalKeyTest),
- unittest.makeSuite(IOTreeSetInternalKeyTest),
- unittest.makeSuite(IOBucketTest),
- unittest.makeSuite(IOTreeSetTest),
- unittest.makeSuite(IOSetTest),
- unittest.makeSuite(IOModuleTest),
- unittest.makeSuite(OIBTreeInternalKeyTest),
- unittest.makeSuite(OITreeSetInternalKeyTest),
- unittest.makeSuite(OIBucketTest),
- unittest.makeSuite(OITreeSetTest),
- unittest.makeSuite(OISetTest),
- unittest.makeSuite(OIModuleTest),
- unittest.makeSuite(IFBTreeInternalKeyTest),
- unittest.makeSuite(IFTreeSetInternalKeyTest),
- unittest.makeSuite(IFBucketTest),
- unittest.makeSuite(IFTreeSetTest),
- unittest.makeSuite(IFSetTest),
- unittest.makeSuite(IFModuleTest),
- unittest.makeSuite(LLBTreeInternalKeyTest),
- unittest.makeSuite(LLTreeSetInternalKeyTest),
- unittest.makeSuite(LLBucketTest),
- unittest.makeSuite(LLTreeSetTest),
- unittest.makeSuite(LLSetTest),
- unittest.makeSuite(LLModuleTest),
- unittest.makeSuite(LOBTreeInternalKeyTest),
- unittest.makeSuite(LOTreeSetInternalKeyTest),
- unittest.makeSuite(LOBucketTest),
- unittest.makeSuite(LOTreeSetTest),
- unittest.makeSuite(LOSetTest),
- unittest.makeSuite(LOModuleTest),
- unittest.makeSuite(OLBTreeInternalKeyTest),
- unittest.makeSuite(OLTreeSetInternalKeyTest),
- unittest.makeSuite(OLBucketTest),
- unittest.makeSuite(OLTreeSetTest),
- unittest.makeSuite(OLSetTest),
- unittest.makeSuite(OLModuleTest),
- unittest.makeSuite(LFBTreeInternalKeyTest),
- unittest.makeSuite(LFTreeSetInternalKeyTest),
- unittest.makeSuite(LFBucketTest),
- unittest.makeSuite(LFTreeSetTest),
- unittest.makeSuite(LFSetTest),
- unittest.makeSuite(LFModuleTest),
- unittest.makeSuite(IIBTreeTest),
- unittest.makeSuite(IFBTreeTest),
- unittest.makeSuite(IOBTreeTest),
- unittest.makeSuite(OIBTreeTest),
- unittest.makeSuite(LLBTreeTest),
- unittest.makeSuite(LFBTreeTest),
- unittest.makeSuite(LOBTreeTest),
- unittest.makeSuite(OLBTreeTest),
- unittest.makeSuite(OOBTreeTest),
- unittest.makeSuite(TestIIBTrees),
- unittest.makeSuite(TestIFBTrees),
- unittest.makeSuite(TestIOBTrees),
- unittest.makeSuite(TestOIBTrees),
- unittest.makeSuite(TestIOSets),
- unittest.makeSuite(TestIOTreeSets),
- unittest.makeSuite(TestIISets),
- unittest.makeSuite(TestIITreeSets),
- unittest.makeSuite(TestLOSets),
- unittest.makeSuite(TestLOTreeSets),
- unittest.makeSuite(TestLLSets),
- unittest.makeSuite(TestLLTreeSets),
unittest.makeSuite(DegenerateBTree),
- unittest.makeSuite(TestCmpError),
unittest.makeSuite(BugFixes),
+ unittest.makeSuite(TestCmpError),
unittest.makeSuite(FamilyTest),
))
Modified: BTrees/trunk/BTrees/tests/testConflict.py
===================================================================
--- BTrees/trunk/BTrees/tests/testConflict.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/tests/testConflict.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -13,498 +13,17 @@
##############################################################################
import unittest
+from .common import _skip_wo_ZODB
+from .common import ConflictTestBase
-def _skip_wo_ZODB(test_method): #pragma NO COVER
- try:
- import ZODB
- except ImportError: # skip this test if ZODB is not available
- def _dummy(*args):
- pass
- return _dummy
- else:
- return test_method
+class NastyConfictFunctionalTests(ConflictTestBase, unittest.TestCase):
+ # FUNCTESTS: Provoke various conflict scenarios using ZODB + transaction
-class Base:
- """ Tests common to all types: sets, buckets, and BTrees """
-
- storage = None
-
- def tearDown(self):
- import transaction
- transaction.abort()
- if self.storage is not None:
- self.storage.close()
- self.storage.cleanup()
-
- def _makeOne(self):
- return self._getTargetClass()()
-
- def openDB(self):
- import os
- from ZODB.FileStorage import FileStorage
- from ZODB.DB import DB
- n = 'fs_tmp__%s' % os.getpid()
- self.storage = FileStorage(n)
- self.db = DB(self.storage)
- return self.db
-
-class MappingBase(Base):
- """ Tests common to mappings (buckets, btrees) """
-
- def _deletefail(self):
- t = self._makeOne()
- del t[1]
-
- def _setupConflict(self):
-
- l=[ -5124, -7377, 2274, 8801, -9901, 7327, 1565, 17, -679,
- 3686, -3607, 14, 6419, -5637, 6040, -4556, -8622, 3847, 7191,
- -4067]
-
-
- e1=[(-1704, 0), (5420, 1), (-239, 2), (4024, 3), (-6984, 4)]
- e2=[(7745, 0), (4868, 1), (-2548, 2), (-2711, 3), (-3154, 4)]
-
-
- base = self._makeOne()
- base.update([(i, i*i) for i in l[:20]])
- b1=base.__class__(base)
- b2=base.__class__(base)
- bm=base.__class__(base)
-
- items=base.items()
-
- return base, b1, b2, bm, e1, e2, items
-
- def testMergeDelete(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- del b1[items[1][0]]
- del b2[items[5][0]]
- del b1[items[-1][0]]
- del b2[items[-2][0]]
- del bm[items[1][0]]
- del bm[items[5][0]]
- del bm[items[-1][0]]
- del bm[items[-2][0]]
- _test_merge(base, b1, b2, bm, 'merge delete')
-
- def testMergeDeleteAndUpdate(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- del b1[items[1][0]]
- b2[items[5][0]]=1
- del b1[items[-1][0]]
- b2[items[-2][0]]=2
- del bm[items[1][0]]
- bm[items[5][0]]=1
- del bm[items[-1][0]]
- bm[items[-2][0]]=2
- _test_merge(base, b1, b2, bm, 'merge update and delete')
-
- def testMergeUpdate(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- b1[items[0][0]]=1
- b2[items[5][0]]=2
- b1[items[-1][0]]=3
- b2[items[-2][0]]=4
- bm[items[0][0]]=1
- bm[items[5][0]]=2
- bm[items[-1][0]]=3
- bm[items[-2][0]]=4
- _test_merge(base, b1, b2, bm, 'merge update')
-
- def testFailMergeDelete(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- del b1[items[0][0]]
- del b2[items[0][0]]
- _test_merge(base, b1, b2, bm, 'merge conflicting delete',
- should_fail=1)
-
- def testFailMergeUpdate(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- b1[items[0][0]]=1
- b2[items[0][0]]=2
- _test_merge(base, b1, b2, bm, 'merge conflicting update',
- should_fail=1)
-
- def testFailMergeDeleteAndUpdate(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- del b1[items[0][0]]
- b2[items[0][0]]=-9
- _test_merge(base, b1, b2, bm, 'merge conflicting update and delete',
- should_fail=1)
-
- def testMergeInserts(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
-
- b1[-99999]=-99999
- b1[e1[0][0]]=e1[0][1]
- b2[99999]=99999
- b2[e1[2][0]]=e1[2][1]
-
- bm[-99999]=-99999
- bm[e1[0][0]]=e1[0][1]
- bm[99999]=99999
- bm[e1[2][0]]=e1[2][1]
- _test_merge(base, b1, b2, bm, 'merge insert')
-
- def testMergeInsertsFromEmpty(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
-
- base.clear()
- b1.clear()
- b2.clear()
- bm.clear()
-
- b1.update(e1)
- bm.update(e1)
- b2.update(e2)
- bm.update(e2)
-
- _test_merge(base, b1, b2, bm, 'merge insert from empty')
-
- def testFailMergeEmptyAndFill(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
-
- b1.clear()
- bm.clear()
- b2.update(e2)
- bm.update(e2)
-
- _test_merge(base, b1, b2, bm, 'merge insert from empty', should_fail=1)
-
- def testMergeEmpty(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
-
- b1.clear()
- bm.clear()
-
- _test_merge(base, b1, b2, bm, 'empty one and not other', should_fail=1)
-
- def testFailMergeInsert(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- b1[-99999]=-99999
- b1[e1[0][0]]=e1[0][1]
- b2[99999]=99999
- b2[e1[0][0]]=e1[0][1]
- _test_merge(base, b1, b2, bm, 'merge conflicting inserts',
- should_fail=1)
-
-class SetTests(Base):
- "Set (as opposed to TreeSet) specific tests."
-
- def _setupConflict(self):
- l=[ -5124, -7377, 2274, 8801, -9901, 7327, 1565, 17, -679,
- 3686, -3607, 14, 6419, -5637, 6040, -4556, -8622, 3847, 7191,
- -4067]
-
- e1=[-1704, 5420, -239, 4024, -6984]
- e2=[7745, 4868, -2548, -2711, -3154]
-
-
- base = self._makeOne()
- base.update(l)
- b1=base.__class__(base)
- b2=base.__class__(base)
- bm=base.__class__(base)
-
- items=base.keys()
-
- return base, b1, b2, bm, e1, e2, items
-
- def testMergeDelete(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- b1.remove(items[1])
- b2.remove(items[5])
- b1.remove(items[-1])
- b2.remove(items[-2])
- bm.remove(items[1])
- bm.remove(items[5])
- bm.remove(items[-1])
- bm.remove(items[-2])
- _test_merge(base, b1, b2, bm, 'merge delete')
-
- def testFailMergeDelete(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- b1.remove(items[0])
- b2.remove(items[0])
- _test_merge(base, b1, b2, bm, 'merge conflicting delete',
- should_fail=1)
-
- def testMergeInserts(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
-
- b1.insert(-99999)
- b1.insert(e1[0])
- b2.insert(99999)
- b2.insert(e1[2])
-
- bm.insert(-99999)
- bm.insert(e1[0])
- bm.insert(99999)
- bm.insert(e1[2])
- _test_merge(base, b1, b2, bm, 'merge insert')
-
- def testMergeInsertsFromEmpty(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
-
- base.clear()
- b1.clear()
- b2.clear()
- bm.clear()
-
- b1.update(e1)
- bm.update(e1)
- b2.update(e2)
- bm.update(e2)
-
- _test_merge(base, b1, b2, bm, 'merge insert from empty')
-
- def testFailMergeEmptyAndFill(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
-
- b1.clear()
- bm.clear()
- b2.update(e2)
- bm.update(e2)
-
- _test_merge(base, b1, b2, bm, 'merge insert from empty', should_fail=1)
-
- def testMergeEmpty(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
-
- b1.clear()
- bm.clear()
-
- _test_merge(base, b1, b2, bm, 'empty one and not other', should_fail=1)
-
- def testFailMergeInsert(self):
- base, b1, b2, bm, e1, e2, items = self._setupConflict()
- b1.insert(-99999)
- b1.insert(e1[0])
- b2.insert(99999)
- b2.insert(e1[0])
- _test_merge(base, b1, b2, bm, 'merge conflicting inserts',
- should_fail=1)
-
-
-def _test_merge(o1, o2, o3, expect, message='failed to merge', should_fail=0):
- from BTrees.Interfaces import BTreesConflictError
- s1 = o1.__getstate__()
- s2 = o2.__getstate__()
- s3 = o3.__getstate__()
- expected = expect.__getstate__()
- if expected is None:
- expected = ((((),),),)
-
- if should_fail:
- try:
- merged = o1._p_resolveConflict(s1, s2, s3)
- except BTreesConflictError, err:
- pass
- else:
- assert 0, message
- else:
- merged = o1._p_resolveConflict(s1, s2, s3)
- assert merged == expected, message
-
-
-class OOBTreeTests(MappingBase, unittest.TestCase):
def _getTargetClass(self):
from BTrees.OOBTree import OOBTree
return OOBTree
-class OOBucketTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OOBTree import OOBucket
- return OOBucket
-
-class OOTreeSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OOBTree import OOTreeSet
- return OOTreeSet
-
-class OOSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OOBTree import OOSet
- return OOSet
-
-
-class IIBTreeTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IIBTree import IIBTree
- return IIBTree
-
-class IIBucketTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IIBTree import IIBucket
- return IIBucket
-
-class IITreeSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IIBTree import IITreeSet
- return IITreeSet
-
-class IISetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IIBTree import IISet
- return IISet
-
-
-class IOBTreeTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IOBTree import IOBTree
- return IOBTree
-
-class IOBucketTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IOBTree import IOBucket
- return IOBucket
-
-class IOTreeSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IOBTree import IOTreeSet
- return IOTreeSet
-
-class IOSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IOBTree import IOSet
- return IOSet
-
-
-class OIBTreeTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OIBTree import OIBTree
- return OIBTree
-
-class OIBucketTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OIBTree import OIBucket
- return OIBucket
-
-class OITreeSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OIBTree import OITreeSet
- return OITreeSet
-
-class OISetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OIBTree import OISet
- return OISet
-
-
-class IFBTreeTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IFBTree import IFBTree
- return IFBTree
-
-class IFBucketTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IFBTree import IFBucket
- return IFBucket
-
-class IFTreeSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IFBTree import IFTreeSet
- return IFTreeSet
-
-class IFSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.IFBTree import IFSet
- return IFSet
-
-
-class LLBTreeTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLBTree
- return LLBTree
-
-class LLBucketTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLBucket
- return LLBucket
-
-class LLTreeSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLTreeSet
- return LLTreeSet
-
-class LLSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LLBTree import LLSet
- return LLSet
-
-
-class LOBTreeTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LOBTree import LOBTree
- return LOBTree
-
-class LOBucketTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LOBTree import LOBucket
- return LOBucket
-
-class LOTreeSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LOBTree import LOTreeSet
- return LOTreeSet
-
-class LOSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LOBTree import LOSet
- return LOSet
-
-
-class OLBTreeTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OLBTree import OLBTree
- return OLBTree
-
-class OLBucketTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OLBTree import OLBucket
- return OLBucket
-
-class OLTreeSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OLBTree import OLTreeSet
- return OLTreeSet
-
-class OLSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.OLBTree import OLSet
- return OLSet
-
-
-class LFBTreeTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LFBTree import LFBTree
- return LFBTree
-
-class LFBucketTests(MappingBase, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LFBTree import LFBucket
- return LFBucket
-
-class LFTreeSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LFBTree import LFTreeSet
- return LFTreeSet
-
-class LFSetTests(SetTests, unittest.TestCase):
- def _getTargetClass(self):
- from BTrees.LFBTree import LFSet
- return LFSet
-
-
-class NastyConfictFunctionalTests(Base, unittest.TestCase):
- # Provoke various conflict scenarios using ZODB + transaction
-
- def _getTargetClass(self):
- from BTrees.OOBTree import OOBTree
- return OOBTree
-
@_skip_wo_ZODB
def testSimpleConflict(self):
# Invoke conflict resolution by committing a transaction and
@@ -1024,55 +543,7 @@
tm1.abort()
-
def test_suite():
- suite = unittest.TestSuite((
- unittest.makeSuite(OOBTreeTests),
- unittest.makeSuite(OOBucketTests),
- unittest.makeSuite(OOTreeSetTests),
- unittest.makeSuite(OOSetTests),
-
- unittest.makeSuite(IIBTreeTests),
- unittest.makeSuite(IIBucketTests),
- unittest.makeSuite(IITreeSetTests),
- unittest.makeSuite(IISetTests),
-
- unittest.makeSuite(IOBTreeTests),
- unittest.makeSuite(IOBucketTests),
- unittest.makeSuite(IOTreeSetTests),
- unittest.makeSuite(IOSetTests),
-
- unittest.makeSuite(OIBTreeTests),
- unittest.makeSuite(OIBucketTests),
- unittest.makeSuite(OITreeSetTests),
- unittest.makeSuite(OISetTests),
-
- unittest.makeSuite(IFBTreeTests),
- unittest.makeSuite(IFBucketTests),
- unittest.makeSuite(IFTreeSetTests),
- unittest.makeSuite(IFSetTests),
-
- unittest.makeSuite(LLBTreeTests),
- unittest.makeSuite(LLBucketTests),
- unittest.makeSuite(LLTreeSetTests),
- unittest.makeSuite(LLSetTests),
-
- unittest.makeSuite(LOBTreeTests),
- unittest.makeSuite(LOBucketTests),
- unittest.makeSuite(LOTreeSetTests),
- unittest.makeSuite(LOSetTests),
-
- unittest.makeSuite(OLBTreeTests),
- unittest.makeSuite(OLBucketTests),
- unittest.makeSuite(OLTreeSetTests),
- unittest.makeSuite(OLSetTests),
-
- unittest.makeSuite(LFBTreeTests),
- unittest.makeSuite(LFBucketTests),
- unittest.makeSuite(LFTreeSetTests),
- unittest.makeSuite(LFSetTests),
-
+ return unittest.TestSuite((
unittest.makeSuite(NastyConfictFunctionalTests),
))
-
- return suite
Deleted: BTrees/trunk/BTrees/tests/testLength.py
===================================================================
--- BTrees/trunk/BTrees/tests/testLength.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/tests/testLength.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,53 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-"""\
-Test for BTrees.Length module.
-
-"""
-__docformat__ = "reStructuredText"
-
-import BTrees.Length
-import copy
-import sys
-import unittest
-
-
-class LengthTestCase(unittest.TestCase):
-
- def test_length_overflows_to_long(self):
- length = BTrees.Length.Length(sys.maxint)
- self.assertEqual(length(), sys.maxint)
- self.assert_(type(length()) is int)
- length.change(+1)
- self.assertEqual(length(), sys.maxint + 1)
- self.assert_(type(length()) is long)
-
- def test_length_underflows_to_long(self):
- minint = (-sys.maxint) - 1
- length = BTrees.Length.Length(minint)
- self.assertEqual(length(), minint)
- self.assert_(type(length()) is int)
- length.change(-1)
- self.assertEqual(length(), minint - 1)
- self.assert_(type(length()) is long)
-
- def test_copy(self):
- # Test for https://bugs.launchpad.net/zodb/+bug/516653
- length = BTrees.Length.Length()
- other = copy.copy(length)
- self.assertEqual(other(), 0)
-
-
-def test_suite():
- return unittest.makeSuite(LengthTestCase)
Deleted: BTrees/trunk/BTrees/tests/testSetOps.py
===================================================================
--- BTrees/trunk/BTrees/tests/testSetOps.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/tests/testSetOps.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,858 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE
-#
-##############################################################################
-import unittest
-
-#from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
-#from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
-#from BTrees.IFBTree import IFBTree, IFBucket, IFSet, IFTreeSet
-#from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
-#from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
-#from BTrees.LOBTree import LOBTree, LOBucket, LOSet, LOTreeSet
-#from BTrees.LFBTree import LFBTree, LFBucket, LFSet, LFTreeSet
-#from BTrees.LLBTree import LLBTree, LLBucket, LLSet, LLTreeSet
-#from BTrees.OLBTree import OLBTree, OLBucket, OLSet, OLTreeSet
-
-# Subclasses have to set up:
-# builders() - function returning functions to build inputs,
-# each returned callable tkes an optional keys arg
-# intersection, union, difference - set to the type-correct versions
-class SetResult(object):
- def setUp(self):
- self.Akeys = [1, 3, 5, 6 ]
- self.Bkeys = [ 2, 3, 4, 6, 7]
- self.As = [makeset(self.Akeys) for makeset in self.builders()]
- self.Bs = [makeset(self.Bkeys) for makeset in self.builders()]
- self.emptys = [makeset() for makeset in self.builders()]
-
- # Slow but obviously correct Python implementations of basic ops.
- def _union(self, x, y):
- result = list(x)
- for e in y:
- if e not in result:
- result.append(e)
- result.sort()
- return result
-
- def _intersection(self, x, y):
- result = []
- for e in x:
- if e in y:
- result.append(e)
- return result
-
- def _difference(self, x, y):
- result = list(x)
- for e in y:
- if e in result:
- result.remove(e)
- # Difference preserves LHS values.
- if hasattr(x, "values"):
- result = [(k, x[k]) for k in result]
- return result
-
- def testNone(self):
- for op in self.union, self.intersection, self.difference:
- C = op(None, None)
- self.assert_(C is None)
-
- for op in self.union, self.intersection, self.difference:
- for A in self.As:
- C = op(A, None)
- self.assert_(C is A)
-
- C = op(None, A)
- if op == self.difference:
- self.assert_(C is None)
- else:
- self.assert_(C is A)
-
- def testEmptyUnion(self):
- for A in self.As:
- for E in self.emptys:
- C = self.union(A, E)
- self.assert_(not hasattr(C, "values"))
- self.assertEqual(list(C), self.Akeys)
-
- C = self.union(E, A)
- self.assert_(not hasattr(C, "values"))
- self.assertEqual(list(C), self.Akeys)
-
- def testEmptyIntersection(self):
- for A in self.As:
- for E in self.emptys:
- C = self.intersection(A, E)
- self.assert_(not hasattr(C, "values"))
- self.assertEqual(list(C), [])
-
- C = self.intersection(E, A)
- self.assert_(not hasattr(C, "values"))
- self.assertEqual(list(C), [])
-
- def testEmptyDifference(self):
- for A in self.As:
- for E in self.emptys:
- C = self.difference(A, E)
- # Difference preserves LHS values.
- self.assertEqual(hasattr(C, "values"), hasattr(A, "values"))
- if hasattr(A, "values"):
- self.assertEqual(list(C.items()), list(A.items()))
- else:
- self.assertEqual(list(C), self.Akeys)
-
- C = self.difference(E, A)
- self.assertEqual(hasattr(C, "values"), hasattr(E, "values"))
- self.assertEqual(list(C), [])
-
- def testUnion(self):
- inputs = self.As + self.Bs
- for A in inputs:
- for B in inputs:
- C = self.union(A, B)
- self.assert_(not hasattr(C, "values"))
- self.assertEqual(list(C), self._union(A, B))
-
- def testIntersection(self):
- inputs = self.As + self.Bs
- for A in inputs:
- for B in inputs:
- C = self.intersection(A, B)
- self.assert_(not hasattr(C, "values"))
- self.assertEqual(list(C), self._intersection(A, B))
-
- def testDifference(self):
- inputs = self.As + self.Bs
- for A in inputs:
- for B in inputs:
- C = self.difference(A, B)
- # Difference preserves LHS values.
- self.assertEqual(hasattr(C, "values"), hasattr(A, "values"))
- want = self._difference(A, B)
- if hasattr(A, "values"):
- self.assertEqual(list(C.items()), want)
- else:
- self.assertEqual(list(C), want)
-
- def testLargerInputs(self):
- from BTrees.IIBTree import IISet
- from random import randint
- MAXSIZE = 200
- MAXVAL = 400
- for i in range(3):
- n = randint(0, MAXSIZE)
- Akeys = [randint(1, MAXVAL) for j in range(n)]
- As = [makeset(Akeys) for makeset in self.builders()]
- Akeys = IISet(Akeys)
-
- n = randint(0, MAXSIZE)
- Bkeys = [randint(1, MAXVAL) for j in range(n)]
- Bs = [makeset(Bkeys) for makeset in self.builders()]
- Bkeys = IISet(Bkeys)
-
- for op, simulator in ((self.union, self._union),
- (self.intersection, self._intersection),
- (self.difference, self._difference)):
- for A in As:
- for B in Bs:
- got = op(A, B)
- want = simulator(Akeys, Bkeys)
- self.assertEqual(list(got), want,
- (A, B, Akeys, Bkeys, list(got), want))
-
-# Given a mapping builder (IIBTree, OOBucket, etc), return a function
-# that builds an object of that type given only a list of keys.
-def makeBuilder(mapbuilder):
- def result(keys=[], mapbuilder=mapbuilder):
- return mapbuilder(zip(keys, keys))
- return result
-
-class PureOO(SetResult, unittest.TestCase):
- def union(self, *args):
- from BTrees.OOBTree import union
- return union(*args)
- def intersection(self, *args):
- from BTrees.OOBTree import intersection
- return intersection(*args)
- def difference(self, *args):
- from BTrees.OOBTree import difference
- return difference(*args)
- def builders(self):
- from BTrees.OOBTree import OOBTree
- from BTrees.OOBTree import OOBucket
- from BTrees.OOBTree import OOTreeSet
- from BTrees.OOBTree import OOSet
- return OOSet, OOTreeSet, makeBuilder(OOBTree), makeBuilder(OOBucket)
-
-class PureII(SetResult, unittest.TestCase):
- def union(self, *args):
- from BTrees.IIBTree import union
- return union(*args)
- def intersection(self, *args):
- from BTrees.IIBTree import intersection
- return intersection(*args)
- def difference(self, *args):
- from BTrees.IIBTree import difference
- return difference(*args)
- def builders(self):
- from BTrees.IIBTree import IIBTree
- from BTrees.IIBTree import IIBucket
- from BTrees.IIBTree import IITreeSet
- from BTrees.IIBTree import IISet
- return IISet, IITreeSet, makeBuilder(IIBTree), makeBuilder(IIBucket)
-
-class PureIO(SetResult, unittest.TestCase):
- def union(self, *args):
- from BTrees.IOBTree import union
- return union(*args)
- def intersection(self, *args):
- from BTrees.IOBTree import intersection
- return intersection(*args)
- def difference(self, *args):
- from BTrees.IOBTree import difference
- return difference(*args)
- def builders(self):
- from BTrees.IOBTree import IOBTree
- from BTrees.IOBTree import IOBucket
- from BTrees.IOBTree import IOTreeSet
- from BTrees.IOBTree import IOSet
- return IOSet, IOTreeSet, makeBuilder(IOBTree), makeBuilder(IOBucket)
-
-class PureIF(SetResult, unittest.TestCase):
- def union(self, *args):
- from BTrees.IFBTree import union
- return union(*args)
- def intersection(self, *args):
- from BTrees.IFBTree import intersection
- return intersection(*args)
- def difference(self, *args):
- from BTrees.IFBTree import difference
- return difference(*args)
- def builders(self):
- from BTrees.IFBTree import IFBTree
- from BTrees.IFBTree import IFBucket
- from BTrees.IFBTree import IFTreeSet
- from BTrees.IFBTree import IFSet
- return IFSet, IFTreeSet, makeBuilder(IFBTree), makeBuilder(IFBucket)
-
-class PureOI(SetResult, unittest.TestCase):
- def union(self, *args):
- from BTrees.OIBTree import union
- return union(*args)
- def intersection(self, *args):
- from BTrees.OIBTree import intersection
- return intersection(*args)
- def difference(self, *args):
- from BTrees.OIBTree import difference
- return difference(*args)
- def builders(self):
- from BTrees.OIBTree import OIBTree
- from BTrees.OIBTree import OIBucket
- from BTrees.OIBTree import OITreeSet
- from BTrees.OIBTree import OISet
- return OISet, OITreeSet, makeBuilder(OIBTree), makeBuilder(OIBucket)
-
-class PureLL(SetResult, unittest.TestCase):
- def union(self, *args):
- from BTrees.LLBTree import union
- return union(*args)
- def intersection(self, *args):
- from BTrees.LLBTree import intersection
- return intersection(*args)
- def difference(self, *args):
- from BTrees.LLBTree import difference
- return difference(*args)
- def builders(self):
- from BTrees.LLBTree import LLBTree
- from BTrees.LLBTree import LLBucket
- from BTrees.LLBTree import LLTreeSet
- from BTrees.LLBTree import LLSet
- return LLSet, LLTreeSet, makeBuilder(LLBTree), makeBuilder(LLBucket)
-
-class PureLO(SetResult, unittest.TestCase):
- def union(self, *args):
- from BTrees.LOBTree import union
- return union(*args)
- def intersection(self, *args):
- from BTrees.LOBTree import intersection
- return intersection(*args)
- def difference(self, *args):
- from BTrees.LOBTree import difference
- return difference(*args)
- def builders(self):
- from BTrees.LOBTree import LOBTree
- from BTrees.LOBTree import LOBucket
- from BTrees.LOBTree import LOTreeSet
- from BTrees.LOBTree import LOSet
- return LOSet, LOTreeSet, makeBuilder(LOBTree), makeBuilder(LOBucket)
-
-class PureLF(SetResult, unittest.TestCase):
- def union(self, *args):
- from BTrees.LFBTree import union
- return union(*args)
- def intersection(self, *args):
- from BTrees.LFBTree import intersection
- return intersection(*args)
- def difference(self, *args):
- from BTrees.LFBTree import difference
- return difference(*args)
- def builders(self):
- from BTrees.LFBTree import LFBTree
- from BTrees.LFBTree import LFBucket
- from BTrees.LFBTree import LFTreeSet
- from BTrees.LFBTree import LFSet
- return LFSet, LFTreeSet, makeBuilder(LFBTree), makeBuilder(LFBucket)
-
-class PureOL(SetResult, unittest.TestCase):
- def union(self, *args):
- from BTrees.OLBTree import union
- return union(*args)
- def intersection(self, *args):
- from BTrees.OLBTree import intersection
- return intersection(*args)
- def difference(self, *args):
- from BTrees.OLBTree import difference
- return difference(*args)
- def builders(self):
- from BTrees.OLBTree import OLBTree
- from BTrees.OLBTree import OLBucket
- from BTrees.OLBTree import OLTreeSet
- from BTrees.OLBTree import OLSet
- return OLSet, OLTreeSet, makeBuilder(OLBTree), makeBuilder(OLBucket)
-
-# Subclasses must set up (as class variables):
-# multiunion, union
-# mkset, mktreeset
-# mkbucket, mkbtree
-class MultiUnion(object):
-
- def testEmpty(self):
- self.assertEqual(len(self.multiunion([])), 0)
-
- def testOne(self):
- for sequence in [3], range(20), range(-10, 0, 2) + range(1, 10, 2):
- seq1 = sequence[:]
- seq2 = sequence[:]
- seq2.reverse()
- seqsorted = sequence[:]
- seqsorted.sort()
- for seq in seq1, seq2, seqsorted:
- for builder in self.mkset, self.mktreeset:
- input = builder(seq)
- output = self.multiunion([input])
- self.assertEqual(len(seq), len(output))
- self.assertEqual(seqsorted, list(output))
-
- def testValuesIgnored(self):
- for builder in self.mkbucket, self.mkbtree:
- input = builder([(1, 2), (3, 4), (5, 6)])
- output = self.multiunion([input])
- self.assertEqual([1, 3, 5], list(output))
-
- def testBigInput(self):
- N = 100000
- input = self.mkset(range(N))
- output = self.multiunion([input] * 10)
- self.assertEqual(len(output), N)
- self.assertEqual(output.minKey(), 0)
- self.assertEqual(output.maxKey(), N-1)
- self.assertEqual(list(output), range(N))
-
- def testLotsOfLittleOnes(self):
- from random import shuffle
- N = 5000
- inputs = []
- mkset, mktreeset = self.mkset, self.mktreeset
- for i in range(N):
- base = i * 4 - N
- inputs.append(mkset([base, base+1]))
- inputs.append(mktreeset([base+2, base+3]))
- shuffle(inputs)
- output = self.multiunion(inputs)
- self.assertEqual(len(output), N*4)
- self.assertEqual(list(output), range(-N, 3*N))
-
- def testFunkyKeyIteration(self):
- # The internal set iteration protocol allows "iterating over" a
- # a single key as if it were a set.
- N = 100
- union, mkset = self.union, self.mkset
- slow = mkset()
- for i in range(N):
- slow = union(slow, mkset([i]))
- fast = self.multiunion(range(N)) # acts like N distinct singleton sets
- self.assertEqual(len(slow), N)
- self.assertEqual(len(fast), N)
- self.assertEqual(list(slow), list(fast))
- self.assertEqual(list(fast), range(N))
-
-class TestIIMultiUnion(MultiUnion, unittest.TestCase):
- def multiunion(self, *args):
- from BTrees.IIBTree import multiunion
- return multiunion(*args)
- def union(self, *args):
- from BTrees.IIBTree import union
- return union(*args)
- def mkset(self, *args):
- from BTrees.IIBTree import IISet as mkset
- return mkset(*args)
- def mktreeset(self, *args):
- from BTrees.IIBTree import IITreeSet as mktreeset
- return mktreeset(*args)
- def mkbucket(self, *args):
- from BTrees.IIBTree import IIBucket as mkbucket
- return mkbucket(*args)
- def mkbtree(self, *args):
- from BTrees.IIBTree import IIBTree as mkbtree
- return mkbtree(*args)
-
-class TestIOMultiUnion(MultiUnion, unittest.TestCase):
- def multiunion(self, *args):
- from BTrees.IOBTree import multiunion
- return multiunion(*args)
- def union(self, *args):
- from BTrees.IOBTree import union
- return union(*args)
- def mkset(self, *args):
- from BTrees.IOBTree import IOSet as mkset
- return mkset(*args)
- def mktreeset(self, *args):
- from BTrees.IOBTree import IOTreeSet as mktreeset
- return mktreeset(*args)
- def mkbucket(self, *args):
- from BTrees.IOBTree import IOBucket as mkbucket
- return mkbucket(*args)
- def mkbtree(self, *args):
- from BTrees.IOBTree import IOBTree as mkbtree
- return mkbtree(*args)
-
-class TestIFMultiUnion(MultiUnion, unittest.TestCase):
- def multiunion(self, *args):
- from BTrees.IFBTree import multiunion
- return multiunion(*args)
- def union(self, *args):
- from BTrees.IFBTree import union
- return union(*args)
- def mkset(self, *args):
- from BTrees.IFBTree import IFSet as mkset
- return mkset(*args)
- def mktreeset(self, *args):
- from BTrees.IFBTree import IFTreeSet as mktreeset
- return mktreeset(*args)
- def mkbucket(self, *args):
- from BTrees.IFBTree import IFBucket as mkbucket
- return mkbucket(*args)
- def mkbtree(self, *args):
- from BTrees.IFBTree import IFBTree as mkbtree
- return mkbtree(*args)
-
-class TestLLMultiUnion(MultiUnion, unittest.TestCase):
- def multiunion(self, *args):
- from BTrees.LLBTree import multiunion
- return multiunion(*args)
- def union(self, *args):
- from BTrees.LLBTree import union
- return union(*args)
- def mkset(self, *args):
- from BTrees.LLBTree import LLSet as mkset
- return mkset(*args)
- def mktreeset(self, *args):
- from BTrees.LLBTree import LLTreeSet as mktreeset
- return mktreeset(*args)
- def mkbucket(self, *args):
- from BTrees.LLBTree import LLBucket as mkbucket
- return mkbucket(*args)
- def mkbtree(self, *args):
- from BTrees.LLBTree import LLBTree as mkbtree
- return mkbtree(*args)
-
-class TestLOMultiUnion(MultiUnion, unittest.TestCase):
- def multiunion(self, *args):
- from BTrees.LOBTree import multiunion
- return multiunion(*args)
- def union(self, *args):
- from BTrees.LOBTree import union
- return union(*args)
- def mkset(self, *args):
- from BTrees.LOBTree import LOSet as mkset
- return mkset(*args)
- def mktreeset(self, *args):
- from BTrees.LOBTree import LOTreeSet as mktreeset
- return mktreeset(*args)
- def mkbucket(self, *args):
- from BTrees.LOBTree import LOBucket as mkbucket
- return mkbucket(*args)
- def mkbtree(self, *args):
- from BTrees.LOBTree import LOBTree as mkbtree
- return mkbtree(*args)
-
-class TestLFMultiUnion(MultiUnion, unittest.TestCase):
- def multiunion(self, *args):
- from BTrees.LFBTree import multiunion
- return multiunion(*args)
- def union(self, *args):
- from BTrees.LFBTree import union
- return union(*args)
- def mkset(self, *args):
- from BTrees.LFBTree import LFSet as mkset
- return mkset(*args)
- def mktreeset(self, *args):
- from BTrees.LFBTree import LFTreeSet as mktreeset
- return mktreeset(*args)
- def mkbucket(self, *args):
- from BTrees.LFBTree import LFBucket as mkbucket
- return mkbucket(*args)
- def mkbtree(self, *args):
- from BTrees.LFBTree import LFBTree as mkbtree
- return mkbtree(*args)
-
-# Check that various special module functions are and aren't imported from
-# the expected BTree modules.
-class TestImports(unittest.TestCase):
- def testWeightedUnion(self):
- from BTrees.IIBTree import weightedUnion
- from BTrees.OIBTree import weightedUnion
-
- try:
- from BTrees.IOBTree import weightedUnion
- except ImportError:
- pass
- else:
- self.fail("IOBTree shouldn't have weightedUnion")
-
- from BTrees.LLBTree import weightedUnion
- from BTrees.OLBTree import weightedUnion
-
- try:
- from BTrees.LOBTree import weightedUnion
- except ImportError:
- pass
- else:
- self.fail("LOBTree shouldn't have weightedUnion")
-
- try:
- from BTrees.OOBTree import weightedUnion
- except ImportError:
- pass
- else:
- self.fail("OOBTree shouldn't have weightedUnion")
-
- def testWeightedIntersection(self):
- from BTrees.IIBTree import weightedIntersection
- from BTrees.OIBTree import weightedIntersection
-
- try:
- from BTrees.IOBTree import weightedIntersection
- except ImportError:
- pass
- else:
- self.fail("IOBTree shouldn't have weightedIntersection")
-
- from BTrees.LLBTree import weightedIntersection
- from BTrees.OLBTree import weightedIntersection
-
- try:
- from BTrees.LOBTree import weightedIntersection
- except ImportError:
- pass
- else:
- self.fail("LOBTree shouldn't have weightedIntersection")
-
- try:
- from BTrees.OOBTree import weightedIntersection
- except ImportError:
- pass
- else:
- self.fail("OOBTree shouldn't have weightedIntersection")
-
- def testMultiunion(self):
- from BTrees.IIBTree import multiunion
- from BTrees.IOBTree import multiunion
-
- try:
- from BTrees.OIBTree import multiunion
- except ImportError:
- pass
- else:
- self.fail("OIBTree shouldn't have multiunion")
-
- from BTrees.LLBTree import multiunion
- from BTrees.LOBTree import multiunion
-
- try:
- from BTrees.OLBTree import multiunion
- except ImportError:
- pass
- else:
- self.fail("OLBTree shouldn't have multiunion")
-
- try:
- from BTrees.OOBTree import multiunion
- except ImportError:
- pass
- else:
- self.fail("OOBTree shouldn't have multiunion")
-
-# Subclasses must set up (as class variables):
-# weightedUnion, weightedIntersection
-# builders -- sequence of constructors, taking items
-# union, intersection -- the module routines of those names
-# mkbucket -- the module bucket builder
-class Weighted(object):
-
- def setUp(self):
- self.Aitems = [(1, 10), (3, 30), (5, 50), (6, 60)]
- self.Bitems = [(2, 21), (3, 31), (4, 41), (6, 61), (7, 71)]
-
- self.As = [make(self.Aitems) for make in self.builders()]
- self.Bs = [make(self.Bitems) for make in self.builders()]
- self.emptys = [make([]) for make in self.builders()]
-
- weights = []
- for w1 in -3, -1, 0, 1, 7:
- for w2 in -3, -1, 0, 1, 7:
- weights.append((w1, w2))
- self.weights = weights
-
- def testBothNone(self):
- for op in self.weightedUnion(), self.weightedIntersection():
- w, C = op(None, None)
- self.assert_(C is None)
- self.assertEqual(w, 0)
-
- w, C = op(None, None, 42, 666)
- self.assert_(C is None)
- self.assertEqual(w, 0)
-
- def testLeftNone(self):
- for op in self.weightedUnion(), self.weightedIntersection():
- for A in self.As + self.emptys:
- w, C = op(None, A)
- self.assert_(C is A)
- self.assertEqual(w, 1)
-
- w, C = op(None, A, 42, 666)
- self.assert_(C is A)
- self.assertEqual(w, 666)
-
- def testRightNone(self):
- for op in self.weightedUnion(), self.weightedIntersection():
- for A in self.As + self.emptys:
- w, C = op(A, None)
- self.assert_(C is A)
- self.assertEqual(w, 1)
-
- w, C = op(A, None, 42, 666)
- self.assert_(C is A)
- self.assertEqual(w, 42)
-
- # If obj is a set, return a bucket with values all 1; else return obj.
- def _normalize(self, obj):
- if isaset(obj):
- obj = self.mkbucket(zip(obj, [1] * len(obj)))
- return obj
-
- # Python simulation of weightedUnion.
- def _wunion(self, A, B, w1=1, w2=1):
- if isaset(A) and isaset(B):
- return 1, self.union()(A, B).keys()
- A = self._normalize(A)
- B = self._normalize(B)
- result = []
- for key in self.union()(A, B):
- v1 = A.get(key, 0)
- v2 = B.get(key, 0)
- result.append((key, v1*w1 + v2*w2))
- return 1, result
-
- def testUnion(self):
- inputs = self.As + self.Bs + self.emptys
- for A in inputs:
- for B in inputs:
- want_w, want_s = self._wunion(A, B)
- got_w, got_s = self.weightedUnion()(A, B)
- self.assertEqual(got_w, want_w)
- if isaset(got_s):
- self.assertEqual(got_s.keys(), want_s)
- else:
- self.assertEqual(got_s.items(), want_s)
-
- for w1, w2 in self.weights:
- want_w, want_s = self._wunion(A, B, w1, w2)
- got_w, got_s = self.weightedUnion()(A, B, w1, w2)
- self.assertEqual(got_w, want_w)
- if isaset(got_s):
- self.assertEqual(got_s.keys(), want_s)
- else:
- self.assertEqual(got_s.items(), want_s)
-
- # Python simulation weightedIntersection.
- def _wintersection(self, A, B, w1=1, w2=1):
- if isaset(A) and isaset(B):
- return w1 + w2, self.intersection()(A, B).keys()
- A = self._normalize(A)
- B = self._normalize(B)
- result = []
- for key in self.intersection()(A, B):
- result.append((key, A[key]*w1 + B[key]*w2))
- return 1, result
-
- def testIntersection(self):
- inputs = self.As + self.Bs + self.emptys
- for A in inputs:
- for B in inputs:
- want_w, want_s = self._wintersection(A, B)
- got_w, got_s = self.weightedIntersection()(A, B)
- self.assertEqual(got_w, want_w)
- if isaset(got_s):
- self.assertEqual(got_s.keys(), want_s)
- else:
- self.assertEqual(got_s.items(), want_s)
-
- for w1, w2 in self.weights:
- want_w, want_s = self._wintersection(A, B, w1, w2)
- got_w, got_s = self.weightedIntersection()(A, B, w1, w2)
- self.assertEqual(got_w, want_w)
- if isaset(got_s):
- self.assertEqual(got_s.keys(), want_s)
- else:
- self.assertEqual(got_s.items(), want_s)
-
-# Given a set builder (like OITreeSet or OISet), return a function that
-# takes a list of (key, value) pairs and builds a set out of the keys.
-def itemsToSet(setbuilder):
- def result(items, setbuilder=setbuilder):
- return setbuilder([key for key, value in items])
- return result
-
-class TestWeightedII(Weighted, unittest.TestCase):
- def weightedUnion(self):
- from BTrees.IIBTree import weightedUnion
- return weightedUnion
- def weightedIntersection(self):
- from BTrees.IIBTree import weightedIntersection
- return weightedIntersection
- def union(self):
- from BTrees.IIBTree import union
- return union
- def intersection(self):
- from BTrees.IIBTree import intersection
- return intersection
- def mkbucket(self, *args):
- from BTrees.IIBTree import IIBucket as mkbucket
- return mkbucket(*args)
- def builders(self):
- from BTrees.IIBTree import IIBTree
- from BTrees.IIBTree import IIBucket
- from BTrees.IIBTree import IITreeSet
- from BTrees.IIBTree import IISet
- return IIBucket, IIBTree, itemsToSet(IISet), itemsToSet(IITreeSet)
-
-class TestWeightedOI(Weighted, unittest.TestCase):
- def weightedUnion(self):
- from BTrees.OIBTree import weightedUnion
- return weightedUnion
- def weightedIntersection(self):
- from BTrees.OIBTree import weightedIntersection
- return weightedIntersection
- def union(self):
- from BTrees.OIBTree import union
- return union
- def intersection(self):
- from BTrees.OIBTree import intersection
- return intersection
- def mkbucket(self, *args):
- from BTrees.OIBTree import OIBucket as mkbucket
- return mkbucket(*args)
- def builders(self):
- from BTrees.OIBTree import OIBTree
- from BTrees.OIBTree import OIBucket
- from BTrees.OIBTree import OITreeSet
- from BTrees.OIBTree import OISet
- return OIBucket, OIBTree, itemsToSet(OISet), itemsToSet(OITreeSet)
-
-class TestWeightedLL(Weighted, unittest.TestCase):
- def weightedUnion(self):
- from BTrees.LLBTree import weightedUnion
- return weightedUnion
- def weightedIntersection(self):
- from BTrees.LLBTree import weightedIntersection
- return weightedIntersection
- def union(self):
- from BTrees.LLBTree import union
- return union
- def intersection(self):
- from BTrees.LLBTree import intersection
- return intersection
- def mkbucket(self, *args):
- from BTrees.LLBTree import LLBucket as mkbucket
- return mkbucket(*args)
- def builders(self):
- from BTrees.LLBTree import LLBTree
- from BTrees.LLBTree import LLBucket
- from BTrees.LLBTree import LLTreeSet
- from BTrees.LLBTree import LLSet
- return LLBucket, LLBTree, itemsToSet(LLSet), itemsToSet(LLTreeSet)
-
-class TestWeightedOL(Weighted, unittest.TestCase):
- def weightedUnion(self):
- from BTrees.OLBTree import weightedUnion
- return weightedUnion
- def weightedIntersection(self):
- from BTrees.OLBTree import weightedIntersection
- return weightedIntersection
- def union(self):
- from BTrees.OLBTree import union
- return union
- def intersection(self):
- from BTrees.OLBTree import intersection
- return intersection
- def mkbucket(self, *args):
- from BTrees.OLBTree import OLBucket as mkbucket
- return mkbucket(*args)
- def builders(self):
- from BTrees.OLBTree import OLBTree
- from BTrees.OLBTree import OLBucket
- from BTrees.OLBTree import OLTreeSet
- from BTrees.OLBTree import OLSet
- return OLBucket, OLBTree, itemsToSet(OLSet), itemsToSet(OLTreeSet)
-
-
-# 'thing' is a bucket, btree, set or treeset. Return true iff it's one of the
-# latter two.
-def isaset(thing):
- return not hasattr(thing, 'values')
-
-
-def test_suite():
- return unittest.TestSuite((
- unittest.makeSuite(TestIIMultiUnion),
- unittest.makeSuite(TestIOMultiUnion),
- unittest.makeSuite(TestIFMultiUnion),
- unittest.makeSuite(TestLLMultiUnion),
- unittest.makeSuite(TestLOMultiUnion),
- unittest.makeSuite(TestLFMultiUnion),
- unittest.makeSuite(TestImports),
- unittest.makeSuite(PureOO),
- unittest.makeSuite(PureII),
- unittest.makeSuite(PureIO),
- unittest.makeSuite(PureIF),
- unittest.makeSuite(PureOI),
- unittest.makeSuite(PureLL),
- unittest.makeSuite(PureLO),
- unittest.makeSuite(PureLF),
- unittest.makeSuite(PureOL),
- unittest.makeSuite(TestWeightedII),
- unittest.makeSuite(TestWeightedOI),
- unittest.makeSuite(TestWeightedLL),
- unittest.makeSuite(TestWeightedOL),
- ))
Copied: BTrees/trunk/BTrees/tests/test_IFBTree.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_IFBTree.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_IFBTree.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_IFBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,378 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+from .common import BTreeTests
+from .common import ExtendedSetTests
+from .common import InternalKeysMappingTest
+from .common import InternalKeysSetTest
+from .common import MappingBase
+from .common import MappingConflictTestBase
+from .common import ModuleTest
+from .common import MultiUnion
+from .common import NormalSetTests
+from .common import SetConflictTestBase
+from .common import SetResult
+from .common import TestLongIntKeys
+from .common import makeBuilder
+from BTrees.IIBTree import using64bits #XXX Ugly, but unavoidable
+
+
+class IFBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFBTree
+ return IFBTree
+
+
+class IFBTreePyInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFBTreePy
+ return IFBTreePy
+
+
+class IFTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFTreeSet
+ return IFTreeSet
+
+
+class IFTreeSetPyInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFTreeSetPy
+ return IFTreeSetPy
+
+
+class IFBucketTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFBucket
+ return IFBucket
+
+
+class IFBucketPyTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFBucketPy
+ return IFBucketPy
+
+
+class IFTreeSetTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFTreeSet
+ return IFTreeSet
+
+
+class IFTreeSetPyTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFTreeSetPy
+ return IFTreeSetPy
+
+
+class IFSetTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFSet
+ return IFSet
+
+
+class IFSetPyTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFSetPy
+ return IFSetPy
+
+
+class IFBTreeTest(BTreeTests, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IFBTree import IFBTree
+ return IFBTree()
+
+
+class IFBTreePyTest(BTreeTests, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IFBTree import IFBTreePy
+ return IFBTreePy()
+
+if using64bits:
+
+ class IFBTreeTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IFBTree import IFBTree
+ return IFBTree()
+
+ def getTwoValues(self):
+ return 0.5, 1.5
+
+ class IFBTreePyTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IFBTree import IFBTreePy
+ return IFBTreePy()
+
+ def getTwoValues(self):
+ return 0.5, 1.5
+
+
+class _TestIFBTreesBase(object):
+
+ def testNonIntegerKeyRaises(self):
+ self.assertRaises(TypeError, self._stringraiseskey)
+ self.assertRaises(TypeError, self._floatraiseskey)
+ self.assertRaises(TypeError, self._noneraiseskey)
+
+ def testNonNumericValueRaises(self):
+ self.assertRaises(TypeError, self._stringraisesvalue)
+ self.assertRaises(TypeError, self._noneraisesvalue)
+ self._makeOne()[1] = 1
+ self._makeOne()[1] = 1.0
+
+ def _stringraiseskey(self):
+ self._makeOne()['c'] = 1
+
+ def _floatraiseskey(self):
+ self._makeOne()[2.5] = 1
+
+ def _noneraiseskey(self):
+ self._makeOne()[None] = 1
+
+ def _stringraisesvalue(self):
+ self._makeOne()[1] = 'c'
+
+ def _floatraisesvalue(self):
+ self._makeOne()[1] = 1.4
+
+ def _noneraisesvalue(self):
+ self._makeOne()[1] = None
+
+
+class TestIFBTrees(_TestIFBTreesBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IFBTree import IFBTree
+ return IFBTree()
+
+
+class TestIFBTreesPy(_TestIFBTreesBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IFBTree import IFBTreePy
+ return IFBTreePy()
+
+
+class TestIFMultiUnion(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.IFBTree import multiunion
+ return multiunion(*args)
+
+ def union(self, *args):
+ from BTrees.IFBTree import union
+ return union(*args)
+
+ def mkset(self, *args):
+ from BTrees.IFBTree import IFSet as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.IFBTree import IFTreeSet as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.IFBTree import IFBucket as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.IFBTree import IFBTree as mkbtree
+ return mkbtree(*args)
+
+
+class TestIFMultiUnionPy(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.IFBTree import multiunionPy
+ return multiunionPy(*args)
+
+ def union(self, *args):
+ from BTrees.IFBTree import unionPy
+ return unionPy(*args)
+
+ def mkset(self, *args):
+ from BTrees.IFBTree import IFSetPy as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.IFBTree import IFTreeSetPy as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.IFBTree import IFBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.IFBTree import IFBTreePy as mkbtree
+ return mkbtree(*args)
+
+
+class PureIF(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.IFBTree import union
+ return union(*args)
+
+ def intersection(self, *args):
+ from BTrees.IFBTree import intersection
+ return intersection(*args)
+
+ def difference(self, *args):
+ from BTrees.IFBTree import difference
+ return difference(*args)
+
+ def builders(self):
+ from BTrees.IFBTree import IFBTree
+ from BTrees.IFBTree import IFBucket
+ from BTrees.IFBTree import IFTreeSet
+ from BTrees.IFBTree import IFSet
+ return IFSet, IFTreeSet, makeBuilder(IFBTree), makeBuilder(IFBucket)
+
+
+class PureIFPy(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.IFBTree import unionPy
+ return unionPy(*args)
+
+ def intersection(self, *args):
+ from BTrees.IFBTree import intersectionPy
+ return intersectionPy(*args)
+
+ def difference(self, *args):
+ from BTrees.IFBTree import differencePy
+ return differencePy(*args)
+
+ def builders(self):
+ from BTrees.IFBTree import IFBTreePy
+ from BTrees.IFBTree import IFBucketPy
+ from BTrees.IFBTree import IFTreeSetPy
+ from BTrees.IFBTree import IFSetPy
+ return (IFSetPy, IFTreeSetPy,
+ makeBuilder(IFBTreePy), makeBuilder(IFBucketPy))
+
+
+class IFBTreeConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFBTree
+ return IFBTree
+
+
+class IFBTreePyConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFBTreePy
+ return IFBTreePy
+
+
+class IFBucketConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFBucket
+ return IFBucket
+
+
+class IFBucketPyConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFBucketPy
+ return IFBucketPy
+
+
+class IFTreeSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFTreeSet
+ return IFTreeSet
+
+
+class IFTreeSetPyConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFTreeSetPy
+ return IFTreeSetPy
+
+
+class IFSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFSet
+ return IFSet
+
+
+class IFSetPyConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IFBTree import IFSetPy
+ return IFSetPy
+
+
+class IFModuleTest(ModuleTest, unittest.TestCase):
+
+ prefix = 'IF'
+
+ def _getModule(self):
+ import BTrees
+ return BTrees.IFBTree
+
+ def _getInterface(self):
+ import BTrees.Interfaces
+ return BTrees.Interfaces.IIntegerFloatBTreeModule
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(IFBTreeInternalKeyTest),
+ unittest.makeSuite(IFBTreePyInternalKeyTest),
+ unittest.makeSuite(IFTreeSetInternalKeyTest),
+ unittest.makeSuite(IFTreeSetPyInternalKeyTest),
+ unittest.makeSuite(IFBucketTest),
+ unittest.makeSuite(IFBucketPyTest),
+ unittest.makeSuite(IFTreeSetTest),
+ unittest.makeSuite(IFTreeSetPyTest),
+ unittest.makeSuite(IFSetTest),
+ unittest.makeSuite(IFSetPyTest),
+ unittest.makeSuite(IFBTreeTest),
+ unittest.makeSuite(IFBTreePyTest),
+ unittest.makeSuite(TestIFBTrees),
+ unittest.makeSuite(TestIFBTreesPy),
+ unittest.makeSuite(TestIFMultiUnion),
+ unittest.makeSuite(TestIFMultiUnionPy),
+ unittest.makeSuite(PureIF),
+ unittest.makeSuite(PureIFPy),
+ unittest.makeSuite(IFBTreeConflictTests),
+ unittest.makeSuite(IFBTreePyConflictTests),
+ unittest.makeSuite(IFBucketConflictTests),
+ unittest.makeSuite(IFBucketPyConflictTests),
+ unittest.makeSuite(IFTreeSetConflictTests),
+ unittest.makeSuite(IFTreeSetPyConflictTests),
+ unittest.makeSuite(IFSetConflictTests),
+ unittest.makeSuite(IFSetPyConflictTests),
+ unittest.makeSuite(IFModuleTest),
+ ))
Copied: BTrees/trunk/BTrees/tests/test_IIBTree.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_IIBTree.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_IIBTree.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_IIBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,505 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+from .common import BTreeTests
+from .common import ExtendedSetTests
+from .common import I_SetsBase
+from .common import InternalKeysMappingTest
+from .common import InternalKeysSetTest
+from .common import MappingBase
+from .common import MappingConflictTestBase
+from .common import ModuleTest
+from .common import MultiUnion
+from .common import NormalSetTests
+from .common import SetConflictTestBase
+from .common import SetResult
+from .common import TestLongIntKeys
+from .common import TestLongIntValues
+from .common import Weighted
+from .common import itemsToSet
+from .common import makeBuilder
+from BTrees.IIBTree import using64bits #XXX Ugly, but unavoidable
+
+
+class IIBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IIBTree
+ return IIBTree
+
+
+class IIBTreePyInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IIBTreePy
+ return IIBTreePy
+
+
+class IITreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IITreeSet
+ return IITreeSet
+
+
+class IITreeSetPyInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IITreeSetPy
+ return IITreeSetPy
+
+
+class IIBucketTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IIBucket
+ return IIBucket
+
+
+class IIBucketPyTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IIBucketPy
+ return IIBucketPy
+
+
+class IITreeSetTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IITreeSet
+ return IITreeSet
+
+
+class IITreeSetPyTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IITreeSetPy
+ return IITreeSetPy
+
+
+class IISetTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IISet
+ return IISet
+
+
+class IISetPyTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IISetPy
+ return IISetPy
+
+
+class _IIBTreeTestBase(BTreeTests):
+
+ def testIIBTreeOverflow(self):
+ good = set()
+ b = self._makeOne()
+
+ def trial(i):
+ i = int(i)
+ try:
+ b[i] = 0
+ except TypeError:
+ self.assertRaises(TypeError, b.__setitem__, 0, i)
+ else:
+ good.add(i)
+ b[0] = i
+ self.assertEqual(b[0], i)
+
+ for i in range((1<<31) - 3, (1<<31) + 3):
+ trial(i)
+ trial(-i)
+
+ del b[0]
+ self.assertEqual(sorted(good), sorted(b))
+
+
+class IIBTreeTest(_IIBTreeTestBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IIBTree
+ return IIBTree()
+
+
+class IIBTreeTestPy(_IIBTreeTestBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IIBTreePy
+ return IIBTreePy()
+
+
+if using64bits:
+
+ class IIBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues,
+ unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IIBTree
+ return IIBTree()
+
+ def getTwoValues(self):
+ return 1, 2
+
+ class IIBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues,
+ unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IIBTreePy
+ return IIBTreePy()
+
+ def getTwoValues(self):
+ return 1, 2
+
+
+class _TestIIBTreesBase(object):
+
+ def testNonIntegerKeyRaises(self):
+ self.assertRaises(TypeError, self._stringraiseskey)
+ self.assertRaises(TypeError, self._floatraiseskey)
+ self.assertRaises(TypeError, self._noneraiseskey)
+
+ def testNonIntegerValueRaises(self):
+ self.assertRaises(TypeError, self._stringraisesvalue)
+ self.assertRaises(TypeError, self._floatraisesvalue)
+ self.assertRaises(TypeError, self._noneraisesvalue)
+
+ def _stringraiseskey(self):
+ self._makeOne()['c'] = 1
+
+ def _floatraiseskey(self):
+ self._makeOne()[2.5] = 1
+
+ def _noneraiseskey(self):
+ self._makeOne()[None] = 1
+
+ def _stringraisesvalue(self):
+ self._makeOne()[1] = 'c'
+
+ def _floatraisesvalue(self):
+ self._makeOne()[1] = 1.4
+
+ def _noneraisesvalue(self):
+ self._makeOne()[1] = None
+
+
+class TestIIBTrees(_TestIIBTreesBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IIBTree
+ return IIBTree()
+
+
+class TestIIBTreesPy(_TestIIBTreesBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IIBTreePy
+ return IIBTreePy()
+
+
+class TestIISets(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IISet
+ return IISet()
+
+
+class TestIISetsPy(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IISetPy
+ return IISetPy()
+
+
+class TestIITreeSets(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IITreeSet
+ return IITreeSet()
+
+
+class TestIITreeSetsPy(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IIBTree import IITreeSetPy
+ return IITreeSetPy()
+
+
+class PureII(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.IIBTree import union
+ return union(*args)
+
+ def intersection(self, *args):
+ from BTrees.IIBTree import intersection
+ return intersection(*args)
+
+ def difference(self, *args):
+ from BTrees.IIBTree import difference
+ return difference(*args)
+
+ def builders(self):
+ from BTrees.IIBTree import IIBTree
+ from BTrees.IIBTree import IIBucket
+ from BTrees.IIBTree import IITreeSet
+ from BTrees.IIBTree import IISet
+ return IISet, IITreeSet, makeBuilder(IIBTree), makeBuilder(IIBucket)
+
+
+class PureIIPy(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.IIBTree import unionPy
+ return unionPy(*args)
+
+ def intersection(self, *args):
+ from BTrees.IIBTree import intersectionPy
+ return intersectionPy(*args)
+
+ def difference(self, *args):
+ from BTrees.IIBTree import differencePy
+ return differencePy(*args)
+
+ def builders(self):
+ from BTrees.IIBTree import IIBTreePy
+ from BTrees.IIBTree import IIBucketPy
+ from BTrees.IIBTree import IITreeSetPy
+ from BTrees.IIBTree import IISetPy
+ return (IISetPy, IITreeSetPy,
+ makeBuilder(IIBTreePy), makeBuilder(IIBucketPy))
+
+
+class TestIIMultiUnion(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.IIBTree import multiunion
+ return multiunion(*args)
+
+ def union(self, *args):
+ from BTrees.IIBTree import union
+ return union(*args)
+
+ def mkset(self, *args):
+ from BTrees.IIBTree import IISet as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.IIBTree import IITreeSet as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.IIBTree import IIBucket as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.IIBTree import IIBTree as mkbtree
+ return mkbtree(*args)
+
+
+class TestIIMultiUnionPy(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.IIBTree import multiunionPy
+ return multiunionPy(*args)
+
+ def union(self, *args):
+ from BTrees.IIBTree import unionPy
+ return unionPy(*args)
+
+ def mkset(self, *args):
+ from BTrees.IIBTree import IISetPy as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.IIBTree import IITreeSetPy as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.IIBTree import IIBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.IIBTree import IIBTreePy as mkbtree
+ return mkbtree(*args)
+
+
+class TestWeightedII(Weighted, unittest.TestCase):
+
+ def weightedUnion(self):
+ from BTrees.IIBTree import weightedUnion
+ return weightedUnion
+
+ def weightedIntersection(self):
+ from BTrees.IIBTree import weightedIntersection
+ return weightedIntersection
+
+ def union(self):
+ from BTrees.IIBTree import union
+ return union
+
+ def intersection(self):
+ from BTrees.IIBTree import intersection
+ return intersection
+
+ def mkbucket(self, *args):
+ from BTrees.IIBTree import IIBucket as mkbucket
+ return mkbucket(*args)
+
+ def builders(self):
+ from BTrees.IIBTree import IIBTree
+ from BTrees.IIBTree import IIBucket
+ from BTrees.IIBTree import IITreeSet
+ from BTrees.IIBTree import IISet
+ return IIBucket, IIBTree, itemsToSet(IISet), itemsToSet(IITreeSet)
+
+
+class TestWeightedIIPy(Weighted, unittest.TestCase):
+
+ def weightedUnion(self):
+ from BTrees.IIBTree import weightedUnionPy
+ return weightedUnionPy
+
+ def weightedIntersection(self):
+ from BTrees.IIBTree import weightedIntersectionPy
+ return weightedIntersectionPy
+
+ def union(self):
+ from BTrees.IIBTree import unionPy
+ return unionPy
+
+ def intersection(self):
+ from BTrees.IIBTree import intersectionPy
+ return intersectionPy
+
+ def mkbucket(self, *args):
+ from BTrees.IIBTree import IIBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def builders(self):
+ from BTrees.IIBTree import IIBTreePy
+ from BTrees.IIBTree import IIBucketPy
+ from BTrees.IIBTree import IITreeSetPy
+ from BTrees.IIBTree import IISetPy
+ return (IIBucketPy, IIBTreePy,
+ itemsToSet(IISetPy), itemsToSet(IITreeSetPy))
+
+
+class IIBTreeConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IIBTree
+ return IIBTree
+
+
+class IIBTreeConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IIBTreePy
+ return IIBTreePy
+
+
+class IIBucketConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IIBucket
+ return IIBucket
+
+
+class IIBucketConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IIBucketPy
+ return IIBucketPy
+
+
+class IITreeSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IITreeSet
+ return IITreeSet
+
+
+class IITreeSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IITreeSetPy
+ return IITreeSetPy
+
+
+class IISetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IISet
+ return IISet
+
+
+class IISetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IIBTree import IISetPy
+ return IISetPy
+
+
+class IIModuleTest(ModuleTest, unittest.TestCase):
+
+ prefix = 'II'
+
+ def _getModule(self):
+ import BTrees
+ return BTrees.IIBTree
+ def _getInterface(self):
+ import BTrees.Interfaces
+ return BTrees.Interfaces.IIntegerIntegerBTreeModule
+
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(IIBTreeInternalKeyTest),
+ unittest.makeSuite(IIBTreePyInternalKeyTest),
+ unittest.makeSuite(IITreeSetInternalKeyTest),
+ unittest.makeSuite(IITreeSetPyInternalKeyTest),
+ unittest.makeSuite(IIBucketTest),
+ unittest.makeSuite(IIBucketPyTest),
+ unittest.makeSuite(IITreeSetTest),
+ unittest.makeSuite(IITreeSetPyTest),
+ unittest.makeSuite(IISetTest),
+ unittest.makeSuite(IISetPyTest),
+ unittest.makeSuite(IIBTreeTest),
+ unittest.makeSuite(IIBTreeTestPy),
+ unittest.makeSuite(TestIIBTrees),
+ unittest.makeSuite(TestIIBTreesPy),
+ unittest.makeSuite(TestIISets),
+ unittest.makeSuite(TestIISetsPy),
+ unittest.makeSuite(TestIITreeSets),
+ unittest.makeSuite(TestIITreeSetsPy),
+ unittest.makeSuite(TestIIMultiUnion),
+ unittest.makeSuite(TestIIMultiUnionPy),
+ unittest.makeSuite(PureII),
+ unittest.makeSuite(PureIIPy),
+ unittest.makeSuite(TestWeightedII),
+ unittest.makeSuite(TestWeightedIIPy),
+ unittest.makeSuite(IIBTreeConflictTests),
+ unittest.makeSuite(IIBTreeConflictTestsPy),
+ unittest.makeSuite(IIBucketConflictTests),
+ unittest.makeSuite(IIBucketConflictTestsPy),
+ unittest.makeSuite(IITreeSetConflictTests),
+ unittest.makeSuite(IITreeSetConflictTestsPy),
+ unittest.makeSuite(IISetConflictTests),
+ unittest.makeSuite(IISetConflictTestsPy),
+ unittest.makeSuite(IIModuleTest),
+ ))
Copied: BTrees/trunk/BTrees/tests/test_IOBTree.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_IOBTree.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_IOBTree.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_IOBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,406 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+from .common import BTreeTests
+from .common import ExtendedSetTests
+from .common import I_SetsBase
+from .common import InternalKeysMappingTest
+from .common import InternalKeysSetTest
+from .common import MappingBase
+from .common import MappingConflictTestBase
+from .common import ModuleTest
+from .common import MultiUnion
+from .common import NormalSetTests
+from .common import SetConflictTestBase
+from .common import SetResult
+from .common import TypeTest
+from .common import TestLongIntKeys
+from .common import makeBuilder
+from BTrees.IIBTree import using64bits #XXX Ugly, but unavoidable
+
+
+class IOBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOBTree
+ return IOBTree
+
+
+class IOBTreePyInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOBTreePy
+ return IOBTreePy
+
+
+class IOTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOTreeSet
+ return IOTreeSet
+
+
+class IOTreeSetPyInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOTreeSetPy
+ return IOTreeSetPy
+
+
+class IOBucketTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOBucket
+ return IOBucket
+
+
+class IOBucketPyTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOBucketPy
+ return IOBucketPy
+
+
+class IOTreeSetTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOTreeSet
+ return IOTreeSet
+
+
+class IOTreeSetPyTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOTreeSetPy
+ return IOTreeSetPy
+
+
+class IOSetTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOSet
+ return IOSet
+
+
+class IOSetPyTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOSetPy
+ return IOSetPy
+
+
+class IOBTreeTest(BTreeTests, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOBTree
+ return IOBTree()
+
+
+class IOBTreePyTest(BTreeTests, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOBTreePy
+ return IOBTreePy()
+
+
+if using64bits:
+
+
+ class IOBTreeTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOBTree
+ return IOBTree()
+
+
+ class IOBTreePyTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOBTreePy
+ return IOBTreePy()
+
+
+class _TestIOBTreesBase(TypeTest):
+
+ def _stringraises(self):
+ self._makeOne()['c'] = 1
+
+ def _floatraises(self):
+ self._makeOne()[2.5] = 1
+
+ def _noneraises(self):
+ self._makeOne()[None] = 1
+
+
+class TestIOBTrees(_TestIOBTreesBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOBTree
+ return IOBTree()
+
+
+class TestIOBTreesPy(_TestIOBTreesBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOBTreePy
+ return IOBTreePy()
+
+
+class TestIOSets(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOSet
+ return IOSet()
+
+
+class TestIOSetsPy(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOSetPy
+ return IOSetPy()
+
+
+class TestIOTreeSets(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOTreeSet
+ return IOTreeSet()
+
+
+class TestIOTreeSetsPy(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.IOBTree import IOTreeSetPy
+ return IOTreeSetPy()
+
+
+class PureIO(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.IOBTree import union
+ return union(*args)
+
+ def intersection(self, *args):
+ from BTrees.IOBTree import intersection
+ return intersection(*args)
+
+ def difference(self, *args):
+ from BTrees.IOBTree import difference
+ return difference(*args)
+
+ def builders(self):
+ from BTrees.IOBTree import IOBTree
+ from BTrees.IOBTree import IOBucket
+ from BTrees.IOBTree import IOTreeSet
+ from BTrees.IOBTree import IOSet
+ return IOSet, IOTreeSet, makeBuilder(IOBTree), makeBuilder(IOBucket)
+
+
+class PureIOPy(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.IOBTree import unionPy
+ return unionPy(*args)
+
+ def intersection(self, *args):
+ from BTrees.IOBTree import intersectionPy
+ return intersectionPy(*args)
+
+ def difference(self, *args):
+ from BTrees.IOBTree import differencePy
+ return differencePy(*args)
+
+ def builders(self):
+ from BTrees.IOBTree import IOBTreePy
+ from BTrees.IOBTree import IOBucketPy
+ from BTrees.IOBTree import IOTreeSetPy
+ from BTrees.IOBTree import IOSetPy
+ return (IOSetPy, IOTreeSetPy,
+ makeBuilder(IOBTreePy), makeBuilder(IOBucketPy))
+
+
+class TestIOMultiUnion(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.IOBTree import multiunion
+ return multiunion(*args)
+
+ def union(self, *args):
+ from BTrees.IOBTree import union
+ return union(*args)
+
+ def mkset(self, *args):
+ from BTrees.IOBTree import IOSet as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.IOBTree import IOTreeSet as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.IOBTree import IOBucket as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.IOBTree import IOBTree as mkbtree
+ return mkbtree(*args)
+
+
+class TestIOMultiUnionPy(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.IOBTree import multiunionPy
+ return multiunionPy(*args)
+
+ def union(self, *args):
+ from BTrees.IOBTree import unionPy
+ return unionPy(*args)
+
+ def mkset(self, *args):
+ from BTrees.IOBTree import IOSetPy as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.IOBTree import IOTreeSetPy as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.IOBTree import IOBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.IOBTree import IOBTreePy as mkbtree
+ return mkbtree(*args)
+
+
+class IOBTreeConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOBTree
+ return IOBTree
+
+
+class IOBTreeConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOBTreePy
+ return IOBTreePy
+
+
+class IOBucketConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOBucket
+ return IOBucket
+
+
+class IOBucketConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOBucketPy
+ return IOBucketPy
+
+
+class IOTreeSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOTreeSet
+ return IOTreeSet
+
+
+class IOTreeSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOTreeSetPy
+ return IOTreeSetPy
+
+
+class IOSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOSet
+ return IOSet
+
+
+class IOSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.IOBTree import IOSetPy
+ return IOSetPy
+
+
+class IOModuleTest(ModuleTest, unittest.TestCase):
+
+ prefix = 'IO'
+
+ def _getModule(self):
+ import BTrees
+ return BTrees.IOBTree
+
+ def _getInterface(self):
+ import BTrees.Interfaces
+ return BTrees.Interfaces.IIntegerObjectBTreeModule
+
+ def test_weightedUnion_not_present(self):
+ try:
+ from BTrees.IOBTree import weightedUnion
+ except ImportError:
+ pass
+ else:
+ self.fail("IOBTree shouldn't have weightedUnion")
+
+ def test_weightedIntersection_not_present(self):
+ try:
+ from BTrees.IOBTree import weightedIntersection
+ except ImportError:
+ pass
+ else:
+ self.fail("IOBTree shouldn't have weightedIntersection")
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(IOBTreeInternalKeyTest),
+ unittest.makeSuite(IOBTreePyInternalKeyTest),
+ unittest.makeSuite(IOTreeSetInternalKeyTest),
+ unittest.makeSuite(IOTreeSetPyInternalKeyTest),
+ unittest.makeSuite(IOBucketTest),
+ unittest.makeSuite(IOBucketPyTest),
+ unittest.makeSuite(IOTreeSetTest),
+ unittest.makeSuite(IOTreeSetPyTest),
+ unittest.makeSuite(IOSetTest),
+ unittest.makeSuite(IOSetPyTest),
+ unittest.makeSuite(IOBTreeTest),
+ unittest.makeSuite(IOBTreePyTest),
+ unittest.makeSuite(TestIOBTrees),
+ unittest.makeSuite(TestIOBTreesPy),
+ unittest.makeSuite(TestIOSets),
+ unittest.makeSuite(TestIOSetsPy),
+ unittest.makeSuite(TestIOTreeSets),
+ unittest.makeSuite(TestIOTreeSetsPy),
+ unittest.makeSuite(TestIOMultiUnion),
+ unittest.makeSuite(TestIOMultiUnionPy),
+ unittest.makeSuite(PureIO),
+ unittest.makeSuite(PureIOPy),
+ unittest.makeSuite(IOBTreeConflictTests),
+ unittest.makeSuite(IOBTreeConflictTestsPy),
+ unittest.makeSuite(IOBucketConflictTests),
+ unittest.makeSuite(IOBucketConflictTestsPy),
+ unittest.makeSuite(IOTreeSetConflictTests),
+ unittest.makeSuite(IOTreeSetConflictTestsPy),
+ unittest.makeSuite(IOSetConflictTests),
+ unittest.makeSuite(IOSetConflictTestsPy),
+ unittest.makeSuite(IOModuleTest),
+ ))
Copied: BTrees/trunk/BTrees/tests/test_LFBTree.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_LFBTree.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_LFBTree.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_LFBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,316 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+from .common import BTreeTests
+from .common import ExtendedSetTests
+from .common import InternalKeysMappingTest
+from .common import InternalKeysSetTest
+from .common import MappingBase
+from .common import MappingConflictTestBase
+from .common import ModuleTest
+from .common import MultiUnion
+from .common import NormalSetTests
+from .common import SetConflictTestBase
+from .common import SetResult
+from .common import TestLongIntKeys
+from .common import makeBuilder
+
+
+class LFBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFBTree
+ return LFBTree
+
+
+class LFBTreePyInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFBTreePy
+ return LFBTreePy
+
+
+class LFTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFTreeSet
+ return LFTreeSet
+
+
+class LFTreeSetPyInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFTreeSetPy
+ return LFTreeSetPy
+
+
+class LFBucketTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFBucket
+ return LFBucket
+
+
+class LFBucketPyTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFBucketPy
+ return LFBucketPy
+
+
+class LFTreeSetTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFTreeSet
+ return LFTreeSet
+
+
+class LFTreeSetPyTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFTreeSetPy
+ return LFTreeSetPy
+
+
+class LFSetTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFSet
+ return LFSet
+
+
+class LFSetPyTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFSetPy
+ return LFSetPy
+
+
+class LFBTreeTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LFBTree import LFBTree
+ return LFBTree()
+
+ def getTwoValues(self):
+ return 0.5, 1.5
+
+
+class LFBTreePyTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LFBTree import LFBTreePy
+ return LFBTreePy()
+
+ def getTwoValues(self):
+ return 0.5, 1.5
+
+
+class TestLFMultiUnion(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.LFBTree import multiunionPy
+ return multiunionPy(*args)
+
+ def union(self, *args):
+ from BTrees.LFBTree import unionPy
+ return unionPy(*args)
+
+ def mkset(self, *args):
+ from BTrees.LFBTree import LFSetPy as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.LFBTree import LFTreeSetPy as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.LFBTree import LFBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.LFBTree import LFBTreePy as mkbtree
+ return mkbtree(*args)
+
+
+class TestLFMultiUnionPy(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.LFBTree import multiunionPy
+ return multiunionPy(*args)
+
+ def union(self, *args):
+ from BTrees.LFBTree import unionPy
+ return unionPy(*args)
+
+ def mkset(self, *args):
+ from BTrees.LFBTree import LFSetPy as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.LFBTree import LFTreeSetPy as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.LFBTree import LFBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.LFBTree import LFBTreePy as mkbtree
+ return mkbtree(*args)
+
+
+class PureLF(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.LFBTree import union
+ return union(*args)
+
+ def intersection(self, *args):
+ from BTrees.LFBTree import intersection
+ return intersection(*args)
+
+ def difference(self, *args):
+ from BTrees.LFBTree import difference
+ return difference(*args)
+
+ def builders(self):
+ from BTrees.LFBTree import LFBTree
+ from BTrees.LFBTree import LFBucket
+ from BTrees.LFBTree import LFTreeSet
+ from BTrees.LFBTree import LFSet
+ return LFSet, LFTreeSet, makeBuilder(LFBTree), makeBuilder(LFBucket)
+
+
+class PureLFPy(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.LFBTree import unionPy
+ return unionPy(*args)
+
+ def intersection(self, *args):
+ from BTrees.LFBTree import intersectionPy
+ return intersectionPy(*args)
+
+ def difference(self, *args):
+ from BTrees.LFBTree import differencePy
+ return differencePy(*args)
+
+ def builders(self):
+ from BTrees.LFBTree import LFBTreePy
+ from BTrees.LFBTree import LFBucketPy
+ from BTrees.LFBTree import LFTreeSetPy
+ from BTrees.LFBTree import LFSetPy
+ return (LFSetPy, LFTreeSetPy,
+ makeBuilder(LFBTreePy), makeBuilder(LFBucketPy))
+
+
+class LFBTreeConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFBTree
+ return LFBTree
+
+
+class LFBTreeConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFBTreePy
+ return LFBTreePy
+
+
+class LFBucketConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFBucket
+ return LFBucket
+
+
+class LFBucketConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFBucketPy
+ return LFBucketPy
+
+
+class LFTreeSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFTreeSet
+ return LFTreeSet
+
+
+class LFTreeSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFTreeSetPy
+ return LFTreeSetPy
+
+
+class LFSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFSet
+ return LFSet
+
+
+class LFSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LFBTree import LFSetPy
+ return LFSetPy
+
+
+class LFModuleTest(ModuleTest, unittest.TestCase):
+
+ prefix = 'LF'
+
+ def _getModule(self):
+ import BTrees
+ return BTrees.LFBTree
+
+ def _getInterface(self):
+ import BTrees.Interfaces
+ return BTrees.Interfaces.IIntegerFloatBTreeModule
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(LFBTreeInternalKeyTest),
+ unittest.makeSuite(LFBTreePyInternalKeyTest),
+ unittest.makeSuite(LFTreeSetInternalKeyTest),
+ unittest.makeSuite(LFTreeSetPyInternalKeyTest),
+ unittest.makeSuite(LFBucketTest),
+ unittest.makeSuite(LFBucketPyTest),
+ unittest.makeSuite(LFTreeSetTest),
+ unittest.makeSuite(LFTreeSetPyTest),
+ unittest.makeSuite(LFSetTest),
+ unittest.makeSuite(LFSetPyTest),
+ unittest.makeSuite(LFBTreeTest),
+ unittest.makeSuite(LFBTreePyTest),
+ unittest.makeSuite(TestLFMultiUnion),
+ unittest.makeSuite(TestLFMultiUnionPy),
+ unittest.makeSuite(PureLF),
+ unittest.makeSuite(PureLFPy),
+ unittest.makeSuite(LFBTreeConflictTests),
+ unittest.makeSuite(LFBTreeConflictTestsPy),
+ unittest.makeSuite(LFBucketConflictTests),
+ unittest.makeSuite(LFBucketConflictTestsPy),
+ unittest.makeSuite(LFTreeSetConflictTests),
+ unittest.makeSuite(LFTreeSetConflictTestsPy),
+ unittest.makeSuite(LFSetConflictTests),
+ unittest.makeSuite(LFSetConflictTestsPy),
+ unittest.makeSuite(LFModuleTest),
+ ))
Copied: BTrees/trunk/BTrees/tests/test_LLBTree.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_LLBTree.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_LLBTree.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_LLBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,415 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+from .common import BTreeTests
+from .common import ExtendedSetTests
+from .common import I_SetsBase
+from .common import InternalKeysMappingTest
+from .common import InternalKeysSetTest
+from .common import MappingBase
+from .common import MappingConflictTestBase
+from .common import ModuleTest
+from .common import MultiUnion
+from .common import NormalSetTests
+from .common import SetConflictTestBase
+from .common import SetResult
+from .common import TestLongIntKeys
+from .common import TestLongIntValues
+from .common import Weighted
+from .common import itemsToSet
+from .common import makeBuilder
+
+
+class LLBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLBTree
+ return LLBTree
+
+
+class LLBTreePyInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLBTreePy
+ return LLBTreePy
+
+
+class LLTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLTreeSet
+ return LLTreeSet
+
+
+class LLTreeSetPyInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLTreeSetPy
+ return LLTreeSetPy
+
+
+class LLBucketTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLBucket
+ return LLBucket
+
+
+class LLBucketTestPy(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLBucketPy
+ return LLBucketPy
+
+
+class LLTreeSetTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLTreeSet
+ return LLTreeSet
+
+
+class LLTreeSetTestPy(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLTreeSetPy
+ return LLTreeSetPy
+
+
+class LLSetTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLSet
+ return LLSet
+
+
+class LLSetTestPy(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLSetPy
+ return LLSetPy
+
+
+class LLBTreeTest(BTreeTests, TestLongIntKeys, TestLongIntValues,
+ unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LLBTree import LLBTree
+ return LLBTree()
+ def getTwoValues(self):
+ return 1, 2
+
+
+class LLBTreeTestPy(BTreeTests, TestLongIntKeys, TestLongIntValues,
+ unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LLBTree import LLBTreePy
+ return LLBTreePy()
+ def getTwoValues(self):
+ return 1, 2
+
+
+class TestLLSets(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LLBTree import LLSet
+ return LLSet()
+
+
+class TestLLSetsPy(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LLBTree import LLSetPy
+ return LLSetPy()
+
+
+class TestLLTreeSets(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LLBTree import LLTreeSet
+ return LLTreeSet()
+
+
+class TestLLTreeSetsPy(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LLBTree import LLTreeSetPy
+ return LLTreeSetPy()
+
+
+class PureLL(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.LLBTree import union
+ return union(*args)
+
+ def intersection(self, *args):
+ from BTrees.LLBTree import intersection
+ return intersection(*args)
+
+ def difference(self, *args):
+ from BTrees.LLBTree import difference
+ return difference(*args)
+
+ def builders(self):
+ from BTrees.LLBTree import LLBTree
+ from BTrees.LLBTree import LLBucket
+ from BTrees.LLBTree import LLTreeSet
+ from BTrees.LLBTree import LLSet
+ return LLSet, LLTreeSet, makeBuilder(LLBTree), makeBuilder(LLBucket)
+
+
+class PureLLPy(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.LLBTree import unionPy
+ return unionPy(*args)
+
+ def intersection(self, *args):
+ from BTrees.LLBTree import intersectionPy
+ return intersectionPy(*args)
+
+ def difference(self, *args):
+ from BTrees.LLBTree import differencePy
+ return differencePy(*args)
+
+ def builders(self):
+ from BTrees.LLBTree import LLBTreePy
+ from BTrees.LLBTree import LLBucketPy
+ from BTrees.LLBTree import LLTreeSetPy
+ from BTrees.LLBTree import LLSetPy
+ return (LLSetPy, LLTreeSetPy,
+ makeBuilder(LLBTreePy), makeBuilder(LLBucketPy))
+
+
+class TestLLMultiUnion(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.LLBTree import multiunion
+ return multiunion(*args)
+
+ def union(self, *args):
+ from BTrees.LLBTree import union
+ return union(*args)
+
+ def mkset(self, *args):
+ from BTrees.LLBTree import LLSet as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.LLBTree import LLTreeSet as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.LLBTree import LLBucket as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.LLBTree import LLBTree as mkbtree
+ return mkbtree(*args)
+
+
+class TestLLMultiUnionPy(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.LLBTree import multiunionPy
+ return multiunionPy(*args)
+
+ def union(self, *args):
+ from BTrees.LLBTree import unionPy
+ return unionPy(*args)
+
+ def mkset(self, *args):
+ from BTrees.LLBTree import LLSetPy as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.LLBTree import LLTreeSetPy as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.LLBTree import LLBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.LLBTree import LLBTreePy as mkbtree
+ return mkbtree(*args)
+
+
+class TestWeightedLL(Weighted, unittest.TestCase):
+
+ def weightedUnion(self):
+ from BTrees.LLBTree import weightedUnion
+ return weightedUnion
+
+ def weightedIntersection(self):
+ from BTrees.LLBTree import weightedIntersection
+ return weightedIntersection
+
+ def union(self):
+ from BTrees.LLBTree import union
+ return union
+
+ def intersection(self):
+ from BTrees.LLBTree import intersection
+ return intersection
+
+ def mkbucket(self, *args):
+ from BTrees.LLBTree import LLBucket as mkbucket
+ return mkbucket(*args)
+
+ def builders(self):
+ from BTrees.LLBTree import LLBTree
+ from BTrees.LLBTree import LLBucket
+ from BTrees.LLBTree import LLTreeSet
+ from BTrees.LLBTree import LLSet
+ return LLBucket, LLBTree, itemsToSet(LLSet), itemsToSet(LLTreeSet)
+
+
+class TestWeightedLLPy(Weighted, unittest.TestCase):
+
+ def weightedUnion(self):
+ from BTrees.LLBTree import weightedUnionPy
+ return weightedUnionPy
+
+ def weightedIntersection(self):
+ from BTrees.LLBTree import weightedIntersectionPy
+ return weightedIntersectionPy
+
+ def union(self):
+ from BTrees.LLBTree import unionPy
+ return unionPy
+
+ def intersection(self):
+ from BTrees.LLBTree import intersectionPy
+ return intersectionPy
+
+ def mkbucket(self, *args):
+ from BTrees.LLBTree import LLBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def builders(self):
+ from BTrees.LLBTree import LLBTreePy
+ from BTrees.LLBTree import LLBucketPy
+ from BTrees.LLBTree import LLTreeSetPy
+ from BTrees.LLBTree import LLSetPy
+ return (LLBucketPy, LLBTreePy,
+ itemsToSet(LLSetPy), itemsToSet(LLTreeSetPy))
+
+
+class LLBTreeConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLBTree
+ return LLBTree
+
+
+class LLBTreeConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLBTreePy
+ return LLBTreePy
+
+
+class LLBucketConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLBucket
+ return LLBucket
+
+
+class LLBucketConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLBucketPy
+ return LLBucketPy
+
+
+class LLTreeSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLTreeSet
+ return LLTreeSet
+
+
+class LLTreeSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLTreeSetPy
+ return LLTreeSetPy
+
+
+class LLSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLSet
+ return LLSet
+
+
+class LLSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LLBTree import LLSetPy
+ return LLSetPy
+
+
+class LLModuleTest(ModuleTest, unittest.TestCase):
+
+ prefix = 'LL'
+
+ def _getModule(self):
+ import BTrees
+ return BTrees.LLBTree
+
+ def _getInterface(self):
+ import BTrees.Interfaces
+ return BTrees.Interfaces.IIntegerIntegerBTreeModule
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(LLBTreeInternalKeyTest),
+ unittest.makeSuite(LLBTreeInternalKeyTest),
+ unittest.makeSuite(LLTreeSetInternalKeyTest),
+ unittest.makeSuite(LLTreeSetInternalKeyTest),
+ unittest.makeSuite(LLBucketTest),
+ unittest.makeSuite(LLBucketTest),
+ unittest.makeSuite(LLTreeSetTest),
+ unittest.makeSuite(LLTreeSetTest),
+ unittest.makeSuite(LLSetTest),
+ unittest.makeSuite(LLSetTest),
+ unittest.makeSuite(LLBTreeTest),
+ unittest.makeSuite(LLBTreeTest),
+ unittest.makeSuite(TestLLSets),
+ unittest.makeSuite(TestLLSets),
+ unittest.makeSuite(TestLLTreeSets),
+ unittest.makeSuite(TestLLTreeSets),
+ unittest.makeSuite(TestLLMultiUnion),
+ unittest.makeSuite(TestLLMultiUnion),
+ unittest.makeSuite(PureLL),
+ unittest.makeSuite(PureLL),
+ unittest.makeSuite(TestWeightedLL),
+ unittest.makeSuite(TestWeightedLL),
+ unittest.makeSuite(LLBTreeConflictTests),
+ unittest.makeSuite(LLBTreeConflictTests),
+ unittest.makeSuite(LLBucketConflictTests),
+ unittest.makeSuite(LLBucketConflictTests),
+ unittest.makeSuite(LLTreeSetConflictTests),
+ unittest.makeSuite(LLTreeSetConflictTests),
+ unittest.makeSuite(LLSetConflictTests),
+ unittest.makeSuite(LLSetConflictTests),
+ unittest.makeSuite(LLModuleTest),
+ ))
Copied: BTrees/trunk/BTrees/tests/test_LOBTree.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_LOBTree.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_LOBTree.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_LOBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,359 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+from .common import BTreeTests
+from .common import ExtendedSetTests
+from .common import I_SetsBase
+from .common import InternalKeysMappingTest
+from .common import InternalKeysSetTest
+from .common import MappingBase
+from .common import MappingConflictTestBase
+from .common import ModuleTest
+from .common import MultiUnion
+from .common import NormalSetTests
+from .common import SetConflictTestBase
+from .common import SetResult
+from .common import TestLongIntKeys
+from .common import makeBuilder
+
+
+class LOBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOBTree
+ return LOBTree
+
+
+class LOBTreePyInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOBTreePy
+ return LOBTreePy
+
+
+class LOTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOTreeSet
+ return LOTreeSet
+
+
+class LOTreeSetPyInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOTreeSetPy
+ return LOTreeSetPy
+
+
+class LOBucketTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOBucket
+ return LOBucket
+
+
+class LOBucketPyTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOBucketPy
+ return LOBucketPy
+
+
+class LOTreeSetTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOTreeSet
+ return LOTreeSet
+
+
+class LOTreeSetPyTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOTreeSetPy
+ return LOTreeSetPy
+
+
+class LOSetTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOSet
+ return LOSet
+
+
+class LOSetPyTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOSetPy
+ return LOSetPy
+
+
+class LOBTreeTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LOBTree import LOBTree
+ return LOBTree()
+
+
+class LOBTreePyTest(BTreeTests, TestLongIntKeys, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LOBTree import LOBTreePy
+ return LOBTreePy()
+
+
+class TestLOSets(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LOBTree import LOSet
+ return LOSet()
+
+
+class TestLOSetsPy(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LOBTree import LOSetPy
+ return LOSetPy()
+
+
+class TestLOTreeSets(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LOBTree import LOTreeSet
+ return LOTreeSet()
+
+
+class TestLOTreeSetsPy(I_SetsBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.LOBTree import LOTreeSetPy
+ return LOTreeSetPy()
+
+
+class TestLOMultiUnion(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.LOBTree import multiunion
+ return multiunion(*args)
+
+ def union(self, *args):
+ from BTrees.LOBTree import union
+ return union(*args)
+
+ def mkset(self, *args):
+ from BTrees.LOBTree import LOSet as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.LOBTree import LOTreeSet as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.LOBTree import LOBucket as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.LOBTree import LOBTree as mkbtree
+ return mkbtree(*args)
+
+
+class TestLOMultiUnionPy(MultiUnion, unittest.TestCase):
+
+ def multiunion(self, *args):
+ from BTrees.LOBTree import multiunionPy
+ return multiunionPy(*args)
+
+ def union(self, *args):
+ from BTrees.LOBTree import unionPy
+ return unionPy(*args)
+
+ def mkset(self, *args):
+ from BTrees.LOBTree import LOSetPy as mkset
+ return mkset(*args)
+
+ def mktreeset(self, *args):
+ from BTrees.LOBTree import LOTreeSetPy as mktreeset
+ return mktreeset(*args)
+
+ def mkbucket(self, *args):
+ from BTrees.LOBTree import LOBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def mkbtree(self, *args):
+ from BTrees.LOBTree import LOBTreePy as mkbtree
+ return mkbtree(*args)
+
+
+class PureLO(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.LOBTree import union
+ return union(*args)
+
+ def intersection(self, *args):
+ from BTrees.LOBTree import intersection
+ return intersection(*args)
+
+ def difference(self, *args):
+ from BTrees.LOBTree import difference
+ return difference(*args)
+
+ def builders(self):
+ from BTrees.LOBTree import LOBTree
+ from BTrees.LOBTree import LOBucket
+ from BTrees.LOBTree import LOTreeSet
+ from BTrees.LOBTree import LOSet
+ return LOSet, LOTreeSet, makeBuilder(LOBTree), makeBuilder(LOBucket)
+
+
+class PureLOPy(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.LOBTree import unionPy
+ return unionPy(*args)
+
+ def intersection(self, *args):
+ from BTrees.LOBTree import intersectionPy
+ return intersectionPy(*args)
+
+ def difference(self, *args):
+ from BTrees.LOBTree import differencePy
+ return differencePy(*args)
+
+ def builders(self):
+ from BTrees.LOBTree import LOBTreePy
+ from BTrees.LOBTree import LOBucketPy
+ from BTrees.LOBTree import LOTreeSetPy
+ from BTrees.LOBTree import LOSetPy
+ return (LOSetPy, LOTreeSetPy,
+ makeBuilder(LOBTreePy), makeBuilder(LOBucketPy))
+
+
+class LOBTreeConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOBTree
+ return LOBTree
+
+
+class LOBTreeConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOBTreePy
+ return LOBTreePy
+
+
+class LOBucketConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOBucket
+ return LOBucket
+
+
+class LOBucketConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOBucketPy
+ return LOBucketPy
+
+
+class LOTreeSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOTreeSet
+ return LOTreeSet
+
+
+class LOTreeSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOTreeSetPy
+ return LOTreeSetPy
+
+
+class LOSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOSet
+ return LOSet
+
+
+class LOSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.LOBTree import LOSetPy
+ return LOSetPy
+
+
+class LOModuleTest(ModuleTest, unittest.TestCase):
+
+ prefix = 'LO'
+
+ def _getModule(self):
+ import BTrees
+ return BTrees.LOBTree
+
+ def _getInterface(self):
+ import BTrees.Interfaces
+ return BTrees.Interfaces.IIntegerObjectBTreeModule
+
+ def test_weightedUnion_not_present(self):
+ try:
+ from BTrees.LOBTree import weightedUnion
+ except ImportError:
+ pass
+ else:
+ self.fail("LOBTree shouldn't have weightedUnion")
+
+ def test_weightedIntersection_not_present(self):
+ try:
+ from BTrees.LOBTree import weightedIntersection
+ except ImportError:
+ pass
+ else:
+ self.fail("LOBTree shouldn't have weightedIntersection")
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(LOBTreeInternalKeyTest),
+ unittest.makeSuite(LOBTreePyInternalKeyTest),
+ unittest.makeSuite(LOTreeSetInternalKeyTest),
+ unittest.makeSuite(LOTreeSetPyInternalKeyTest),
+ unittest.makeSuite(LOBucketTest),
+ unittest.makeSuite(LOBucketPyTest),
+ unittest.makeSuite(LOTreeSetTest),
+ unittest.makeSuite(LOTreeSetPyTest),
+ unittest.makeSuite(LOSetTest),
+ unittest.makeSuite(LOSetPyTest),
+ unittest.makeSuite(LOBTreeTest),
+ unittest.makeSuite(LOBTreePyTest),
+ unittest.makeSuite(TestLOSets),
+ unittest.makeSuite(TestLOSetsPy),
+ unittest.makeSuite(TestLOTreeSets),
+ unittest.makeSuite(TestLOTreeSetsPy),
+ unittest.makeSuite(TestLOMultiUnion),
+ unittest.makeSuite(TestLOMultiUnionPy),
+ unittest.makeSuite(PureLO),
+ unittest.makeSuite(PureLOPy),
+ unittest.makeSuite(LOBTreeConflictTests),
+ unittest.makeSuite(LOBTreeConflictTestsPy),
+ unittest.makeSuite(LOBucketConflictTests),
+ unittest.makeSuite(LOBucketConflictTestsPy),
+ unittest.makeSuite(LOTreeSetConflictTests),
+ unittest.makeSuite(LOTreeSetConflictTestsPy),
+ unittest.makeSuite(LOSetConflictTests),
+ unittest.makeSuite(LOSetConflictTestsPy),
+ unittest.makeSuite(LOModuleTest),
+ ))
Copied: BTrees/trunk/BTrees/tests/test_Length.py (from rev 128094, BTrees/trunk/BTrees/tests/testLength.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_Length.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_Length.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,92 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+
+_marker = object()
+
+class LengthTestCase(unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.Length import Length
+ return Length
+
+ def _makeOne(self, value=_marker):
+ if value is _marker:
+ return self._getTargetClass()()
+ return self._getTargetClass()(value)
+
+ def test_ctor_default(self):
+ length = self._makeOne()
+ self.assertEqual(length.value, 0)
+
+ def test_ctor_explict(self):
+ length = self._makeOne(42)
+ self.assertEqual(length.value, 42)
+
+ def test___getstate___(self):
+ length = self._makeOne(42)
+ self.assertEqual(length.__getstate__(), 42)
+
+ def test___setstate__(self):
+ length = self._makeOne()
+ length.__setstate__(42)
+ self.assertEqual(length.value, 42)
+
+ def test_set(self):
+ length = self._makeOne()
+ length.set(42)
+ self.assertEqual(length.value, 42)
+
+ def test__p_resolveConflict(self):
+ length = self._makeOne()
+ self.assertEqual(length._p_resolveConflict(5, 7, 9), 11)
+
+ def test_change_overflows_to_long(self):
+ import sys
+ length = self._makeOne(sys.maxint)
+ self.assertEqual(length(), sys.maxint)
+ self.assert_(type(length()) is int)
+ length.change(+1)
+ self.assertEqual(length(), sys.maxint + 1)
+ self.assert_(type(length()) is long)
+
+ def test_change_underflows_to_long(self):
+ import sys
+ minint = (-sys.maxint) - 1
+ length = self._makeOne(minint)
+ self.assertEqual(length(), minint)
+ self.assert_(type(length()) is int)
+ length.change(-1)
+ self.assertEqual(length(), minint - 1)
+ self.assert_(type(length()) is long)
+
+ def test___call___no_args(self):
+ length = self._makeOne(42)
+ self.assertEqual(length(), 42)
+
+ def test___call___w_args(self):
+ length = self._makeOne(42)
+ self.assertEqual(length(0, None, (), [], {}), 42)
+
+ def test_lp_516653(self):
+ # Test for https://bugs.launchpad.net/zodb/+bug/516653
+ import copy
+ length = self._makeOne()
+ other = copy.copy(length)
+ self.assertEqual(other(), 0)
+
+
+def test_suite():
+ return unittest.makeSuite(LengthTestCase)
Copied: BTrees/trunk/BTrees/tests/test_OIBTree.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_OIBTree.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_OIBTree.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_OIBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,382 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+from .common import BTreeTests
+from .common import ExtendedSetTests
+from .common import InternalKeysMappingTest
+from .common import InternalKeysSetTest
+from .common import MappingBase
+from .common import MappingConflictTestBase
+from .common import ModuleTest
+from .common import NormalSetTests
+from .common import SetConflictTestBase
+from .common import SetResult
+from .common import TestLongIntValues
+from .common import TypeTest
+from .common import Weighted
+from .common import itemsToSet
+from .common import makeBuilder
+from BTrees.IIBTree import using64bits #XXX Ugly, but necessary
+
+
+class OIBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OIBTree
+ return OIBTree
+
+
+class OIBTreePyInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OIBTreePy
+ return OIBTreePy
+
+
+class OITreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OITreeSet
+ return OITreeSet
+
+
+class OITreeSetPyInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OITreeSetPy
+ return OITreeSetPy
+
+
+class OIBucketTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OIBucket
+ return OIBucket
+
+
+class OIBucketPyTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OIBucketPy
+ return OIBucketPy
+
+
+class OITreeSetTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OITreeSet
+ return OITreeSet
+
+
+class OITreeSetPyTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OITreeSetPy
+ return OITreeSetPy
+
+
+class OISetTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OISet
+ return OISet
+
+
+class OISetPyTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OISetPy
+ return OISetPy
+
+
+class OIBTreeTest(BTreeTests, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.OIBTree import OIBTree
+ return OIBTree()
+
+
+class OIBTreePyTest(BTreeTests, unittest.TestCase):
+ def _makeOne(self):
+ from BTrees.OIBTree import OIBTreePy
+ return OIBTreePy()
+
+
+if using64bits:
+
+ class OIBTreeTest(BTreeTests, TestLongIntValues, unittest.TestCase):
+ def _makeOne(self):
+ from BTrees.OIBTree import OIBTree
+ return OIBTree()
+ def getTwoKeys(self):
+ return object(), object()
+
+ class OIBTreePyTest(BTreeTests, TestLongIntValues, unittest.TestCase):
+ def _makeOne(self):
+ from BTrees.OIBTree import OIBTreePy
+ return OIBTreePy()
+ def getTwoKeys(self):
+ return object(), object()
+
+
+class _TestOIBTreesBase(TypeTest):
+
+ def _stringraises(self):
+ self._makeOne()[1] = 'c'
+
+ def _floatraises(self):
+ self._makeOne()[1] = 1.4
+
+ def _noneraises(self):
+ self._makeOne()[1] = None
+
+ def testEmptyFirstBucketReportedByGuido(self):
+ b = self._makeOne()
+ for i in xrange(29972): # reduce to 29971 and it works
+ b[i] = i
+ for i in xrange(30): # reduce to 29 and it works
+ del b[i]
+ b[i+40000] = i
+
+ self.assertEqual(b.keys()[0], 30)
+
+
+class TestOIBTrees(_TestOIBTreesBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.OIBTree import OIBTree
+ return OIBTree()
+
+
+class TestOIBTreesPy(_TestOIBTreesBase, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.OIBTree import OIBTreePy
+ return OIBTreePy()
+
+
+class PureOI(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.OIBTree import union
+ return union(*args)
+
+ def intersection(self, *args):
+ from BTrees.OIBTree import intersection
+ return intersection(*args)
+
+ def difference(self, *args):
+ from BTrees.OIBTree import difference
+ return difference(*args)
+
+ def builders(self):
+ from BTrees.OIBTree import OIBTree
+ from BTrees.OIBTree import OIBucket
+ from BTrees.OIBTree import OITreeSet
+ from BTrees.OIBTree import OISet
+ return OISet, OITreeSet, makeBuilder(OIBTree), makeBuilder(OIBucket)
+
+
+class PureOIPy(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.OIBTree import unionPy
+ return unionPy(*args)
+
+ def intersection(self, *args):
+ from BTrees.OIBTree import intersectionPy
+ return intersectionPy(*args)
+
+ def difference(self, *args):
+ from BTrees.OIBTree import differencePy
+ return differencePy(*args)
+
+ def builders(self):
+ from BTrees.OIBTree import OIBTreePy
+ from BTrees.OIBTree import OIBucketPy
+ from BTrees.OIBTree import OITreeSetPy
+ from BTrees.OIBTree import OISetPy
+ return (OISetPy, OITreeSetPy,
+ makeBuilder(OIBTreePy), makeBuilder(OIBucketPy))
+
+
+class TestWeightedOI(Weighted, unittest.TestCase):
+
+ def weightedUnion(self):
+ from BTrees.OIBTree import weightedUnion
+ return weightedUnion
+
+ def weightedIntersection(self):
+ from BTrees.OIBTree import weightedIntersection
+ return weightedIntersection
+
+ def union(self):
+ from BTrees.OIBTree import union
+ return union
+
+ def intersection(self):
+ from BTrees.OIBTree import intersection
+ return intersection
+
+ def mkbucket(self, *args):
+ from BTrees.OIBTree import OIBucket as mkbucket
+ return mkbucket(*args)
+
+ def builders(self):
+ from BTrees.OIBTree import OIBTree
+ from BTrees.OIBTree import OIBucket
+ from BTrees.OIBTree import OITreeSet
+ from BTrees.OIBTree import OISet
+ return OIBucket, OIBTree, itemsToSet(OISet), itemsToSet(OITreeSet)
+
+
+class TestWeightedOIPy(Weighted, unittest.TestCase):
+
+ def weightedUnion(self):
+ from BTrees.OIBTree import weightedUnionPy
+ return weightedUnionPy
+
+ def weightedIntersection(self):
+ from BTrees.OIBTree import weightedIntersectionPy
+ return weightedIntersectionPy
+
+ def union(self):
+ from BTrees.OIBTree import unionPy
+ return unionPy
+
+ def intersection(self):
+ from BTrees.OIBTree import intersectionPy
+ return intersectionPy
+
+ def mkbucket(self, *args):
+ from BTrees.OIBTree import OIBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def builders(self):
+ from BTrees.OIBTree import OIBTreePy
+ from BTrees.OIBTree import OIBucketPy
+ from BTrees.OIBTree import OITreeSetPy
+ from BTrees.OIBTree import OISetPy
+ return (OIBucketPy, OIBTreePy,
+ itemsToSet(OISetPy), itemsToSet(OITreeSetPy))
+
+
+class OIBucketConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OIBucket
+ return OIBucket
+
+
+class OIBucketConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OIBucketPy
+ return OIBucketPy
+
+
+class OISetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OISet
+ return OISet
+
+
+class OISetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OISetPy
+ return OISetPy
+
+
+class OIBTreeConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OIBTree
+ return OIBTree
+
+
+class OIBTreeConflictTestsPy(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OIBTreePy
+ return OIBTreePy
+
+
+class OITreeSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OITreeSet
+ return OITreeSet
+
+
+class OITreeSetConflictTestsPy(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OIBTree import OITreeSetPy
+ return OITreeSetPy
+
+
+class OIModuleTest(ModuleTest, unittest.TestCase):
+
+ prefix = 'OI'
+
+ def _getModule(self):
+ import BTrees
+ return BTrees.OIBTree
+
+ def _getInterface(self):
+ import BTrees.Interfaces
+ return BTrees.Interfaces.IObjectIntegerBTreeModule
+
+ def test_multiunion_not_present(self):
+ try:
+ from BTrees.OIBTree import multiunion
+ except ImportError:
+ pass
+ else:
+ self.fail("OIBTree shouldn't have multiunion")
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(OIBTreeInternalKeyTest),
+ unittest.makeSuite(OIBTreePyInternalKeyTest),
+ unittest.makeSuite(OITreeSetInternalKeyTest),
+ unittest.makeSuite(OITreeSetPyInternalKeyTest),
+ unittest.makeSuite(OIBucketTest),
+ unittest.makeSuite(OIBucketPyTest),
+ unittest.makeSuite(OITreeSetTest),
+ unittest.makeSuite(OITreeSetPyTest),
+ unittest.makeSuite(OISetTest),
+ unittest.makeSuite(OISetPyTest),
+ unittest.makeSuite(OIBTreeTest),
+ unittest.makeSuite(OIBTreePyTest),
+ unittest.makeSuite(TestOIBTrees),
+ unittest.makeSuite(TestOIBTreesPy),
+ unittest.makeSuite(PureOI),
+ unittest.makeSuite(PureOIPy),
+ unittest.makeSuite(TestWeightedOI),
+ unittest.makeSuite(TestWeightedOIPy),
+ unittest.makeSuite(OIBucketConflictTests),
+ unittest.makeSuite(OIBucketConflictTestsPy),
+ unittest.makeSuite(OISetConflictTests),
+ unittest.makeSuite(OISetConflictTestsPy),
+ unittest.makeSuite(OIBTreeConflictTests),
+ unittest.makeSuite(OIBTreeConflictTestsPy),
+ unittest.makeSuite(OITreeSetConflictTests),
+ unittest.makeSuite(OITreeSetConflictTestsPy),
+ unittest.makeSuite(OIModuleTest),
+ ))
Copied: BTrees/trunk/BTrees/tests/test_OLBTree.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_OLBTree.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_OLBTree.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_OLBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,332 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+from .common import BTreeTests
+from .common import ExtendedSetTests
+from .common import InternalKeysMappingTest
+from .common import InternalKeysSetTest
+from .common import MappingBase
+from .common import MappingConflictTestBase
+from .common import ModuleTest
+from .common import NormalSetTests
+from .common import SetConflictTestBase
+from .common import SetResult
+from .common import TestLongIntValues
+from .common import Weighted
+from .common import itemsToSet
+from .common import makeBuilder
+
+
+class OLBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLBTree
+ return OLBTree
+
+
+class OLBTreePyInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLBTreePy
+ return OLBTreePy
+
+
+class OLTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLTreeSet
+ return OLTreeSet
+
+
+class OLTreeSetPyInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLTreeSetPy
+ return OLTreeSetPy
+
+
+class OLBucketTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLBucket
+ return OLBucket
+
+
+class OLBucketPyTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLBucketPy
+ return OLBucketPy
+
+
+class OLTreeSetTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLTreeSet
+ return OLTreeSet
+
+
+class OLTreeSetPyTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLTreeSetPy
+ return OLTreeSetPy
+
+
+class OLSetTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLSet
+ return OLSet
+
+
+class OLSetPyTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLSetPy
+ return OLSetPy
+
+
+class OLBTreeTest(BTreeTests, TestLongIntValues, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.OLBTree import OLBTree
+ return OLBTree()
+
+ def getTwoKeys(self):
+ return object(), object()
+
+
+class OLBTreePyTest(BTreeTests, TestLongIntValues, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.OLBTree import OLBTreePy
+ return OLBTreePy()
+
+ def getTwoKeys(self):
+ return object(), object()
+
+
+class PureOL(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.OLBTree import union
+ return union(*args)
+
+ def intersection(self, *args):
+ from BTrees.OLBTree import intersection
+ return intersection(*args)
+
+ def difference(self, *args):
+ from BTrees.OLBTree import difference
+ return difference(*args)
+
+ def builders(self):
+ from BTrees.OLBTree import OLBTree
+ from BTrees.OLBTree import OLBucket
+ from BTrees.OLBTree import OLTreeSet
+ from BTrees.OLBTree import OLSet
+ return OLSet, OLTreeSet, makeBuilder(OLBTree), makeBuilder(OLBucket)
+
+
+class PureOLPy(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.OLBTree import unionPy
+ return unionPy(*args)
+
+ def intersection(self, *args):
+ from BTrees.OLBTree import intersectionPy
+ return intersectionPy(*args)
+
+ def difference(self, *args):
+ from BTrees.OLBTree import differencePy
+ return differencePy(*args)
+
+ def builders(self):
+ from BTrees.OLBTree import OLBTreePy
+ from BTrees.OLBTree import OLBucketPy
+ from BTrees.OLBTree import OLTreeSetPy
+ from BTrees.OLBTree import OLSetPy
+ return (OLSetPy, OLTreeSetPy,
+ makeBuilder(OLBTreePy), makeBuilder(OLBucketPy))
+
+
+class TestWeightedOL(Weighted, unittest.TestCase):
+
+ def weightedUnion(self):
+ from BTrees.OLBTree import weightedUnion
+ return weightedUnion
+
+ def weightedIntersection(self):
+ from BTrees.OLBTree import weightedIntersection
+ return weightedIntersection
+
+ def union(self):
+ from BTrees.OLBTree import union
+ return union
+
+ def intersection(self):
+ from BTrees.OLBTree import intersection
+ return intersection
+
+ def mkbucket(self, *args):
+ from BTrees.OLBTree import OLBucket as mkbucket
+ return mkbucket(*args)
+
+ def builders(self):
+ from BTrees.OLBTree import OLBTree
+ from BTrees.OLBTree import OLBucket
+ from BTrees.OLBTree import OLTreeSet
+ from BTrees.OLBTree import OLSet
+ return OLBucket, OLBTree, itemsToSet(OLSet), itemsToSet(OLTreeSet)
+
+
+class TestWeightedOLPy(Weighted, unittest.TestCase):
+
+ def weightedUnion(self):
+ from BTrees.OLBTree import weightedUnionPy
+ return weightedUnionPy
+
+ def weightedIntersection(self):
+ from BTrees.OLBTree import weightedIntersectionPy
+ return weightedIntersectionPy
+
+ def union(self):
+ from BTrees.OLBTree import unionPy
+ return unionPy
+
+ def intersection(self):
+ from BTrees.OLBTree import intersectionPy
+ return intersectionPy
+
+ def mkbucket(self, *args):
+ from BTrees.OLBTree import OLBucketPy as mkbucket
+ return mkbucket(*args)
+
+ def builders(self):
+ from BTrees.OLBTree import OLBTreePy
+ from BTrees.OLBTree import OLBucketPy
+ from BTrees.OLBTree import OLTreeSetPy
+ from BTrees.OLBTree import OLSetPy
+ return (OLBucketPy, OLBTreePy,
+ itemsToSet(OLSetPy), itemsToSet(OLTreeSetPy))
+
+
+class OLBucketConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLBucket
+ return OLBucket
+
+
+class OLBucketPyConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLBucketPy
+ return OLBucketPy
+
+
+class OLSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLSet
+ return OLSet
+
+
+class OLSetPyConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLSetPy
+ return OLSetPy
+
+
+class OLBTreeConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLBTree
+ return OLBTree
+
+
+class OLBTreePyConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLBTreePy
+ return OLBTreePy
+
+
+class OLTreeSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLTreeSet
+ return OLTreeSet
+
+
+class OLTreeSetPyConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OLBTree import OLTreeSetPy
+ return OLTreeSetPy
+
+
+class OLModuleTest(ModuleTest, unittest.TestCase):
+
+ prefix = 'OL'
+
+ def _getModule(self):
+ import BTrees
+ return BTrees.OLBTree
+
+ def _getInterface(self):
+ import BTrees.Interfaces
+ return BTrees.Interfaces.IObjectIntegerBTreeModule
+
+ def test_multiunion_not_present(self):
+ try:
+ from BTrees.OLBTree import multiunion
+ except ImportError:
+ pass
+ else:
+ self.fail("OLBTree shouldn't have multiunion")
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(OLBTreeInternalKeyTest),
+ unittest.makeSuite(OLBTreePyInternalKeyTest),
+ unittest.makeSuite(OLTreeSetInternalKeyTest),
+ unittest.makeSuite(OLTreeSetPyInternalKeyTest),
+ unittest.makeSuite(OLBucketTest),
+ unittest.makeSuite(OLBucketPyTest),
+ unittest.makeSuite(OLTreeSetTest),
+ unittest.makeSuite(OLTreeSetPyTest),
+ unittest.makeSuite(OLSetTest),
+ unittest.makeSuite(OLSetPyTest),
+ unittest.makeSuite(OLBTreeTest),
+ unittest.makeSuite(OLBTreePyTest),
+ unittest.makeSuite(PureOL),
+ unittest.makeSuite(PureOLPy),
+ unittest.makeSuite(TestWeightedOL),
+ unittest.makeSuite(TestWeightedOLPy),
+ unittest.makeSuite(OLBucketConflictTests),
+ unittest.makeSuite(OLBucketPyConflictTests),
+ unittest.makeSuite(OLSetConflictTests),
+ unittest.makeSuite(OLSetPyConflictTests),
+ unittest.makeSuite(OLBTreeConflictTests),
+ unittest.makeSuite(OLBTreePyConflictTests),
+ unittest.makeSuite(OLTreeSetConflictTests),
+ unittest.makeSuite(OLTreeSetPyConflictTests),
+ unittest.makeSuite(OLModuleTest),
+ ))
Copied: BTrees/trunk/BTrees/tests/test_OOBTree.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_OOBTree.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_OOBTree.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_OOBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,316 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+from .common import BTreeTests
+from .common import ExtendedSetTests
+from .common import InternalKeysMappingTest
+from .common import InternalKeysSetTest
+from .common import MappingBase
+from .common import MappingConflictTestBase
+from .common import ModuleTest
+from .common import NormalSetTests
+from .common import SetResult
+from .common import SetConflictTestBase
+from .common import makeBuilder
+
+
+
+class OOBTreeInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOBTreePy
+ return OOBTreePy
+
+class OOBTreePyInternalKeyTest(InternalKeysMappingTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOBTree
+ return OOBTree
+
+
+class OOTreeSetInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOTreeSet
+ return OOTreeSet
+
+
+class OOTreeSetPyInternalKeyTest(InternalKeysSetTest, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOTreeSetPy
+ return OOTreeSetPy
+
+
+class OOBucketTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOBucket
+ return OOBucket
+
+
+class OOBucketPyTest(MappingBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOBucketPy
+ return OOBucketPy
+
+
+class OOTreeSetTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOTreeSet
+ return OOTreeSet
+
+
+class OOTreeSetPyTest(NormalSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOTreeSetPy
+ return OOTreeSetPy
+
+
+class OOSetTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOSet
+ return OOSet
+
+
+class OOSetPyTest(ExtendedSetTests, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOSetPy
+ return OOSetPy
+
+
+
+class OOBTreeTest(BTreeTests, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.OOBTree import OOBTree
+ return OOBTree()
+
+ def testRejectDefaultComparison(self):
+ # Check that passing int keys w default comparison fails.
+ # Only applies to new-style class instances. Old-style
+ # instances are too hard to introspect.
+
+ # This is white box because we know that the check is being
+ # used in a function that's used in lots of places.
+ # Otherwise, there are many permutations that would have to be
+ # checked.
+ t = self._makeOne()
+
+ class C(object):
+ pass
+
+ self.assertRaises(TypeError, lambda : t.__setitem__(C(), 1))
+
+ class C(object):
+ def __cmp__(*args):
+ return 1
+
+ c = C()
+ t[c] = 1
+
+ t.clear()
+
+ class C(object):
+ def __lt__(*args):
+ return 1
+
+ c = C()
+ t[c] = 1
+
+ t.clear()
+
+
+#class OOBTreePyTest(OOBTreeTest):
+#
+# Right now, we can't match the C extension's test / prohibition of the
+# default 'object' comparison semantics.
+class OOBTreePyTest(BTreeTests, unittest.TestCase):
+
+ def _makeOne(self):
+ from BTrees.OOBTree import OOBTreePy
+ return OOBTreePy()
+
+
+
+class PureOO(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.OOBTree import union
+ return union(*args)
+
+ def intersection(self, *args):
+ from BTrees.OOBTree import intersection
+ return intersection(*args)
+
+ def difference(self, *args):
+ from BTrees.OOBTree import difference
+ return difference(*args)
+
+ def builders(self):
+ from BTrees.OOBTree import OOBTree
+ from BTrees.OOBTree import OOBucket
+ from BTrees.OOBTree import OOTreeSet
+ from BTrees.OOBTree import OOSet
+ return OOSet, OOTreeSet, makeBuilder(OOBTree), makeBuilder(OOBucket)
+
+
+class PureOOPy(SetResult, unittest.TestCase):
+
+ def union(self, *args):
+ from BTrees.OOBTree import unionPy
+ return unionPy(*args)
+
+ def intersection(self, *args):
+ from BTrees.OOBTree import intersectionPy
+ return intersectionPy(*args)
+
+ def difference(self, *args):
+ from BTrees.OOBTree import differencePy
+ return differencePy(*args)
+
+ def builders(self):
+ from BTrees.OOBTree import OOBTreePy
+ from BTrees.OOBTree import OOBucketPy
+ from BTrees.OOBTree import OOTreeSetPy
+ from BTrees.OOBTree import OOSetPy
+ return (OOSetPy, OOTreeSetPy,
+ makeBuilder(OOBTreePy), makeBuilder(OOBucketPy))
+
+
+class OOBucketConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOBucket
+ return OOBucket
+
+
+class OOBucketPyConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOBucketPy
+ return OOBucketPy
+
+
+class OOSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOSet
+ return OOSet
+
+
+class OOSetPyConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOSetPy
+ return OOSetPy
+
+
+class OOBTreeConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOBTree
+ return OOBTree
+
+
+class OOBTreePyConflictTests(MappingConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOBTreePy
+ return OOBTreePy
+
+
+class OOTreeSetConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOTreeSet
+ return OOTreeSet
+
+
+class OOTreeSetPyConflictTests(SetConflictTestBase, unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.OOBTree import OOTreeSetPy
+ return OOTreeSetPy
+
+
+class OOModuleTest(ModuleTest, unittest.TestCase):
+
+ prefix = 'OO'
+
+ def _getModule(self):
+ import BTrees
+ return BTrees.OOBTree
+
+ def _getInterface(self):
+ import BTrees.Interfaces
+ return BTrees.Interfaces.IObjectObjectBTreeModule
+
+ def test_weightedUnion_not_present(self):
+ try:
+ from BTrees.OOBTree import weightedUnion
+ except ImportError:
+ pass
+ else:
+ self.fail("OOBTree shouldn't have weightedUnion")
+
+ def test_weightedIntersection_not_present(self):
+ try:
+ from BTrees.OOBTree import weightedIntersection
+ except ImportError:
+ pass
+ else:
+ self.fail("OOBTree shouldn't have weightedIntersection")
+
+ def test_multiunion_not_present(self):
+ try:
+ from BTrees.OOBTree import multiunion
+ except ImportError:
+ pass
+ else:
+ self.fail("OOBTree shouldn't have multiunion")
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(OOBTreeInternalKeyTest),
+ unittest.makeSuite(OOBTreePyInternalKeyTest),
+ unittest.makeSuite(OOTreeSetInternalKeyTest),
+ unittest.makeSuite(OOTreeSetPyInternalKeyTest),
+ unittest.makeSuite(OOBucketTest),
+ unittest.makeSuite(OOBucketPyTest),
+ unittest.makeSuite(OOTreeSetTest),
+ unittest.makeSuite(OOTreeSetPyTest),
+ unittest.makeSuite(OOSetTest),
+ unittest.makeSuite(OOSetPyTest),
+ unittest.makeSuite(OOBTreeTest),
+ unittest.makeSuite(OOBTreePyTest),
+ unittest.makeSuite(PureOO),
+ unittest.makeSuite(PureOOPy),
+ unittest.makeSuite(OOBucketConflictTests),
+ unittest.makeSuite(OOBucketPyConflictTests),
+ unittest.makeSuite(OOSetConflictTests),
+ unittest.makeSuite(OOSetPyConflictTests),
+ unittest.makeSuite(OOBTreeConflictTests),
+ unittest.makeSuite(OOBTreePyConflictTests),
+ unittest.makeSuite(OOTreeSetConflictTests),
+ unittest.makeSuite(OOTreeSetPyConflictTests),
+ unittest.makeSuite(OOModuleTest),
+ ))
Copied: BTrees/trunk/BTrees/tests/test__base.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test__base.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test__base.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test__base.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,2986 @@
+##############################################################################
+#
+# Copyright 2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+import unittest
+
+
+def _assertRaises(self, e_type, checked, *args, **kw):
+ try:
+ checked(*args, **kw)
+ except e_type as e:
+ return e
+ self.fail("Didn't raise: %s" % e_type.__name__)
+
+
+class Test_Base(unittest.TestCase):
+
+ def _getTargetClass(self):
+ from .._base import _Base
+ return _Base
+
+ def _makeOne(self, items=None):
+ class _Test(self._getTargetClass()):
+ def clear(self):
+ self._data = {}
+ def update(self, d):
+ self._data.update(d)
+ return _Test(items)
+
+ def test_ctor_wo_items(self):
+ base = self._makeOne()
+ self.assertEqual(base._data, {})
+
+ def test_ctor_w_items(self):
+ base = self._makeOne({'a': 'b'})
+ self.assertEqual(base._data, {'a': 'b'})
+
+
+class Test_BucketBase(unittest.TestCase):
+
+ def _getTargetClass(self):
+ from .._base import _BucketBase
+ return _BucketBase
+
+ def _makeOne(self, *args, **kw):
+ return self._getTargetClass()(*args, **kw)
+
+ def test_ctor_defaults(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket._keys, [])
+ self.assertEqual(bucket._next, None)
+ self.assertEqual(len(bucket), 0)
+ self.assertEqual(bucket.size, 0)
+
+ def test__deleteNextBucket_none(self):
+ bucket = self._makeOne()
+ bucket._deleteNextBucket() # no raise
+ self.assertTrue(bucket._next is None)
+
+ def test__deleteNextBucket_one(self):
+ bucket1 = self._makeOne()
+ bucket2 = bucket1._next = self._makeOne()
+ bucket1._deleteNextBucket() # no raise
+ self.assertTrue(bucket1._next is None)
+
+ def test__deleteNextBucket_two(self):
+ bucket1 = self._makeOne()
+ bucket2 = bucket1._next = self._makeOne()
+ bucket3 = bucket2._next = self._makeOne()
+ bucket1._deleteNextBucket() # no raise
+ self.assertTrue(bucket1._next is bucket3)
+
+ def test__search_empty(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket._search('nonesuch'), -1)
+
+ def test__search_nonempty_miss(self):
+ bucket = self._makeOne()
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._search('candy'), -3)
+
+ def test__search_nonempty_hit(self):
+ bucket = self._makeOne()
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._search('charlie'), 2)
+
+ def test_minKey_empty(self):
+ bucket = self._makeOne()
+ self.assertRaises(IndexError, bucket.minKey)
+
+ def test_minKey_no_bound(self):
+ bucket = self._makeOne()
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.minKey(), 'alpha')
+
+ def test_minKey_w_bound_hit(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.minKey('bravo'), 'bravo')
+
+ def test_minKey_w_bound_miss(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.minKey('candy'), 'charlie')
+
+ def test_minKey_w_bound_fail(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertRaises(ValueError, bucket.minKey, 'foxtrot')
+
+ def test_maxKey_empty(self):
+ bucket = self._makeOne()
+ self.assertRaises(IndexError, bucket.maxKey)
+
+ def test_maxKey_no_bound(self):
+ bucket = self._makeOne()
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.maxKey(), 'echo')
+
+ def test_maxKey_w_bound_hit(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.maxKey('bravo'), 'bravo')
+
+ def test_maxKey_w_bound_miss(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.maxKey('candy'), 'bravo')
+
+ def test_maxKey_w_bound_fail(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertRaises(ValueError, bucket.maxKey, 'abacus')
+
+ def test__range_defaults_empty(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket._range(), (0, 0))
+
+ def test__range_defaults_filled(self):
+ bucket = self._makeOne()
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._range(), (0, 5))
+
+ def test__range_defaults_exclude_min(self):
+ bucket = self._makeOne()
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._range(excludemin=True), (1, 5))
+
+ def test__range_defaults_exclude_max(self):
+ bucket = self._makeOne()
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._range(excludemax=True), (0, 4))
+
+ def test__range_w_min_hit(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._range(min='bravo'), (1, 5))
+
+ def test__range_w_min_miss(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._range(min='candy'), (2, 5))
+
+ def test__range_w_min_hit_w_exclude_min(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._range(min='bravo', excludemin=True), (2, 5))
+
+ def test__range_w_min_miss_w_exclude_min(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ # 'excludemin' doesn't fire on miss
+ self.assertEqual(bucket._range(min='candy', excludemin=True), (2, 5))
+
+ def test__range_w_max_hit(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._range(max='delta'), (0, 4))
+
+ def test__range_w_max_miss(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._range(max='dandy'), (0, 3))
+
+ def test__range_w_max_hit_w_exclude_max(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket._range(max='delta', excludemax=True), (0, 3))
+
+ def test__range_w_max_miss_w_exclude_max(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ # 'excludemax' doesn't fire on miss
+ self.assertEqual(bucket._range(max='dandy', excludemax=True), (0, 3))
+
+ def test_keys_defaults_empty(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.keys(), [])
+
+ def test_keys_defaults_filled(self):
+ bucket = self._makeOne()
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.keys(), KEYS[0: 5])
+
+ def test_keys_defaults_exclude_min(self):
+ bucket = self._makeOne()
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.keys(excludemin=True), KEYS[1: 5])
+
+ def test_keys_defaults_exclude_max(self):
+ bucket = self._makeOne()
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.keys(excludemax=True), KEYS[0: 4])
+
+ def test_keys_w_min_hit(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.keys(min='bravo'), KEYS[1: 5])
+
+ def test_keys_w_min_miss(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.keys(min='candy'), KEYS[2: 5])
+
+ def test_keys_w_min_hit_w_exclude_min(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.keys(min='bravo', excludemin=True), KEYS[2: 5])
+
+ def test_keys_w_min_miss_w_exclude_min(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ # 'excludemin' doesn't fire on miss
+ self.assertEqual(bucket.keys(min='candy', excludemin=True), KEYS[2: 5])
+
+ def test_keys_w_max_hit(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.keys(max='delta'), KEYS[0: 4])
+
+ def test_keys_w_max_miss(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.keys(max='dandy'), KEYS[0: 3])
+
+ def test_keys_w_max_hit_w_exclude_max(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(bucket.keys(max='delta', excludemax=True), KEYS[0: 3])
+
+ def test_keys_w_max_miss_w_exclude_max(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ # 'excludemax' doesn't fire on miss
+ self.assertEqual(bucket.keys(max='dandy', excludemax=True), KEYS[0: 3])
+
+ def test_iterkeys_defaults_empty(self):
+ bucket = self._makeOne()
+ self.assertEqual(list(bucket.iterkeys()), [])
+
+ def test_iterkeys_defaults_filled(self):
+ bucket = self._makeOne()
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(list(bucket.iterkeys()), KEYS[0: 5])
+
+ def test_iterkeys_defaults_exclude_min(self):
+ bucket = self._makeOne()
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(list(bucket.iterkeys(excludemin=True)), KEYS[1: 5])
+
+ def test_iterkeys_defaults_exclude_max(self):
+ bucket = self._makeOne()
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(list(bucket.iterkeys(excludemax=True)), KEYS[0: 4])
+
+ def test_iterkeys_w_min_hit(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(list(bucket.iterkeys(min='bravo')), KEYS[1: 5])
+
+ def test_iterkeys_w_min_miss(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(list(bucket.iterkeys(min='candy')), KEYS[2: 5])
+
+ def test_iterkeys_w_min_hit_w_exclude_min(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(list(bucket.iterkeys(min='bravo', excludemin=True)),
+ KEYS[2: 5])
+
+ def test_iterkeys_w_min_miss_w_exclude_min(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ # 'excludemin' doesn't fire on miss
+ self.assertEqual(list(bucket.iterkeys(min='candy', excludemin=True)),
+ KEYS[2: 5])
+
+ def test_iterkeys_w_max_hit(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(list(bucket.iterkeys(max='delta')), KEYS[0: 4])
+
+ def test_iterkeys_w_max_miss(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(list(bucket.iterkeys(max='dandy')), KEYS[0: 3])
+
+ def test_iterkeys_w_max_hit_w_exclude_max(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual(list(bucket.keys(max='delta', excludemax=True)),
+ KEYS[0: 3])
+
+ def test_iterkeys_w_max_miss_w_exclude_max(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ # 'excludemax' doesn't fire on miss
+ self.assertEqual(list(bucket.iterkeys(max='dandy', excludemax=True)),
+ KEYS[0: 3])
+
+ def test___iter___empty(self):
+ bucket = self._makeOne()
+ self.assertEqual([x for x in bucket], [])
+
+ def test___iter___filled(self):
+ bucket = self._makeOne()
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertEqual([x for x in bucket], KEYS[0: 5])
+
+ def test___contains___empty(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ self.assertFalse('nonesuch' in bucket)
+
+ def test___contains___filled_miss(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ self.assertFalse('nonesuch' in bucket)
+
+ def test___contains___filled_hit(self):
+ bucket = self._makeOne()
+ bucket._to_key = lambda x: x
+ KEYS = bucket._keys = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ self.assertTrue(key in bucket)
+
+
+class Test_SetIteration(unittest.TestCase):
+
+ assertRaises = _assertRaises
+
+ def _getTargetClass(self):
+ from .._base import _SetIteration
+ return _SetIteration
+
+ def _makeOne(self, to_iterate, useValues=False, default=None):
+ return self._getTargetClass()(to_iterate, useValues, default)
+
+ def test_ctor_w_None(self):
+ from .._base import _marker
+ si = self._makeOne(None)
+ self.assertEqual(si.useValues, False)
+ self.assertTrue(si.key is _marker)
+ self.assertEqual(si.value, None)
+ self.assertEqual(si.active, False)
+ self.assertEqual(si.position, -1)
+
+ def test_ctor_w_non_empty_list(self):
+ si = self._makeOne(['a', 'b', 'c'])
+ self.assertEqual(si.useValues, False)
+ self.assertEqual(si.key, 'a')
+ self.assertEqual(si.value, None)
+ self.assertEqual(si.active, True)
+ self.assertEqual(si.position, 1)
+
+
+class BucketTests(unittest.TestCase):
+
+ assertRaises = _assertRaises
+
+ def _getTargetClass(self):
+ from .._base import Bucket
+ return Bucket
+
+ def _makeOne(self):
+ class _Bucket(self._getTargetClass()):
+ def _to_key(self, x):
+ return x
+ def _to_value(self, x):
+ return x
+ return _Bucket()
+
+ def test_ctor_defaults(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket._keys, [])
+ self.assertEqual(bucket._values, [])
+
+ def test_setdefault_miss(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.setdefault('a', 'b'), 'b')
+ self.assertEqual(bucket._keys, ['a'])
+ self.assertEqual(bucket._values, ['b'])
+
+ def test_setdefault_hit(self):
+ bucket = self._makeOne()
+ bucket._keys.append('a')
+ bucket._values.append('b')
+ self.assertEqual(bucket.setdefault('a', 'b'), 'b')
+ self.assertEqual(bucket._keys, ['a'])
+ self.assertEqual(bucket._values, ['b'])
+
+ def test_pop_miss_no_default(self):
+ bucket = self._makeOne()
+ self.assertRaises(KeyError, bucket.pop, 'nonesuch')
+
+ def test_pop_miss_w_default(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.pop('nonesuch', 'b'), 'b')
+
+ def test_pop_hit(self):
+ bucket = self._makeOne()
+ bucket._keys.append('a')
+ bucket._values.append('b')
+ self.assertEqual(bucket.pop('a'), 'b')
+ self.assertEqual(bucket._keys, [])
+ self.assertEqual(bucket._values, [])
+
+ def test_update_value_w_iteritems(self):
+ bucket = self._makeOne()
+ bucket.update({'a': 'b'})
+ self.assertEqual(bucket._keys, ['a'])
+ self.assertEqual(bucket._values, ['b'])
+
+ def test_update_value_w_items(self):
+ bucket = self._makeOne()
+ class Foo(object):
+ def items(self):
+ return [('a', 'b')]
+ bucket.update(Foo())
+ self.assertEqual(bucket._keys, ['a'])
+ self.assertEqual(bucket._values, ['b'])
+
+ def test_update_value_w_invalid_items(self):
+ bucket = self._makeOne()
+ class Foo(object):
+ def items(self):
+ return ('a', 'b', 'c')
+ self.assertRaises(TypeError, bucket.update, Foo())
+
+ def test_update_sequence(self):
+ bucket = self._makeOne()
+ bucket.update([('a', 'b')])
+ self.assertEqual(bucket._keys, ['a'])
+ self.assertEqual(bucket._values, ['b'])
+
+ def test_update_replacing(self):
+ bucket = self._makeOne()
+ bucket['a'] = 'b'
+ bucket.update([('a', 'c')])
+ self.assertEqual(bucket['a'], 'c')
+
+ def test___setitem___incomparable(self):
+ bucket = self._makeOne()
+ def _should_error():
+ bucket[object()] = 'b'
+ self.assertRaises(TypeError, _should_error)
+
+ def test___setitem___comparable(self):
+ bucket = self._makeOne()
+ bucket['a'] = 'b'
+ self.assertEqual(bucket['a'], 'b')
+
+ def test___setitem___replace(self):
+ bucket = self._makeOne()
+ bucket['a'] = 'b'
+ bucket['a'] = 'c'
+ self.assertEqual(bucket['a'], 'c')
+
+ def test___delitem___miss(self):
+ bucket = self._makeOne()
+ def _should_error():
+ del bucket['nonesuch']
+ self.assertRaises(KeyError, _should_error)
+
+ def test___delitem___hit(self):
+ bucket = self._makeOne()
+ bucket._keys.append('a')
+ bucket._values.append('b')
+ del bucket['a']
+ self.assertEqual(bucket._keys, [])
+ self.assertEqual(bucket._values, [])
+
+ def test_clear_filled(self):
+ bucket = self._makeOne()
+ bucket['a'] = 'b'
+ bucket['c'] = 'd'
+ bucket.clear()
+ self.assertEqual(len(bucket._keys), 0)
+ self.assertEqual(len(bucket._values), 0)
+
+ def test_clear_empty(self):
+ bucket = self._makeOne()
+ bucket.clear()
+ self.assertEqual(len(bucket._keys), 0)
+ self.assertEqual(len(bucket._values), 0)
+
+ def test_get_miss_no_default(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.get('nonesuch'), None)
+
+ def test_get_miss_w_default(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.get('nonesuch', 'b'), 'b')
+
+ def test_get_hit(self):
+ bucket = self._makeOne()
+ bucket._keys.append('a')
+ bucket._values.append('b')
+ self.assertEqual(bucket.get('a'), 'b')
+
+ def test___getitem___miss(self):
+ bucket = self._makeOne()
+ def _should_error():
+ return bucket['nonesuch']
+ self.assertRaises(KeyError, _should_error)
+
+ def test___getitem___hit(self):
+ bucket = self._makeOne()
+ bucket._keys.append('a')
+ bucket._values.append('b')
+ self.assertEqual(bucket['a'], 'b')
+
+ def test__split_empty(self):
+ bucket = self._makeOne()
+ next_b = bucket._next = self._makeOne()
+ new_b = bucket._split()
+ self.assertEqual(len(bucket._keys), 0)
+ self.assertEqual(len(bucket._values), 0)
+ self.assertEqual(len(new_b._keys), 0)
+ self.assertEqual(len(new_b._values), 0)
+ self.assertTrue(bucket._next is new_b)
+ self.assertTrue(new_b._next is next_b)
+
+ def test__split_filled_default_index(self):
+ bucket = self._makeOne()
+ next_b = bucket._next = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ new_b = bucket._split()
+ self.assertEqual(list(bucket._keys), ['a', 'b', 'c'])
+ self.assertEqual(list(bucket._values), [0, 1, 2])
+ self.assertEqual(list(new_b._keys), ['d', 'e', 'f'])
+ self.assertEqual(list(new_b._values), [3, 4, 5])
+ self.assertTrue(bucket._next is new_b)
+ self.assertTrue(new_b._next is next_b)
+
+ def test_keys_empty_no_args(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.keys(), [])
+
+ def test_keys_filled_no_args(self):
+ bucket = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ self.assertEqual(bucket.keys(),
+ ['a', 'b', 'c', 'd', 'e', 'f'])
+
+ def test_keys_filled_w_args(self):
+ bucket = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ self.assertEqual(bucket.keys(min='b', excludemin=True,
+ max='f', excludemax=True), ['c', 'd', 'e'])
+
+ def test_iterkeys_empty_no_args(self):
+ bucket = self._makeOne()
+ self.assertEqual(list(bucket.iterkeys()), [])
+
+ def test_iterkeys_filled_no_args(self):
+ bucket = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ self.assertEqual(list(bucket.iterkeys()),
+ ['a', 'b', 'c', 'd', 'e', 'f'])
+
+ def test_iterkeys_filled_w_args(self):
+ bucket = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ self.assertEqual(list(bucket.iterkeys(
+ min='b', excludemin=True,
+ max='f', excludemax=True)), ['c', 'd', 'e'])
+
+ def test_values_empty_no_args(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.values(), [])
+
+ def test_values_filled_no_args(self):
+ bucket = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ self.assertEqual(bucket.values(), range(6))
+
+ def test_values_filled_w_args(self):
+ bucket = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ self.assertEqual(bucket.values(min='b', excludemin=True,
+ max='f', excludemax=True), [2, 3, 4])
+
+ def test_itervalues_empty_no_args(self):
+ bucket = self._makeOne()
+ self.assertEqual(list(bucket.itervalues()), [])
+
+ def test_itervalues_filled_no_args(self):
+ bucket = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ self.assertEqual(list(bucket.itervalues()), range(6))
+
+ def test_itervalues_filled_w_args(self):
+ bucket = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ self.assertEqual(list(bucket.itervalues(
+ min='b', excludemin=True,
+ max='f', excludemax=True)), [2, 3, 4])
+
+ def test_items_empty_no_args(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.items(), [])
+
+ def test_items_filled_no_args(self):
+ bucket = self._makeOne()
+ EXPECTED = []
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ EXPECTED.append((c, i))
+ self.assertEqual(bucket.items(), EXPECTED)
+
+ def test_items_filled_w_args(self):
+ bucket = self._makeOne()
+ EXPECTED = []
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ EXPECTED.append((c, i))
+ self.assertEqual(bucket.items(min='b', excludemin=True,
+ max='f', excludemax=True),
+ EXPECTED[2:5])
+
+ def test_iteritems_empty_no_args(self):
+ bucket = self._makeOne()
+ self.assertEqual(list(bucket.iteritems()), [])
+
+ def test_iteritems_filled_no_args(self):
+ bucket = self._makeOne()
+ EXPECTED = []
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ EXPECTED.append((c, i))
+ self.assertEqual(list(bucket.iteritems()), EXPECTED)
+
+ def test_iteritems_filled_w_args(self):
+ bucket = self._makeOne()
+ EXPECTED = []
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ EXPECTED.append((c, i))
+ self.assertEqual(list(bucket.iteritems(min='b', excludemin=True,
+ max='f', excludemax=True)),
+ EXPECTED[2:5])
+
+ def test___getstate___empty_no_next(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.__getstate__(), ((),))
+
+ def test___getstate___empty_w_next(self):
+ bucket = self._makeOne()
+ bucket._next = next_b = self._makeOne()
+ self.assertEqual(bucket.__getstate__(), ((), next_b))
+
+ def test___getstate___non_empty_no_next(self):
+ bucket = self._makeOne()
+ EXPECTED = ()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ EXPECTED += (c, i)
+ self.assertEqual(bucket.__getstate__(), (EXPECTED,))
+
+ def test___getstate___non_empty_w_next(self):
+ bucket = self._makeOne()
+ bucket._next = next_b = self._makeOne()
+ EXPECTED = ()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ EXPECTED += (c, i)
+ self.assertEqual(bucket.__getstate__(), (EXPECTED, next_b))
+
+ def test___setstate___w_non_tuple(self):
+ bucket = self._makeOne()
+ self.assertRaises(TypeError, bucket.__setstate__, (None,))
+
+ def test___setstate___w_empty_no_next(self):
+ bucket = self._makeOne()
+ bucket._next = next_b = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ bucket[c] = i
+ bucket.__setstate__(((),))
+ self.assertEqual(len(bucket.keys()), 0)
+ self.assertTrue(bucket._next is None)
+
+ def test___setstate___w_non_empty_w_next(self):
+ bucket = self._makeOne()
+ next_b = self._makeOne()
+ ITEMS = ()
+ EXPECTED = []
+ for i, c in enumerate('abcdef'):
+ ITEMS += (c, i)
+ EXPECTED.append((c, i))
+ bucket.__setstate__((ITEMS, next_b))
+ self.assertEqual(bucket.items(), EXPECTED)
+ self.assertTrue(bucket._next is next_b)
+
+ def test__p_resolveConflict_x_on_com_next(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ N_NEW = object()
+ s_old = ((), None)
+ s_com = ((), N_NEW)
+ s_new = ((), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 0)
+
+ def test__p_resolveConflict_x_on_new_next(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ N_NEW = object()
+ s_old = ((), None)
+ s_com = ((), None)
+ s_new = ((), N_NEW)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 0)
+
+ def test__p_resolveConflict_x_on_com_empty(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 'b', 'c', 'd'), None)
+ s_com = ((), None)
+ s_new = (('a', 'b'), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 12)
+
+ def test__p_resolveConflict_x_on_new_empty(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1), None)
+ s_com = (('a', 0), None)
+ s_new = ((), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 12)
+
+ def test__p_resolveConflict_x_both_update_same_key(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0), None)
+ s_com = (('a', 5, 'b', 1, 'c', 2), None)
+ s_new = (('a', 6, 'd', 3), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 1)
+
+ def test__p_resolveConflict_x_on_del_first_com_x(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'c', 2), None)
+ s_com = (('b', 1), None)
+ s_new = (('a', 0, 'b', 1), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 13)
+
+ def test__p_resolveConflict_x_on_del_first_new_x(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'c', 2), None)
+ s_com = (('a', 0, 'b', 1), None)
+ s_new = (('b', 1), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 13)
+
+ def test__p_resolveConflict_x_on_del_first_new(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1), None)
+ s_com = (('a', 1, 'b', 2, 'c', 3), None)
+ s_new = (('b', 4), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 2)
+
+ def test__p_resolveConflict_x_on_del_first_com(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1), None)
+ s_com = (('b', 4), None)
+ s_new = (('a', 1, 'b', 2, 'c', 3), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 3)
+
+ def test__p_resolveConflict_x_on_ins_same_after_del(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1), None)
+ s_com = (('a', 0, 'c', 2), None)
+ s_new = (('a', 0, 'c', 2, 'd', 3), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 4)
+
+ def test__p_resolveConflict_x_on_del_same(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'c', 2), None)
+ s_com = (('a', 0, 'c', 2), None)
+ s_new = (('a', 0, 'd', 3, 'e', 4), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 5)
+
+ def test__p_resolveConflict_x_on_append_same(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, ), None)
+ s_com = (('a', 0, 'b', 1), None)
+ s_new = (('a', 0, 'b', 1, 'c', 2), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 6)
+
+ def test__p_resolveConflict_x_on_new_deletes_all_com_adds(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'c', 2), None)
+ s_com = (('a', 0, 'd', 3, 'e', 4, 'f', 5), None)
+ s_new = (('a', 0, ), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 7)
+
+ def test__p_resolveConflict_x_on_com_deletes_all_new_adds(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'c', 2), None)
+ s_com = (('a', 0, ), None)
+ s_new = (('a', 0, 'd', 3, 'e', 4, 'f', 5), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 8)
+
+ def test__p_resolveConflict_x_on_com_deletes_all_new_deletes(self):
+ from ..Interfaces import BTreesConflictError
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'c', 2), None)
+ s_com = (('a', 0, ), None)
+ s_new = (('a', 0, 'b', 1), None)
+ e = self.assertRaises(BTreesConflictError,
+ bucket._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 9)
+
+ def test__p_resolveConflict_ok_both_add_new_max(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0), None)
+ s_com = (('a', 0, 'b', 1), None)
+ s_new = (('a', 0, 'c', 2), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'b', 1, 'c', 2),))
+
+ def test__p_resolveConflict_ok_com_updates(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0), None)
+ s_com = (('a', 5), None)
+ s_new = (('a', 0, 'd', 3), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 5, 'd', 3),))
+
+ def test__p_resolveConflict_ok_new_updates(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0), None)
+ s_com = (('a', 0, 'd', 3), None)
+ s_new = (('a', 5), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 5, 'd', 3),))
+
+ def test__p_resolveConflict_ok_com_inserts_new_adds(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'c', 2), None)
+ s_com = (('a', 0, 'b', 1, 'c', 2), None)
+ s_new = (('a', 0, 'c', 2, 'd', 3), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'b', 1, 'c', 2, 'd', 3),))
+
+ def test__p_resolveConflict_ok_com_adds_new_inserts(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'c', 2), None)
+ s_com = (('a', 0, 'c', 2, 'd', 3), None)
+ s_new = (('a', 0, 'b', 1, 'c', 2), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'b', 1, 'c', 2, 'd', 3),))
+
+ def test__p_resolveConflict_ok_com_adds_new_deletes(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'c', 2), None)
+ s_com = (('a', 0, 'b', 1, 'c', 2, 'd', 3), None)
+ s_new = (('a', 0, 'e', 4), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'd', 3, 'e', 4),))
+
+ def test__p_resolveConflict_ok_com_deletes_new_adds(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'c', 2), None)
+ s_com = (('a', 0, 'e', 4), None)
+ s_new = (('a', 0, 'b', 1, 'c', 2, 'd', 3), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'd', 3, 'e', 4),))
+
+ def test__p_resolveConflict_ok_both_insert_new_lt_com(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'd', 3), None)
+ s_com = (('a', 0, 'c', 2, 'd', 3), None)
+ s_new = (('a', 0, 'b', 1, 'd', 3), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'b', 1, 'c', 2, 'd', 3),))
+
+ def test__p_resolveConflict_ok_both_insert_new_gt_com(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'd', 3), None)
+ s_com = (('a', 0, 'b', 1, 'd', 3), None)
+ s_new = (('a', 0, 'c', 2, 'd', 3), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'b', 1, 'c', 2, 'd', 3),))
+
+ def test__p_resolveConflict_ok_new_insert_then_com_append(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'd', 3), None)
+ s_com = (('a', 0, 'e', 4), None)
+ s_new = (('a', 0, 'b', 1, 'd', 3), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'b', 1, 'e', 4),))
+
+ def test__p_resolveConflict_ok_com_insert_then_new_append(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'd', 3), None)
+ s_com = (('a', 0, 'b', 1, 'd', 3), None)
+ s_new = (('a', 0, 'e', 4), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'b', 1, 'e', 4),))
+
+ def test__p_resolveConflict_ok_new_deletes_tail_com_inserts(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'd', 3), None)
+ s_com = (('a', 0, 'b', 1, 'c', 2, 'd', 3), None)
+ s_new = (('a', 0), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'c', 2),))
+
+ def test__p_resolveConflict_ok_com_deletes_tail_new_inserts(self):
+ bucket = self._makeOne()
+ s_old = (('a', 0, 'b', 1, 'd', 3), None)
+ s_com = (('a', 0), None)
+ s_new = (('a', 0, 'b', 1, 'c', 2, 'd', 3), None)
+ result = bucket._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 0, 'c', 2),))
+
+
+class SetTests(unittest.TestCase):
+
+ assertRaises = _assertRaises
+
+ def _getTargetClass(self):
+ from .._base import Set
+ return Set
+
+ def _makeOne(self):
+ class _Set(self._getTargetClass()):
+ def _to_key(self, x):
+ return x
+ return _Set()
+
+ def test_add_not_extant(self):
+ _set = self._makeOne()
+ _set.add('not_extant')
+ self.assertEqual(list(_set), ['not_extant'])
+
+ def test_add_extant(self):
+ _set = self._makeOne()
+ _set.add('extant')
+ _set.add('extant')
+ self.assertEqual(list(_set), ['extant'])
+
+ def test_insert(self):
+ _set = self._makeOne()
+ _set.insert('inserted')
+ self.assertEqual(list(_set), ['inserted'])
+
+ def test_remove_miss(self):
+ _set = self._makeOne()
+ self.assertRaises(KeyError, _set.remove, 'not_extant')
+
+ def test_remove_extant(self):
+ _set = self._makeOne()
+ _set.add('one')
+ _set.add('another')
+ _set.remove('one')
+ self.assertEqual(list(_set), ['another'])
+
+ def test_update(self):
+ _set = self._makeOne()
+ _set.update(['one', 'after', 'another'])
+ self.assertEqual(sorted(_set), ['after', 'another', 'one'])
+
+ def test___getstate___empty_no_next(self):
+ _set = self._makeOne()
+ self.assertEqual(_set.__getstate__(), ((),))
+
+ def test___getstate___empty_w_next(self):
+ _set = self._makeOne()
+ _set._next = next_s = self._makeOne()
+ self.assertEqual(_set.__getstate__(), ((), next_s))
+
+ def test___getstate___non_empty_no_next(self):
+ _set = self._makeOne()
+ EXPECTED = ()
+ for c in 'abcdef':
+ _set.add(c)
+ EXPECTED += (c,)
+ self.assertEqual(_set.__getstate__(), (EXPECTED,))
+
+ def test___getstate___non_empty_w_next(self):
+ _set = self._makeOne()
+ _set._next = next_s = self._makeOne()
+ EXPECTED = ()
+ for c in 'abcdef':
+ _set.add(c)
+ EXPECTED += (c,)
+ self.assertEqual(_set.__getstate__(), (EXPECTED, next_s))
+
+ def test___setstate___w_non_tuple(self):
+ _set = self._makeOne()
+ self.assertRaises(TypeError, _set.__setstate__, (None,))
+
+ def test___setstate___w_empty_no_next(self):
+ _set = self._makeOne()
+ _set._next = next_s = self._makeOne()
+ for c in 'abcdef':
+ _set.add(c)
+ _set.__setstate__(((),))
+ self.assertEqual(len(_set), 0)
+ self.assertTrue(_set._next is None)
+
+ def test___setstate___w_non_empty_w_next(self):
+ _set = self._makeOne()
+ next_s = self._makeOne()
+ ITEMS = ()
+ EXPECTED = []
+ for c in 'abcdef':
+ ITEMS += (c,)
+ EXPECTED.append(c)
+ _set.__setstate__((ITEMS, next_s))
+ self.assertEqual(sorted(_set), EXPECTED)
+ self.assertTrue(_set._next is next_s)
+
+ def test___getitem___out_of_bounds(self):
+ _set = self._makeOne()
+ self.assertRaises(IndexError, _set.__getitem__, 1)
+
+ def test___getitem___hit_bounds(self):
+ _set = self._makeOne()
+ _set.add('b')
+ _set.add('a')
+ _set.add('c')
+ self.assertEqual(_set[0], 'a')
+ self.assertEqual(_set[1], 'b')
+ self.assertEqual(_set[2], 'c')
+
+ def test__split_empty(self):
+ _set = self._makeOne()
+ next_b = _set._next = self._makeOne()
+ new_b = _set._split()
+ self.assertEqual(len(_set._keys), 0)
+ self.assertEqual(len(new_b._keys), 0)
+ self.assertTrue(_set._next is new_b)
+ self.assertTrue(new_b._next is next_b)
+
+ def test__split_filled_default_index(self):
+ _set = self._makeOne()
+ next_b = _set._next = self._makeOne()
+ for c in 'abcdef':
+ _set.add(c)
+ new_b = _set._split()
+ self.assertEqual(list(_set._keys), ['a', 'b', 'c'])
+ self.assertEqual(list(new_b._keys), ['d', 'e', 'f'])
+ self.assertTrue(_set._next is new_b)
+ self.assertTrue(new_b._next is next_b)
+
+ def test__p_resolveConflict_x_on_com_next(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ N_NEW = object()
+ s_old = ((), None)
+ s_com = ((), N_NEW)
+ s_new = ((), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 0)
+
+ def test__p_resolveConflict_x_on_new_next(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ N_NEW = object()
+ s_old = ((), None)
+ s_com = ((), None)
+ s_new = ((), N_NEW)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 0)
+
+ def test__p_resolveConflict_x_on_com_empty(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a', 'b'), None)
+ s_com = ((), None)
+ s_new = (('a',), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 12)
+
+ def test__p_resolveConflict_x_on_new_empty(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a', 'b'), None)
+ s_com = (('a',), None)
+ s_new = ((), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 12)
+
+ def test__p_resolveConflict_x_on_del_first_com(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a','b'), None)
+ s_com = (('b',), None)
+ s_new = (('a', 'b', 'c'), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 13)
+
+ def test__p_resolveConflict_x_on_del_first_new(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a', 'b'), None)
+ s_com = (('a', 'b', 'c'), None)
+ s_new = (('b',), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 13)
+
+ def test__p_resolveConflict_x_on_ins_same_after_del(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a', 'b'), None)
+ s_com = (('a', 'c'), None)
+ s_new = (('a', 'c', 'd'), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 4)
+
+ def test__p_resolveConflict_x_on_del_same(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a', 'b', 'c'), None)
+ s_com = (('a', 'c'), None)
+ s_new = (('a', 'd', 'e'), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 5)
+
+ def test__p_resolveConflict_x_on_append_same(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a',), None)
+ s_com = (('a', 'b'), None)
+ s_new = (('a', 'b', 'c'), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 6)
+
+ def test__p_resolveConflict_x_on_new_deletes_all_com_adds(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a', 'b', 'c'), None)
+ s_com = (('a', 'd', 'e', 'f'), None)
+ s_new = (('a',), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 7)
+
+ def test__p_resolveConflict_x_on_com_deletes_all_new_adds(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a', 'b', 'c'), None)
+ s_com = (('a',), None)
+ s_new = (('a', 'd', 'e', 'f'), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 8)
+
+ def test__p_resolveConflict_x_on_com_deletes_all_new_deletes(self):
+ from ..Interfaces import BTreesConflictError
+ _set = self._makeOne()
+ s_old = (('a', 'b', 'c'), None)
+ s_com = (('a',), None)
+ s_new = (('a', 'b'), None)
+ e = self.assertRaises(BTreesConflictError,
+ _set._p_resolveConflict, s_old, s_com, s_new)
+ self.assertEqual(e.reason, 9)
+
+ def test__p_resolveConflict_ok_insert_in_new_add_in_com(self):
+ _set = self._makeOne()
+ s_old = (('a', 'c'), None)
+ s_com = (('a', 'c', 'd'), None)
+ s_new = (('a', 'b', 'c'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ # Note that _SetBase uses default __getstate__
+ self.assertEqual(result, (('a', 'b', 'c', 'd'),))
+
+ def test__p_resolveConflict_ok_insert_in_com_add_in_new(self):
+ _set = self._makeOne()
+ s_old = (('a', 'c'), None)
+ s_com = (('a', 'b', 'c'), None)
+ s_new = (('a', 'c', 'd'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'b', 'c', 'd'),))
+
+ def test__p_resolveConflict_ok_delete_in_new_add_in_com(self):
+ _set = self._makeOne()
+ s_old = (('a', 'b', 'c'), None)
+ s_com = (('a', 'b', 'c', 'd'), None)
+ s_new = (('a', 'c'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'c', 'd'),))
+
+ def test__p_resolveConflict_ok_delete_in_com_add_in_new(self):
+ _set = self._makeOne()
+ s_old = (('a', 'b', 'c'), None)
+ s_com = (('a', 'c'), None)
+ s_new = (('a', 'b', 'c', 'd'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'c', 'd'),))
+
+ def test__p_resolveConflict_ok_add_new_lt_add_com(self):
+ _set = self._makeOne()
+ s_old = (('a',), None)
+ s_com = (('a', 'd'), None)
+ s_new = (('a', 'b', 'c'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'b', 'c', 'd'),))
+
+ def test__p_resolveConflict_ok_add_com_lt_add_new(self):
+ _set = self._makeOne()
+ s_old = (('a',), None)
+ s_com = (('a', 'b', 'c'), None)
+ s_new = (('a', 'd'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'b', 'c', 'd'),))
+
+ def test__p_resolveConflict_ok_ins_in_com_del_add_in_new(self):
+ _set = self._makeOne()
+ s_old = (('a', 'c'), None)
+ s_com = (('a', 'b', 'c'), None)
+ s_new = (('a', 'd', 'e'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'b', 'd', 'e'),))
+
+ def test__p_resolveConflict_ok_ins_in_new_del_add_in_com(self):
+ _set = self._makeOne()
+ s_old = (('a', 'c'), None)
+ s_com = (('a', 'd', 'e'), None)
+ s_new = (('a', 'b', 'c'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'b', 'd', 'e'),))
+
+ def test__p_resolveConflict_ok_ins_both_new_lt_com(self):
+ _set = self._makeOne()
+ s_old = (('a', 'e'), None)
+ s_com = (('a', 'c', 'd', 'e'), None)
+ s_new = (('a', 'b', 'e'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'b', 'c', 'd', 'e'),))
+
+ def test__p_resolveConflict_ok_del_new_add_com(self):
+ _set = self._makeOne()
+ s_old = (('a', 'e'), None)
+ s_com = (('a', 'c', 'd', 'e'), None)
+ s_new = (('a',), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'c', 'd'),))
+
+ def test__p_resolveConflict_ok_del_com_add_new(self):
+ _set = self._makeOne()
+ s_old = (('a', 'e'), None)
+ s_com = (('a',), None)
+ s_new = (('a', 'c', 'd', 'e'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'c', 'd'),))
+
+ def test__p_resolveConflict_add_new_gt_old_com_lt_old(self):
+ _set = self._makeOne()
+ s_old = (('a', 'b', 'c'), None)
+ s_com = (('a', 'b', 'bb', 'c'), None)
+ s_new = (('a', 'b', 'c', 'd'), None)
+ result = _set._p_resolveConflict(s_old, s_com, s_new)
+ self.assertEqual(result, (('a', 'b', 'bb', 'c', 'd'),))
+
+
+class Test_TreeItem(unittest.TestCase):
+
+ def _getTargetClass(self):
+ from .._base import _TreeItem
+ return _TreeItem
+
+ def _makeOne(self, key, child):
+ return self._getTargetClass()(key, child)
+
+ def test_ctor(self):
+ child = object()
+ item = self._makeOne('key', child)
+ self.assertEqual(item.key, 'key')
+ self.assertTrue(item.child is child)
+
+
+class Test_Tree(unittest.TestCase):
+
+ assertRaises = _assertRaises
+
+ def _getTargetClass(self):
+ from .._base import _Tree
+ return _Tree
+
+ def _makeOne(self, items=None):
+ from .._base import Bucket
+ class _Bucket(Bucket):
+ MAX_SIZE = 10
+ def _to_key(self, k):
+ return k
+ class _Test(self._getTargetClass()):
+ _to_key = _to_value = lambda self, x: x
+ _bucket_type = _Bucket
+ MAX_SIZE = 15
+ return _Test(items)
+
+ def test_setdefault_miss(self):
+ tree = self._makeOne()
+ value = object()
+ self.assertTrue(tree.setdefault('non_extant', value) is value)
+ self.assertTrue('non_extant' in tree)
+ self.assertTrue(tree._findbucket('non_extant')['non_extant'] is value)
+
+ def test_setdefault_hit(self):
+ tree = self._makeOne()
+ value1 = object()
+ value2 = object()
+ tree['extant'] = value1
+ self.assertTrue(tree.setdefault('extant', value2) is value1)
+ self.assertTrue('extant' in tree)
+ self.assertTrue(tree._findbucket('extant')['extant'] is value1)
+
+ def test_pop_miss_no_default(self):
+ tree = self._makeOne()
+ self.assertRaises(KeyError, tree.pop, 'nonesuch')
+
+ def test_pop_miss_w_default(self):
+ default = object()
+ tree = self._makeOne()
+ self.assertTrue(tree.pop('nonesuch', default) is default)
+
+ def test_pop_hit(self):
+ tree = self._makeOne()
+ value = object()
+ tree['extant'] = value
+ self.assertTrue(tree.pop('extant', value) is value)
+ self.assertFalse('extant' in tree)
+
+ def test_update_value_w_iteritems(self):
+ tree = self._makeOne()
+ tree.update({'a': 'b'})
+ self.assertEqual(tree._findbucket('a')['a'], 'b')
+
+ def test_update_value_w_items(self):
+ tree = self._makeOne()
+ class Foo(object):
+ def items(self):
+ return [('a', 'b')]
+ tree.update(Foo())
+ self.assertEqual(tree._findbucket('a')['a'], 'b')
+
+ def test_update_value_w_invalid_items(self):
+ tree = self._makeOne()
+ class Foo(object):
+ def items(self):
+ return ('a', 'b', 'c')
+ self.assertRaises(TypeError, tree.update, Foo())
+
+ def test_update_sequence(self):
+ tree = self._makeOne()
+ tree.update([('a', 'b')])
+ self.assertEqual(tree._findbucket('a')['a'], 'b')
+
+ def test_update_replacing(self):
+ tree = self._makeOne()
+ tree['a'] = 'b'
+ tree.update([('a', 'c')])
+ self.assertEqual(tree._findbucket('a')['a'], 'c')
+
+ def test___setitem___incomparable(self):
+ tree = self._makeOne()
+ def _should_error():
+ tree[object()] = 'b'
+ self.assertRaises(TypeError, _should_error)
+
+ def test___delitem___miss(self):
+ tree = self._makeOne()
+ def _should_error():
+ del tree['a']
+ self.assertRaises(KeyError, _should_error)
+
+ def test___delitem___hit(self):
+ tree = self._makeOne()
+ tree['a'] = 'b'
+ del tree['a']
+ self.assertFalse('a' in tree)
+
+ def test_clear(self):
+ tree = self._makeOne()
+ tree['a'] = 'b'
+ tree.clear()
+ self.assertFalse('a' in tree)
+ self.assertEqual(tree._firstbucket, None)
+
+ def test___nonzero___empty(self):
+ tree = self._makeOne()
+ self.assertFalse(tree)
+
+ def test___nonzero___nonempty(self):
+ tree = self._makeOne()
+ tree['a'] = 'b'
+ self.assertTrue(tree)
+
+ def test___len__empty(self):
+ tree = self._makeOne()
+ self.assertEqual(len(tree), 0)
+
+ def test___len__nonempty(self):
+ tree = self._makeOne()
+ tree['a'] = 'b'
+ self.assertEqual(len(tree), 1)
+
+ def test___len__nonempty_multiple_buckets(self):
+ tree = self._makeOne()
+ for i in range(100):
+ tree[str(i)] = i
+ self.assertEqual(len(tree), 100)
+ b_count = 0
+ bucket = tree._firstbucket
+
+ def test_size_empty(self):
+ tree = self._makeOne()
+ self.assertEqual(tree.size, 0)
+
+ def test_size_nonempty(self):
+ tree = self._makeOne()
+ tree['a'] = 'b'
+ self.assertEqual(tree.size, 1)
+
+ def test_size_nonempty_multiple_buckets(self):
+ tree = self._makeOne()
+ for i in range(100):
+ tree[str(i)] = i
+ b_count = 0
+ bucket = tree._firstbucket
+ while bucket is not None:
+ b_count += 1
+ bucket = bucket._next
+ self.assertEqual(tree.size, b_count)
+
+ def test__search_empty(self):
+ tree = self._makeOne()
+ self.assertEqual(tree._search('nonesuch'), -1)
+
+ def test__search_miss_high(self):
+ tree = self._makeOne()
+ for i in range(100):
+ tree[float(i)] = i
+ b_count = 0
+ bucket = tree._firstbucket
+ while bucket is not None:
+ b_count += 1
+ bucket = bucket._next
+ self.assertEqual(tree.size, b_count)
+ self.assertEqual(tree._search(99.5), b_count - 1)
+
+ def test__search_miss_low(self):
+ tree = self._makeOne()
+ for i in range(100):
+ tree[float(i)] = i
+ self.assertEqual(tree._search(0.1), 0)
+
+ def test__search_miss_between(self):
+ tree = self._makeOne()
+ for i in range(100):
+ tree[float(i)] = i
+ self.assertEqual(tree._search(1.5), 0)
+
+ def test__search_hit(self):
+ tree = self._makeOne()
+ for i in range(100):
+ tree[float(i)] = i
+ key = tree._data[1].key
+ self.assertEqual(tree._search(key), 1)
+
+ def test__find_bucket_low(self):
+ tree = self._makeOne()
+ for i in range(1000):
+ tree[float(i)] = i
+ self.assertTrue(tree._findbucket(0.1) is tree._firstbucket)
+
+ def test__find_bucket_high(self):
+ tree = self._makeOne()
+ for i in range(1000):
+ tree[float(i)] = i
+ bucket = tree._firstbucket
+ while bucket._next is not None:
+ bucket = bucket._next
+ self.assertTrue(tree._findbucket(999.5) is bucket)
+
+ def test___contains___empty(self):
+ tree = self._makeOne()
+ self.assertFalse('nonesuch' in tree)
+
+ def test___contains___miss(self):
+ tree = self._makeOne()
+ for i in range(1000):
+ tree[float(i)] = i
+ self.assertFalse(1000.0 in tree)
+
+ def test___contains___hit(self):
+ tree = self._makeOne()
+ keys = []
+ for i in range(1000):
+ key = float(i)
+ tree[key] = i
+ keys.append(key)
+ for key in keys:
+ self.assertTrue(key in tree)
+
+ def test_has_key_empty(self):
+ tree = self._makeOne()
+ self.assertFalse(tree.has_key('nonesuch'))
+
+ def test_has_key_miss(self):
+ tree = self._makeOne()
+ for i in range(1000):
+ tree[float(i)] = i
+ self.assertFalse(tree.has_key(1000.0))
+
+ def test_has_key_hit(self):
+ tree = self._makeOne()
+ KEYS = []
+ for i in range(1000):
+ key = float(i)
+ tree[key] = i
+ KEYS.append(key)
+ for key in KEYS:
+ # XXX should we be testing for the 'depth' value?
+ self.assertTrue(tree.has_key(key))
+
+ def test_keys_defaults_empty(self):
+ tree = self._makeOne()
+ self.assertEqual(list(tree.keys()), [])
+
+ def test_keys_defaults_filled(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.keys()), KEYS[:])
+
+ def test_keys_defaults_exclude_min(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.keys(excludemin=True)), KEYS[1: 5])
+
+ def test_keys_defaults_exclude_max(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.keys(excludemax=True)), KEYS[0: 4])
+
+ def test_keys_w_min_hit(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.keys(min='bravo')), KEYS[1: 5])
+
+ def test_keys_w_min_miss(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.keys(min='candy')), KEYS[2: 5])
+
+ def test_keys_w_min_hit_w_exclude_min(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.keys(min='bravo', excludemin=True)),
+ KEYS[2: 5])
+
+ def test_keys_w_min_miss_w_exclude_min(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ # 'excludemin' doesn't fire on miss
+ self.assertEqual(list(tree.keys(min='candy', excludemin=True)),
+ KEYS[2: 5])
+
+ def test_keys_w_max_hit(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.keys(max='delta')), KEYS[0: 4])
+
+ def test_keys_w_max_miss(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.keys(max='dandy')), KEYS[0: 3])
+
+ def test_keys_w_max_hit_w_exclude_max(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.keys(max='delta', excludemax=True)),
+ KEYS[0: 3])
+
+ def test_keys_w_max_miss_w_exclude_max(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ # 'excludemax' doesn't fire on miss
+ self.assertEqual(list(tree.keys(max='dandy', excludemax=True)),
+ KEYS[0: 3])
+
+ def test_iterkeys(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree.iterkeys()), KEYS)
+
+ def test___iter__(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(list(tree), KEYS)
+
+ def test_minKey_empty(self):
+ tree = self._makeOne()
+ self.assertRaises(ValueError, tree.minKey)
+
+ def test_minKey_filled_default(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(tree.minKey(), KEYS[0])
+
+ def test_minKey_filled_explicit_hit(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(tree.minKey(min='bravo'), 'bravo')
+
+ def test_minKey_filled_explicit_miss(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(tree.minKey(min='basso'), 'bravo')
+
+ def test_maxKey_empty(self):
+ tree = self._makeOne()
+ self.assertRaises(ValueError, tree.maxKey)
+
+ def test_maxKey_filled_default(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(tree.maxKey(), 'echo')
+
+ def test_maxKey_filled_explicit_hit(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(tree.maxKey('bravo'), 'bravo')
+
+ def test_maxKey_filled_explicit_miss(self):
+ tree = self._makeOne()
+ KEYS = ['alpha', 'bravo', 'charlie', 'delta', 'echo']
+ for key in KEYS:
+ tree[key] = key.upper()
+ self.assertEqual(tree.maxKey('candy'), 'bravo')
+
+ def test__set_calls_readCurrent_on_jar(self):
+ tree = self._makeOne()
+ tree._p_oid = 'OID'
+ tree._p_serial = '01234567'
+ tree._p_jar = jar = _Jar()
+ tree._set('a', 'b')
+ self.assertTrue(tree in jar._current)
+
+ def test__split_empty(self):
+ tree = self._makeOne()
+ self.assertRaises(IndexError, tree._split)
+
+ def test__split_filled_empties_original(self):
+ tree = self._makeOne()
+ next_t = tree._next = self._makeOne()
+ for i, c in enumerate('abcdef'):
+ tree[c] = i
+ fb = tree._firstbucket
+ new_t = tree._split()
+ self.assertEqual(list(tree), [])
+ self.assertTrue(tree._firstbucket is None)
+ self.assertEqual(list(new_t), ['a', 'b', 'c', 'd', 'e', 'f'])
+ self.assertTrue(new_t._firstbucket is fb)
+
+ def test__split_filled_divides_original(self):
+ tree = self._makeOne()
+ next_t = tree._next = self._makeOne()
+ LETTERS = 'abcdefghijklmnopqrstuvwxyz'
+ for i, c in enumerate(LETTERS):
+ tree[c] = i
+ fb = tree._firstbucket
+ new_t = tree._split()
+ # Note that original tree still links to split buckets
+ self.assertEqual(''.join(list(tree)), LETTERS)
+ self.assertTrue(tree._firstbucket is fb)
+ self.assertEqual(''.join(list(new_t)), LETTERS[10:])
+ self.assertFalse(new_t._firstbucket is fb)
+
+ def test__split_filled_divides_deeper(self):
+ tree = self._makeOne()
+ next_t = tree._next = self._makeOne()
+ KEYS = []
+ FMT = '%05d'
+ for i in range(1000):
+ key = FMT % i
+ tree[key] = i
+ KEYS.append(key)
+ fb = tree._firstbucket
+ new_t = tree._split()
+ # Note that original tree still links to split buckets
+ self.assertEqual(list(tree), KEYS)
+ self.assertTrue(tree._firstbucket is fb)
+ new_min = new_t.minKey()
+ self.assertEqual(list(new_t), KEYS[int(new_min):])
+ self.assertFalse(new_t._firstbucket is fb)
+
+ def test__del_calls_readCurrent_on_jar(self):
+ tree = self._makeOne({'a': 'b'})
+ tree._p_oid = 'OID'
+ tree._p_serial = '01234567'
+ tree._p_jar = jar = _Jar()
+ tree._del('a')
+ self.assertTrue(tree in jar._current)
+
+ def test__del_miss(self):
+ tree = self._makeOne({'a': 'b'})
+ self.assertRaises(KeyError, tree._del, 'nonesuch')
+
+ def test__del_fixes_up_node_key(self):
+ SOURCE = dict([('%05d' % i, i) for i in range(1000)])
+ tree = self._makeOne(SOURCE)
+ before = tree._data[1].key
+ del tree[before]
+ after = tree._data[1].key
+ self.assertTrue(after > before)
+
+ def test__del_empties_first_bucket_not_zeroth_item(self):
+ SOURCE = dict([('%05d' % i, i) for i in range(1000)])
+ tree = self._makeOne(SOURCE)
+ bucket = tree._data[1].child._firstbucket
+ next_b = bucket._next
+ for key in list(bucket): # don't del while iterting
+ del tree[key]
+ self.assertTrue(tree._data[1].child._firstbucket is next_b)
+
+ def test__del_empties_first_bucket_zeroth_item(self):
+ SOURCE = dict([('%05d' % i, i) for i in range(1000)])
+ tree = self._makeOne(SOURCE)
+ bucket = tree._data[0].child._firstbucket
+ next_b = bucket._next
+ for key in list(bucket): # don't del while iterting
+ del tree[key]
+ self.assertTrue(tree._data[0].child._firstbucket is next_b)
+ self.assertTrue(tree._firstbucket is next_b)
+
+ def test__del_empties_other_bucket_not_zeroth_item(self):
+ SOURCE = dict([('%05d' % i, i) for i in range(1000)])
+ tree = self._makeOne(SOURCE)
+ bucket = tree._data[1].child._firstbucket._next
+ next_b = bucket._next
+ for key in list(bucket): # don't del while iterting
+ del tree[key]
+ self.assertTrue(tree._data[1].child._firstbucket._next is next_b)
+
+ def test___getstate___empty(self):
+ tree = self._makeOne()
+ self.assertEqual(tree.__getstate__(), None)
+
+ def test___getstate___single_bucket_wo_oid(self):
+ tree = self._makeOne({'a': 'b'})
+ self.assertEqual(tree.__getstate__(), (((('a', 'b'),),),))
+
+ def test___getstate___single_bucket_w_oid(self):
+ tree = self._makeOne({'a': 'b'})
+ bucket = tree._firstbucket
+ jar = _Jar()
+ bucket._p_jar = jar
+ bucket._p_oid = 'OID'
+ self.assertEqual(tree.__getstate__(), ((bucket,), bucket))
+
+ def test___getstate___multiple_buckets(self):
+ tree = self._makeOne()
+ FMT = '%05d'
+ for i in range(1000):
+ key = FMT % i
+ tree[key] = i
+ bucket = tree._firstbucket
+ EXPECTED = (tree._data[0].child,)
+ for item in tree._data[1:]:
+ EXPECTED += (item.key, item.child)
+ self.assertEqual(tree.__getstate__(), (EXPECTED, bucket))
+
+ def test___setstate___invalid(self):
+ tree = self._makeOne()
+ self.assertRaises(TypeError, tree.__setstate__, ('a', 'b'))
+
+ def test___setstate___to_empty(self):
+ tree = self._makeOne({'a': 'b'})
+ tree.__setstate__(None)
+ self.assertEqual(len(tree), 0)
+
+ def test___setstate___to_single_bucket_wo_oid(self):
+ tree = self._makeOne()
+ tree.__setstate__((((('a', 'b'),),),))
+ self.assertEqual(list(tree.keys()), ['a'])
+ self.assertEqual(tree._findbucket('a')['a'], 'b')
+ self.assertTrue(len(tree._data), 1)
+ self.assertTrue(tree._data[0].child is tree._firstbucket)
+ self.assertTrue(tree._firstbucket._p_oid is None)
+
+ def test___setstate___to_multiple_buckets(self):
+ from .._base import Bucket
+ class _Bucket(Bucket):
+ def _to_key(self, x):
+ return x
+ tree = self._makeOne()
+ b1 = _Bucket({'a': 0, 'b': 1})
+ b2 = _Bucket({'c': 2, 'd': 3})
+ b1._next = b2
+ tree.__setstate__(((b1, 'c', b2), b1))
+ self.assertEqual(list(tree.keys()), ['a', 'b', 'c', 'd'])
+ self.assertTrue(len(tree._data), 2)
+ self.assertEqual(tree._data[0].key, None)
+ self.assertEqual(tree._data[0].child, b1)
+ self.assertEqual(tree._data[1].key, 'c')
+ self.assertEqual(tree._data[1].child, b2)
+ self.assertTrue(tree._firstbucket is b1)
+
+ def test__check_empty_wo_firstbucket(self):
+ tree = self._makeOne()
+ tree._check() # no raise
+
+ def test__check_empty_w_firstbucket(self):
+ tree = self._makeOne()
+ tree._firstbucket = object()
+ e = self.assertRaises(AssertionError, tree._check)
+ self.assertEqual(str(e), "Empty BTree has non-NULL firstbucket")
+
+ def test__check_nonempty_wo_firstbucket(self):
+ tree = self._makeOne({'a': 'b'})
+ tree._firstbucket = None
+ e = self.assertRaises(AssertionError, tree._check)
+ self.assertEqual(str(e), "Non-empty BTree has NULL firstbucket")
+
+ def test__check_nonempty_w_null_child(self):
+ tree = self._makeOne({'a': 'b'})
+ tree._data.append(tree._data[0].__class__('c', None))
+ e = self.assertRaises(AssertionError, tree._check)
+ self.assertEqual(str(e), "BTree has NULL child")
+
+ def test__check_nonempty_w_heterogenous_child(self):
+ class Other(object):
+ pass
+ tree = self._makeOne({'a': 'b'})
+ tree._data.append(tree._data[0].__class__('c', Other()))
+ e = self.assertRaises(AssertionError, tree._check)
+ self.assertEqual(str(e), "BTree children have different types")
+
+ def test__check_nonempty_w_empty_child(self):
+ tree = self._makeOne({'a': 'b'})
+ first = tree._data[0]
+ tree._data.append(first.__class__('c', first.child.__class__()))
+ e = self.assertRaises(AssertionError, tree._check)
+ self.assertEqual(str(e), "Bucket length < 1")
+
+ def test__check_branch_w_mismatched_firstbucket(self):
+ tree = self._makeOne()
+ c_tree = tree.__class__({'a': 'b'})
+ c_first = c_tree._data[0]
+ tree._data.append(c_first.__class__('a', c_tree))
+ tree._firstbucket = object()
+ e = self.assertRaises(AssertionError, tree._check)
+ self.assertEqual(str(e), "BTree has firstbucket different than "
+ "its first child's firstbucket")
+
+ def test__check_nonempty_w_invalid_child(self):
+ class Invalid(object):
+ size = 2
+ tree = self._makeOne({'a': 'b'})
+ tree._data[0].child = Invalid()
+ e = self.assertRaises(AssertionError, tree._check)
+ self.assertEqual(str(e), "Incorrect child type")
+
+ def test__check_branch_traverse_bucket_pointers(self):
+ tree = self._makeOne()
+ t_first = tree.__class__({'a': 'b'})
+ c_first = t_first._data[0]
+ b_first = c_first.child
+ t_second = tree.__class__({'c': 'd'})
+ b_first._next = t_second._firstbucket
+ tree._data.append(c_first.__class__('a', t_first))
+ tree._data.append(c_first.__class__('c', t_second))
+ tree._firstbucket = t_first._firstbucket
+ tree._check() #no raise
+
+ def test__check_nonempty_leaf_traverse_bucket_pointers(self):
+ tree = self._makeOne({'a': 'b'})
+ first = tree._data[0]
+ first.child._next = b2 = first.child.__class__({'c': 'd'})
+ tree._data.append(first.__class__('c', b2))
+ tree._check() #no raise
+
+ def test__p_resolveConflict_invalid_state_non_tuple(self):
+ tree = self._makeOne()
+ INVALID = []
+ EMPTY = None
+ DEGEN = (((('a', 'b'),),),)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ INVALID, EMPTY, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, INVALID, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, DEGEN, INVALID)
+
+ def test__p_resolveConflict_non_degenerate_state(self):
+ from ..Interfaces import BTreesConflictError
+ tree = self._makeOne()
+ FIRST = object()
+ NON_DEGEN = ((FIRST, 'a', object(), 'b', object()), FIRST)
+ EMPTY = None
+ DEGEN = (((('a', 'b'),),),)
+ e = self.assertRaises(BTreesConflictError, tree._p_resolveConflict,
+ NON_DEGEN, EMPTY, DEGEN)
+ self.assertEqual(e.reason, 11)
+ e = self.assertRaises(BTreesConflictError, tree._p_resolveConflict,
+ EMPTY, NON_DEGEN, DEGEN)
+ self.assertEqual(e.reason, 11)
+ e = self.assertRaises(BTreesConflictError, tree._p_resolveConflict,
+ EMPTY, DEGEN, NON_DEGEN)
+ self.assertEqual(e.reason, 11)
+
+ def test__p_resolveConflict_invalid_state_non_1_tuple(self):
+ tree = self._makeOne()
+ INVALID = ('a', 'b', 'c')
+ EMPTY = None
+ DEGEN = (((('a', 'b'),),),)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ INVALID, EMPTY, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, INVALID, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, DEGEN, INVALID)
+
+ def test__p_resolveConflict_invalid_state_nested_non_tuple(self):
+ tree = self._makeOne()
+ INVALID = ([],)
+ EMPTY = None
+ DEGEN = (((('a', 'b'),),),)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ INVALID, EMPTY, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, INVALID, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, DEGEN, INVALID)
+
+ def test__p_resolveConflict_invalid_state_nested_non_1_tuple(self):
+ tree = self._makeOne()
+ INVALID = (('a', 'b', 'c'),)
+ EMPTY = None
+ DEGEN = (((('a', 'b'),),),)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ INVALID, EMPTY, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, INVALID, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, DEGEN, INVALID)
+
+ def test__p_resolveConflict_invalid_state_nested2_non_tuple(self):
+ tree = self._makeOne()
+ INVALID = (([],),)
+ EMPTY = None
+ DEGEN = (((('a', 'b'),),),)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ INVALID, EMPTY, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, INVALID, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, DEGEN, INVALID)
+
+ def test__p_resolveConflict_invalid_state_nested2_non_1_tuple(self):
+ tree = self._makeOne()
+ INVALID = ((('a', 'b', 'c'),))
+ EMPTY = None
+ DEGEN = (((('a', 'b'),),),)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ INVALID, EMPTY, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, INVALID, DEGEN)
+ self.assertRaises(TypeError, tree._p_resolveConflict,
+ EMPTY, DEGEN, INVALID)
+
+ def test__p_resolveConflict_w_degenerate_state(self):
+ tree = self._makeOne()
+ OLD = (((('a', 'b', 'c', 'd'),),),)
+ COM = (((('a', 'b', 'c', 'd', 'e', 'f'),),),)
+ NEW = (((('a', 'b'),),),)
+ resolved = tree._p_resolveConflict(OLD, COM, NEW)
+ self.assertEqual(resolved, (((('a', 'b', 'e', 'f'),),),))
+
+
+class Test_TreeItems(unittest.TestCase):
+
+ assertRaises = _assertRaises
+
+ def _getTargetClass(self):
+ from .._base import _TreeItems
+ return _TreeItems
+
+ def _makeOne(self, firstbucket, itertype, iterargs):
+ return self._getTargetClass()(firstbucket, itertype, iterargs)
+
+ def _makeBucket(self, items=None):
+ from .._base import Bucket
+ class _Bucket(Bucket):
+ MAX_SIZE = 10
+ def _to_key(self, k):
+ return k
+ return _Bucket(items)
+
+ def test___getitem___w_slice(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ bucket = self._makeBucket(ITEMS)
+ ti = self._makeOne(bucket, 'iterkeys', ())
+ self.assertEqual(list(ti[0:3]), ['a', 'b', 'c'])
+
+ def test___getitem___w_negative_index_le_minus_length(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ bucket = self._makeBucket(ITEMS)
+ ti = self._makeOne(bucket, 'iterkeys', ())
+ def _should_error():
+ return ti[-27]
+ self.assertRaises(IndexError, _should_error)
+
+ def test___getitem___w_index_gt_length(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ bucket = self._makeBucket(ITEMS)
+ ti = self._makeOne(bucket, 'iterkeys', ())
+ def _should_error():
+ return ti[27]
+ self.assertRaises(IndexError, _should_error)
+
+ def test___getitem___w_index_smaller_than_cursor(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ bucket = self._makeBucket(ITEMS)
+ ti = self._makeOne(bucket, 'iterkeys', ())
+ ti[12]
+ self.assertEqual(ti[1], 'b')
+
+ def test___len__(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ bucket = self._makeBucket(ITEMS)
+ ti = self._makeOne(bucket, 'iterkeys', ())
+ self.assertEqual(len(ti), 26)
+ # short-circuit on second pass
+ self.assertEqual(len(ti), 26)
+
+ def test___iter___w_iterkeys(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ bucket = self._makeBucket(ITEMS)
+ ti = self._makeOne(bucket, 'iterkeys', ())
+ self.assertEqual(list(ti), [x[0] for x in ITEMS])
+
+ def test___iter___w_iteritems(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ bucket = self._makeBucket(ITEMS)
+ ti = self._makeOne(bucket, 'iteritems', ())
+ self.assertEqual(list(ti), ITEMS)
+
+ def test___iter___w_itervalues(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ bucket = self._makeBucket(ITEMS)
+ ti = self._makeOne(bucket, 'itervalues', ())
+ self.assertEqual(list(ti), [x[1] for x in ITEMS])
+
+ def test___iter___w_empty_last_bucket(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ bucket1 = self._makeBucket(ITEMS)
+ bucket2 = bucket1._next = self._makeBucket()
+ ti = self._makeOne(bucket1, 'iterkeys', ())
+ self.assertEqual(list(ti), [x[0] for x in ITEMS])
+
+
+class TreeTests(unittest.TestCase):
+
+ assertRaises = _assertRaises
+
+ def _getTargetClass(self):
+ from .._base import Tree
+ return Tree
+
+ def _makeOne(self, items=None):
+ from .._base import Bucket
+ class _Bucket(Bucket):
+ MAX_SIZE = 10
+ def _to_key(self, k):
+ return k
+ class _Test(self._getTargetClass()):
+ _to_key = _to_value = lambda self, x: x
+ _bucket_type = _Bucket
+ MAX_SIZE = 15
+ return _Test(items)
+
+ def test_get_empty_miss(self):
+ tree = self._makeOne()
+ self.assertEqual(tree.get('nonesuch'), None)
+
+ def test_get_empty_miss_w_default(self):
+ DEFAULT = object()
+ tree = self._makeOne()
+ self.assertTrue(tree.get('nonesuch', DEFAULT) is DEFAULT)
+
+ def test_get_filled_miss(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(tree.get('nonesuch'), None)
+
+ def test_get_filled_miss_w_default(self):
+ DEFAULT = object()
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertTrue(tree.get('nonesuch', DEFAULT) is DEFAULT)
+
+ def test_get_filled_hit(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(tree.get('a'), 0)
+
+ def test___getitem___empty_miss(self):
+ tree = self._makeOne()
+ def _should_error():
+ return tree['nonesuch']
+ self.assertRaises(KeyError, _should_error)
+
+ def test___getitem___filled_miss(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ def _should_error():
+ return tree['nonesuch']
+ self.assertRaises(KeyError, _should_error)
+
+ def test___getitem___filled_hit(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(tree['a'], 0)
+
+ def test_values_empty_no_args(self):
+ tree = self._makeOne()
+ self.assertEqual(list(tree.values()), [])
+
+ def test_values_filled_no_args(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(list(tree.values()), range(26))
+
+ def test_values_filled_w_args(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(list(tree.values(min='b', excludemin=True,
+ max='f', excludemax=True)),
+ [2, 3, 4])
+
+ def test_itervalues_empty_no_args(self):
+ tree = self._makeOne()
+ self.assertEqual(list(tree.itervalues()), [])
+
+ def test_itervalues_filled_no_args(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(list(tree.itervalues()), range(26))
+
+ def test_itervalues_filled_w_args(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(list(tree.itervalues(min='b', excludemin=True,
+ max='f', excludemax=True)),
+ [2, 3, 4])
+
+ def test_items_empty_no_args(self):
+ tree = self._makeOne()
+ self.assertEqual(list(tree.items()), [])
+
+ def test_items_filled_no_args(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(list(tree.items()), ITEMS)
+
+ def test_items_filled_w_args(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(list(tree.items(min='b', excludemin=True,
+ max='f', excludemax=True)),
+ ITEMS[2:5])
+
+ def test_iteritems_empty_no_args(self):
+ tree = self._makeOne()
+ self.assertEqual(list(tree.iteritems()), [])
+
+ def test_iteritems_filled_no_args(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(list(tree.iteritems()), ITEMS)
+
+ def test_iteritems_filled_w_args(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(list(tree.iteritems(min='b', excludemin=True,
+ max='f', excludemax=True)),
+ ITEMS[2:5])
+
+ def test_byValue(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertEqual(list(tree.byValue(min=22)),
+ [(y, x) for x, y in ITEMS[22:]])
+
+ def test_insert_new_key(self):
+ tree = self._makeOne()
+ self.assertTrue(tree.insert('a', 0))
+ self.assertEqual(tree['a'], 0)
+
+ def test_insert_would_change_key(self):
+ ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
+ tree = self._makeOne(ITEMS)
+ self.assertFalse(tree.insert('a', 1))
+ self.assertEqual(tree['a'], 0)
+
+
+class TreeSetTests(unittest.TestCase):
+
+ assertRaises = _assertRaises
+
+ def _getTargetClass(self):
+ from .._base import TreeSet
+ return TreeSet
+
+ def _makeOne(self, items=None):
+ from .._base import Bucket
+ class _Bucket(Bucket):
+ MAX_SIZE = 10
+ def _to_key(self, k):
+ return k
+ class _Test(self._getTargetClass()):
+ _to_key = _to_value = lambda self, x: x
+ _bucket_type = _Bucket
+ MAX_SIZE = 15
+ return _Test(items)
+
+ def test_add_new_key(self):
+ _set = self._makeOne()
+ self.assertTrue(_set.add('a'))
+ self.assertTrue('a' in _set)
+
+ def test_add_existing_key(self):
+ _set = self._makeOne()
+ _set.add('a')
+ self.assertFalse(_set.add('a'))
+
+ def test_remove_miss(self):
+ _set = self._makeOne()
+ self.assertRaises(KeyError, _set.remove, 'a')
+
+ def test_remove_hit(self):
+ _set = self._makeOne()
+ _set.add('a')
+ self.assertEqual(_set.remove('a'), None)
+ self.assertFalse('a' in _set)
+
+ def test_update_empty_sequence(self):
+ _set = self._makeOne()
+ _set.update(())
+ self.assertEqual(len(_set), 0)
+
+ def test_update_simple_sequence(self):
+ _set = self._makeOne()
+ LETTERS = 'abcdefghijklmnopqrstuvwxyz'
+ _set.update(LETTERS)
+ self.assertEqual(len(_set), len(LETTERS))
+ for letter in LETTERS:
+ self.assertTrue(letter in _set)
+
+ def test_update_mppaing(self):
+ _set = self._makeOne()
+ LETTERS = 'abcdefghijklmnopqrstuvwxyz'
+ a_dict = dict([(y, x) for x, y in enumerate(LETTERS)])
+ _set.update(a_dict)
+ self.assertEqual(len(_set), len(LETTERS))
+ for letter in LETTERS:
+ self.assertTrue(letter in _set)
+
+
+class Test_set_operation(unittest.TestCase):
+
+ assertRaises = _assertRaises
+
+ def _getTargetClass(self):
+ from .._base import set_operation
+ return set_operation
+
+ def _makeOne(self, func, set_type):
+ return self._getTargetClass()(func, set_type)
+
+ def test_it(self):
+ class _SetType(object):
+ pass
+ _called_with = []
+ def _func(*args, **kw):
+ _called_with.append((args, kw))
+ set_op = self._makeOne(_func, _SetType)
+ set_op('a', b=1)
+ self.assertEqual(_called_with, [((_SetType, 'a',), {'b': 1})])
+
+
+class _SetObBase(object):
+
+ def _makeSet(self, *args):
+ return _Set(*args)
+
+ def _makeMapping(self, *args, **kw):
+ return _Mapping(*args, **kw)
+
+
+class Test_difference(unittest.TestCase, _SetObBase):
+
+ def _callFUT(self, *args, **kw):
+ from .._base import difference
+ return difference(*args, **kw)
+
+ def test_lhs_none(self):
+ rhs = self._makeSet('a', 'b', 'c')
+ self.assertEqual(self._callFUT(rhs.__class__, None, rhs), None)
+
+ def test_rhs_none(self):
+ lhs = self._makeSet('a', 'b', 'c')
+ self.assertEqual(self._callFUT(lhs.__class__, lhs, None), lhs)
+
+ def test_both_sets_rhs_empty(self):
+ lhs = self._makeSet('a', 'b', 'c')
+ rhs = self._makeSet()
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), list(lhs))
+
+ def test_both_sets_lhs_empty(self):
+ lhs = self._makeSet()
+ rhs = self._makeSet('a', 'b', 'c')
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), list(lhs))
+
+ def test_lhs_set_rhs_mapping(self):
+ lhs = self._makeSet('a', 'b', 'c')
+ rhs = self._makeMapping({'a': 13, 'b': 12})
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), ['c'])
+
+ def test_lhs_mapping_rhs_set(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeSet('a', 'b')
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), ['c'])
+ self.assertEqual(result['c'], 11)
+
+ def test_both_mappings_rhs_empty(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeMapping({})
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), ['a', 'b', 'c'])
+ self.assertEqual(result['a'], 13)
+ self.assertEqual(result['b'], 12)
+ self.assertEqual(result['c'], 11)
+
+ def test_both_mappings_rhs_non_empty(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11, 'f': 10})
+ rhs = self._makeMapping({'b': 22, 'e': 37})
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), ['a', 'c', 'f'])
+ self.assertEqual(result['a'], 13)
+ self.assertEqual(result['c'], 11)
+ self.assertEqual(result['f'], 10)
+
+
+class Test_union(unittest.TestCase, _SetObBase):
+
+ def _callFUT(self, *args, **kw):
+ from .._base import union
+ return union(*args, **kw)
+
+ def test_lhs_none(self):
+ rhs = self._makeSet('a', 'b', 'c')
+ self.assertEqual(self._callFUT(rhs.__class__, None, rhs), rhs)
+
+ def test_rhs_none(self):
+ lhs = self._makeSet('a', 'b', 'c')
+ self.assertEqual(self._callFUT(lhs.__class__, lhs, None), lhs)
+
+ def test_both_sets_rhs_empty(self):
+ lhs = self._makeSet('a', 'b', 'c')
+ rhs = self._makeSet()
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), list(lhs))
+
+ def test_both_sets_lhs_empty(self):
+ lhs = self._makeSet()
+ rhs = self._makeSet('a', 'b', 'c')
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), list(rhs))
+
+ def test_lhs_set_rhs_mapping(self):
+ lhs = self._makeSet('a', 'b', 'c')
+ rhs = self._makeMapping({'a': 13, 'd': 12})
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), ['a', 'b', 'c', 'd'])
+
+ def test_lhs_mapping_rhs_set(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeSet('a', 'd')
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertTrue(isinstance(result, _Set))
+ self.assertEqual(list(result), ['a', 'b', 'c', 'd'])
+
+ def test_both_mappings_rhs_empty(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeMapping({})
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), ['a', 'b', 'c'])
+
+ def test_both_mappings_rhs_non_empty(self):
+ lhs = self._makeMapping({'a': 13, 'c': 12, 'e': 11})
+ rhs = self._makeMapping({'b': 22, 'd': 33})
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), ['a', 'b', 'c', 'd', 'e'])
+
+
+class Test_intersection(unittest.TestCase, _SetObBase):
+
+ def _callFUT(self, *args, **kw):
+ from .._base import intersection
+ return intersection(*args, **kw)
+
+ def test_lhs_none(self):
+ rhs = self._makeSet(('a', 'b', 'c'))
+ self.assertEqual(self._callFUT(rhs.__class__, None, rhs), rhs)
+
+ def test_rhs_none(self):
+ lhs = self._makeSet(('a', 'b', 'c'))
+ self.assertEqual(self._callFUT(lhs.__class__, lhs, None), lhs)
+
+ def test_both_sets_rhs_empty(self):
+ lhs = self._makeSet('a', 'b', 'c')
+ rhs = self._makeSet()
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), [])
+
+ def test_both_sets_lhs_empty(self):
+ lhs = self._makeSet()
+ rhs = self._makeSet('a', 'b', 'c')
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), [])
+
+ def test_lhs_set_rhs_mapping(self):
+ lhs = self._makeSet('a', 'b', 'c')
+ rhs = self._makeMapping({'a': 13, 'd': 12})
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), ['a'])
+
+ def test_lhs_mapping_rhs_set(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeSet('a', 'd')
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertTrue(isinstance(result, _Set))
+ self.assertEqual(list(result), ['a'])
+
+ def test_both_mappings_rhs_empty(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeMapping({})
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), [])
+
+ def test_both_mappings_rhs_non_empty(self):
+ lhs = self._makeMapping({'a': 13, 'c': 12, 'e': 11})
+ rhs = self._makeMapping({'b': 22, 'c': 44, 'd': 33})
+ result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(list(result), ['c'])
+
+
+class Test_weightedUnion(unittest.TestCase, _SetObBase):
+
+ def _callFUT(self, *args, **kw):
+ from .._base import weightedUnion
+ return weightedUnion(*args, **kw)
+
+ def test_both_none(self):
+ self.assertEqual(self._callFUT(_Mapping, None, None), (0, None))
+
+ def test_lhs_none(self):
+ rhs = self._makeMapping({'a': 13, 'c': 12, 'e': 11})
+ self.assertEqual(self._callFUT(rhs.__class__, None, rhs), (1, rhs))
+
+ def test_rhs_none(self):
+ lhs = self._makeMapping({'a': 13, 'c': 12, 'e': 11})
+ self.assertEqual(self._callFUT(lhs.__class__, lhs, None), (1, lhs))
+
+ def test_both_mappings_but_no_merge(self):
+ lhs = {'a': 13, 'b': 12, 'c': 11}
+ rhs = {'b': 22, 'd': 14}
+ self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
+
+ def test_lhs_set_wo_MERGE_DEFAULT_rhs_set(self):
+ lhs = self._makeSet('a', 'd')
+ lhs.MERGE = lambda v1, w1, v2, w2: (v1 * w1) + (v2 * w2)
+ lhs.MERGE_WEIGHT = lambda v, w: v
+ lhs._mapping_type = _Mapping
+ rhs = self._makeSet('a', 'b', 'c')
+ self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
+
+ def test_lhs_set_wo_MERGE_DEFAULT_rhs_mapping(self):
+ lhs = self._makeSet('a', 'd')
+ lhs.MERGE = lambda v1, w1, v2, w2: (v1 * w1) + (v2 * w2)
+ lhs.MERGE_WEIGHT = lambda v, w: v
+ lhs._mapping_type = _Mapping
+ rhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
+
+ def test_lhs_mergeable_set_rhs_mapping(self):
+ lhs = self._makeSet('a', 'd')
+ lhs.MERGE = lambda v1, w1, v2, w2: (v1 * w1) + (v2 * w2)
+ lhs.MERGE_WEIGHT = lambda v, w: v
+ lhs.MERGE_DEFAULT = 1
+ lhs._mapping_type = _Mapping
+ rhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ weight, result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(weight, 1)
+ self.assertTrue(isinstance(result, _Mapping))
+ self.assertEqual(list(result), ['a', 'b', 'c', 'd'])
+ self.assertEqual(result['a'], 14)
+ self.assertEqual(result['b'], 12)
+ self.assertEqual(result['c'], 11)
+ self.assertEqual(result['d'], 1)
+
+ def test_lhs_mapping_rhs_set(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeSet('a', 'd')
+ weight, result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(weight, 1)
+ self.assertTrue(isinstance(result, _Mapping))
+ self.assertEqual(list(result), ['a', 'b', 'c', 'd'])
+ self.assertEqual(result['a'], 55)
+ self.assertEqual(result['b'], 12)
+ self.assertEqual(result['c'], 11)
+ self.assertEqual(result['d'], 42)
+
+ def test_both_mappings_rhs_empty(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeMapping({})
+ weight, result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(weight, 1)
+ self.assertEqual(list(result), ['a', 'b', 'c'])
+ self.assertEqual(result['a'], 13)
+ self.assertEqual(result['b'], 12)
+ self.assertEqual(result['c'], 11)
+
+ def test_both_mappings_rhs_non_empty(self):
+ lhs = self._makeMapping({'a': 13, 'c': 12, 'e': 11})
+ rhs = self._makeMapping({'a': 10, 'b': 22, 'd': 33})
+ weight, result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(weight, 1)
+ self.assertEqual(list(result), ['a', 'b', 'c', 'd', 'e'])
+ self.assertEqual(result['a'], 23)
+ self.assertEqual(result['b'], 22)
+ self.assertEqual(result['c'], 12)
+ self.assertEqual(result['d'], 33)
+ self.assertEqual(result['e'], 11)
+
+ def test_w_lhs_Set_rhs_Set(self):
+ from BTrees.IIBTree import IISetPy
+ lhs = IISetPy([1, 2, 3])
+ rhs = IISetPy([1, 4])
+ weight, result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(weight, 1)
+ self.assertEqual(list(result), [1, 2, 3, 4])
+
+ #TODO: test non-default weights
+
+
+class Test_weightedIntersection(unittest.TestCase, _SetObBase):
+
+ def _callFUT(self, *args, **kw):
+ from .._base import weightedIntersection
+ return weightedIntersection(*args, **kw)
+
+ def test_both_none(self):
+ self.assertEqual(self._callFUT(_Mapping, None, None), (0, None))
+
+ def test_lhs_none(self):
+ rhs = self._makeMapping({'a': 13, 'c': 12, 'e': 11})
+ self.assertEqual(self._callFUT(rhs.__class__, None, rhs), (1, rhs))
+
+ def test_rhs_none(self):
+ lhs = self._makeMapping({'a': 13, 'c': 12, 'e': 11})
+ self.assertEqual(self._callFUT(lhs.__class__, lhs, None), (1, lhs))
+
+ def test_both_mappings_but_no_merge(self):
+ lhs = {'a': 13, 'b': 12, 'c': 11}
+ rhs = {'b': 22, 'd': 14}
+ self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
+
+ def test_lhs_set_wo_MERGE_DEFAULT_rhs_set(self):
+ lhs = self._makeSet('a', 'd')
+ lhs.MERGE = lambda v1, w1, v2, w2: (v1 * w1) + (v2 * w2)
+ lhs.MERGE_WEIGHT = lambda v, w: v
+ lhs._mapping_type = _Mapping
+ rhs = self._makeSet('a', 'b', 'c')
+ self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
+
+ def test_lhs_set_wo_MERGE_DEFAULT_rhs_mapping(self):
+ lhs = self._makeSet('a', 'd')
+ lhs.MERGE = lambda v1, w1, v2, w2: (v1 * w1) + (v2 * w2)
+ lhs.MERGE_WEIGHT = lambda v, w: v
+ lhs._mapping_type = _Mapping
+ rhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
+
+ def test_lhs_mapping_rhs_set(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeSet('a', 'd')
+ weight, result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(weight, 1)
+ self.assertTrue(isinstance(result, _Mapping))
+ self.assertEqual(list(result), ['a'])
+ self.assertEqual(result['a'], 55)
+
+ def test_both_mappings_rhs_empty(self):
+ lhs = self._makeMapping({'a': 13, 'b': 12, 'c': 11})
+ rhs = self._makeMapping({})
+ weight, result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(weight, 1)
+ self.assertEqual(list(result), [])
+
+ def test_both_mappings_rhs_non_empty(self):
+ lhs = self._makeMapping({'a': 13, 'c': 12, 'e': 11})
+ rhs = self._makeMapping({'a': 10, 'b': 22, 'd': 33})
+ weight, result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(weight, 1)
+ self.assertEqual(list(result), ['a'])
+ self.assertEqual(result['a'], 23)
+
+ def test_w_lhs_Set_rhs_Set(self):
+ from BTrees.IIBTree import IISetPy
+ lhs = IISetPy([1, 2, 3])
+ rhs = IISetPy([1, 4])
+ weight, result = self._callFUT(lhs.__class__, lhs, rhs)
+ self.assertEqual(weight, 2)
+ self.assertEqual(list(result), [1])
+
+ #TODO: test non-default weights
+
+
+class Test_multiunion(unittest.TestCase, _SetObBase):
+
+ def _callFUT(self, *args, **kw):
+ from .._base import multiunion
+ return multiunion(*args, **kw)
+
+ def test_no_seqs(self):
+ result = self._callFUT(_Set, ())
+ self.assertEqual(list(result), [])
+
+ def test_w_non_iterable_seq(self):
+ result = self._callFUT(_Set, (1, 2))
+ self.assertEqual(list(result), [1, 2])
+
+ def test_w_iterable_seqs(self):
+ result = self._callFUT(_Set, [(1,), (2,)])
+ self.assertEqual(list(result), [1, 2])
+
+ def test_w_mix(self):
+ result = self._callFUT(_Set, [1, (2,)])
+ self.assertEqual(list(result), [1, 2])
+
+
+class Test_helpers(unittest.TestCase):
+
+ def test_to_ob(self):
+ from BTrees._base import to_ob
+ faux_self = object()
+ for thing in "abc", 0, 1.3, (), frozenset((1, 2)), object():
+ self.assertTrue(to_ob(faux_self, thing) is thing)
+
+ def test_to_int_w_int(self):
+ from BTrees._base import to_int
+ faux_self = object()
+ self.assertEqual(to_int(faux_self, 3), 3)
+
+ def test_to_int_w_long_in_range(self):
+ from BTrees._base import to_int
+ faux_self = object()
+ try:
+ self.assertEqual(to_int(faux_self, long(3)), 3)
+ except NameError: #Python3
+ pass
+
+ def test_to_int_w_overflow(self):
+ import sys
+ from BTrees._base import to_int
+ faux_self = object()
+ self.assertRaises(TypeError, to_int, faux_self, sys.maxint + 1)
+
+ def test_to_int_w_invalid(self):
+ from BTrees._base import to_int
+ faux_self = object()
+ self.assertRaises(TypeError, to_int, faux_self, ())
+
+ def test_to_float_w_float(self):
+ from BTrees._base import to_float
+ faux_self = object()
+ self.assertEqual(to_float(faux_self, 3.14159), 3.14159)
+
+ def test_to_float_w_int(self):
+ from BTrees._base import to_float
+ faux_self = object()
+ self.assertEqual(to_float(faux_self, 3), 3.0)
+
+ def test_to_float_w_invalid(self):
+ from BTrees._base import to_float
+ faux_self = object()
+ self.assertRaises(TypeError, to_float, faux_self, ())
+
+ def test_to_long_w_int(self):
+ from BTrees._base import to_long
+ faux_self = object()
+ self.assertEqual(to_long(faux_self, 3), 3)
+
+ def test_to_long_w_long_in_range(self):
+ from BTrees._base import to_long
+ faux_self = object()
+ try:
+ self.assertEqual(to_long(faux_self, long(3)), 3)
+ except NameError: #Python3
+ pass
+
+ def test_to_long_w_overflow(self):
+ import sys
+ from BTrees._base import to_long
+ faux_self = object()
+ self.assertRaises(ValueError, to_long, faux_self, sys.maxint + 1)
+
+ def test_to_long_w_invalid(self):
+ from BTrees._base import to_long
+ faux_self = object()
+ self.assertRaises(TypeError, to_long, faux_self, ())
+
+ def test_to_str_w_ok(self):
+ from BTrees._base import to_str
+ faux_self = object()
+ conv = to_str(3)
+ self.assertEqual(conv(faux_self, 'abc'), 'abc')
+
+ def test_to_str_w_invalid_length(self):
+ from BTrees._base import to_str
+ faux_self = object()
+ conv = to_str(3)
+ self.assertRaises(TypeError, conv, faux_self, 'ab')
+ self.assertRaises(TypeError, conv, faux_self, 'abcd')
+
+ def test_MERGE(self):
+ from BTrees._base import MERGE
+ faux_self = object()
+ self.assertEqual(MERGE(faux_self, 1, 1, 1, 1), 2)
+ self.assertEqual(MERGE(faux_self, 1, 2, 1, 3), 5)
+
+ def test_MERGE_WEIGHT_default(self):
+ from BTrees._base import MERGE_WEIGHT_default
+ faux_self = object()
+ self.assertEqual(MERGE_WEIGHT_default(faux_self, 1, 17), 1)
+ self.assertEqual(MERGE_WEIGHT_default(faux_self, 7, 1), 7)
+
+ def test_MERGE_WEIGHT_numeric(self):
+ from BTrees._base import MERGE_WEIGHT_numeric
+ faux_self = object()
+ self.assertEqual(MERGE_WEIGHT_numeric(faux_self, 1, 17), 17)
+ self.assertEqual(MERGE_WEIGHT_numeric(faux_self, 7, 1), 7)
+
+
+class _Cache(object):
+ def __init__(self):
+ self._mru = []
+ def mru(self, oid):
+ self._mru.append(oid)
+
+
+class _Jar(object):
+ def __init__(self):
+ self._current = set()
+ self._cache = _Cache()
+ def readCurrent(self, obj):
+ self._current.add(obj)
+ def register(self, obj):
+ pass
+
+
+class _Set(object):
+ def __init__(self, *args, **kw):
+ if len(args) == 1 and isinstance(args[0], tuple):
+ keys = args[0]
+ else:
+ keys = set(args)
+ self._keys = sorted(keys)
+ def keys(self):
+ return self._keys
+ def __iter__(self):
+ return iter(self._keys)
+ def update(self, items):
+ self._keys = sorted(self._keys + list(items))
+_Set._set_type = _Set
+
+
+class _Mapping(dict):
+ def __init__(self, source=None):
+ if source is None:
+ source = {}
+ self._keys = []
+ self._values = []
+ for k, v in sorted(source.items()):
+ self._keys.append(k)
+ self._values.append(v)
+ MERGE_DEFAULT = 42
+ def MERGE_WEIGHT(self, v, w):
+ return v
+ def MERGE(self, v1, w1, v2, w2):
+ return v1 * w1 + v2 * w2
+ def iteritems(self):
+ for k, v in zip(self._keys, self._values):
+ yield k,v
+ def __iter__(self):
+ return iter(self._keys)
+ def __getitem__(self, key):
+ search = dict(zip(self._keys, self._values))
+ return search[key]
+ def __repr__(self):
+ return repr(dict(zip(self._keys, self._values)))
+_Mapping._set_type = _Set
+_Mapping._mapping_type = _Mapping
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(Test_Base),
+ unittest.makeSuite(Test_BucketBase),
+ unittest.makeSuite(Test_SetIteration),
+ unittest.makeSuite(BucketTests),
+ unittest.makeSuite(SetTests),
+ unittest.makeSuite(Test_TreeItem),
+ unittest.makeSuite(Test_Tree),
+ unittest.makeSuite(Test_TreeItems),
+ unittest.makeSuite(TreeTests),
+ unittest.makeSuite(TreeSetTests),
+ unittest.makeSuite(Test_set_operation),
+ unittest.makeSuite(Test_difference),
+ unittest.makeSuite(Test_union),
+ unittest.makeSuite(Test_intersection),
+ unittest.makeSuite(Test_weightedUnion),
+ unittest.makeSuite(Test_weightedIntersection),
+ unittest.makeSuite(Test_multiunion),
+ unittest.makeSuite(Test_helpers),
+ ))
Modified: BTrees/trunk/BTrees/tests/test_check.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_check.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/tests/test_check.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -11,65 +11,348 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-"""Test the BTree check.check() function."""
-
import unittest
-from BTrees.OOBTree import OOBTree
-from BTrees.check import check
-class CheckTest(unittest.TestCase):
+def _assertRaises(self, e_type, checked, *args, **kw):
+ try:
+ checked(*args, **kw)
+ except e_type as e:
+ return e
+ self.fail("Didn't raise: %s" % e_type.__name__)
- def setUp(self):
- self.t = t = OOBTree()
- for i in range(31):
- t[i] = 2*i
- self.state = t.__getstate__()
- def testNormal(self):
- s = self.state
- # Looks like (state, first_bucket)
- # where state looks like (bucket0, 15, bucket1).
- self.assertEqual(len(s), 2)
- self.assertEqual(len(s[0]), 3)
- self.assertEqual(s[0][1], 15)
- self.t._check() # shouldn't blow up
- check(self.t) # shouldn't blow up
+class Test_classify(unittest.TestCase):
- def testKeyTooLarge(self):
+ def _callFUT(self, obj):
+ from BTrees.check import classify
+ return classify(obj)
+
+ def test_classify_w_unknown(self):
+ class NotClassified(object):
+ pass
+ self.assertRaises(KeyError, self._callFUT, NotClassified())
+
+ def test_classify_w_bucket(self):
+ from BTrees.OOBTree import OOBucketPy
+ from BTrees.check import TYPE_BUCKET
+ kind, is_mapping = self._callFUT(OOBucketPy())
+ self.assertEqual(kind, TYPE_BUCKET)
+ self.assertTrue(is_mapping)
+
+ def test_classify_w_set(self):
+ from BTrees.OOBTree import OOSetPy
+ from BTrees.check import TYPE_BUCKET
+ kind, is_mapping = self._callFUT(OOSetPy())
+ self.assertEqual(kind, TYPE_BUCKET)
+ self.assertFalse(is_mapping)
+
+ def test_classify_w_tree(self):
+ from BTrees.OOBTree import OOBTreePy
+ from BTrees.check import TYPE_BTREE
+ kind, is_mapping = self._callFUT(OOBTreePy())
+ self.assertEqual(kind, TYPE_BTREE)
+ self.assertTrue(is_mapping)
+
+ def test_classify_w_treeset(self):
+ from BTrees.OOBTree import OOTreeSetPy
+ from BTrees.check import TYPE_BTREE
+ kind, is_mapping = self._callFUT(OOTreeSetPy())
+ self.assertEqual(kind, TYPE_BTREE)
+ self.assertFalse(is_mapping)
+
+
+class Test_crack_btree(unittest.TestCase):
+
+ def _callFUT(self, obj, is_mapping):
+ from BTrees.check import crack_btree
+ return crack_btree(obj, is_mapping)
+
+ def test_w_empty_tree(self):
+ from BTrees.check import BTREE_EMPTY
+ class Empty(object):
+ def __getstate__(self):
+ return None
+ kind, keys, kids = self._callFUT(Empty(), True)
+ self.assertEqual(kind, BTREE_EMPTY)
+ self.assertEqual(keys, [])
+ self.assertEqual(kids, [])
+
+ def test_w_degenerate_tree(self):
+ from BTrees.check import BTREE_ONE
+ class Degenerate(object):
+ def __getstate__(self):
+ return ((('a', 1, 'b', 2),),)
+ kind, keys, kids = self._callFUT(Degenerate(), True)
+ self.assertEqual(kind, BTREE_ONE)
+ self.assertEqual(keys, ('a', 1, 'b', 2))
+ self.assertEqual(kids, None)
+
+ def test_w_normal_tree(self):
+ from BTrees.check import BTREE_NORMAL
+ first_bucket = [object()] * 8
+ second_bucket = [object()] * 8
+ class Normal(object):
+ def __getstate__(self):
+ return ((first_bucket, 'b', second_bucket), first_bucket)
+ kind, keys, kids = self._callFUT(Normal(), True)
+ self.assertEqual(kind, BTREE_NORMAL)
+ self.assertEqual(keys, ['b'])
+ self.assertEqual(kids, [first_bucket, second_bucket])
+
+
+class Test_crack_bucket(unittest.TestCase):
+
+ def _callFUT(self, obj, is_mapping):
+ from BTrees.check import crack_bucket
+ return crack_bucket(obj, is_mapping)
+
+ def test_w_empty_set(self):
+ class EmptySet(object):
+ def __getstate__(self):
+ return ([],)
+ keys, values = self._callFUT(EmptySet(), False)
+ self.assertEqual(keys, [])
+ self.assertEqual(values, [])
+
+ def test_w_non_empty_set(self):
+ class NonEmptySet(object):
+ def __getstate__(self):
+ return (['a', 'b', 'c'],)
+ keys, values = self._callFUT(NonEmptySet(), False)
+ self.assertEqual(keys, ['a', 'b', 'c'])
+ self.assertEqual(values, [])
+
+ def test_w_empty_mapping(self):
+ class EmptyMapping(object):
+ def __getstate__(self):
+ return ([], object())
+ keys, values = self._callFUT(EmptyMapping(), True)
+ self.assertEqual(keys, [])
+ self.assertEqual(values, [])
+
+ def test_w_non_empty_mapping(self):
+ class NonEmptyMapping(object):
+ def __getstate__(self):
+ return (['a', 1, 'b', 2, 'c', 3], object())
+ keys, values = self._callFUT(NonEmptyMapping(), True)
+ self.assertEqual(keys, ['a', 'b', 'c'])
+ self.assertEqual(values, [1, 2, 3])
+
+
+class Test_type_and_adr(unittest.TestCase):
+
+ def _callFUT(self, obj):
+ from BTrees.check import type_and_adr
+ return type_and_adr(obj)
+
+ def test_type_and_adr_w_oid(self):
+ from BTrees.utils import oid_repr
+ class WithOid(object):
+ _p_oid = 'DEADBEEF'
+ t_and_a = self._callFUT(WithOid())
+ self.assertTrue(t_and_a.startswith('WithOid (0x'))
+ self.assertTrue(t_and_a.endswith('oid=%s)' % oid_repr('DEADBEEF')))
+
+ def test_type_and_adr_wo_oid(self):
+ class WithoutOid(object):
+ pass
+ t_and_a = self._callFUT(WithoutOid())
+ self.assertTrue(t_and_a.startswith('WithoutOid (0x'))
+ self.assertTrue(t_and_a.endswith('oid=None)'))
+
+
+class WalkerTests(unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.check import Walker
+ return Walker
+
+ def _makeOne(self, obj):
+ return self._getTargetClass()(obj)
+
+ def test_visit_btree_abstract(self):
+ walker = self._makeOne(object())
+ obj = object()
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ self.assertRaises(NotImplementedError, walker.visit_btree,
+ obj, path, parent, is_mapping, keys, kids, lo, hi)
+
+ def test_visit_bucket_abstract(self):
+ walker = self._makeOne(object())
+ obj = object()
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ self.assertRaises(NotImplementedError, walker.visit_bucket,
+ obj, path, parent, is_mapping, keys, kids, lo, hi)
+
+ def test_walk_w_empty_bucket(self):
+ from BTrees.OOBTree import OOBucket
+ obj = OOBucket()
+ walker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ self.assertRaises(NotImplementedError, walker.walk)
+
+ def test_walk_w_empty_btree(self):
+ from BTrees.OOBTree import OOBTree
+ obj = OOBTree()
+ walker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ self.assertRaises(NotImplementedError, walker.walk)
+
+ def test_walk_w_degenerate_btree(self):
+ from BTrees.OOBTree import OOBTree
+ obj = OOBTree()
+ obj['a'] = 1
+ walker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ self.assertRaises(NotImplementedError, walker.walk)
+
+ def test_walk_w_normal_btree(self):
+ from BTrees.IIBTree import IIBTree
+ obj = IIBTree()
+ for i in range(1000):
+ obj[i] = i
+ walker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ self.assertRaises(NotImplementedError, walker.walk)
+
+
+class CheckerTests(unittest.TestCase):
+
+ assertRaises = _assertRaises
+
+ def _getTargetClass(self):
+ from BTrees.check import Checker
+ return Checker
+
+ def _makeOne(self, obj):
+ return self._getTargetClass()(obj)
+
+ def test_walk_w_empty_bucket(self):
+ from BTrees.OOBTree import OOBucket
+ obj = OOBucket()
+ checker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ checker.check() #noraise
+
+ def test_walk_w_empty_btree(self):
+ obj = _makeTree(False)
+ checker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ checker.check() #noraise
+
+ def test_walk_w_degenerate_btree(self):
+ obj = _makeTree(False)
+ obj['a'] = 1
+ checker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ checker.check() #noraise
+
+ def test_walk_w_normal_btree(self):
+ obj = _makeTree(False)
+ checker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ checker.check() #noraise
+
+ def test_walk_w_key_too_large(self):
+ obj = _makeTree(True)
+ state = obj.__getstate__()
# Damage an invariant by dropping the BTree key to 14.
- s = self.state
- news = (s[0][0], 14, s[0][2]), s[1]
- self.t.__setstate__(news)
- self.t._check() # not caught
- try:
- # Expecting "... key %r >= upper bound %r at index %d"
- check(self.t)
- except AssertionError, detail:
- self.failUnless(str(detail).find(">= upper bound") > 0)
- else:
- self.fail("expected self.t_check() to catch the problem")
+ new_state = (state[0][0], 14, state[0][2]), state[1]
+ obj.__setstate__(new_state)
+ checker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ e = self.assertRaises(AssertionError, checker.check)
+ self.assertTrue(">= upper bound" in str(e))
- def testKeyTooSmall(self):
+ def test_walk_w_key_too_small(self):
+ obj = _makeTree(True)
+ state = obj.__getstate__()
# Damage an invariant by bumping the BTree key to 16.
- s = self.state
- news = (s[0][0], 16, s[0][2]), s[1]
- self.t.__setstate__(news)
- self.t._check() # not caught
- try:
- # Expecting "... key %r < lower bound %r at index %d"
- check(self.t)
- except AssertionError, detail:
- self.failUnless(str(detail).find("< lower bound") > 0)
- else:
- self.fail("expected self.t_check() to catch the problem")
+ new_state = (state[0][0], 16, state[0][2]), state[1]
+ obj.__setstate__(new_state)
+ checker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ e = self.assertRaises(AssertionError, checker.check)
+ self.assertTrue("< lower bound" in str(e))
- def testKeysSwapped(self):
- # Damage an invariant by swapping two key/value pairs.
- s = self.state
- # Looks like (state, first_bucket)
- # where state looks like (bucket0, 15, bucket1).
- (b0, num, b1), firstbucket = s
+ def test_walk_w_keys_swapped(self):
+ obj = _makeTree(True)
+ state = obj.__getstate__()
+ # Damage an invariant by bumping the BTree key to 16.
+ (b0, num, b1), firstbucket = state
self.assertEqual(b0[4], 8)
self.assertEqual(b0[5], 10)
b0state = b0.__getstate__()
@@ -83,14 +366,60 @@
self.assertEqual(pairs[11], 10)
newpairs = pairs[:8] + (5, 10, 4, 8) + pairs[12:]
b0.__setstate__((newpairs, nextbucket))
- self.t._check() # not caught
- try:
- check(self.t)
- except AssertionError, detail:
- self.failUnless(str(detail).find(
- "key 5 at index 4 >= key 4 at index 5") > 0)
- else:
- self.fail("expected self.t_check() to catch the problem")
+ checker = self._makeOne(obj)
+ path = '/'
+ parent = object()
+ is_mapping = True
+ keys = []
+ kids = []
+ lo = 0
+ hi = None
+ e = self.assertRaises(AssertionError, checker.check)
+ self.assertTrue("key 5 at index 4 >= key 4 at index 5" in str(e))
+
+class Test_check(unittest.TestCase):
+
+ def _callFUT(self, tree):
+ from BTrees.check import check
+ return check(tree)
+
+ def _makeOne(self):
+ from BTrees.OOBTree import OOBTree
+ tree = OOBTree()
+ for i in range(31):
+ tree[i] = 2*i
+ return tree
+
+ def test_normal(self):
+ from BTrees.OOBTree import OOBTree
+ tree = OOBTree()
+ for i in range(31):
+ tree[i] = 2*i
+ state = tree.__getstate__()
+ self.assertEqual(len(state), 2)
+ self.assertEqual(len(state[0]), 3)
+ self.assertEqual(state[0][1], 15)
+ self._callFUT(tree) #noraise
+
+
+def _makeTree(fill):
+ from BTrees.OOBTree import OOBTree
+ from BTrees.OOBTree import _BUCKET_SIZE
+ tree = OOBTree()
+ if fill:
+ for i in range(_BUCKET_SIZE + 1):
+ tree[i] = 2*i
+ return tree
+
+
def test_suite():
- return unittest.makeSuite(CheckTest)
+ return unittest.TestSuite((
+ unittest.makeSuite(Test_classify),
+ unittest.makeSuite(Test_crack_btree),
+ unittest.makeSuite(Test_crack_bucket),
+ unittest.makeSuite(Test_type_and_adr),
+ unittest.makeSuite(WalkerTests),
+ unittest.makeSuite(CheckerTests),
+ unittest.makeSuite(Test_check),
+ ))
Modified: BTrees/trunk/BTrees/tests/test_fsBTree.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_fsBTree.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/tests/test_fsBTree.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -11,26 +11,57 @@
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
-import doctest
import unittest
-def test_fsbucket_string_conversion():
- """
-fsBuckets have toString and fromString methods that can be used to
-get and set their state very efficiently:
- >>> from BTrees.fsBTree import fsBucket
- >>> b = fsBucket([(c*2, c*6) for c in 'abcdef'])
- >>> import pprint
- >>> b.toString()
- 'aabbccddeeffaaaaaabbbbbbccccccddddddeeeeeeffffff'
+class fsBucketTests(unittest.TestCase):
- >>> b2 = fsBucket().fromString(b.toString())
- >>> b.__getstate__() == b2.__getstate__()
- True
+ def _getTargetClass(self):
+ from BTrees.fsBTree import fsBucket
+ return fsBucket
- """
+ def _makeOne(self, *args, **kw):
+ return self._getTargetClass()(*args, **kw)
+ def test_MERGE_WEIGHT(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.MERGE_WEIGHT(42, 17), 42)
+
+ def test_toString(self):
+ bucket = self._makeOne([(c*2, c*6) for c in 'abcdef'])
+ self.assertEqual(bucket.toString(),
+ 'aabbccddeeffaaaaaabbbbbbccccccddddddeeeeeeffffff')
+
+ def test_fromString(self):
+ before = self._makeOne([(c*2, c*6) for c in 'abcdef'])
+ after = before.fromString(before.toString())
+ self.assertEqual(before.__getstate__(), after.__getstate__())
+
+ def test_fromString_empty(self):
+ before = self._makeOne([(c*2, c*6) for c in 'abcdef'])
+ after = before.fromString('')
+ self.assertEqual(after.__getstate__(), ((),))
+
+ def test_fromString_invalid(self):
+ bucket = self._makeOne([(c*2, c*6) for c in 'abcdef'])
+ self.assertRaises(ValueError, bucket.fromString, 'xxx')
+
+
+class fsBTreeTests(unittest.TestCase):
+
+ def _getTargetClass(self):
+ from BTrees.fsBTree import fsBTree
+ return fsBTree
+
+ def _makeOne(self, *args, **kw):
+ return self._getTargetClass()(*args, **kw)
+
+ def test_MERGE_WEIGHT(self):
+ bucket = self._makeOne()
+ self.assertEqual(bucket.MERGE_WEIGHT(42, 17), 42)
+
+
def test_suite():
- return doctest.DocTestSuite()
-
+ return unittest.TestSuite((
+ unittest.makeSuite(fsBucketTests),
+ ))
Copied: BTrees/trunk/BTrees/tests/test_utils.py (from rev 128532, BTrees/branches/pure_python/BTrees/tests/test_utils.py)
===================================================================
--- BTrees/trunk/BTrees/tests/test_utils.py (rev 0)
+++ BTrees/trunk/BTrees/tests/test_utils.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
+import unittest
+
+
+class Test_non_negative(unittest.TestCase):
+
+ def _callFUT(self, int_val):
+ from BTrees.utils import non_negative
+ return non_negative(int_val)
+
+ def test_w_big_negative(self):
+ import sys
+ self.assertEqual(self._callFUT(-sys.maxint), 1)
+
+ def test_w_negative(self):
+ import sys
+ self.assertEqual(self._callFUT(-1), sys.maxint)
+
+ def test_w_zero(self):
+ self.assertEqual(self._callFUT(0), 0)
+
+ def test_w_positive(self):
+ self.assertEqual(self._callFUT(1), 1)
+
+ def test_w_big_positive(self):
+ import sys
+ self.assertEqual(self._callFUT(sys.maxint), sys.maxint)
+
+
+class Test_oid_repr(unittest.TestCase):
+
+ def _callFUT(self, oid):
+ from BTrees.utils import oid_repr
+ return oid_repr(oid)
+
+ def test_w_non_strings(self):
+ self.assertEqual(self._callFUT(None), repr(None))
+ self.assertEqual(self._callFUT(()), repr(()))
+ self.assertEqual(self._callFUT([]), repr([]))
+ self.assertEqual(self._callFUT({}), repr({}))
+ self.assertEqual(self._callFUT(0), repr(0))
+
+ def test_w_short_strings(self):
+ for length in range(8):
+ faux = 'x' * length
+ self.assertEqual(self._callFUT(faux), repr(faux))
+
+ def test_w_long_strings(self):
+ for length in range(9, 1024):
+ faux = 'x' * length
+ self.assertEqual(self._callFUT(faux), repr(faux))
+
+ def test_w_zero(self):
+ self.assertEqual(self._callFUT('\0\0\0\0\0\0\0\0'), '0x00')
+
+ def test_w_one(self):
+ self.assertEqual(self._callFUT('\0\0\0\0\0\0\0\1'), '0x01')
+
+ def test_w_even_length(self):
+ self.assertEqual(self._callFUT('\0\0\0\0\0\0\xAB\xC4'), '0xabc4')
+
+ def test_w_odd_length(self):
+ self.assertEqual(self._callFUT('\0\0\0\0\0\0\x0D\xEF'), '0x0def')
+
+
+def test_suite():
+ return unittest.TestSuite((
+ unittest.makeSuite(Test_non_negative),
+ unittest.makeSuite(Test_oid_repr),
+ ))
Modified: BTrees/trunk/BTrees/utils.py
===================================================================
--- BTrees/trunk/BTrees/utils.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/BTrees/utils.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -1,18 +1,31 @@
+##############################################################################
+#
+# Copyright (c) 2001-2012 Zope Foundation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE
+#
+##############################################################################
# Copied from ZODB/utils.py
from binascii import hexlify
-from struct import calcsize
-_ADDRESS_MASK = 256 ** calcsize('P')
+def non_negative(int_val):
+ if int_val < 0:
+ # Coerce to non-negative.
+ int_val &= 0x7FFFFFFFFFFFFFFF
+ return int_val
-def positive_id(obj):
+
+def positive_id(obj): #pragma NO COVER
"""Return id(obj) as a non-negative integer."""
+ return non_negative(id(obj))
- result = id(obj)
- if result < 0:
- result += _ADDRESS_MASK
- assert result > 0
- return result
def oid_repr(oid):
if isinstance(oid, str) and len(oid) == 8:
Modified: BTrees/trunk/CHANGES.txt
===================================================================
--- BTrees/trunk/CHANGES.txt 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/CHANGES.txt 2012-12-10 19:38:15 UTC (rev 128563)
@@ -5,8 +5,12 @@
4.0.2 (unreleased)
------------------
+- Python reference implementations now tested separately from the C
+ verions on all platforms.
+- 100% unit test coverage.
+
4.0.1 (2012-10-21)
------------------
Modified: BTrees/trunk/setup.py
===================================================================
--- BTrees/trunk/setup.py 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/setup.py 2012-12-10 19:38:15 UTC (rev 128563)
@@ -93,13 +93,14 @@
return Extension(name, sources, **kwargs)
py_impl = getattr(platform, 'python_implementation', lambda: None)
+pure_python = os.environ.get('PURE_PYTHON', False)
is_pypy = py_impl() == 'PyPy'
is_jython = 'java' in sys.platform
# Jython cannot build the C optimizations, while on PyPy they are
# anti-optimizations (the C extension compatibility layer is known-slow,
# and defeats JIT opportunities).
-if is_pypy or is_jython or sys.version_info[0] > 2:
+if pure_python or is_pypy or is_jython or sys.version_info[0] > 2:
ext_modules = []
else:
@@ -125,7 +126,7 @@
#'Programming Language :: Python :: 3',
#'Programming Language :: Python :: 3.2',
"Programming Language :: Python :: Implementation :: CPython",
- #"Programming Language :: Python :: Implementation :: PyPy",
+ "Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Database",
"Topic :: Software Development :: Libraries :: Python Modules",
"Operating System :: Microsoft :: Windows",
@@ -143,7 +144,7 @@
extras_require = {
'test': TESTS_REQUIRE,
'ZODB': ['ZODB3'],
- 'testing': ['nose', 'coverage'],
+ 'testing': TESTS_REQUIRE + ['nose', 'coverage'],
'docs': ['Sphinx', 'repoze.sphinx.autointerface'],
},
test_suite="BTrees.tests",
Modified: BTrees/trunk/tox.ini
===================================================================
--- BTrees/trunk/tox.ini 2012-12-10 18:46:07 UTC (rev 128562)
+++ BTrees/trunk/tox.ini 2012-12-10 19:38:15 UTC (rev 128563)
@@ -3,7 +3,7 @@
# Jython support pending 2.7 support, due 2012-07-15 or so. See:
# http://fwierzbicki.blogspot.com/2012/03/adconion-to-fund-jython-27.html
# py26,py27,py32,jython,pypy,coverage,docs
- py26,py27,w_zodb,coverage,docs
+ py26,py27,pypy,w_zodb,coverage,docs
[testenv]
deps =
@@ -35,7 +35,7 @@
basepython =
python2.6
commands =
- nosetests --with-xunit --with-xcoverage
+ nosetests --with-xunit --with-xcoverage --cover-package=BTrees
deps =
zope.interface
persistent
More information about the checkins
mailing list