Commit f70f5c92 authored by Tres Seaver's avatar Tres Seaver

Merge 'BTrees-pure_python' branch.

parents aec0aa5d 81e6c4fe
##############################################################################
#
# 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)
##############################################################################
#
# 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)
##############################################################################
#
# 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)
......@@ -511,7 +511,9 @@ try:
from ZODB.POSException import BTreesConflictError
except ImportError:
class BTreesConflictError(ValueError):
pass
@property
def reason(self):
return self.args[-1]
###############################################################
# IMPORTANT NOTE
......
##############################################################################
#
# 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)
##############################################################################
#
# 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)
##############################################################################
#
# 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)
......@@ -28,8 +28,9 @@ class Length(persistent.Persistent):
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):
......
##############################################################################
#
# 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)
##############################################################################
#
# 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)
##############################################################################
#
# 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)
##############################################################################
#
# 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
......@@ -32,15 +32,24 @@ addresses and/or object identity (the synthesized bucket has an address
that doesn't exist in the actual BTree).
"""
from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
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.OLBTree import OLBTree, OLBucket, OLSet, OLTreeSet
from BTrees.LOBTree import LOBTree, LOBucket, LOSet, LOTreeSet
from BTrees.LLBTree import LLBTree, LLBucket, LLSet, LLTreeSet
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.OIBTree import OIBTreePy, OIBucketPy, OISetPy, OITreeSetPy
from BTrees.OLBTree import OLBTree, OLBucket, OLSet, OLTreeSet
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 @@ for kv in ('OO',
('Set', (TYPE_BUCKET, False)),
):
_type2kind[globals()[kv+name]] = kind
py = kv + name + 'Py'
if py in globals():
_type2kind[globals()[py]] = kind
# Return pair
#
......@@ -114,7 +126,14 @@ for kv in ('OO',
'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__()
......@@ -349,7 +368,7 @@ class Checker(Walker):
".".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 @@ def check(btree):
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()
##############################################################################
#
# 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)
##############################################################################
#
# 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
......@@ -13,1227 +13,7 @@
##############################################################################
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
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()
from BTrees.tests.common import permutations
class DegenerateBTree(unittest.TestCase):
......@@ -1407,8 +187,10 @@ class DegenerateBTree(unittest.TestCase):
# 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 @@ class ToBeDeleted(object):
def __hash__(self):
return hash(self.id)
class BugFixes(unittest.TestCase):
# Collector 1843. Error returns were effectively ignored in
......@@ -1596,461 +379,18 @@ class BugFixes(unittest.TestCase):
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,32 +403,6 @@ class TestCmpError(unittest.TestCase):
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):
......@@ -2143,6 +457,7 @@ class FamilyTest(unittest.TestCase):
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 @@ class FamilyTest(unittest.TestCase):
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),
))
......@@ -13,493 +13,12 @@
##############################################################################
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 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
class NastyConfictFunctionalTests(ConflictTestBase, unittest.TestCase):
# FUNCTESTS: Provoke various conflict scenarios using ZODB + transaction
def _getTargetClass(self):
from BTrees.OOBTree import OOBTree
......@@ -1024,55 +543,7 @@ class NastyConfictFunctionalTests(Base, unittest.TestCase):
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
##############################################################################
#
# 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),
))
##############################################################################
#
# 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),
))
##############################################################################
#
# 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),
))
##############################################################################
#
# 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),
))
##############################################################################
#
# 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),
))
##############################################################################
#
# 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),
))
##############################################################################
#
# 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),
))
......@@ -11,40 +11,79 @@
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""\
Test for BTrees.Length module.
"""
__docformat__ = "reStructuredText"
import BTrees.Length
import copy
import sys
import unittest
_marker = object()
class LengthTestCase(unittest.TestCase):
def test_length_overflows_to_long(self):
length = BTrees.Length.Length(sys.maxint)
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_length_underflows_to_long(self):
def test_change_underflows_to_long(self):
import sys
minint = (-sys.maxint) - 1
length = BTrees.Length.Length(minint)
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_copy(self):
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
length = BTrees.Length.Length()
import copy
length = self._makeOne()
other = copy.copy(length)
self.assertEqual(other(), 0)
......
##############################################################################
#
# 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),
))
##############################################################################
#
# 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),
))
##############################################################################
#
# 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),
))
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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
def testKeyTooLarge(self):
class Test_classify(unittest.TestCase):
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")
def testKeyTooSmall(self):
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 test_walk_w_key_too_small(self):
obj = _makeTree(True)
state = obj.__getstate__()
# Damage an invariant by bumping the BTree key to 16.
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 test_walk_w_keys_swapped(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")
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
(b0, num, b1), firstbucket = state
self.assertEqual(b0[4], 8)
self.assertEqual(b0[5], 10)
b0state = b0.__getstate__()
......@@ -83,14 +366,60 @@ class CheckTest(unittest.TestCase):
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),
))
......@@ -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')
def test_suite():
return doctest.DocTestSuite()
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 unittest.TestSuite((
unittest.makeSuite(fsBucketTests),
))
##############################################################################
#
# 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),
))
##############################################################################
#
# 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:
......
......@@ -5,6 +5,10 @@
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)
......
......@@ -93,13 +93,14 @@ def BTreeExtension(family):
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 @@ setup(name='BTrees',
#'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 @@ setup(name='BTrees',
extras_require = {
'test': TESTS_REQUIRE,
'ZODB': ['ZODB3'],
'testing': ['nose', 'coverage'],
'testing': TESTS_REQUIRE + ['nose', 'coverage'],
'docs': ['Sphinx', 'repoze.sphinx.autointerface'],
},
test_suite="BTrees.tests",
......
......@@ -3,7 +3,7 @@ envlist =
# 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 @@ deps =
basepython =
python2.6
commands =
nosetests --with-xunit --with-xcoverage
nosetests --with-xunit --with-xcoverage --cover-package=BTrees
deps =
zope.interface
persistent
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment