Commit aef4ddf2 authored by Tim Peters's avatar Tim Peters

Merge rev 28586 from Zope3/branches/jim-index-restructure-2004-12.

This adds a new IFBTree type, intended for use in indices.  Still
needs NEWS, still needs docs, and there are a pile of legitimate
compiler warnings on Windows that need fixing.
parent 60f7fe4b
...@@ -69,7 +69,7 @@ base_btrees_depends = [ ...@@ -69,7 +69,7 @@ base_btrees_depends = [
"src/persistent/cPersistence.h", "src/persistent/cPersistence.h",
] ]
_flavors = {"O": "object", "I": "int"} _flavors = {"O": "object", "I": "int", "F": "float"}
KEY_H = "src/BTrees/%skeymacros.h" KEY_H = "src/BTrees/%skeymacros.h"
VALUE_H = "src/BTrees/%svaluemacros.h" VALUE_H = "src/BTrees/%svaluemacros.h"
...@@ -87,7 +87,8 @@ def BTreeExtension(flavor): ...@@ -87,7 +87,8 @@ def BTreeExtension(flavor):
kwargs["define_macros"] = [('EXCLUDE_INTSET_SUPPORT', None)] kwargs["define_macros"] = [('EXCLUDE_INTSET_SUPPORT', None)]
return Extension(name, sources, **kwargs) return Extension(name, sources, **kwargs)
exts = [BTreeExtension(flavor) for flavor in ["OO", "IO", "OI", "II", "fs"]] exts = [BTreeExtension(flavor)
for flavor in ("OO", "IO", "OI", "II", "IF", "fs")]
cPersistence = Extension(name = 'persistent.cPersistence', cPersistence = Extension(name = 'persistent.cPersistence',
include_dirs = include, include_dirs = include,
......
##############################################################################
#
# Copyright (c) 2001, 2002 Zope Corporation 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
#
##############################################################################
# hack to overcome dynamic-linking headache.
from _IFBTree import *
...@@ -40,6 +40,25 @@ ...@@ -40,6 +40,25 @@
depends-on sorters.c depends-on sorters.c
</extension> </extension>
<extension _IFBTree>
source _IFBTree.c
# Specialization:
depends-on intkeymacros.h
depends-on floatvaluemacros.h
# Common btree includes:
depends-on BTreeItemsTemplate.c
depends-on BTreeModuleTemplate.c
depends-on BTreeTemplate.c
depends-on BucketTemplate.c
depends-on MergeTemplate.c
depends-on SetOpTemplate.c
depends-on SetTemplate.c
depends-on TreeSetTemplate.c
depends-on sorters.c
</extension>
<extension _IOBTree> <extension _IOBTree>
source _IOBTree.c source _IOBTree.c
......
...@@ -143,7 +143,14 @@ initSetIteration(SetIteration *i, PyObject *s, int useValues) ...@@ -143,7 +143,14 @@ initSetIteration(SetIteration *i, PyObject *s, int useValues)
#endif #endif
static int static int
copyRemaining(Bucket *r, SetIteration *i, int merge, int w) copyRemaining(Bucket *r, SetIteration *i, int merge,
/* See comment # 42 */
#ifdef MERGE
VALUE_TYPE w)
#else
int w)
#endif
{ {
while (i->position >= 0) while (i->position >= 0)
{ {
...@@ -193,8 +200,25 @@ copyRemaining(Bucket *r, SetIteration *i, int merge, int w) ...@@ -193,8 +200,25 @@ copyRemaining(Bucket *r, SetIteration *i, int merge, int w)
static PyObject * static PyObject *
set_operation(PyObject *s1, PyObject *s2, set_operation(PyObject *s1, PyObject *s2,
int usevalues1, int usevalues2, int usevalues1, int usevalues2,
/* Comment # 42
The following ifdef works around a template/type problem
Weights are passed as integers. In particular, the weight passed by
difference is one. This works find in the int value and float value
cases but makes no sense in the object value case. In the object
value case, we don't do merging, so we don't use the weights, so it
doesn't matter what they are.
*/
#ifdef MERGE
VALUE_TYPE w1, VALUE_TYPE w2,
#else
int w1, int w2, int w1, int w2,
#endif
int c1, int c12, int c2) int c1, int c12, int c2)
{ {
Bucket *r=0; Bucket *r=0;
SetIteration i1 = {0,0,0}, i2 = {0,0,0}; SetIteration i1 = {0,0,0}, i2 = {0,0,0};
...@@ -214,9 +238,16 @@ set_operation(PyObject *s1, PyObject *s2, ...@@ -214,9 +238,16 @@ set_operation(PyObject *s1, PyObject *s2,
SetIteration t; SetIteration t;
int i; int i;
/* See comment # 42 above */
#ifdef MERGE
VALUE_TYPE v;
#else
int v;
#endif
t=i1; i1=i2; i2=t; t=i1; i1=i2; i2=t;
i=c1; c1=c2; c2=i; i=c1; c1=c2; c2=i;
i=w1; w1=w2; w2=i; v=w1; w1=w2; w2=v;
} }
#ifdef MERGE_DEFAULT #ifdef MERGE_DEFAULT
i1.value=MERGE_DEFAULT; i1.value=MERGE_DEFAULT;
...@@ -394,17 +425,20 @@ static PyObject * ...@@ -394,17 +425,20 @@ static PyObject *
wunion_m(PyObject *ignored, PyObject *args) wunion_m(PyObject *ignored, PyObject *args)
{ {
PyObject *o1, *o2; PyObject *o1, *o2;
int w1 = 1, w2 = 1; VALUE_TYPE w1 = 1, w2 = 1;
UNLESS(PyArg_ParseTuple(args, "OO|ii", &o1, &o2, &w1, &w2)) return NULL; UNLESS(PyArg_ParseTuple(args, "OO|" VALUE_PARSE VALUE_PARSE,
&o1, &o2, &w1, &w2)
) return NULL;
if (o1 == Py_None) if (o1 == Py_None)
return Py_BuildValue("iO", (o2 == Py_None ? 0 : w2), o2); return Py_BuildValue(VALUE_PARSE "O", (o2 == Py_None ? 0 : w2), o2);
else if (o2 == Py_None) else if (o2 == Py_None)
return Py_BuildValue("iO", w1, o1); return Py_BuildValue(VALUE_PARSE "O", w1, o1);
o1 = set_operation(o1, o2, 1, 1, w1, w2, 1, 1, 1); o1 = set_operation(o1, o2, 1, 1, w1, w2, 1, 1, 1);
if (o1) ASSIGN(o1, Py_BuildValue("iO", 1, o1)); if (o1)
ASSIGN(o1, Py_BuildValue(VALUE_PARSE "O", (VALUE_TYPE)1, o1));
return o1; return o1;
} }
...@@ -413,18 +447,20 @@ static PyObject * ...@@ -413,18 +447,20 @@ static PyObject *
wintersection_m(PyObject *ignored, PyObject *args) wintersection_m(PyObject *ignored, PyObject *args)
{ {
PyObject *o1, *o2; PyObject *o1, *o2;
int w1 = 1, w2 = 1; VALUE_TYPE w1 = 1, w2 = 1;
UNLESS(PyArg_ParseTuple(args, "OO|ii", &o1, &o2, &w1, &w2)) return NULL; UNLESS(PyArg_ParseTuple(args, "OO|" VALUE_PARSE VALUE_PARSE,
&o1, &o2, &w1, &w2)
) return NULL;
if (o1 == Py_None) if (o1 == Py_None)
return Py_BuildValue("iO", (o2 == Py_None ? 0 : w2), o2); return Py_BuildValue(VALUE_PARSE "O", (o2 == Py_None ? 0 : w2), o2);
else if (o2 == Py_None) else if (o2 == Py_None)
return Py_BuildValue("iO", w1, o1); return Py_BuildValue(VALUE_PARSE "O", w1, o1);
o1 = set_operation(o1, o2, 1, 1, w1, w2, 0, 1, 0); o1 = set_operation(o1, o2, 1, 1, w1, w2, 0, 1, 0);
if (o1) if (o1)
ASSIGN(o1, Py_BuildValue("iO", ASSIGN(o1, Py_BuildValue(VALUE_PARSE "O",
((o1->ob_type == (PyTypeObject*)(&SetType)) ? w2+w1 : 1), ((o1->ob_type == (PyTypeObject*)(&SetType)) ? w2+w1 : 1),
o1)); o1));
......
/*############################################################################
#
# Copyright (c) 2004 Zope Corporation 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.
#
############################################################################*/
#define MASTER_ID "$Id$\n"
/* IIBTree - int key, int value BTree
Implements a collection using int type keys
and int type values
*/
/* Setup template macros */
#define PERSISTENT
#define MOD_NAME_PREFIX "IF"
#define INITMODULE init_IFBTree
#define DEFAULT_MAX_BUCKET_SIZE 120
#define DEFAULT_MAX_BTREE_SIZE 500
#include "intkeymacros.h"
#include "floatvaluemacros.h"
#include "BTreeModuleTemplate.c"
...@@ -38,6 +38,7 @@ from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet ...@@ -38,6 +38,7 @@ from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
from BTrees.IFBTree import IFBTree, IFBucket, IFSet, IFTreeSet
from ZODB.utils import positive_id, oid_repr from ZODB.utils import positive_id, oid_repr
...@@ -45,21 +46,25 @@ TYPE_UNKNOWN, TYPE_BTREE, TYPE_BUCKET = range(3) ...@@ -45,21 +46,25 @@ TYPE_UNKNOWN, TYPE_BTREE, TYPE_BUCKET = range(3)
_type2kind = {IOBTree: (TYPE_BTREE, True), _type2kind = {IOBTree: (TYPE_BTREE, True),
IIBTree: (TYPE_BTREE, True), IIBTree: (TYPE_BTREE, True),
IFBTree: (TYPE_BTREE, True),
OIBTree: (TYPE_BTREE, True), OIBTree: (TYPE_BTREE, True),
OOBTree: (TYPE_BTREE, True), OOBTree: (TYPE_BTREE, True),
IOBucket: (TYPE_BUCKET, True), IOBucket: (TYPE_BUCKET, True),
IIBucket: (TYPE_BUCKET, True), IIBucket: (TYPE_BUCKET, True),
IFBucket: (TYPE_BUCKET, True),
OIBucket: (TYPE_BUCKET, True), OIBucket: (TYPE_BUCKET, True),
OOBucket: (TYPE_BUCKET, True), OOBucket: (TYPE_BUCKET, True),
IOTreeSet: (TYPE_BTREE, False), IOTreeSet: (TYPE_BTREE, False),
IITreeSet: (TYPE_BTREE, False), IITreeSet: (TYPE_BTREE, False),
IFTreeSet: (TYPE_BTREE, False),
OITreeSet: (TYPE_BTREE, False), OITreeSet: (TYPE_BTREE, False),
OOTreeSet: (TYPE_BTREE, False), OOTreeSet: (TYPE_BTREE, False),
IOSet: (TYPE_BUCKET, False), IOSet: (TYPE_BUCKET, False),
IISet: (TYPE_BUCKET, False), IISet: (TYPE_BUCKET, False),
IFSet: (TYPE_BUCKET, False),
OISet: (TYPE_BUCKET, False), OISet: (TYPE_BUCKET, False),
OOSet: (TYPE_BUCKET, False), OOSet: (TYPE_BUCKET, False),
} }
...@@ -118,6 +123,9 @@ _btree2bucket = {IOBTree: IOBucket, ...@@ -118,6 +123,9 @@ _btree2bucket = {IOBTree: IOBucket,
IIBTree: IIBucket, IIBTree: IIBucket,
IITreeSet: IISet, IITreeSet: IISet,
IFBTree: IFBucket,
IFTreeSet: IFSet,
OIBTree: OIBucket, OIBTree: OIBucket,
OITreeSet: OISet, OITreeSet: OISet,
......
#define VALUEMACROS_H "$Id$\n"
#define VALUE_TYPE float
#undef VALUE_TYPE_IS_PYOBJECT
#define TEST_VALUE(K, T) (((K) < (T)) ? -1 : (((K) > (T)) ? 1: 0))
#define VALUE_SAME(VALUE, TARGET) ( (VALUE) == (TARGET) )
#define DECLARE_VALUE(NAME) VALUE_TYPE NAME
#define VALUE_PARSE "f"
#define DECREF_VALUE(k)
#define INCREF_VALUE(k)
#define COPY_VALUE(V, E) (V=(E))
#define COPY_VALUE_TO_OBJECT(O, K) O=PyFloat_FromDouble(K)
#define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
if (PyFloat_Check(ARG)) TARGET = PyFloat_AsDouble(ARG); \
else if (PyInt_Check(ARG)) TARGET = PyInt_AsLong(ARG); \
else { \
PyErr_SetString(PyExc_TypeError, "expected float or int value"); \
(STATUS)=0; (TARGET)=0; }
#define NORMALIZE_VALUE(V, MIN) ((MIN) > 0) ? ((V)/=(MIN)) : 0
#define MERGE_DEFAULT 1.0f
#define MERGE(O1, w1, O2, w2) ((O1)*(w1)+(O2)*(w2))
#define MERGE_WEIGHT(O, w) ((O)*(w))
...@@ -17,6 +17,7 @@ from unittest import TestCase, TestSuite, TextTestRunner, makeSuite ...@@ -17,6 +17,7 @@ from unittest import TestCase, TestSuite, TextTestRunner, makeSuite
from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
from BTrees.IFBTree import IFBTree, IFBucket, IFSet, IFTreeSet
from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
from BTrees.check import check from BTrees.check import check
...@@ -1126,6 +1127,39 @@ class TestIIBTrees(TestCase): ...@@ -1126,6 +1127,39 @@ class TestIIBTrees(TestCase):
def _noneraisesvalue(self): def _noneraisesvalue(self):
self.t[1] = None self.t[1] = None
class TestIFBTrees(TestCase):
def setUp(self):
self.t = 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.t[1] = 1
self.t[1] = 1.0
def _stringraiseskey(self):
self.t['c'] = 1
def _floatraiseskey(self):
self.t[2.5] = 1
def _noneraiseskey(self):
self.t[None] = 1
def _stringraisesvalue(self):
self.t[1] = 'c'
def _floatraisesvalue(self):
self.t[1] = 1.4
def _noneraisesvalue(self):
self.t[1] = None
class TestIOSets(TestCase): class TestIOSets(TestCase):
def setUp(self): def setUp(self):
self.t = IOSet() self.t = IOSet()
...@@ -1315,6 +1349,9 @@ class DegenerateBTree(TestCase): ...@@ -1315,6 +1349,9 @@ class DegenerateBTree(TestCase):
class IIBucketTest(MappingBase): class IIBucketTest(MappingBase):
def setUp(self): def setUp(self):
self.t = IIBucket() self.t = IIBucket()
class IFBucketTest(MappingBase):
def setUp(self):
self.t = IFBucket()
class IOBucketTest(MappingBase): class IOBucketTest(MappingBase):
def setUp(self): def setUp(self):
self.t = IOBucket() self.t = IOBucket()
...@@ -1328,6 +1365,9 @@ class OOBucketTest(MappingBase): ...@@ -1328,6 +1365,9 @@ class OOBucketTest(MappingBase):
class IITreeSetTest(NormalSetTests): class IITreeSetTest(NormalSetTests):
def setUp(self): def setUp(self):
self.t = IITreeSet() self.t = IITreeSet()
class IFTreeSetTest(NormalSetTests):
def setUp(self):
self.t = IFTreeSet()
class IOTreeSetTest(NormalSetTests): class IOTreeSetTest(NormalSetTests):
def setUp(self): def setUp(self):
self.t = IOTreeSet() self.t = IOTreeSet()
...@@ -1341,6 +1381,9 @@ class OOTreeSetTest(NormalSetTests): ...@@ -1341,6 +1381,9 @@ class OOTreeSetTest(NormalSetTests):
class IISetTest(ExtendedSetTests): class IISetTest(ExtendedSetTests):
def setUp(self): def setUp(self):
self.t = IISet() self.t = IISet()
class IFSetTest(ExtendedSetTests):
def setUp(self):
self.t = IFSet()
class IOSetTest(ExtendedSetTests): class IOSetTest(ExtendedSetTests):
def setUp(self): def setUp(self):
self.t = IOSet() self.t = IOSet()
...@@ -1354,6 +1397,9 @@ class OOSetTest(ExtendedSetTests): ...@@ -1354,6 +1397,9 @@ class OOSetTest(ExtendedSetTests):
class IIBTreeTest(BTreeTests): class IIBTreeTest(BTreeTests):
def setUp(self): def setUp(self):
self.t = IIBTree() self.t = IIBTree()
class IFBTreeTest(BTreeTests):
def setUp(self):
self.t = IFBTree()
class IOBTreeTest(BTreeTests): class IOBTreeTest(BTreeTests):
def setUp(self): def setUp(self):
self.t = IOBTree() self.t = IOBTree()
...@@ -1385,14 +1431,17 @@ class TestCmpError(TestCase): ...@@ -1385,14 +1431,17 @@ class TestCmpError(TestCase):
def test_suite(): def test_suite():
s = TestSuite() s = TestSuite()
for klass in (IIBucketTest, IOBucketTest, OIBucketTest, OOBucketTest, for klass in (
IITreeSetTest, IOTreeSetTest, OITreeSetTest, OOTreeSetTest, IIBucketTest, IIBTreeTest, IISetTest, IITreeSetTest,
IISetTest, IOSetTest, OISetTest, OOSetTest, IFBucketTest, IFBTreeTest, IFSetTest, IFTreeSetTest,
IIBTreeTest, IOBTreeTest, OIBTreeTest, OOBTreeTest, IOBucketTest, IOBTreeTest, IOSetTest, IOTreeSetTest,
OOBucketTest, OOBTreeTest, OOSetTest, OOTreeSetTest,
OIBucketTest, OIBTreeTest, OISetTest, OITreeSetTest,
# Note: there is no TestOOBTrees. The next three are # Note: there is no TestOOBTrees. The next three are
# checking for assorted TypeErrors, and when both keys # checking for assorted TypeErrors, and when both keys
# and values oare objects (OO), there's nothing to test. # and values oare objects (OO), there's nothing to test.
TestIIBTrees, TestIOBTrees, TestOIBTrees, TestIIBTrees, TestIFBTrees, TestIOBTrees, TestOIBTrees,
TestIOSets, TestIOSets,
DegenerateBTree, DegenerateBTree,
TestCmpError): TestCmpError):
......
...@@ -17,6 +17,7 @@ from unittest import TestCase, TestSuite, makeSuite ...@@ -17,6 +17,7 @@ from unittest import TestCase, TestSuite, makeSuite
from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet from BTrees.OOBTree import OOBTree, OOBucket, OOSet, OOTreeSet
from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
from BTrees.IFBTree import IFBTree, IFBucket, IFSet, IFTreeSet
from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
import transaction import transaction
...@@ -345,6 +346,10 @@ class TestIIBTrees(BTreeTests, TestCase): ...@@ -345,6 +346,10 @@ class TestIIBTrees(BTreeTests, TestCase):
def setUp(self): def setUp(self):
self.t = IIBTree() self.t = IIBTree()
class TestIFBTrees(BTreeTests, TestCase):
def setUp(self):
self.t = IFBTree()
## Set tests ## Set tests
class TestIOSets(SetTests, TestCase): class TestIOSets(SetTests, TestCase):
...@@ -359,6 +364,10 @@ class TestIISets(SetTests, TestCase): ...@@ -359,6 +364,10 @@ class TestIISets(SetTests, TestCase):
def setUp(self): def setUp(self):
self.t = IISet() self.t = IISet()
class TestIFSets(SetTests, TestCase):
def setUp(self):
self.t = IFSet()
class TestOISets(SetTests, TestCase): class TestOISets(SetTests, TestCase):
def setUp(self): def setUp(self):
self.t = OISet() self.t = OISet()
...@@ -375,6 +384,10 @@ class TestIITreeSets(SetTests, TestCase): ...@@ -375,6 +384,10 @@ class TestIITreeSets(SetTests, TestCase):
def setUp(self): def setUp(self):
self.t = IITreeSet() self.t = IITreeSet()
class TestIFTreeSets(SetTests, TestCase):
def setUp(self):
self.t = IFTreeSet()
class TestOITreeSets(SetTests, TestCase): class TestOITreeSets(SetTests, TestCase):
def setUp(self): def setUp(self):
self.t = OITreeSet() self.t = OITreeSet()
...@@ -393,6 +406,10 @@ class TestIIBuckets(BucketTests, TestCase): ...@@ -393,6 +406,10 @@ class TestIIBuckets(BucketTests, TestCase):
def setUp(self): def setUp(self):
self.t = IIBucket() self.t = IIBucket()
class TestIFBuckets(BucketTests, TestCase):
def setUp(self):
self.t = IFBucket()
class TestOIBuckets(BucketTests, TestCase): class TestOIBuckets(BucketTests, TestCase):
def setUp(self): def setUp(self):
self.t = OIBucket() self.t = OIBucket()
...@@ -745,10 +762,12 @@ class NastyConfict(Base, TestCase): ...@@ -745,10 +762,12 @@ class NastyConfict(Base, TestCase):
def test_suite(): def test_suite():
suite = TestSuite() suite = TestSuite()
for k in (TestIOBTrees, TestOOBTrees, TestOIBTrees, TestIIBTrees, for k in (
TestIOSets, TestOOSets, TestOISets, TestIISets, TestIIBTrees, TestIISets, TestIITreeSets, TestIIBuckets,
TestIOTreeSets, TestOOTreeSets, TestOITreeSets, TestIITreeSets, TestIFBTrees, TestIFSets, TestIFTreeSets, TestIFBuckets,
TestIOBuckets, TestOOBuckets, TestOIBuckets, TestIIBuckets, TestIOBTrees, TestIOSets, TestIOTreeSets, TestIOBuckets,
TestOOBTrees, TestOOSets, TestOOTreeSets, TestOOBuckets,
TestOIBTrees, TestOISets, TestOITreeSets, TestOIBuckets,
NastyConfict): NastyConfict):
suite.addTest(makeSuite(k)) suite.addTest(makeSuite(k))
return suite return suite
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