[Checkins] SVN: BTrees/trunk/ Merge py3k branch.

Tres Seaver cvs-admin at zope.org
Mon Dec 17 17:08:59 UTC 2012


Log message for revision 128692:
  Merge py3k branch.

Changed:
  _U  BTrees/trunk/
  U   BTrees/trunk/.bzrignore
  U   BTrees/trunk/BTrees/BTreeItemsTemplate.c
  U   BTrees/trunk/BTrees/BTreeModuleTemplate.c
  U   BTrees/trunk/BTrees/BTreeTemplate.c
  U   BTrees/trunk/BTrees/BucketTemplate.c
  U   BTrees/trunk/BTrees/IFBTree.py
  U   BTrees/trunk/BTrees/IIBTree.py
  U   BTrees/trunk/BTrees/IOBTree.py
  U   BTrees/trunk/BTrees/LFBTree.py
  U   BTrees/trunk/BTrees/LLBTree.py
  U   BTrees/trunk/BTrees/LOBTree.py
  U   BTrees/trunk/BTrees/OIBTree.py
  U   BTrees/trunk/BTrees/OLBTree.py
  U   BTrees/trunk/BTrees/OOBTree.py
  U   BTrees/trunk/BTrees/SetTemplate.c
  U   BTrees/trunk/BTrees/TreeSetTemplate.c
  U   BTrees/trunk/BTrees/_IFBTree.c
  U   BTrees/trunk/BTrees/_IIBTree.c
  U   BTrees/trunk/BTrees/_IOBTree.c
  U   BTrees/trunk/BTrees/_LFBTree.c
  U   BTrees/trunk/BTrees/_LLBTree.c
  U   BTrees/trunk/BTrees/_LOBTree.c
  U   BTrees/trunk/BTrees/_OIBTree.c
  U   BTrees/trunk/BTrees/_OLBTree.c
  U   BTrees/trunk/BTrees/_OOBTree.c
  U   BTrees/trunk/BTrees/_base.py
  A   BTrees/trunk/BTrees/_compat.h
  A   BTrees/trunk/BTrees/_compat.py
  U   BTrees/trunk/BTrees/_fsBTree.c
  U   BTrees/trunk/BTrees/check.py
  U   BTrees/trunk/BTrees/floatvaluemacros.h
  U   BTrees/trunk/BTrees/fsBTree.py
  U   BTrees/trunk/BTrees/intkeymacros.h
  U   BTrees/trunk/BTrees/intvaluemacros.h
  U   BTrees/trunk/BTrees/objectkeymacros.h
  U   BTrees/trunk/BTrees/objectvaluemacros.h
  D   BTrees/trunk/BTrees/py24compat.h
  U   BTrees/trunk/BTrees/tests/common.py
  U   BTrees/trunk/BTrees/tests/testBTrees.py
  U   BTrees/trunk/BTrees/tests/testBTreesUnicode.py
  U   BTrees/trunk/BTrees/tests/testConflict.py
  U   BTrees/trunk/BTrees/tests/test_Length.py
  U   BTrees/trunk/BTrees/tests/test_OIBTree.py
  U   BTrees/trunk/BTrees/tests/test_OOBTree.py
  U   BTrees/trunk/BTrees/tests/test__base.py
  U   BTrees/trunk/BTrees/tests/test_btreesubclass.py
  U   BTrees/trunk/BTrees/tests/test_check.py
  D   BTrees/trunk/BTrees/tests/test_compare.py
  U   BTrees/trunk/BTrees/tests/test_fsBTree.py
  U   BTrees/trunk/BTrees/tests/test_utils.py
  U   BTrees/trunk/BTrees/utils.py
  U   BTrees/trunk/CHANGES.txt
  U   BTrees/trunk/setup.py
  U   BTrees/trunk/tox.ini

-=-

Property changes on: BTrees/trunk
___________________________________________________________________
Modified: svn:mergeinfo
   - /BTrees/branches/pure_python:128123-128130,128182-128183,128197-128212,128221-128238,128254-128268,128274-128280,128286-128295,128318-128320,128332-128334,128357-128363,128496-128532

   + /BTrees/branches/pure_python:128123-128130,128182-128183,128197-128212,128221-128238,128254-128268,128274-128280,128286-128295,128318-128320,128332-128334,128357-128363,128496-128532
/BTrees/branches/py3k:128564,128566-128579,128602-128620,128622,128657-128658,128666-128674,128687-128688

Modified: svk:merge
   - 62d5b8a3-27da-0310-9561-8e5933582275:/BTrees/branches/pure_python:128532

   + 62d5b8a3-27da-0310-9561-8e5933582275:/BTrees/branches/pure_python:128532
62d5b8a3-27da-0310-9561-8e5933582275:/BTrees/branches/py3k:128688


Modified: BTrees/trunk/.bzrignore
===================================================================
--- BTrees/trunk/.bzrignore	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/.bzrignore	2012-12-17 17:08:58 UTC (rev 128692)
@@ -6,3 +6,4 @@
 coverage.xml
 *.egg
 docs/_build
+__pycache__

Modified: BTrees/trunk/BTrees/BTreeItemsTemplate.c
===================================================================
--- BTrees/trunk/BTrees/BTreeItemsTemplate.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/BTreeItemsTemplate.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -41,16 +41,17 @@
  * a search finger weren't being used at all, but is still quadratic time
  * in the number of buckets in the slice.
  */
-typedef struct {
-  PyObject_HEAD
-  Bucket *firstbucket;		/* First bucket		          */
-  Bucket *currentbucket;	/* Current bucket (search finger) */
-  Bucket *lastbucket;		/* Last bucket		          */
-  int currentoffset;		/* Offset in currentbucket        */
-  int pseudoindex;		/* search finger index            */
-  int first;                    /* Start offset in firstbucket    */
-  int last;                     /* End offset in lastbucket       */
-  char kind;                    /* 'k', 'v', 'i'                  */
+typedef struct
+{
+    PyObject_HEAD
+    Bucket *firstbucket;    /* First bucket                    */
+    Bucket *currentbucket;  /* Current bucket (search finger) */
+    Bucket *lastbucket;     /* Last bucket                    */
+    int currentoffset;      /* Offset in currentbucket        */
+    int pseudoindex;        /* search finger index            */
+    int first;              /* Start offset in firstbucket    */
+    int last;               /* End offset in lastbucket       */
+    char kind;              /* 'k', 'v', 'i'                  */
 } BTreeItems;
 
 #define ITEMS(O)((BTreeItems*)(O))
@@ -63,10 +64,10 @@
 static void
 BTreeItems_dealloc(BTreeItems *self)
 {
-  Py_XDECREF(self->firstbucket);
-  Py_XDECREF(self->lastbucket);
-  Py_XDECREF(self->currentbucket);
-  PyObject_DEL(self);
+    Py_XDECREF(self->firstbucket);
+    Py_XDECREF(self->lastbucket);
+    Py_XDECREF(self->currentbucket);
+    PyObject_DEL(self);
 }
 
 static Py_ssize_t
@@ -77,33 +78,34 @@
 
     b = self->firstbucket;
     if (b == NULL)
-	return 0;
+        return 0;
 
     r = self->last + 1 - self->first;
 
     if (nonzero && r > 0)
-	/* Short-circuit if all we care about is nonempty */
-	return 1;
+    /* Short-circuit if all we care about is nonempty */
+        return 1;
 
     if (b == self->lastbucket)
-	return r;
+        return r;
 
     Py_INCREF(b);
     PER_USE_OR_RETURN(b, -1);
-    while ((next = b->next)) {
-	r += b->len;
-	if (nonzero && r > 0)
-	    /* Short-circuit if all we care about is nonempty */
-	    break;
+    while ((next = b->next))
+    {
+        r += b->len;
+        if (nonzero && r > 0)
+            /* Short-circuit if all we care about is nonempty */
+            break;
 
-	if (next == self->lastbucket)
-	    break; /* we already counted the last bucket */
+        if (next == self->lastbucket)
+            break; /* we already counted the last bucket */
 
-	Py_INCREF(next);
-	PER_UNUSE(b);
-	Py_DECREF(b);
-	b = next;
-	PER_USE_OR_RETURN(b, -1);
+        Py_INCREF(next);
+        PER_UNUSE(b);
+        Py_DECREF(b);
+        b = next;
+        PER_USE_OR_RETURN(b, -1);
     }
     PER_UNUSE(b);
     Py_DECREF(b);
@@ -114,7 +116,7 @@
 static Py_ssize_t
 BTreeItems_length(BTreeItems *self)
 {
-  return BTreeItems_length_or_nonzero(self, 0);
+    return BTreeItems_length_or_nonzero(self, 0);
 }
 
 /*
@@ -122,8 +124,8 @@
 **
 ** Find the ith position in the BTreeItems.
 **
-** Arguments:  	self	The BTree
-**		i	the index to seek to, in 0 .. len(self)-1, or in
+** Arguments:      self    The BTree
+**        i    the index to seek to, in 0 .. len(self)-1, or in
 **                      -len(self) .. -1, as for indexing a Python sequence.
 **
 **
@@ -141,10 +143,12 @@
     pseudoindex = self->pseudoindex;
     currentoffset = self->currentoffset;
     currentbucket = self->currentbucket;
-    if (currentbucket == NULL) goto no_match;
+    if (currentbucket == NULL)
+        goto no_match;
 
     delta = i - pseudoindex;
-    while (delta > 0) {         /* move right */
+    while (delta > 0) /* move right */
+    {
         int max;
         /* Want to move right delta positions; the most we can move right in
          * this bucket is currentbucket->len - currentoffset - 1 positions.
@@ -153,34 +157,41 @@
         max = currentbucket->len - currentoffset - 1;
         b = currentbucket->next;
         PER_UNUSE(currentbucket);
-        if (delta <= max) {
+        if (delta <= max)
+        {
             currentoffset += delta;
             pseudoindex += delta;
             if (currentbucket == self->lastbucket
-                && currentoffset > self->last) goto no_match;
+                && currentoffset > self->last)
+                goto no_match;
             break;
         }
         /* Move to start of next bucket. */
-        if (currentbucket == self->lastbucket || b == NULL) goto no_match;
+        if (currentbucket == self->lastbucket || b == NULL)
+            goto no_match;
         currentbucket = b;
         pseudoindex += max + 1;
         delta -= max + 1;
         currentoffset = 0;
     }
-    while (delta < 0) {         /* move left */
+    while (delta < 0) /* move left */
+    {
         int status;
         /* Want to move left -delta positions; the most we can move left in
          * this bucket is currentoffset positions.
          */
-        if ((-delta) <= currentoffset) {
+        if ((-delta) <= currentoffset)
+        {
             currentoffset += delta;
             pseudoindex += delta;
             if (currentbucket == self->firstbucket
-                && currentoffset < self->first) goto no_match;
+                && currentoffset < self->first)
+                goto no_match;
             break;
         }
         /* Move to end of previous bucket. */
-        if (currentbucket == self->firstbucket) goto no_match;
+        if (currentbucket == self->firstbucket)
+            goto no_match;
         status = PreviousBucket(&currentbucket, self->firstbucket);
         if (status == 0)
             goto no_match;
@@ -202,10 +213,11 @@
     PER_USE_OR_RETURN(currentbucket, -1);
     error = currentoffset < 0 || currentoffset >= currentbucket->len;
     PER_UNUSE(currentbucket);
-    if (error) {
-	PyErr_SetString(PyExc_RuntimeError,
-	                "the bucket being iterated changed size");
-	return -1;
+    if (error)
+    {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "the bucket being iterated changed size");
+        return -1;
     }
 
     Py_INCREF(currentbucket);
@@ -232,8 +244,8 @@
     assert(b);
     assert(0 <= i && i < b->len);
 
-    switch (kind) {
-
+    switch (kind)
+    {
         case 'k':
             COPY_KEY_TO_OBJECT(result, b->keys[i]);
             break;
@@ -242,25 +254,30 @@
             COPY_VALUE_TO_OBJECT(result, b->values[i]);
             break;
 
-        case 'i': {
+        case 'i':
+        {
             PyObject *key;
             PyObject *value;;
 
             COPY_KEY_TO_OBJECT(key, b->keys[i]);
-            if (!key) break;
+            if (!key)
+                break;
 
             COPY_VALUE_TO_OBJECT(value, b->values[i]);
-            if (!value) {
+            if (!value)
+            {
                 Py_DECREF(key);
                 break;
             }
 
             result = PyTuple_New(2);
-            if (result) {
+            if (result)
+            {
                 PyTuple_SET_ITEM(result, 0, key);
                 PyTuple_SET_ITEM(result, 1, value);
             }
-            else {
+            else
+            {
                 Py_DECREF(key);
                 Py_DECREF(value);
             }
@@ -278,18 +295,19 @@
 /*
 ** BTreeItems_item
 **
-** Arguments:	self	a BTreeItems structure
-**		i	Which item to inspect
+** Arguments:    self    a BTreeItems structure
+**        i    Which item to inspect
 **
-** Returns:	the BTreeItems_item_BTree of self->kind, i
-**		(ie pulls the ith item out)
+** Returns:    the BTreeItems_item_BTree of self->kind, i
+**        (ie pulls the ith item out)
 */
 static PyObject *
 BTreeItems_item(BTreeItems *self, Py_ssize_t i)
 {
     PyObject *result;
 
-    if (BTreeItems_seek(self, i) < 0) return NULL;
+    if (BTreeItems_seek(self, i) < 0)
+        return NULL;
 
     PER_USE_OR_RETURN(self->currentbucket, NULL);
     result = getBucketEntry(self->currentbucket, self->currentoffset,
@@ -304,132 +322,200 @@
 ** Creates a new BTreeItems structure representing the slice
 ** between the low and high range
 **
-** Arguments:	self	The old BTreeItems structure
-**		ilow	The start index
-**		ihigh	The end index
+** Arguments:    self    The old BTreeItems structure
+**        ilow    The start index
+**        ihigh    The end index
 **
-** Returns:	BTreeItems item
+** Returns:    BTreeItems item
 */
 static PyObject *
 BTreeItems_slice(BTreeItems *self, Py_ssize_t ilow, Py_ssize_t ihigh)
 {
-  Bucket *lowbucket;
-  Bucket *highbucket;
-  int lowoffset;
-  int highoffset;
-  Py_ssize_t length = -1;  /* len(self), but computed only if needed */
+    Bucket *lowbucket;
+    Bucket *highbucket;
+    int lowoffset;
+    int highoffset;
+    Py_ssize_t length = -1;  /* len(self), but computed only if needed */
 
-  /* Complications:
-   * A Python slice never raises IndexError, but BTreeItems_seek does.
-   * Python did only part of index normalization before calling this:
-   *     ilow may be < 0 now, and ihigh may be arbitrarily large.  It's
-   *     our responsibility to clip them.
-   * A Python slice is exclusive of the high index, but a BTreeItems
-   *     struct is inclusive on both ends.
-   */
+    /* Complications:
+     * A Python slice never raises IndexError, but BTreeItems_seek does.
+     * Python did only part of index normalization before calling this:
+     *     ilow may be < 0 now, and ihigh may be arbitrarily large.  It's
+     *     our responsibility to clip them.
+     * A Python slice is exclusive of the high index, but a BTreeItems
+     *     struct is inclusive on both ends.
+     */
 
-  /* First adjust ilow and ihigh to be legit endpoints in the Python
-   * sense (ilow inclusive, ihigh exclusive).  This block duplicates the
-   * logic from Python's list_slice function (slicing for builtin lists).
-   */
-  if (ilow < 0)
-      ilow = 0;
-  else {
-      if (length < 0)
-          length = BTreeItems_length(self);
-      if (ilow > length)
-          ilow = length;
-  }
+    /* First adjust ilow and ihigh to be legit endpoints in the Python
+     * sense (ilow inclusive, ihigh exclusive).  This block duplicates the
+     * logic from Python's list_slice function (slicing for builtin lists).
+     */
+    if (ilow < 0)
+        ilow = 0;
+    else
+    {
+        if (length < 0)
+            length = BTreeItems_length(self);
+        if (ilow > length)
+            ilow = length;
+    }
 
-  if (ihigh < ilow)
-      ihigh = ilow;
-  else {
-      if (length < 0)
-          length = BTreeItems_length(self);
-      if (ihigh > length)
-          ihigh = length;
-  }
-  assert(0 <= ilow && ilow <= ihigh);
-  assert(length < 0 || ihigh <= length);
+    if (ihigh < ilow)
+        ihigh = ilow;
+    else
+    {
+        if (length < 0)
+            length = BTreeItems_length(self);
+        if (ihigh > length)
+            ihigh = length;
+    }
+    assert(0 <= ilow && ilow <= ihigh);
+    assert(length < 0 || ihigh <= length);
 
-  /* Now adjust for that our struct is inclusive on both ends.  This is
-   * easy *except* when the slice is empty:  there's no good way to spell
-   * that in an inclusive-on-both-ends scheme.  For example, if the
-   * slice is btree.items([:0]), ilow == ihigh == 0 at this point, and if
-   * we were to subtract 1 from ihigh that would get interpreted by
-   * BTreeItems_seek as meaning the *entire* set of items.  Setting ilow==1
-   * and ihigh==0 doesn't work either, as BTreeItems_seek raises IndexError
-   * if we attempt to seek to ilow==1 when the underlying sequence is empty.
-   * It seems simplest to deal with empty slices as a special case here.
-   */
-   if (ilow == ihigh) {
-       /* empty slice */
-       lowbucket = highbucket = NULL;
-       lowoffset = 1;
-       highoffset = 0;
-   }
-   else {
-       assert(ilow < ihigh);
-       --ihigh;  /* exclusive -> inclusive */
+    /* Now adjust for that our struct is inclusive on both ends.  This is
+    * easy *except* when the slice is empty:  there's no good way to spell
+    * that in an inclusive-on-both-ends scheme.  For example, if the
+    * slice is btree.items([:0]), ilow == ihigh == 0 at this point, and if
+    * we were to subtract 1 from ihigh that would get interpreted by
+    * BTreeItems_seek as meaning the *entire* set of items.  Setting ilow==1
+    * and ihigh==0 doesn't work either, as BTreeItems_seek raises IndexError
+    * if we attempt to seek to ilow==1 when the underlying sequence is empty.
+    * It seems simplest to deal with empty slices as a special case here.
+    */
+    if (ilow == ihigh) /* empty slice */
+    {
+        lowbucket = highbucket = NULL;
+        lowoffset = 1;
+        highoffset = 0;
+    }
+    else
+    {
+        assert(ilow < ihigh);
+        --ihigh;  /* exclusive -> inclusive */
 
-       if (BTreeItems_seek(self, ilow) < 0) return NULL;
-       lowbucket = self->currentbucket;
-       lowoffset = self->currentoffset;
+        if (BTreeItems_seek(self, ilow) < 0)
+            return NULL;
+        lowbucket = self->currentbucket;
+        lowoffset = self->currentoffset;
 
-       if (BTreeItems_seek(self, ihigh) < 0) return NULL;
+        if (BTreeItems_seek(self, ihigh) < 0)
+            return NULL;
 
-       highbucket = self->currentbucket;
-       highoffset = self->currentoffset;
-  }
-  return newBTreeItems(self->kind,
-                       lowbucket, lowoffset, highbucket, highoffset);
+        highbucket = self->currentbucket;
+        highoffset = self->currentoffset;
+    }
+    return newBTreeItems(self->kind,
+                         lowbucket, lowoffset, highbucket, highoffset);
 }
 
-static PySequenceMethods BTreeItems_as_sequence = {
-  (lenfunc) BTreeItems_length,
-  (binaryfunc)0,
-  (ssizeargfunc)0,
-  (ssizeargfunc) BTreeItems_item,
-  (ssizessizeargfunc) BTreeItems_slice,
+static PyObject *
+BTreeItems_subscript(BTreeItems *self, PyObject* subscript)
+{
+    Py_ssize_t len = BTreeItems_length_or_nonzero(self, 0);
+
+    if (PyIndex_Check(subscript))
+    {
+        Py_ssize_t i = PyNumber_AsSsize_t(subscript, PyExc_IndexError);
+        if (i == -1 && PyErr_Occurred())
+            return NULL;
+        if (i < 0)
+            i += len;
+        return BTreeItems_item(self, i);
+    }
+    if (PySlice_Check(subscript))
+    {
+        Py_ssize_t start, stop, step, slicelength;
+
+#ifdef PY3K
+#define SLICEOBJ(x) (x)
+#else
+#define SLICEOBJ(x) (PySliceObject*)(x)
+#endif
+
+        if (PySlice_GetIndicesEx(SLICEOBJ(subscript), len,
+                                 &start, &stop, &step, &slicelength) < 0)
+        {
+            return NULL;
+        }
+
+        if (step != 1)
+        {
+            PyErr_SetString(PyExc_RuntimeError,
+                            "slices must have step size of 1");
+            return NULL;
+        }
+        return BTreeItems_slice(self, start, stop);
+    }
+    PyErr_SetString(PyExc_RuntimeError,
+                    "Unknown index type:  must be int or slice");
+    return NULL;
+}
+
+/* Py3K doesn't honor sequence slicing, so implement via mapping */
+static PyMappingMethods BTreeItems_as_mapping = {
+    (lenfunc)BTreeItems_length,             /* mp_length */
+    (binaryfunc)BTreeItems_subscript,       /* mp_subscript */
 };
 
+static PySequenceMethods BTreeItems_as_sequence =
+{
+    (lenfunc) BTreeItems_length,            /* sq_length */
+    (binaryfunc)0,                          /* sq_concat */
+    (ssizeargfunc)0,                        /* sq_repeat */
+    (ssizeargfunc) BTreeItems_item,         /* sq_item */
+#ifndef PY3K
+    /* Py3K doesn't honor this slot */
+    (ssizessizeargfunc) BTreeItems_slice,   /* sq_slice */
+#endif
+};
+
 /* Number Method items (just for nb_nonzero!) */
 
 static int
 BTreeItems_nonzero(BTreeItems *self)
 {
-  return BTreeItems_length_or_nonzero(self, 1);
+    return BTreeItems_length_or_nonzero(self, 1);
 }
 
 static PyNumberMethods BTreeItems_as_number_for_nonzero = {
-  0,0,0,0,0,0,0,0,0,0,
-   (inquiry)BTreeItems_nonzero};
+    0,                                      /* nb_add */
+    0,                                      /* nb_subtract */
+    0,                                      /* nb_multiply */
+#ifndef PY3K
+    0,                                      /* nb_divide */
+#endif
+    0,                                      /* nb_remainder */
+    0,                                      /* nb_divmod */
+    0,                                      /* nb_power */
+    0,                                      /* nb_negative */
+    0,                                      /* nb_positive */
+    0,                                      /* nb_absolute */
+   (inquiry)BTreeItems_nonzero              /* nb_nonzero */
+};
 
 static PyTypeObject BTreeItemsType = {
-  PyObject_HEAD_INIT(NULL)
-  0,					/*ob_size*/
-  MOD_NAME_PREFIX "BTreeItems",	        /*tp_name*/
-  sizeof(BTreeItems),		        /*tp_basicsize*/
-  0,					/*tp_itemsize*/
-  /* methods */
-  (destructor) BTreeItems_dealloc,	/*tp_dealloc*/
-  (printfunc)0,				/*tp_print*/
-  (getattrfunc)0,			/*obsolete tp_getattr*/
-  (setattrfunc)0,			/*obsolete tp_setattr*/
-  (cmpfunc)0,				/*tp_compare*/
-  (reprfunc)0,				/*tp_repr*/
-  &BTreeItems_as_number_for_nonzero,	/*tp_as_number*/
-  &BTreeItems_as_sequence,		/*tp_as_sequence*/
-  0,					/*tp_as_mapping*/
-  (hashfunc)0,				/*tp_hash*/
-  (ternaryfunc)0,			/*tp_call*/
-  (reprfunc)0,				/*tp_str*/
-  0,					/*tp_getattro*/
-  0,					/*tp_setattro*/
-
-  /* Space for future expansion */
-  0L,0L,
-  "Sequence type used to iterate over BTree items." /* Documentation string */
+    PyVarObject_HEAD_INIT(NULL, 0)
+    MOD_NAME_PREFIX "BTreeItems",           /* tp_name */
+    sizeof(BTreeItems),                     /* tp_basicsize */
+    0,                                      /* tp_itemsize */
+    /* methods */
+    (destructor) BTreeItems_dealloc,        /* tp_dealloc */
+    0,                                      /* tp_print */
+    0,                                      /* obsolete tp_getattr */
+    0,                                      /* obsolete tp_setattr */
+    0,                                      /* tp_compare */
+    0,                                      /* tp_repr */
+    &BTreeItems_as_number_for_nonzero,      /* tp_as_number */
+    &BTreeItems_as_sequence,                /* tp_as_sequence */
+    &BTreeItems_as_mapping,                 /* tp_as_mapping */
+    (hashfunc)0,                            /* tp_hash */
+    (ternaryfunc)0,                         /* tp_call */
+    (reprfunc)0,                            /* tp_str */
+    0,                                      /* tp_getattro */
+    0,                                      /* tp_setattro */
+    /* Space for future expansion */
+    0L,0L,
+    "Sequence type used to iterate over BTree items." /* Documentation string */
 };
 
 /* Returns a new BTreeItems object representing the contiguous slice from
@@ -443,120 +529,121 @@
               Bucket *lowbucket, int lowoffset,
               Bucket *highbucket, int highoffset)
 {
-  BTreeItems *self;
+    BTreeItems *self;
 
-  UNLESS (self = PyObject_NEW(BTreeItems, &BTreeItemsType)) return NULL;
-  self->kind=kind;
+    UNLESS (self = PyObject_NEW(BTreeItems, &BTreeItemsType))
+        return NULL;
+    self->kind=kind;
 
-  self->first=lowoffset;
-  self->last=highoffset;
+    self->first=lowoffset;
+    self->last=highoffset;
 
-  if (! lowbucket || ! highbucket
-      || (lowbucket == highbucket && lowoffset > highoffset))
+    if (! lowbucket || ! highbucket
+        || (lowbucket == highbucket && lowoffset > highoffset))
     {
-      self->firstbucket   = 0;
-      self->lastbucket    = 0;
-      self->currentbucket = 0;
+        self->firstbucket   = 0;
+        self->lastbucket    = 0;
+        self->currentbucket = 0;
     }
-  else
+    else
     {
-      Py_INCREF(lowbucket);
-      self->firstbucket = lowbucket;
-      Py_INCREF(highbucket);
-      self->lastbucket = highbucket;
-      Py_INCREF(lowbucket);
-      self->currentbucket = lowbucket;
+        Py_INCREF(lowbucket);
+        self->firstbucket = lowbucket;
+        Py_INCREF(highbucket);
+        self->lastbucket = highbucket;
+        Py_INCREF(lowbucket);
+        self->currentbucket = lowbucket;
     }
 
-  self->currentoffset = lowoffset;
-  self->pseudoindex = 0;
+    self->currentoffset = lowoffset;
+    self->pseudoindex = 0;
 
-  return OBJECT(self);
+    return OBJECT(self);
 }
 
 static int
 nextBTreeItems(SetIteration *i)
 {
-  if (i->position >= 0)
+    if (i->position >= 0)
     {
-      if (i->position)
+        if (i->position)
         {
-          DECREF_KEY(i->key);
-          DECREF_VALUE(i->value);
+            DECREF_KEY(i->key);
+            DECREF_VALUE(i->value);
         }
 
-      if (BTreeItems_seek(ITEMS(i->set), i->position) >= 0)
+        if (BTreeItems_seek(ITEMS(i->set), i->position) >= 0)
         {
-          Bucket *currentbucket;
+            Bucket *currentbucket;
 
-          currentbucket = BUCKET(ITEMS(i->set)->currentbucket);
-          UNLESS(PER_USE(currentbucket))
+            currentbucket = BUCKET(ITEMS(i->set)->currentbucket);
+            UNLESS(PER_USE(currentbucket))
             {
-              /* Mark iteration terminated, so that finiSetIteration doesn't
-               * try to redundantly decref the key and value
-               */
-              i->position = -1;
-              return -1;
+                /* Mark iteration terminated, so that finiSetIteration doesn't
+                * try to redundantly decref the key and value
+                */
+                i->position = -1;
+                return -1;
             }
 
-          COPY_KEY(i->key, currentbucket->keys[ITEMS(i->set)->currentoffset]);
-          INCREF_KEY(i->key);
+            COPY_KEY(i->key, currentbucket->keys[ITEMS(i->set)->currentoffset]);
+            INCREF_KEY(i->key);
 
-          COPY_VALUE(i->value,
-                     currentbucket->values[ITEMS(i->set)->currentoffset]);
-          INCREF_VALUE(i->value);
+            COPY_VALUE(i->value,
+                        currentbucket->values[ITEMS(i->set)->currentoffset]);
+            INCREF_VALUE(i->value);
 
-          i->position ++;
+            i->position ++;
 
-          PER_UNUSE(currentbucket);
+            PER_UNUSE(currentbucket);
         }
-      else
+        else
         {
-          i->position = -1;
-          PyErr_Clear();
+            i->position = -1;
+            PyErr_Clear();
         }
     }
-  return 0;
+    return 0;
 }
 
 static int
 nextTreeSetItems(SetIteration *i)
 {
-  if (i->position >= 0)
+    if (i->position >= 0)
     {
-      if (i->position)
+        if (i->position)
         {
-          DECREF_KEY(i->key);
+            DECREF_KEY(i->key);
         }
 
-      if (BTreeItems_seek(ITEMS(i->set), i->position) >= 0)
+        if (BTreeItems_seek(ITEMS(i->set), i->position) >= 0)
         {
-          Bucket *currentbucket;
+            Bucket *currentbucket;
 
-          currentbucket = BUCKET(ITEMS(i->set)->currentbucket);
-          UNLESS(PER_USE(currentbucket))
+            currentbucket = BUCKET(ITEMS(i->set)->currentbucket);
+            UNLESS(PER_USE(currentbucket))
             {
-              /* Mark iteration terminated, so that finiSetIteration doesn't
-               * try to redundantly decref the key and value
-               */
-              i->position = -1;
-              return -1;
+                /* Mark iteration terminated, so that finiSetIteration doesn't
+                * try to redundantly decref the key and value
+                */
+                i->position = -1;
+                return -1;
             }
 
-          COPY_KEY(i->key, currentbucket->keys[ITEMS(i->set)->currentoffset]);
-          INCREF_KEY(i->key);
+            COPY_KEY(i->key, currentbucket->keys[ITEMS(i->set)->currentoffset]);
+            INCREF_KEY(i->key);
 
-          i->position ++;
+            i->position ++;
 
-          PER_UNUSE(currentbucket);
+            PER_UNUSE(currentbucket);
         }
-      else
+        else
         {
-          i->position = -1;
-          PyErr_Clear();
+            i->position = -1;
+            PyErr_Clear();
         }
     }
-  return 0;
+    return 0;
 }
 
 /* Support for the iteration protocol new in Python 2.2. */
@@ -564,7 +651,8 @@
 static PyTypeObject BTreeIter_Type;
 
 /* The type of iterator objects, returned by e.g. iter(IIBTree()). */
-typedef struct {
+typedef struct
+{
     PyObject_HEAD
     /* We use a BTreeItems object because it's convenient and flexible.
      * We abuse it two ways:
@@ -584,7 +672,8 @@
 
     assert(pitems != NULL);
     result = PyObject_New(BTreeIter, &BTreeIter_Type);
-    if (result) {
+    if (result)
+    {
         Py_INCREF(pitems);
         result->pitems = pitems;
     }
@@ -595,8 +684,8 @@
 static void
 BTreeIter_dealloc(BTreeIter *bi)
 {
-	Py_DECREF(bi->pitems);
-	PyObject_Del(bi);
+    Py_DECREF(bi->pitems);
+    PyObject_Del(bi);
 }
 
 /* The implementation of the iterator's tp_iternext slot.  Returns "the next"
@@ -606,45 +695,49 @@
 static PyObject *
 BTreeIter_next(BTreeIter *bi, PyObject *args)
 {
-	PyObject *result = NULL;        /* until proven innocent */
-        BTreeItems *items = bi->pitems;
-        int i = items->currentoffset;
-	Bucket *bucket = items->currentbucket;
+    PyObject *result = NULL;        /* until proven innocent */
+    BTreeItems *items = bi->pitems;
+    int i = items->currentoffset;
+    Bucket *bucket = items->currentbucket;
 
-        if (bucket == NULL)	/* iteration termination is sticky */
-	    return NULL;
+    if (bucket == NULL)    /* iteration termination is sticky */
+        return NULL;
 
-        PER_USE_OR_RETURN(bucket, NULL);
-        if (i >= bucket->len) {
-            /* We never leave this routine normally with i >= len:  somebody
-             * else mutated the current bucket.
-             */
-	    PyErr_SetString(PyExc_RuntimeError,
-		            "the bucket being iterated changed size");
-	    /* Arrange for that this error is sticky too. */
-	    items->currentoffset = INT_MAX;
-	    goto Done;
-	}
+    PER_USE_OR_RETURN(bucket, NULL);
+    if (i >= bucket->len)
+    {
+        /* We never leave this routine normally with i >= len:  somebody
+            * else mutated the current bucket.
+            */
+        PyErr_SetString(PyExc_RuntimeError,
+                    "the bucket being iterated changed size");
+        /* Arrange for that this error is sticky too. */
+        items->currentoffset = INT_MAX;
+        goto Done;
+    }
 
-        /* Build the result object, from bucket at offset i. */
-        result = getBucketEntry(bucket, i, items->kind);
+    /* Build the result object, from bucket at offset i. */
+    result = getBucketEntry(bucket, i, items->kind);
 
-        /* Advance position for next call. */
-        if (bucket == items->lastbucket && i >= items->last) {
-            /* Next call should terminate the iteration. */
-            Py_DECREF(items->currentbucket);
-            items->currentbucket = NULL;
+    /* Advance position for next call. */
+    if (bucket == items->lastbucket && i >= items->last)
+    {
+        /* Next call should terminate the iteration. */
+        Py_DECREF(items->currentbucket);
+        items->currentbucket = NULL;
+    }
+    else
+    {
+        ++i;
+        if (i >= bucket->len)
+        {
+            Py_XINCREF(bucket->next);
+            items->currentbucket = bucket->next;
+            Py_DECREF(bucket);
+            i = 0;
         }
-        else {
-            ++i;
-            if (i >= bucket->len) {
-                Py_XINCREF(bucket->next);
-                items->currentbucket = bucket->next;
-                Py_DECREF(bucket);
-                i = 0;
-            }
-            items->currentoffset = i;
-        }
+        items->currentoffset = i;
+    }
 
 Done:
     PER_UNUSE(bucket);
@@ -659,40 +752,39 @@
 }
 
 static PyTypeObject BTreeIter_Type = {
-        PyObject_HEAD_INIT(NULL)
-	0,					/* ob_size */
-	MOD_NAME_PREFIX "-iterator",		/* tp_name */
-	sizeof(BTreeIter),			/* tp_basicsize */
-	0,					/* tp_itemsize */
-	/* methods */
-	(destructor)BTreeIter_dealloc,          /* tp_dealloc */
-	0,					/* tp_print */
-	0,					/* tp_getattr */
-	0,					/* tp_setattr */
-	0,					/* tp_compare */
-	0,					/* tp_repr */
-	0,					/* tp_as_number */
-	0,					/* tp_as_sequence */
-	0,					/* tp_as_mapping */
-	0,					/* tp_hash */
-	0,					/* tp_call */
-	0,					/* tp_str */
-	0, /*PyObject_GenericGetAttr,*/		/* tp_getattro */
-	0,					/* tp_setattro */
-	0,					/* tp_as_buffer */
-	Py_TPFLAGS_DEFAULT,			/* tp_flags */
- 	0,					/* tp_doc */
- 	0,					/* tp_traverse */
- 	0,					/* tp_clear */
-	0,					/* tp_richcompare */
-	0,					/* tp_weaklistoffset */
-	(getiterfunc)BTreeIter_getiter,		/* tp_iter */
-	(iternextfunc)BTreeIter_next,	        /* tp_iternext */
-	0,					/* tp_methods */
-	0,					/* tp_members */
-	0,					/* tp_getset */
-	0,					/* tp_base */
-	0,					/* tp_dict */
-	0,					/* tp_descr_get */
-	0,					/* tp_descr_set */
+    PyVarObject_HEAD_INIT(NULL, 0)
+    MOD_NAME_PREFIX "-iterator",        /* tp_name */
+    sizeof(BTreeIter),                  /* tp_basicsize */
+    0,                                  /* tp_itemsize */
+    /* methods */
+    (destructor)BTreeIter_dealloc,      /* tp_dealloc */
+    0,                                  /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    0,                                  /* tp_compare */
+    0,                                  /* tp_repr */
+    0,                                  /* tp_as_number */
+    0,                                  /* tp_as_sequence */
+    0,                                  /* tp_as_mapping */
+    0,                                  /* tp_hash */
+    0,                                  /* tp_call */
+    0,                                  /* tp_str */
+    0, /*PyObject_GenericGetAttr,*/     /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
+    0,                                  /* tp_doc */
+    0,                                  /* tp_traverse */
+    0,                                  /* tp_clear */
+    0,                                  /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    (getiterfunc)BTreeIter_getiter,     /* tp_iter */
+    (iternextfunc)BTreeIter_next,       /* tp_iternext */
+    0,                                  /* tp_methods */
+    0,                                  /* tp_members */
+    0,                                  /* tp_getset */
+    0,                                  /* tp_base */
+    0,                                  /* tp_dict */
+    0,                                  /* tp_descr_get */
+    0,                                  /* tp_descr_set */
 };

Modified: BTrees/trunk/BTrees/BTreeModuleTemplate.c
===================================================================
--- BTrees/trunk/BTrees/BTreeModuleTemplate.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/BTreeModuleTemplate.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -15,6 +15,7 @@
 #include "Python.h"
 /* include structmember.h for offsetof */
 #include "structmember.h"
+#include "bytesobject.h"
 
 #ifdef PERSISTENT
 #include "persistent/cPersistence.h"
@@ -27,7 +28,7 @@
 #define PER_ACCESSED(O) 1
 #endif
 
-#include "py24compat.h"
+#include "_compat.h"
 
 /* So sue me.  This pair gets used all over the place, so much so that it
  * interferes with understanding non-persistence parts of algorithms.
@@ -65,7 +66,7 @@
 #define MAX_BTREE_SIZE(B) DEFAULT_MAX_BTREE_SIZE
 #define MAX_BUCKET_SIZE(B) DEFAULT_MAX_BUCKET_SIZE
 
-#define SameType_Check(O1, O2) ((O1)->ob_type==(O2)->ob_type)
+#define SameType_Check(O1, O2) (Py_TYPE((O1))==Py_TYPE((O2)))
 
 #define ASSERT(C, S, R) if (! (C)) { \
   PyErr_SetString(PyExc_AssertionError, (S)); return (R); }
@@ -81,7 +82,7 @@
 static int
 longlong_check(PyObject *ob)
 {
-    if (PyInt_Check(ob))
+    if (INT_CHECK(ob))
         return 1;
 
     if (PyLong_Check(ob)) {
@@ -101,14 +102,56 @@
     static PY_LONG_LONG maxint = 0;
 
     if (maxint == 0)
-        maxint = PyInt_GetMax();
+        maxint = INT_GETMAX();
     if ((val > maxint) || (val < (-maxint-1)))
         return PyLong_FromLongLong(val);
-    return PyInt_FromLong((long)val);
+    return INT_FROM_LONG((long)val);
 }
 #endif
 
 
+#ifdef NEED_LONG_LONG_KEYS
+static int
+longlong_convert(PyObject *ob, PY_LONG_LONG *value)
+{
+#ifndef PY3K
+    if (PyInt_Check(ob))
+    {
+        (*value) = (PY_LONG_LONG)PyInt_AS_LONG(ob);
+        return 1;
+    }
+#endif
+
+    if (!PyLong_Check(ob))
+    {
+        PyErr_SetString(PyExc_TypeError, "expected integer key");
+        return 0;
+    }
+    else
+    {
+        PY_LONG_LONG val;
+#if PY_VERSION_HEX < 0x02070000
+        /* check magnitude */
+        val = PyLong_AsLongLong(ob);
+
+        if (val == -1 && PyErr_Occurred())
+            goto overflow;
+#else
+        int overflow;
+        val = PyLong_AsLongLongAndOverflow(ob, &overflow);
+        if (overflow)
+            goto overflow;
+#endif
+        (*value) = val;
+        return 1;
+    }
+overflow:
+    PyErr_SetString(PyExc_ValueError, "long integer out of range");
+    return 0;
+}
+#endif
+
+
 /* Various kinds of BTree and Bucket structs are instances of
  * "sized containers", and have a common initial layout:
  *     The stuff needed for all Python objects, or all Persistent objects.
@@ -291,7 +334,7 @@
 {
     PyObject *v;
 
-    v = PyInt_FromLong(i);
+    v = INT_FROM_LONG(i);
     if (!v) {
 	v = Py_None;
 	Py_INCREF(v);
@@ -451,7 +494,11 @@
 int
 init_persist_type(PyTypeObject *type)
 {
+#ifdef PY3K
+    ((PyObject*)type)->ob_type = &PyType_Type;
+#else
     type->ob_type = &PyType_Type;
+#endif
     type->tp_base = cPersistenceCAPI->pertype;
 
     if (PyType_Ready(type) < 0)
@@ -460,120 +507,167 @@
     return 1;
 }
 
-void
-INITMODULE (void)
+#ifdef PY3K
+static struct PyModuleDef moduledef = {
+        PyModuleDef_HEAD_INIT,
+        "_" MOD_NAME_PREFIX "BTree",    /* m_name */
+        BTree_module_documentation,     /* m_doc */
+        -1,                             /* m_size */
+        module_methods,                 /* m_methods */
+        NULL,                           /* m_reload */
+        NULL,                           /* m_traverse */
+        NULL,                           /* m_clear */
+        NULL,                           /* m_free */
+    };
+
+#endif
+
+static PyObject*
+module_init(void)
 {
-    PyObject *m, *d, *c;
+    PyObject *module, *mod_dict, *interfaces, *conflicterr;
 
 #ifdef KEY_TYPE_IS_PYOBJECT
-    object_ = PyTuple_GetItem(Py_None->ob_type->tp_bases, 0);
+    object_ = PyTuple_GetItem(Py_TYPE(Py_None)->tp_bases, 0);
     if (object_ == NULL)
-      return;
+      return NULL;
 #endif
 
-    sort_str = PyString_InternFromString("sort");
+    sort_str = INTERN("sort");
     if (!sort_str)
-	return;
-    reverse_str = PyString_InternFromString("reverse");
+        return NULL;
+    reverse_str = INTERN("reverse");
     if (!reverse_str)
-	return;
-    __setstate___str = PyString_InternFromString("__setstate__");
+        return NULL;
+    __setstate___str = INTERN("__setstate__");
     if (!__setstate___str)
-	return;
-    _bucket_type_str = PyString_InternFromString("_bucket_type");
+        return NULL;
+    _bucket_type_str = INTERN("_bucket_type");
     if (!_bucket_type_str)
-	return;
+        return NULL;
 
     /* Grab the ConflictError class */
-    m = PyImport_ImportModule("BTrees.Interfaces");
-    if (m != NULL) {
-  	c = PyObject_GetAttrString(m, "BTreesConflictError");
-  	if (c != NULL)
-	    ConflictError = c;
-	Py_DECREF(m);
+    interfaces = PyImport_ImportModule("BTrees.Interfaces");
+    if (interfaces != NULL)
+    {
+        conflicterr = PyObject_GetAttrString(interfaces, "BTreesConflictError");
+        if (conflicterr != NULL)
+            ConflictError = conflicterr;
+        Py_DECREF(interfaces);
     }
 
-    if (ConflictError == NULL) {
-  	Py_INCREF(PyExc_ValueError);
-	ConflictError=PyExc_ValueError;
+    if (ConflictError == NULL)
+    {
+        Py_INCREF(PyExc_ValueError);
+        ConflictError=PyExc_ValueError;
     }
 
     /* Initialize the PyPersist_C_API and the type objects. */
-    cPersistenceCAPI = PyCObject_Import("persistent.cPersistence", "CAPI");
+#ifdef PY3K
+    cPersistenceCAPI = (cPersistenceCAPIstruct *)PyCapsule_Import(
+                "persistent.cPersistence.CAPI", 0);
+#else
+    cPersistenceCAPI = (cPersistenceCAPIstruct *)PyCObject_Import(
+                "persistent.cPersistence", "CAPI");
+#endif
     if (cPersistenceCAPI == NULL)
-	return;
+        return NULL;
 
-    BTreeItemsType.ob_type = &PyType_Type;
-    BTreeIter_Type.ob_type = &PyType_Type;
+#ifdef PY3K
+#define _SET_TYPE(typ) ((PyObject*)(&typ))->ob_type = &PyType_Type
+#else
+#define _SET_TYPE(typ) (typ).ob_type = &PyType_Type
+#endif
+    _SET_TYPE(BTreeItemsType);
+    _SET_TYPE(BTreeIter_Type);
     BTreeIter_Type.tp_getattro = PyObject_GenericGetAttr;
     BucketType.tp_new = PyType_GenericNew;
     SetType.tp_new = PyType_GenericNew;
     BTreeType.tp_new = PyType_GenericNew;
     TreeSetType.tp_new = PyType_GenericNew;
     if (!init_persist_type(&BucketType))
-	return;
+	    return NULL;
     if (!init_persist_type(&BTreeType))
-	return;
+	    return NULL;
     if (!init_persist_type(&SetType))
-	return;
+	    return NULL;
     if (!init_persist_type(&TreeSetType))
-	return;
+	    return NULL;
 
     if (PyDict_SetItem(BTreeType.tp_dict, _bucket_type_str,
-		       (PyObject *)&BucketType) < 0) {
-	fprintf(stderr, "btree failed\n");
-	return;
+		       (PyObject *)&BucketType) < 0)
+    {
+        fprintf(stderr, "btree failed\n");
+        return NULL;
     }
     if (PyDict_SetItem(TreeSetType.tp_dict, _bucket_type_str,
-		       (PyObject *)&SetType) < 0) {
-	fprintf(stderr, "bucket failed\n");
-	return;
+		       (PyObject *)&SetType) < 0)
+    {
+        fprintf(stderr, "bucket failed\n");
+        return NULL;
     }
 
     /* Create the module and add the functions */
-    m = Py_InitModule4("_" MOD_NAME_PREFIX "BTree",
+#ifdef PY3K
+    module = PyModule_Create(&moduledef);
+#else
+    module = Py_InitModule4("_" MOD_NAME_PREFIX "BTree",
 		       module_methods, BTree_module_documentation,
 		       (PyObject *)NULL, PYTHON_API_VERSION);
+#endif
 
     /* Add some symbolic constants to the module */
-    d = PyModule_GetDict(m);
-    if (PyDict_SetItemString(d, MOD_NAME_PREFIX "Bucket",
+    mod_dict = PyModule_GetDict(module);
+    if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "Bucket",
 			     (PyObject *)&BucketType) < 0)
-	return;
-    if (PyDict_SetItemString(d, MOD_NAME_PREFIX "BTree",
+        return NULL;
+    if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "BTree",
 			     (PyObject *)&BTreeType) < 0)
-	return;
-    if (PyDict_SetItemString(d, MOD_NAME_PREFIX "Set",
+        return NULL;
+    if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "Set",
 			     (PyObject *)&SetType) < 0)
-	return;
-    if (PyDict_SetItemString(d, MOD_NAME_PREFIX "TreeSet",
+        return NULL;
+    if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "TreeSet",
 			     (PyObject *)&TreeSetType) < 0)
-	return;
-    if (PyDict_SetItemString(d, MOD_NAME_PREFIX "TreeIterator",
+        return NULL;
+    if (PyDict_SetItemString(mod_dict, MOD_NAME_PREFIX "TreeIterator",
 			     (PyObject *)&BTreeIter_Type) < 0)
-	return;
+        return NULL;
 	/* We also want to be able to access these constants without the prefix
 	 * so that code can more easily exchange modules (particularly the integer
 	 * and long modules, but also others).  The TreeIterator is only internal,
 	 * so we don't bother to expose that.
      */
-    if (PyDict_SetItemString(d, "Bucket",
+    if (PyDict_SetItemString(mod_dict, "Bucket",
 			     (PyObject *)&BucketType) < 0)
-	return;
-    if (PyDict_SetItemString(d, "BTree",
+        return NULL;
+    if (PyDict_SetItemString(mod_dict, "BTree",
 			     (PyObject *)&BTreeType) < 0)
-	return;
-    if (PyDict_SetItemString(d, "Set",
+        return NULL;
+    if (PyDict_SetItemString(mod_dict, "Set",
 			     (PyObject *)&SetType) < 0)
-	return;
-    if (PyDict_SetItemString(d, "TreeSet",
+        return NULL;
+    if (PyDict_SetItemString(mod_dict, "TreeSet",
 			     (PyObject *)&TreeSetType) < 0)
-	return;
+        return NULL;
 #if defined(ZODB_64BIT_INTS) && defined(NEED_LONG_LONG_SUPPORT)
-    if (PyDict_SetItemString(d, "using64bits", Py_True) < 0)
-        return;
+    if (PyDict_SetItemString(mod_dict, "using64bits", Py_True) < 0)
+        return NULL;
 #else
-    if (PyDict_SetItemString(d, "using64bits", Py_False) < 0)
-        return;
+    if (PyDict_SetItemString(mod_dict, "using64bits", Py_False) < 0)
+        return NULL;
 #endif
+    return module;
 }
+
+#ifdef PY3K
+PyMODINIT_FUNC INITMODULE(void)
+{
+    return module_init();
+}
+#else
+PyMODINIT_FUNC INITMODULE(void)
+{
+    module_init();
+}
+#endif

Modified: BTrees/trunk/BTrees/BTreeTemplate.c
===================================================================
--- BTrees/trunk/BTrees/BTreeTemplate.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/BTreeTemplate.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -11,6 +11,7 @@
   FOR A PARTICULAR PURPOSE
 
 ****************************************************************************/
+#include "_compat.h"
 
 #define BTREETEMPLATE_C "$Id$\n"
 
@@ -26,12 +27,12 @@
 static int
 BTree_check_inner(BTree *self, Bucket *nextbucket)
 {
-  int i;
-  Bucket *bucketafter;
-  Sized *child;
-  char *errormsg = "internal error";  /* someone should have overriden */
-  Sized *activated_child = NULL;
-  int result = -1;    /* until proved innocent */
+    int i;
+    Bucket *bucketafter;
+    Sized *child;
+    char *errormsg = "internal error";  /* someone should have overriden */
+    Sized *activated_child = NULL;
+    int result = -1;    /* until proved innocent */
 
 #define CHECK(CONDITION, ERRORMSG)              \
   if (!(CONDITION)) {                           \
@@ -39,103 +40,114 @@
     goto Error;                                 \
   }
 
-  PER_USE_OR_RETURN(self, -1);
-  CHECK(self->len >= 0, "BTree len < 0");
-  CHECK(self->len <= self->size, "BTree len > size");
-  if (self->len == 0) {
-    /* Empty BTree. */
-    CHECK(self->firstbucket == NULL,
-          "Empty BTree has non-NULL firstbucket");
-    result = 0;
-    goto Done;
-  }
-  /* Non-empty BTree. */
-  CHECK(self->firstbucket != NULL, "Non-empty BTree has NULL firstbucket");
+    PER_USE_OR_RETURN(self, -1);
+    CHECK(self->len >= 0, "BTree len < 0");
+    CHECK(self->len <= self->size, "BTree len > size");
+    if (self->len == 0) /* Empty BTree. */
+    {
+        CHECK(self->firstbucket == NULL,
+            "Empty BTree has non-NULL firstbucket");
+        result = 0;
+        goto Done;
+    }
+    /* Non-empty BTree. */
+    CHECK(self->firstbucket != NULL, "Non-empty BTree has NULL firstbucket");
 
-  /* Obscure:  The first bucket is pointed to at least by self->firstbucket
-   * and data[0].child of whichever BTree node it's a child of.  However,
-   * if persistence is enabled then the latter BTree node may be a ghost
-   * at this point, and so its pointers "don't count":  we can only rely
-   * on self's pointers being intact.
-   */
+    /* Obscure:  The first bucket is pointed to at least by self->firstbucket
+    * and data[0].child of whichever BTree node it's a child of.  However,
+    * if persistence is enabled then the latter BTree node may be a ghost
+    * at this point, and so its pointers "don't count":  we can only rely
+    * on self's pointers being intact.
+    */
 #ifdef PERSISTENT
-  CHECK(self->firstbucket->ob_refcnt >= 1,
-        "Non-empty BTree firstbucket has refcount < 1");
+    CHECK(Py_REFCNT(self->firstbucket) >= 1,
+            "Non-empty BTree firstbucket has refcount < 1");
 #else
-  CHECK(self->firstbucket->ob_refcnt >= 2,
-        "Non-empty BTree firstbucket has refcount < 2");
+    CHECK(Py_REFCNT(self->firstbucket) >= 2,
+            "Non-empty BTree firstbucket has refcount < 2");
 #endif
 
-  for (i = 0; i < self->len; ++i) {
-    CHECK(self->data[i].child != NULL, "BTree has NULL child");
-  }
+    for (i = 0; i < self->len; ++i)
+    {
+        CHECK(self->data[i].child != NULL, "BTree has NULL child");
+    }
 
-  if (SameType_Check(self, self->data[0].child)) {
-    /* Our children are also BTrees. */
-    child = self->data[0].child;
-    UNLESS (PER_USE(child)) goto Done;
-    activated_child = child;
-    CHECK(self->firstbucket == BTREE(child)->firstbucket,
-          "BTree has firstbucket different than "
-          "its first child's firstbucket");
-    PER_ALLOW_DEACTIVATION(child);
-    activated_child = NULL;
-    for (i = 0; i < self->len; ++i) {
-      child = self->data[i].child;
-      CHECK(SameType_Check(self, child),
-            "BTree children have different types");
-      if (i == self->len - 1)
-        bucketafter = nextbucket;
-      else {
-        BTree *child2 = BTREE(self->data[i+1].child);
-        UNLESS (PER_USE(child2)) goto Done;
-        bucketafter = child2->firstbucket;
-        PER_ALLOW_DEACTIVATION(child2);
-      }
-      if (BTree_check_inner(BTREE(child), bucketafter) < 0) goto Done;
+    if (SameType_Check(self, self->data[0].child))
+    {
+        /* Our children are also BTrees. */
+        child = self->data[0].child;
+        UNLESS (PER_USE(child))
+            goto Done;
+        activated_child = child;
+        CHECK(self->firstbucket == BTREE(child)->firstbucket,
+            "BTree has firstbucket different than "
+            "its first child's firstbucket");
+        PER_ALLOW_DEACTIVATION(child);
+        activated_child = NULL;
+        for (i = 0; i < self->len; ++i)
+        {
+            child = self->data[i].child;
+            CHECK(SameType_Check(self, child),
+                    "BTree children have different types");
+            if (i == self->len - 1)
+                bucketafter = nextbucket;
+            else
+            {
+                BTree *child2 = BTREE(self->data[i+1].child);
+                UNLESS (PER_USE(child2))
+                    goto Done;
+                bucketafter = child2->firstbucket;
+                PER_ALLOW_DEACTIVATION(child2);
+            }
+            if (BTree_check_inner(BTREE(child), bucketafter) < 0)
+                goto Done;
+        }
     }
-  }
-  else {
-    /* Our children are buckets. */
-    CHECK(self->firstbucket == BUCKET(self->data[0].child),
-          "Bottom-level BTree node has inconsistent firstbucket belief");
-    for (i = 0; i < self->len; ++i) {
-      child = self->data[i].child;
-      UNLESS (PER_USE(child)) goto Done;
-      activated_child = child;
-      CHECK(!SameType_Check(self, child),
-            "BTree children have different types");
-      CHECK(child->len >= 1, "Bucket length < 1"); /* no empty buckets! */
-      CHECK(child->len <= child->size, "Bucket len > size");
+    else /* Our children are buckets. */
+    {
+        CHECK(self->firstbucket == BUCKET(self->data[0].child),
+            "Bottom-level BTree node has inconsistent firstbucket belief");
+        for (i = 0; i < self->len; ++i)
+        {
+            child = self->data[i].child;
+            UNLESS (PER_USE(child))
+                goto Done;
+            activated_child = child;
+            CHECK(!SameType_Check(self, child),
+                    "BTree children have different types");
+            CHECK(child->len >= 1, "Bucket length < 1");/* no empty buckets! */
+            CHECK(child->len <= child->size, "Bucket len > size");
 #ifdef PERSISTENT
-      CHECK(child->ob_refcnt >= 1, "Bucket has refcount < 1");
+            CHECK(Py_REFCNT(child) >= 1, "Bucket has refcount < 1");
 #else
-      CHECK(child->ob_refcnt >= 2, "Bucket has refcount < 2");
+            CHECK(Py_REFCNT(child) >= 2, "Bucket has refcount < 2");
 #endif
-      if (i == self->len - 1)
-        bucketafter = nextbucket;
-      else
-        bucketafter = BUCKET(self->data[i+1].child);
-      CHECK(BUCKET(child)->next == bucketafter,
-            "Bucket next pointer is damaged");
-      PER_ALLOW_DEACTIVATION(child);
-      activated_child = NULL;
+            if (i == self->len - 1)
+                bucketafter = nextbucket;
+            else
+                bucketafter = BUCKET(self->data[i+1].child);
+            CHECK(BUCKET(child)->next == bucketafter,
+                    "Bucket next pointer is damaged");
+            PER_ALLOW_DEACTIVATION(child);
+            activated_child = NULL;
+        }
     }
-  }
-  result = 0;
-  goto Done;
+    result = 0;
+    goto Done;
 
- Error:
-  PyErr_SetString(PyExc_AssertionError, errormsg);
-  result = -1;
- Done:
-  /* No point updating access time -- this isn't a "real" use. */
-  PER_ALLOW_DEACTIVATION(self);
-  if (activated_child) {
-    PER_ALLOW_DEACTIVATION(activated_child);
-  }
-  return result;
+Error:
+    PyErr_SetString(PyExc_AssertionError, errormsg);
+    result = -1;
 
+Done:
+    /* No point updating access time -- this isn't a "real" use. */
+    PER_ALLOW_DEACTIVATION(self);
+    if (activated_child)
+    {
+        PER_ALLOW_DEACTIVATION(activated_child);
+    }
+    return result;
+
 #undef CHECK
 }
 
@@ -147,14 +159,15 @@
 static PyObject*
 BTree_check(BTree *self)
 {
-  PyObject *result = NULL;
-  int i = BTree_check_inner(self, NULL);
+    PyObject *result = NULL;
+    int i = BTree_check_inner(self, NULL);
 
-  if (i >= 0) {
-    result = Py_None;
-    Py_INCREF(result);
-  }
-  return result;
+    if (i >= 0)
+    {
+        result = Py_None;
+        Py_INCREF(result);
+    }
+    return result;
 }
 
 /*
@@ -179,50 +192,55 @@
 static PyObject *
 _BTree_get(BTree *self, PyObject *keyarg, int has_key)
 {
-  KEY_TYPE key;
-  PyObject *result = NULL;    /* guilty until proved innocent */
-  int copied = 1;
+    KEY_TYPE key;
+    PyObject *result = NULL;    /* guilty until proved innocent */
+    int copied = 1;
 
-  COPY_KEY_FROM_ARG(key, keyarg, copied);
-  UNLESS (copied) return NULL;
+    COPY_KEY_FROM_ARG(key, keyarg, copied);
+    UNLESS (copied) return NULL;
 
-  PER_USE_OR_RETURN(self, NULL);
-  if (self->len == 0) {
-    /* empty BTree */
-    if (has_key)
-      result = PyInt_FromLong(0);
+    PER_USE_OR_RETURN(self, NULL);
+    if (self->len == 0)
+    {
+        /* empty BTree */
+        if (has_key)
+            result = INT_FROM_LONG(0);
+        else
+            PyErr_SetObject(PyExc_KeyError, keyarg);
+    }
     else
-      PyErr_SetObject(PyExc_KeyError, keyarg);
-  }
-  else {
-    for (;;) {
-      int i;
-      Sized *child;
+    {
+        for (;;)
+        {
+            int i;
+            Sized *child;
 
-      BTREE_SEARCH(i, self, key, goto Done);
-      child = self->data[i].child;
-      has_key += has_key != 0;    /* bump depth counter, maybe */
-      if (SameType_Check(self, child)) {
-        PER_UNUSE(self);
-        self = BTREE(child);
-        PER_USE_OR_RETURN(self, NULL);
-      }
-      else {
-        result = _bucket_get(BUCKET(child), keyarg, has_key);
-        break;
-      }
+            BTREE_SEARCH(i, self, key, goto Done);
+            child = self->data[i].child;
+            has_key += has_key != 0;    /* bump depth counter, maybe */
+            if (SameType_Check(self, child))
+            {
+                PER_UNUSE(self);
+                self = BTREE(child);
+                PER_USE_OR_RETURN(self, NULL);
+            }
+            else
+            {
+                result = _bucket_get(BUCKET(child), keyarg, has_key);
+                break;
+            }
+        }
     }
-  }
 
- Done:
-  PER_UNUSE(self);
-  return result;
+Done:
+    PER_UNUSE(self);
+    return result;
 }
 
 static PyObject *
 BTree_get(BTree *self, PyObject *key)
 {
-  return _BTree_get(self, key, 0);
+    return _BTree_get(self, key, 0);
 }
 
 /* Create a new bucket for the BTree or TreeSet using the class attribute
@@ -232,21 +250,21 @@
 static Sized *
 BTree_newBucket(BTree *self)
 {
-  PyObject *factory;
-  Sized *result;
+    PyObject *factory;
+    Sized *result;
 
-  /* _bucket_type_str defined in BTreeModuleTemplate.c */
-  factory = PyObject_GetAttr((PyObject *)self->ob_type, _bucket_type_str);
-  if (factory == NULL)
-    return NULL;
-  /* TODO: Should we check that the factory actually returns something
-     of the appropriate type? How?  The C code here is going to
-     depend on any custom bucket type having the same layout at the
-     C level.
-  */
-  result = SIZED(PyObject_CallObject(factory, NULL));
-  Py_DECREF(factory);
-  return result;
+    /* _bucket_type_str defined in BTreeModuleTemplate.c */
+    factory = PyObject_GetAttr((PyObject *)Py_TYPE(self), _bucket_type_str);
+    if (factory == NULL)
+        return NULL;
+    /* TODO: Should we check that the factory actually returns something
+        of the appropriate type? How?  The C code here is going to
+        depend on any custom bucket type having the same layout at the
+        C level.
+    */
+    result = SIZED(PyObject_CallObject(factory, NULL));
+    Py_DECREF(factory);
+    return result;
 }
 
 /*
@@ -264,36 +282,37 @@
 static int
 BTree_split(BTree *self, int index, BTree *next)
 {
-  int next_size;
-  Sized *child;
+    int next_size;
+    Sized *child;
 
-  if (index < 0 || index >= self->len)
-    index = self->len / 2;
+    if (index < 0 || index >= self->len)
+        index = self->len / 2;
 
-  next_size = self->len - index;
-  ASSERT(index > 0, "split creates empty tree", -1);
-  ASSERT(next_size > 0, "split creates empty tree", -1);
+    next_size = self->len - index;
+    ASSERT(index > 0, "split creates empty tree", -1);
+    ASSERT(next_size > 0, "split creates empty tree", -1);
 
-  next->data = BTree_Malloc(sizeof(BTreeItem) * next_size);
-  if (!next->data)
-    return -1;
-  memcpy(next->data, self->data + index, sizeof(BTreeItem) * next_size);
-  next->size = next_size;  /* but don't set len until we succeed */
+    next->data = BTree_Malloc(sizeof(BTreeItem) * next_size);
+    if (!next->data)
+        return -1;
+    memcpy(next->data, self->data + index, sizeof(BTreeItem) * next_size);
+    next->size = next_size;  /* but don't set len until we succeed */
 
-  /* Set next's firstbucket.  self->firstbucket is still correct. */
-  child = next->data[0].child;
-  if (SameType_Check(self, child)) {
-    PER_USE_OR_RETURN(child, -1);
-    next->firstbucket = BTREE(child)->firstbucket;
-    PER_UNUSE(child);
-  }
-  else
-    next->firstbucket = BUCKET(child);
-  Py_INCREF(next->firstbucket);
+    /* Set next's firstbucket.  self->firstbucket is still correct. */
+    child = next->data[0].child;
+    if (SameType_Check(self, child))
+    {
+        PER_USE_OR_RETURN(child, -1);
+        next->firstbucket = BTREE(child)->firstbucket;
+        PER_UNUSE(child);
+    }
+    else
+        next->firstbucket = BUCKET(child);
+    Py_INCREF(next->firstbucket);
 
-  next->len = next_size;
-  self->len = index;
-  return PER_CHANGED(self) >= 0 ? 0 : -1;
+    next->len = next_size;
+    self->len = index;
+    return PER_CHANGED(self) >= 0 ? 0 : -1;
 }
 
 
@@ -314,32 +333,33 @@
 static int
 BTree_split_root(BTree *self, int noval)
 {
-  BTree *child;
-  BTreeItem *d;
+    BTree *child;
+    BTreeItem *d;
 
-  /* Create a child BTree, and a new data vector for self. */
-  child = BTREE(PyObject_CallObject(OBJECT(self->ob_type), NULL));
-  if (!child) return -1;
+    /* Create a child BTree, and a new data vector for self. */
+    child = BTREE(PyObject_CallObject(OBJECT(Py_TYPE(self)), NULL));
+    if (!child)
+        return -1;
 
-  d = BTree_Malloc(sizeof(BTreeItem) * 2);
-  if (!d) {
-    Py_DECREF(child);
-    return -1;
-  }
+    d = BTree_Malloc(sizeof(BTreeItem) * 2);
+    if (!d) {
+        Py_DECREF(child);
+        return -1;
+    }
 
-  /* Move our data to new BTree. */
-  child->size = self->size;
-  child->len = self->len;
-  child->data = self->data;
-  child->firstbucket = self->firstbucket;
-  Py_INCREF(child->firstbucket);
+    /* Move our data to new BTree. */
+    child->size = self->size;
+    child->len = self->len;
+    child->data = self->data;
+    child->firstbucket = self->firstbucket;
+    Py_INCREF(child->firstbucket);
 
-  /* Point self to child and split the child. */
-  self->data = d;
-  self->len = 1;
-  self->size = 2;
-  self->data[0].child = SIZED(child); /* transfers reference ownership */
-  return BTree_grow(self, 0, noval);
+    /* Point self to child and split the child. */
+    self->data = d;
+    self->len = 1;
+    self->size = 2;
+    self->data[0].child = SIZED(child); /* transfers reference ownership */
+    return BTree_grow(self, 0, noval);
 }
 
 /*
@@ -347,14 +367,14 @@
 **
 ** Grow a BTree
 **
-** Arguments:	self	The BTree
-**		index	self->data[index].child needs to be split.  index
+** Arguments:    self    The BTree
+**        index    self->data[index].child needs to be split.  index
 **                      must be 0 if self is empty (len == 0), and a new
 **                      empty bucket is created then.
 **              noval   Boolean; is this a set (true) or mapping (false)?
 **
-** Returns:	 0	on success
-**		-1	on failure
+** Returns:     0    on success
+**        -1    on failure
 **
 ** CAUTION:  If self is empty on entry, this routine adds an empty bucket.
 ** That isn't a legitimate BTree; if the caller doesn't put something in
@@ -364,91 +384,100 @@
 static int
 BTree_grow(BTree *self, int index, int noval)
 {
-  int i;
-  Sized *v, *e = 0;
-  BTreeItem *d;
+    int i;
+    Sized *v, *e = 0;
+    BTreeItem *d;
 
-  if (self->len == self->size) {
-    if (self->size) {
-      d = BTree_Realloc(self->data, sizeof(BTreeItem) * self->size * 2);
-      if (d == NULL)
-        return -1;
-      self->data = d;
-      self->size *= 2;
+    if (self->len == self->size)
+    {
+        if (self->size)
+        {
+            d = BTree_Realloc(self->data, sizeof(BTreeItem) * self->size * 2);
+            if (d == NULL)
+                return -1;
+            self->data = d;
+            self->size *= 2;
+        }
+        else
+        {
+            d = BTree_Malloc(sizeof(BTreeItem) * 2);
+            if (d == NULL)
+                return -1;
+            self->data = d;
+            self->size = 2;
+        }
     }
-    else {
-      d = BTree_Malloc(sizeof(BTreeItem) * 2);
-      if (d == NULL)
-        return -1;
-      self->data = d;
-      self->size = 2;
-    }
-  }
 
-  if (self->len) {
-    d = self->data + index;
-    v = d->child;
-    /* Create a new object of the same type as the target value */
-    e = (Sized *)PyObject_CallObject((PyObject *)v->ob_type, NULL);
-    if (e == NULL)
-      return -1;
+    if (self->len)
+    {
+        d = self->data + index;
+        v = d->child;
+        /* Create a new object of the same type as the target value */
+        e = (Sized *)PyObject_CallObject((PyObject *)Py_TYPE(v), NULL);
+        if (e == NULL)
+            return -1;
 
-    UNLESS(PER_USE(v)) {
-      Py_DECREF(e);
-      return -1;
-    }
+        UNLESS(PER_USE(v))
+        {
+            Py_DECREF(e);
+            return -1;
+        }
 
-    /* Now split between the original (v) and the new (e) at the midpoint*/
-    if (SameType_Check(self, v))
-      i = BTree_split((BTree *)v, -1, (BTree *)e);
-    else
-      i = bucket_split((Bucket *)v, -1, (Bucket *)e);
-    PER_ALLOW_DEACTIVATION(v);
+        /* Now split between the original (v) and the new (e) at the midpoint*/
+        if (SameType_Check(self, v))
+            i = BTree_split((BTree *)v, -1, (BTree *)e);
+        else
+            i = bucket_split((Bucket *)v, -1, (Bucket *)e);
+        PER_ALLOW_DEACTIVATION(v);
 
-    if (i < 0) {
-      Py_DECREF(e);
-      assert(PyErr_Occurred());
-      return -1;
-    }
+        if (i < 0)
+        {
+            Py_DECREF(e);
+            assert(PyErr_Occurred());
+            return -1;
+        }
 
-    index++;
-    d++;
-    if (self->len > index)	/* Shift up the old values one array slot */
-      memmove(d+1, d, sizeof(BTreeItem)*(self->len-index));
+        index++;
+        d++;
+        if (self->len > index)    /* Shift up the old values one array slot */
+            memmove(d+1, d, sizeof(BTreeItem)*(self->len-index));
 
-    if (SameType_Check(self, v)) {
-      COPY_KEY(d->key, BTREE(e)->data->key);
+        if (SameType_Check(self, v))
+        {
+            COPY_KEY(d->key, BTREE(e)->data->key);
 
-      /* We take the unused reference from e, so there's no
-         reason to INCREF!
-      */
-      /* INCREF_KEY(self->data[1].key); */
+            /* We take the unused reference from e, so there's no
+                reason to INCREF!
+            */
+            /* INCREF_KEY(self->data[1].key); */
+        }
+        else
+        {
+            COPY_KEY(d->key, BUCKET(e)->keys[0]);
+            INCREF_KEY(d->key);
+        }
+        d->child = e;
+        self->len++;
+
+        if (self->len >= MAX_BTREE_SIZE(self) * 2)    /* the root is huge */
+            return BTree_split_root(self, noval);
     }
-    else {
-      COPY_KEY(d->key, BUCKET(e)->keys[0]);
-      INCREF_KEY(d->key);
+    else
+    {
+        /* The BTree is empty.  Create an empty bucket.  See CAUTION in
+        * the comments preceding.
+        */
+        assert(index == 0);
+        d = self->data;
+        d->child = BTree_newBucket(self);
+        if (d->child == NULL)
+            return -1;
+        self->len = 1;
+        Py_INCREF(d->child);
+        self->firstbucket = (Bucket *)d->child;
     }
-    d->child = e;
-    self->len++;
 
-    if (self->len >= MAX_BTREE_SIZE(self) * 2)    /* the root is huge */
-      return BTree_split_root(self, noval);
-  }
-  else {
-    /* The BTree is empty.  Create an empty bucket.  See CAUTION in
-     * the comments preceding.
-     */
-    assert(index == 0);
-    d = self->data;
-    d->child = BTree_newBucket(self);
-    if (d->child == NULL)
-      return -1;
-    self->len = 1;
-    Py_INCREF(d->child);
-    self->firstbucket = (Bucket *)d->child;
-  }
-
-  return 0;
+    return 0;
 }
 
 /* Return the rightmost bucket reachable from following child pointers
@@ -465,50 +494,54 @@
 static Bucket *
 BTree_lastBucket(BTree *self)
 {
-  Sized *pchild;
-  Bucket *result;
+    Sized *pchild;
+    Bucket *result;
 
-  UNLESS (self->data && self->len) {
-    IndexError(-1); /* is this the best action to take? */
-    return NULL;
-  }
+    UNLESS (self->data && self->len)
+    {
+        IndexError(-1); /* is this the best action to take? */
+        return NULL;
+    }
 
-  pchild = self->data[self->len - 1].child;
-  if (SameType_Check(self, pchild)) {
-    self = BTREE(pchild);
-    PER_USE_OR_RETURN(self, NULL);
-    result = BTree_lastBucket(self);
-    PER_UNUSE(self);
-  }
-  else {
-    Py_INCREF(pchild);
-    result = BUCKET(pchild);
-  }
-  return result;
+    pchild = self->data[self->len - 1].child;
+    if (SameType_Check(self, pchild))
+    {
+        self = BTREE(pchild);
+        PER_USE_OR_RETURN(self, NULL);
+        result = BTree_lastBucket(self);
+        PER_UNUSE(self);
+    }
+    else
+    {
+        Py_INCREF(pchild);
+        result = BUCKET(pchild);
+    }
+    return result;
 }
 
 static int
 BTree_deleteNextBucket(BTree *self)
 {
-  Bucket *b;
+    Bucket *b;
 
-  UNLESS (PER_USE(self)) return -1;
+    UNLESS (PER_USE(self))
+        return -1;
 
-  b = BTree_lastBucket(self);
-  if (b == NULL)
-    goto err;
-  if (Bucket_deleteNextBucket(b) < 0)
-    goto err;
+    b = BTree_lastBucket(self);
+    if (b == NULL)
+        goto err;
+    if (Bucket_deleteNextBucket(b) < 0)
+        goto err;
 
-  Py_DECREF(b);
-  PER_UNUSE(self);
+    Py_DECREF(b);
+    PER_UNUSE(self);
 
-  return 0;
+    return 0;
 
- err:
-  Py_XDECREF(b);
-  PER_ALLOW_DEACTIVATION(self);
-  return -1;
+err:
+    Py_XDECREF(b);
+    PER_ALLOW_DEACTIVATION(self);
+    return -1;
 }
 
 /*
@@ -517,10 +550,10 @@
 ** Clears out all of the values in the BTree (firstbucket, keys, and children);
 ** leaving self an empty BTree.
 **
-** Arguments:	self	The BTree
+** Arguments:    self    The BTree
 **
-** Returns:	 0	on success
-**		-1	on failure
+** Returns:     0    on success
+**        -1    on failure
 **
 ** Internal:  Deallocation order is important.  The danger is that a long
 ** list of buckets may get freed "at once" via decref'ing the first bucket,
@@ -536,44 +569,48 @@
 static int
 _BTree_clear(BTree *self)
 {
-  const int len = self->len;
+    const int len = self->len;
 
-  if (self->firstbucket) {
-    /* Obscure:  The first bucket is pointed to at least by
-     * self->firstbucket and data[0].child of whichever BTree node it's
-     * a child of.  However, if persistence is enabled then the latter
-     * BTree node may be a ghost at this point, and so its pointers "don't
-     * count":  we can only rely on self's pointers being intact.
-     */
+    if (self->firstbucket)
+    {
+        /* Obscure:  The first bucket is pointed to at least by
+        * self->firstbucket and data[0].child of whichever BTree node it's
+        * a child of.  However, if persistence is enabled then the latter
+        * BTree node may be a ghost at this point, and so its pointers "don't
+        * count":  we can only rely on self's pointers being intact.
+        */
 #ifdef PERSISTENT
-    ASSERT(self->firstbucket->ob_refcnt > 0,
-           "Invalid firstbucket pointer", -1);
+        ASSERT(Py_REFCNT(self->firstbucket) > 0,
+            "Invalid firstbucket pointer", -1);
 #else
-    ASSERT(self->firstbucket->ob_refcnt > 1,
-           "Invalid firstbucket pointer", -1);
+        ASSERT(Py_REFCNT(self->firstbucket) > 1,
+            "Invalid firstbucket pointer", -1);
 #endif
-    Py_DECREF(self->firstbucket);
-    self->firstbucket = NULL;
-  }
-
-  if (self->data) {
-    int i;
-    if (len > 0) { /* 0 is special because key 0 is trash */
-      Py_DECREF(self->data[0].child);
+        Py_DECREF(self->firstbucket);
+        self->firstbucket = NULL;
     }
 
-    for (i = 1; i < len; i++) {
+    if (self->data)
+    {
+        int i;
+        if (len > 0) /* 0 is special because key 0 is trash */
+        {
+            Py_DECREF(self->data[0].child);
+        }
+
+        for (i = 1; i < len; i++)
+        {
 #ifdef KEY_TYPE_IS_PYOBJECT
-      DECREF_KEY(self->data[i].key);
+            DECREF_KEY(self->data[i].key);
 #endif
-      Py_DECREF(self->data[i].child);
+            Py_DECREF(self->data[i].child);
+        }
+        free(self->data);
+        self->data = NULL;
     }
-    free(self->data);
-    self->data = NULL;
-  }
 
-  self->len = self->size = 0;
-  return 0;
+    self->len = self->size = 0;
+    return 0;
 }
 
 /*
@@ -606,241 +643,270 @@
 _BTree_set(BTree *self, PyObject *keyarg, PyObject *value,
            int unique, int noval)
 {
-  int changed = 0;    /* did I mutate? */
-  int min;            /* index of child I searched */
-  BTreeItem *d;       /* self->data[min] */
-  int childlength;    /* len(self->data[min].child) */
-  int status;         /* our return value; and return value from callee */
-  int self_was_empty; /* was self empty at entry? */
+    int changed = 0;    /* did I mutate? */
+    int min;            /* index of child I searched */
+    BTreeItem *d;       /* self->data[min] */
+    int childlength;    /* len(self->data[min].child) */
+    int status;         /* our return value; and return value from callee */
+    int self_was_empty; /* was self empty at entry? */
 
-  KEY_TYPE key;
-  int copied = 1;
+    KEY_TYPE key;
+    int copied = 1;
 
-  COPY_KEY_FROM_ARG(key, keyarg, copied);
-  if (!copied) return -1;
+    COPY_KEY_FROM_ARG(key, keyarg, copied);
+    if (!copied)
+        return -1;
 
-  PER_USE_OR_RETURN(self, -1);
+    PER_USE_OR_RETURN(self, -1);
 
-  self_was_empty = self->len == 0;
-  if (self_was_empty) {
-    /* We're empty.  Make room. */
-    if (value) {
-      if (BTree_grow(self, 0, noval) < 0)
-        goto Error;
+    self_was_empty = self->len == 0;
+    if (self_was_empty)
+    {
+        /* We're empty.  Make room. */
+        if (value)
+        {
+            if (BTree_grow(self, 0, noval) < 0)
+                goto Error;
+        }
+        else
+        {
+            /* Can't delete a key from an empty BTree. */
+            PyErr_SetObject(PyExc_KeyError, keyarg);
+            goto Error;
+        }
     }
-    else {
-      /* Can't delete a key from an empty BTree. */
-      PyErr_SetObject(PyExc_KeyError, keyarg);
-      goto Error;
-    }
-  }
 
-  /* Find the right child to search, and hand the work off to it. */
-  BTREE_SEARCH(min, self, key, goto Error);
-  d = self->data + min;
+    /* Find the right child to search, and hand the work off to it. */
+    BTREE_SEARCH(min, self, key, goto Error);
+    d = self->data + min;
 
 #ifdef PERSISTENT
-  PER_READCURRENT(self, goto Error);
+    PER_READCURRENT(self, goto Error);
 #endif
 
-  if (SameType_Check(self, d->child))
-    status = _BTree_set(BTREE(d->child), keyarg, value, unique, noval);
-  else {
-    int bucket_changed = 0;
-    status = _bucket_set(BUCKET(d->child), keyarg,
-                         value, unique, noval, &bucket_changed);
+    if (SameType_Check(self, d->child))
+        status = _BTree_set(BTREE(d->child), keyarg, value, unique, noval);
+    else
+    {
+        int bucket_changed = 0;
+        status = _bucket_set(BUCKET(d->child), keyarg,
+                            value, unique, noval, &bucket_changed);
 #ifdef PERSISTENT
-    /* If a BTree contains only a single bucket, BTree.__getstate__()
-     * includes the bucket's entire state, and the bucket doesn't get
-     * an oid of its own.  So if we have a single oid-less bucket that
-     * changed, it's *our* oid that should be marked as changed -- the
-     * bucket doesn't have one.
-     */
-    if (bucket_changed
-        && self->len == 1
-        && self->data[0].child->oid == NULL)
-      {
-        changed = 1;
-      }
+        /* If a BTree contains only a single bucket, BTree.__getstate__()
+        * includes the bucket's entire state, and the bucket doesn't get
+        * an oid of its own.  So if we have a single oid-less bucket that
+        * changed, it's *our* oid that should be marked as changed -- the
+        * bucket doesn't have one.
+        */
+        if (bucket_changed
+            && self->len == 1
+            && self->data[0].child->oid == NULL)
+        {
+            changed = 1;
+        }
 #endif
-  }
-  if (status == 0) goto Done;
-  if (status < 0) goto Error;
-  assert(status == 1 || status == 2);
+    }
+    if (status == 0)
+        goto Done;
+    if (status < 0)
+        goto Error;
+    assert(status == 1 || status == 2);
 
-  /* The child changed size.  Get its new size.  Note that since the tree
-   * rooted at the child changed size, so did the tree rooted at self:
-   * our status must be >= 1 too.
-   */
-  UNLESS(PER_USE(d->child)) goto Error;
-  childlength = d->child->len;
-  PER_UNUSE(d->child);
+    /* The child changed size.  Get its new size.  Note that since the tree
+    * rooted at the child changed size, so did the tree rooted at self:
+    * our status must be >= 1 too.
+    */
+    UNLESS(PER_USE(d->child))
+        goto Error;
+    childlength = d->child->len;
+    PER_UNUSE(d->child);
 
-  if (value) {
-    /* A bucket got bigger -- if it's "too big", split it. */
-    int toobig;
+    if (value)
+    {
+        /* A bucket got bigger -- if it's "too big", split it. */
+        int toobig;
 
-    assert(status == 1);    /* can be 2 only on deletes */
-    if (SameType_Check(self, d->child))
-      toobig = childlength > MAX_BTREE_SIZE(d->child);
-    else
-      toobig = childlength > MAX_BUCKET_SIZE(d->child);
+        assert(status == 1);    /* can be 2 only on deletes */
+        if (SameType_Check(self, d->child))
+            toobig = childlength > MAX_BTREE_SIZE(d->child);
+        else
+            toobig = childlength > MAX_BUCKET_SIZE(d->child);
 
-    if (toobig) {
-      if (BTree_grow(self, min, noval) < 0) goto Error;
-      changed = 1;        /* BTree_grow mutated self */
+        if (toobig) {
+            if (BTree_grow(self, min, noval) < 0)
+                goto Error;
+            changed = 1;        /* BTree_grow mutated self */
+        }
+        goto Done;      /* and status still == 1 */
     }
-    goto Done;      /* and status still == 1 */
-  }
 
-  /* A bucket got smaller.  This is much harder, and despite that we
-   * don't try to rebalance the tree.
-   */
+    /* A bucket got smaller.  This is much harder, and despite that we
+    * don't try to rebalance the tree.
+    */
 
-  if (min && childlength)
+    if (min && childlength)
     {  /* We removed a key. but the node child is non-empty.  If the
-          deleted key is the node key, then update the node key using
-          the smallest key of the node child.
+        deleted key is the node key, then update the node key using
+        the smallest key of the node child.
 
-          This doesn't apply to the 0th node, whos key is unused.
-       */
-      int _cmp = 1;
-      TEST_KEY_SET_OR(_cmp, key, d->key) goto Error;
-      if (_cmp == 0)
-        { /* Need to replace key with first key from child */
-          Bucket *bucket;
+        This doesn't apply to the 0th node, whos key is unused.
+        */
+        int _cmp = 1;
+        TEST_KEY_SET_OR(_cmp, key, d->key) goto Error;
+        if (_cmp == 0) /* Need to replace key with first key from child */
+        {
+            Bucket *bucket;
 
-          if (SameType_Check(self, d->child))
+            if (SameType_Check(self, d->child))
             {
-              UNLESS(PER_USE(d->child)) goto Error;
-              bucket = BTREE(d->child)->firstbucket;
-              PER_UNUSE(d->child);
+                UNLESS(PER_USE(d->child))
+                    goto Error;
+                bucket = BTREE(d->child)->firstbucket;
+                PER_UNUSE(d->child);
             }
-          else
-            bucket = BUCKET(d->child);
+            else
+                bucket = BUCKET(d->child);
 
-          UNLESS(PER_USE(bucket)) goto Error;
-          DECREF_KEY(d->key);
-          COPY_KEY(d->key, bucket->keys[0]);
-          INCREF_KEY(d->key);
-          PER_UNUSE(bucket);
-          if (PER_CHANGED(self) < 0) goto Error;
+            UNLESS(PER_USE(bucket))
+                goto Error;
+            DECREF_KEY(d->key);
+            COPY_KEY(d->key, bucket->keys[0]);
+            INCREF_KEY(d->key);
+            PER_UNUSE(bucket);
+            if (PER_CHANGED(self) < 0)
+                    goto Error;
         }
     }
 
-  if (status == 2) {
-    /* The child must be a BTree because bucket.set never returns 2 */
-    /* Two problems to solve:  May have to adjust our own firstbucket,
-     * and the bucket that went away needs to get unlinked.
-     */
-    if (min) {
-      /* This wasn't our firstbucket, so no need to adjust ours (note
-       * that it can't be the firstbucket of any node above us either).
-       * Tell "the tree to the left" to do the unlinking.
-       */
-      if (BTree_deleteNextBucket(BTREE(d[-1].child)) < 0) goto Error;
-      status = 1;     /* we solved the child's firstbucket problem */
-    }
-    else {
-      /* This was our firstbucket.  Update to new firstbucket value. */
-      Bucket *nextbucket;
-      UNLESS(PER_USE(d->child)) goto Error;
-      nextbucket = BTREE(d->child)->firstbucket;
-      PER_UNUSE(d->child);
+    if (status == 2)
+    {
+        /* The child must be a BTree because bucket.set never returns 2 */
+        /* Two problems to solve:  May have to adjust our own firstbucket,
+        * and the bucket that went away needs to get unlinked.
+        */
+        if (min)
+        {
+            /* This wasn't our firstbucket, so no need to adjust ours (note
+            * that it can't be the firstbucket of any node above us either).
+            * Tell "the tree to the left" to do the unlinking.
+            */
+            if (BTree_deleteNextBucket(BTREE(d[-1].child)) < 0)
+                goto Error;
+            status = 1;     /* we solved the child's firstbucket problem */
+        }
+        else
+        {
+            /* This was our firstbucket.  Update to new firstbucket value. */
+            Bucket *nextbucket;
+            UNLESS(PER_USE(d->child))
+                goto Error;
+            nextbucket = BTREE(d->child)->firstbucket;
+            PER_UNUSE(d->child);
 
-      Py_XINCREF(nextbucket);
-      Py_DECREF(self->firstbucket);
-      self->firstbucket = nextbucket;
-      changed = 1;
+            Py_XINCREF(nextbucket);
+            Py_DECREF(self->firstbucket);
+            self->firstbucket = nextbucket;
+            changed = 1;
 
-      /* The caller has to do the unlinking -- we can't.  Also, since
-       * it was our firstbucket, it may also be theirs.
-       */
-      assert(status == 2);
+            /* The caller has to do the unlinking -- we can't.  Also, since
+            * it was our firstbucket, it may also be theirs.
+            */
+            assert(status == 2);
+        }
     }
-  }
 
-  /* If the child isn't empty, we're done!  We did all that was possible for
-   * us to do with the firstbucket problems the child gave us, and since the
-   * child isn't empty don't create any new firstbucket problems of our own.
-   */
-  if (childlength) goto Done;
+    /* If the child isn't empty, we're done!  We did all that was possible for
+    * us to do with the firstbucket problems the child gave us, and since the
+    * child isn't empty don't create any new firstbucket problems of our own.
+    */
+    if (childlength)
+        goto Done;
 
-  /* The child became empty:  we need to remove it from self->data.
-   * But first, if we're a bottom-level node, we've got more bucket-fiddling
-   * to set up.
-   */
-  if (! SameType_Check(self, d->child)) {
-    /* We're about to delete a bucket, so need to adjust bucket pointers. */
-    if (min) {
-      /* It's not our first bucket, so we can tell the previous
-       * bucket to adjust its reference to it.  It can't be anyone
-       * else's first bucket either, so the caller needn't do anything.
-       */
-      if (Bucket_deleteNextBucket(BUCKET(d[-1].child)) < 0) goto Error;
-      /* status should be 1, and already is:  if it were 2, the
-       * block above would have set it to 1 in its min != 0 branch.
-       */
-      assert(status == 1);
-    }
-    else {
-      Bucket *nextbucket;
-      /* It's our first bucket.  We can't unlink it directly. */
-      /* 'changed' will be set true by the deletion code following. */
-      UNLESS(PER_USE(d->child)) goto Error;
-      nextbucket = BUCKET(d->child)->next;
-      PER_UNUSE(d->child);
+    /* The child became empty:  we need to remove it from self->data.
+    * But first, if we're a bottom-level node, we've got more bucket-fiddling
+    * to set up.
+    */
+    if (! SameType_Check(self, d->child))
+    {
+        /* We're about to delete a bucket, so need to adjust bucket pointers. */
+        if (min)
+        {
+            /* It's not our first bucket, so we can tell the previous
+            * bucket to adjust its reference to it.  It can't be anyone
+            * else's first bucket either, so the caller needn't do anything.
+            */
+            if (Bucket_deleteNextBucket(BUCKET(d[-1].child)) < 0)
+                goto Error;
+            /* status should be 1, and already is:  if it were 2, the
+            * block above would have set it to 1 in its min != 0 branch.
+            */
+            assert(status == 1);
+        }
+        else
+        {
+            Bucket *nextbucket;
+            /* It's our first bucket.  We can't unlink it directly. */
+            /* 'changed' will be set true by the deletion code following. */
+            UNLESS(PER_USE(d->child))
+                goto Error;
+            nextbucket = BUCKET(d->child)->next;
+            PER_UNUSE(d->child);
 
-      Py_XINCREF(nextbucket);
-      Py_DECREF(self->firstbucket);
-      self->firstbucket = nextbucket;
+            Py_XINCREF(nextbucket);
+            Py_DECREF(self->firstbucket);
+            self->firstbucket = nextbucket;
 
-      status = 2; /* we're giving our caller a new firstbucket problem */
+            status = 2; /* we're giving our caller a new firstbucket problem */
+        }
     }
-  }
 
-  /* Remove the child from self->data. */
-  Py_DECREF(d->child);
+    /* Remove the child from self->data. */
+    Py_DECREF(d->child);
 #ifdef KEY_TYPE_IS_PYOBJECT
-  if (min) {
-    DECREF_KEY(d->key);
-  }
-  else if (self->len > 1) {
-    /* We're deleting the first child of a BTree with more than one
-     * child.  The key at d+1 is about to be shifted into slot 0,
-     * and hence never to be referenced again (the key in slot 0 is
-     * trash).
-     */
-    DECREF_KEY((d+1)->key);
-  }
-  /* Else min==0 and len==1:  we're emptying the BTree entirely, and
-   * there is no key in need of decrefing.
-   */
+    if (min)
+    {
+        DECREF_KEY(d->key);
+    }
+    else if (self->len > 1)
+    {
+        /* We're deleting the first child of a BTree with more than one
+        * child.  The key at d+1 is about to be shifted into slot 0,
+        * and hence never to be referenced again (the key in slot 0 is
+        * trash).
+        */
+        DECREF_KEY((d+1)->key);
+    }
+    /* Else min==0 and len==1:  we're emptying the BTree entirely, and
+    * there is no key in need of decrefing.
+    */
 #endif
-  --self->len;
-  if (min < self->len)
-    memmove(d, d+1, (self->len - min) * sizeof(BTreeItem));
-  changed = 1;
+    --self->len;
+    if (min < self->len)
+        memmove(d, d+1, (self->len - min) * sizeof(BTreeItem));
+    changed = 1;
 
- Done:
+Done:
 #ifdef PERSISTENT
-  if (changed) {
-    if (PER_CHANGED(self) < 0) goto Error;
-  }
+    if (changed)
+    {
+        if (PER_CHANGED(self) < 0)
+            goto Error;
+    }
 #endif
-  PER_UNUSE(self);
-  return status;
+    PER_UNUSE(self);
+    return status;
 
- Error:
-  assert(PyErr_Occurred());
-  if (self_was_empty) {
-    /* BTree_grow may have left the BTree in an invalid state.  Make
-     * sure the tree is a legitimate empty tree.
-     */
-    _BTree_clear(self);
-  }
-  PER_UNUSE(self);
-  return -1;
+Error:
+    assert(PyErr_Occurred());
+    if (self_was_empty)
+    {
+        /* BTree_grow may have left the BTree in an invalid state.  Make
+        * sure the tree is a legitimate empty tree.
+        */
+        _BTree_clear(self);
+    }
+    PER_UNUSE(self);
+    return -1;
 }
 
 /*
@@ -848,86 +914,92 @@
 **
 ** wrapper for _BTree_set
 **
-** Arguments:	self	The BTree
-**		key	The key to insert
-**		v	The value to insert
+** Arguments:    self    The BTree
+**        key    The key to insert
+**        v    The value to insert
 **
-** Returns	-1	on failure
-**		 0	on success
+** Returns    -1    on failure
+**         0    on success
 */
 static int
 BTree_setitem(BTree *self, PyObject *key, PyObject *v)
 {
-  if (_BTree_set(self, key, v, 0, 0) < 0)
-    return -1;
-  return 0;
+    if (_BTree_set(self, key, v, 0, 0) < 0)
+        return -1;
+    return 0;
 }
 
 #ifdef PERSISTENT
 static PyObject *
 BTree__p_deactivate(BTree *self, PyObject *args, PyObject *keywords)
 {
-  int ghostify = 1;
-  PyObject *force = NULL;
+    int ghostify = 1;
+    PyObject *force = NULL;
 
-  if (args && PyTuple_GET_SIZE(args) > 0) {
-    PyErr_SetString(PyExc_TypeError,
-                    "_p_deactivate takes not positional arguments");
-    return NULL;
-  }
-  if (keywords) {
-    int size = PyDict_Size(keywords);
-    force = PyDict_GetItemString(keywords, "force");
-    if (force)
-      size--;
-    if (size) {
-      PyErr_SetString(PyExc_TypeError,
-                      "_p_deactivate only accepts keyword arg force");
-      return NULL;
-    }
-  }
-
-  if (self->jar && self->oid) {
-    ghostify = self->state == cPersistent_UPTODATE_STATE;
-    if (!ghostify && force) {
-      if (PyObject_IsTrue(force))
-        ghostify = 1;
-      if (PyErr_Occurred())
+    if (args && PyTuple_GET_SIZE(args) > 0)
+    {
+        PyErr_SetString(PyExc_TypeError,
+                        "_p_deactivate takes not positional arguments");
         return NULL;
     }
-    if (ghostify) {
-      if (_BTree_clear(self) < 0)
-        return NULL;
-      PER_GHOSTIFY(self);
+    if (keywords)
+    {
+        int size = PyDict_Size(keywords);
+        force = PyDict_GetItemString(keywords, "force");
+        if (force)
+            size--;
+        if (size)
+        {
+            PyErr_SetString(PyExc_TypeError,
+                            "_p_deactivate only accepts keyword arg force");
+            return NULL;
+        }
     }
-  }
 
-  Py_INCREF(Py_None);
-  return Py_None;
+    if (self->jar && self->oid)
+    {
+        ghostify = self->state == cPersistent_UPTODATE_STATE;
+        if (!ghostify && force)
+        {
+            if (PyObject_IsTrue(force))
+                ghostify = 1;
+            if (PyErr_Occurred())
+                return NULL;
+        }
+        if (ghostify)
+        {
+            if (_BTree_clear(self) < 0)
+                return NULL;
+            PER_GHOSTIFY(self);
+        }
+    }
+
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 #endif
 
 static PyObject *
 BTree_clear(BTree *self)
 {
-  UNLESS (PER_USE(self)) return NULL;
+    UNLESS (PER_USE(self)) return NULL;
 
-  if (self->len)
+    if (self->len)
     {
-      if (_BTree_clear(self) < 0)
-        goto err;
-      if (PER_CHANGED(self) < 0)
-        goto err;
+        if (_BTree_clear(self) < 0)
+            goto err;
+        if (PER_CHANGED(self) < 0)
+            goto err;
     }
 
-  PER_UNUSE(self);
+    PER_UNUSE(self);
 
-  Py_INCREF(Py_None);
-  return Py_None;
+    Py_INCREF(Py_None);
+    return Py_None;
 
- err:
-  PER_UNUSE(self);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    return NULL;
 }
 
 /*
@@ -960,170 +1032,185 @@
 static PyObject *
 BTree_getstate(BTree *self)
 {
-  PyObject *r = NULL;
-  PyObject *o;
-  int i, l;
+    PyObject *r = NULL;
+    PyObject *o;
+    int i, l;
 
-  UNLESS (PER_USE(self)) return NULL;
+    UNLESS (PER_USE(self))
+        return NULL;
 
-  if (self->len) {
-    r = PyTuple_New(self->len * 2 - 1);
-    if (r == NULL)
-      goto err;
+    if (self->len)
+    {
+        r = PyTuple_New(self->len * 2 - 1);
+        if (r == NULL)
+            goto err;
 
-    if (self->len == 1
-        && self->data->child->ob_type != self->ob_type
+        if (self->len == 1
+            && Py_TYPE(self->data->child) != Py_TYPE(self)
 #ifdef PERSISTENT
-        && BUCKET(self->data->child)->oid == NULL
+            && BUCKET(self->data->child)->oid == NULL
 #endif
-        ) {
-      /* We have just one bucket. Save its data directly. */
-      o = bucket_getstate((Bucket *)self->data->child);
-      if (o == NULL)
-        goto err;
-      PyTuple_SET_ITEM(r, 0, o);
-      ASSIGN(r, Py_BuildValue("(O)", r));
-    }
-    else {
-      for (i=0, l=0; i < self->len; i++) {
-        if (i) {
-          COPY_KEY_TO_OBJECT(o, self->data[i].key);
-          PyTuple_SET_ITEM(r, l, o);
-          l++;
+            )
+        {
+            /* We have just one bucket. Save its data directly. */
+            o = bucket_getstate((Bucket *)self->data->child);
+            if (o == NULL)
+                goto err;
+            PyTuple_SET_ITEM(r, 0, o);
+            ASSIGN(r, Py_BuildValue("(O)", r));
         }
-        o = (PyObject *)self->data[i].child;
-        Py_INCREF(o);
-        PyTuple_SET_ITEM(r,l,o);
-        l++;
-      }
-      ASSIGN(r, Py_BuildValue("OO", r, self->firstbucket));
+        else
+        {
+            for (i=0, l=0; i < self->len; i++)
+            {
+                if (i)
+                {
+                    COPY_KEY_TO_OBJECT(o, self->data[i].key);
+                    PyTuple_SET_ITEM(r, l, o);
+                    l++;
+                }
+                o = (PyObject *)self->data[i].child;
+                Py_INCREF(o);
+                PyTuple_SET_ITEM(r,l,o);
+                l++;
+            }
+            ASSIGN(r, Py_BuildValue("OO", r, self->firstbucket));
+        }
+
     }
+    else
+    {
+        r = Py_None;
+        Py_INCREF(r);
+    }
 
-  }
-  else {
-    r = Py_None;
-    Py_INCREF(r);
-  }
+    PER_UNUSE(self);
 
-  PER_UNUSE(self);
+    return r;
 
-  return r;
-
- err:
-  PER_UNUSE(self);
-  Py_XDECREF(r);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    Py_XDECREF(r);
+    return NULL;
 }
 
 static int
 _BTree_setstate(BTree *self, PyObject *state, int noval)
 {
-  PyObject *items, *firstbucket = NULL;
-  BTreeItem *d;
-  int len, l, i, copied=1;
+    PyObject *items, *firstbucket = NULL;
+    BTreeItem *d;
+    int len, l, i, copied=1;
 
-  if (_BTree_clear(self) < 0)
-    return -1;
+    if (_BTree_clear(self) < 0)
+        return -1;
 
-  /* The state of a BTree can be one of the following:
-     None -- an empty BTree
-     A one-tuple -- a single bucket btree
-     A two-tuple -- a BTree with more than one bucket
-     See comments for BTree_getstate() for the details.
-  */
+    /* The state of a BTree can be one of the following:
+        None -- an empty BTree
+        A one-tuple -- a single bucket btree
+        A two-tuple -- a BTree with more than one bucket
+        See comments for BTree_getstate() for the details.
+    */
 
-  if (state == Py_None)
-    return 0;
+    if (state == Py_None)
+        return 0;
 
-  if (!PyArg_ParseTuple(state, "O|O:__setstate__", &items, &firstbucket))
-    return -1;
+    if (!PyArg_ParseTuple(state, "O|O:__setstate__", &items, &firstbucket))
+        return -1;
 
-  if (!PyTuple_Check(items)) {
-    PyErr_SetString(PyExc_TypeError,
-                    "tuple required for first state element");
-    return -1;
-  }
+    if (!PyTuple_Check(items))
+    {
+        PyErr_SetString(PyExc_TypeError,
+                        "tuple required for first state element");
+        return -1;
+    }
 
-  len = PyTuple_Size(items);
-  if (len < 0)
-    return -1;
-  len = (len + 1) / 2;
+    len = PyTuple_Size(items);
+    if (len < 0)
+        return -1;
+    len = (len + 1) / 2;
 
-  assert(len > 0); /* If the BTree is empty, it's state is None. */
-  assert(self->size == 0); /* We called _BTree_clear(). */
+    assert(len > 0); /* If the BTree is empty, it's state is None. */
+    assert(self->size == 0); /* We called _BTree_clear(). */
 
-  self->data = BTree_Malloc(sizeof(BTreeItem) * len);
-  if (self->data == NULL)
-    return -1;
-  self->size = len;
+    self->data = BTree_Malloc(sizeof(BTreeItem) * len);
+    if (self->data == NULL)
+        return -1;
+    self->size = len;
 
-  for (i = 0, d = self->data, l = 0; i < len; i++, d++) {
-    PyObject *v;
-    if (i) { /* skip the first key slot */
-      COPY_KEY_FROM_ARG(d->key, PyTuple_GET_ITEM(items, l), copied);
-      l++;
-      if (!copied)
-        return -1;
-      INCREF_KEY(d->key);
+    for (i = 0, d = self->data, l = 0; i < len; i++, d++)
+    {
+        PyObject *v;
+        if (i)
+        { /* skip the first key slot */
+            COPY_KEY_FROM_ARG(d->key, PyTuple_GET_ITEM(items, l), copied);
+            l++;
+            if (!copied)
+                return -1;
+            INCREF_KEY(d->key);
+        }
+        v = PyTuple_GET_ITEM(items, l);
+        if (PyTuple_Check(v))
+        {
+            /* Handle the special case in __getstate__() for a BTree
+                with a single bucket. */
+            d->child = BTree_newBucket(self);
+            if (!d->child)
+                return -1;
+            if (noval)
+            {
+                if (_set_setstate(BUCKET(d->child), v) < 0)
+                return -1;
+            }
+            else
+            {
+                if (_bucket_setstate(BUCKET(d->child), v) < 0)
+                return -1;
+            }
+        }
+        else
+        {
+            d->child = (Sized *)v;
+            Py_INCREF(v);
+        }
+        l++;
     }
-    v = PyTuple_GET_ITEM(items, l);
-    if (PyTuple_Check(v)) {
-      /* Handle the special case in __getstate__() for a BTree
-         with a single bucket. */
-      d->child = BTree_newBucket(self);
-      if (!d->child)
+
+    if (!firstbucket)
+        firstbucket = (PyObject *)self->data->child;
+
+    if (!PyObject_IsInstance(firstbucket, (PyObject *)
+                            (noval ? &SetType : &BucketType)))
+    {
+        PyErr_SetString(PyExc_TypeError,
+                        "No firstbucket in non-empty BTree");
         return -1;
-      if (noval) {
-        if (_set_setstate(BUCKET(d->child), v) < 0)
-          return -1;
-      }
-      else {
-        if (_bucket_setstate(BUCKET(d->child), v) < 0)
-          return -1;
-      }
     }
-    else {
-      d->child = (Sized *)v;
-      Py_INCREF(v);
-    }
-    l++;
-  }
-
-  if (!firstbucket)
-    firstbucket = (PyObject *)self->data->child;
-
-  if (!PyObject_IsInstance(firstbucket, (PyObject *)
-                           (noval ? &SetType : &BucketType))) {
-    PyErr_SetString(PyExc_TypeError,
-                    "No firstbucket in non-empty BTree");
-    return -1;
-  }
-  self->firstbucket = BUCKET(firstbucket);
-  Py_INCREF(firstbucket);
+    self->firstbucket = BUCKET(firstbucket);
+    Py_INCREF(firstbucket);
 #ifndef PERSISTENT
-  /* firstbucket is also the child of some BTree node, but that node may
-   * be a ghost if persistence is enabled.
-   */
-  assert(self->firstbucket->ob_refcnt > 1);
+    /* firstbucket is also the child of some BTree node, but that node may
+    * be a ghost if persistence is enabled.
+    */
+    assert(Py_REFCNT(self->firstbucket) > 1);
 #endif
-  self->len = len;
+    self->len = len;
 
-  return 0;
+    return 0;
 }
 
 static PyObject *
 BTree_setstate(BTree *self, PyObject *arg)
 {
-  int r;
+    int r;
 
-  PER_PREVENT_DEACTIVATION(self);
-  r = _BTree_setstate(self, arg, 0);
-  PER_UNUSE(self);
+    PER_PREVENT_DEACTIVATION(self);
+    r = _BTree_setstate(self, arg, 0);
+    PER_UNUSE(self);
 
-  if (r < 0)
-    return NULL;
-  Py_INCREF(Py_None);
-  return Py_None;
+    if (r < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 
 #ifdef PERSISTENT
@@ -1147,43 +1234,48 @@
 PyObject *
 get_bucket_state(PyObject *t)
 {
-  if (t == Py_None)
-    return Py_None;		/* an empty BTree */
-  if (! PyTuple_Check(t)) {
-    PyErr_SetString(PyExc_TypeError,
-                    "_p_resolveConflict: expected tuple or None for state");
-    return NULL;
-  }
+    if (t == Py_None)
+        return Py_None;        /* an empty BTree */
+    if (! PyTuple_Check(t))
+    {
+        PyErr_SetString(PyExc_TypeError,
+                        "_p_resolveConflict: expected tuple or None for state");
+        return NULL;
+    }
 
-  if (PyTuple_GET_SIZE(t) == 2) {
-    /* A non-degenerate BTree. */
-    return merge_error(-1, -1, -1, 11);
-  }
+    if (PyTuple_GET_SIZE(t) == 2)
+    {
+        /* A non-degenerate BTree. */
+        return merge_error(-1, -1, -1, 11);
+    }
 
-  /* We're in the one-bucket case. */
+    /* We're in the one-bucket case. */
 
-  if (PyTuple_GET_SIZE(t) != 1) {
-    PyErr_SetString(PyExc_TypeError,
-                    "_p_resolveConflict: expected 1- or 2-tuple for state");
-    return NULL;
-  }
+    if (PyTuple_GET_SIZE(t) != 1)
+    {
+        PyErr_SetString(PyExc_TypeError,
+                        "_p_resolveConflict: expected 1- or 2-tuple for state");
+        return NULL;
+    }
 
-  t = PyTuple_GET_ITEM(t, 0);
-  if (! PyTuple_Check(t) || PyTuple_GET_SIZE(t) != 1) {
-    PyErr_SetString(PyExc_TypeError,
-                    "_p_resolveConflict: expected 1-tuple containing "
-                    "bucket state");
-    return NULL;
-  }
+    t = PyTuple_GET_ITEM(t, 0);
+    if (! PyTuple_Check(t) || PyTuple_GET_SIZE(t) != 1)
+    {
+        PyErr_SetString(PyExc_TypeError,
+                        "_p_resolveConflict: expected 1-tuple containing "
+                        "bucket state");
+        return NULL;
+    }
 
-  t = PyTuple_GET_ITEM(t, 0);
-  if (! PyTuple_Check(t)) {
-    PyErr_SetString(PyExc_TypeError,
-                    "_p_resolveConflict: expected tuple for bucket state");
-    return NULL;
-  }
+    t = PyTuple_GET_ITEM(t, 0);
+    if (! PyTuple_Check(t))
+    {
+        PyErr_SetString(PyExc_TypeError,
+                        "_p_resolveConflict: expected tuple for bucket state");
+        return NULL;
+    }
 
-  return t;
+    return t;
 }
 
 /* Tricky.  The only kind of BTree conflict we can actually potentially
@@ -1194,31 +1286,31 @@
 static PyObject *
 BTree__p_resolveConflict(BTree *self, PyObject *args)
 {
-  PyObject *s[3];
-  PyObject *x, *y, *z;
+    PyObject *s[3];
+    PyObject *x, *y, *z;
 
-  if (!PyArg_ParseTuple(args, "OOO", &x, &y, &z))
-    return NULL;
+    if (!PyArg_ParseTuple(args, "OOO", &x, &y, &z))
+        return NULL;
 
-  s[0] = get_bucket_state(x);
-  if (s[0] == NULL)
-    return NULL;
-  s[1] = get_bucket_state(y);
-  if (s[1] == NULL)
-    return NULL;
-  s[2] = get_bucket_state(z);
-  if (s[2] == NULL)
-    return NULL;
+    s[0] = get_bucket_state(x);
+    if (s[0] == NULL)
+        return NULL;
+    s[1] = get_bucket_state(y);
+    if (s[1] == NULL)
+        return NULL;
+    s[2] = get_bucket_state(z);
+    if (s[2] == NULL)
+        return NULL;
 
-  if (PyObject_IsInstance((PyObject *)self, (PyObject *)&BTreeType))
-    x = _bucket__p_resolveConflict(OBJECT(&BucketType), s);
-  else
-    x = _bucket__p_resolveConflict(OBJECT(&SetType), s);
+    if (PyObject_IsInstance((PyObject *)self, (PyObject *)&BTreeType))
+        x = _bucket__p_resolveConflict(OBJECT(&BucketType), s);
+    else
+        x = _bucket__p_resolveConflict(OBJECT(&SetType), s);
 
-  if (x == NULL)
-    return NULL;
+    if (x == NULL)
+        return NULL;
 
-  return Py_BuildValue("((N))", x);
+    return Py_BuildValue("((N))", x);
 }
 #endif
 
@@ -1279,173 +1371,194 @@
 */
 static int
 BTree_findRangeEnd(BTree *self, PyObject *keyarg, int low, int exclude_equal,
-                   Bucket **bucket, int *offset) {
-  Sized *deepest_smaller = NULL;      /* last possibility to move left */
-  int deepest_smaller_is_btree = 0;   /* Boolean; if false, it's a bucket */
-  Bucket *pbucket;
-  int self_got_rebound = 0;   /* Boolean; when true, deactivate self */
-  int result = -1;            /* Until proven innocent */
-  int i;
-  KEY_TYPE key;
-  int copied = 1;
+                   Bucket **bucket, int *offset)
+{
+    Sized *deepest_smaller = NULL;      /* last possibility to move left */
+    int deepest_smaller_is_btree = 0;   /* Boolean; if false, it's a bucket */
+    Bucket *pbucket;
+    int self_got_rebound = 0;   /* Boolean; when true, deactivate self */
+    int result = -1;            /* Until proven innocent */
+    int i;
+    KEY_TYPE key;
+    int copied = 1;
 
-  COPY_KEY_FROM_ARG(key, keyarg, copied);
-  UNLESS (copied) return -1;
+    COPY_KEY_FROM_ARG(key, keyarg, copied);
+    UNLESS (copied)
+        return -1;
 
-  /* We don't need to: PER_USE_OR_RETURN(self, -1);
-     because the caller does. */
-  UNLESS (self->data && self->len) return 0;
+    /* We don't need to: PER_USE_OR_RETURN(self, -1);
+        because the caller does. */
+    UNLESS (self->data && self->len)
+        return 0;
 
-  /* Search downward until hitting a bucket, stored in pbucket. */
-  for (;;) {
-    Sized *pchild;
-    int pchild_is_btree;
+    /* Search downward until hitting a bucket, stored in pbucket. */
+    for (;;)
+    {
+        Sized *pchild;
+        int pchild_is_btree;
 
-    BTREE_SEARCH(i, self, key, goto Done);
-    pchild = self->data[i].child;
-    pchild_is_btree = SameType_Check(self, pchild);
-    if (i) {
-      deepest_smaller = self->data[i-1].child;
-      deepest_smaller_is_btree = pchild_is_btree;
+        BTREE_SEARCH(i, self, key, goto Done);
+        pchild = self->data[i].child;
+        pchild_is_btree = SameType_Check(self, pchild);
+        if (i)
+        {
+            deepest_smaller = self->data[i-1].child;
+            deepest_smaller_is_btree = pchild_is_btree;
+        }
+
+        if (pchild_is_btree)
+        {
+            if (self_got_rebound)
+            {
+                PER_UNUSE(self);
+            }
+            self = BTREE(pchild);
+            self_got_rebound = 1;
+            PER_USE_OR_RETURN(self, -1);
+        }
+        else
+        {
+            pbucket = BUCKET(pchild);
+            break;
+        }
     }
 
-    if (pchild_is_btree) {
-      if (self_got_rebound) {
-        PER_UNUSE(self);
-      }
-      self = BTREE(pchild);
-      self_got_rebound = 1;
-      PER_USE_OR_RETURN(self, -1);
+    /* Search the bucket for a suitable key. */
+    i = Bucket_findRangeEnd(pbucket, keyarg, low, exclude_equal, offset);
+    if (i < 0)
+        goto Done;
+    if (i > 0)
+    {
+        Py_INCREF(pbucket);
+        *bucket = pbucket;
+        result = 1;
+        goto Done;
     }
-    else {
-      pbucket = BUCKET(pchild);
-      break;
-    }
-  }
+    /* This may be one of the two difficult cases detailed in the comments. */
+    if (low)
+    {
+        Bucket *next;
 
-  /* Search the bucket for a suitable key. */
-  i = Bucket_findRangeEnd(pbucket, keyarg, low, exclude_equal, offset);
-  if (i < 0)
-    goto Done;
-  if (i > 0) {
-    Py_INCREF(pbucket);
-    *bucket = pbucket;
-    result = 1;
-    goto Done;
-  }
-  /* This may be one of the two difficult cases detailed in the comments. */
-  if (low) {
-    Bucket *next;
-
-    UNLESS(PER_USE(pbucket)) goto Done;
-    next = pbucket->next;
-    if (next) {
-      result = 1;
-      Py_INCREF(next);
-      *bucket = next;
-      *offset = 0;
+        UNLESS(PER_USE(pbucket)) goto Done;
+        next = pbucket->next;
+        if (next) {
+        result = 1;
+        Py_INCREF(next);
+        *bucket = next;
+        *offset = 0;
+        }
+        else
+        result = 0;
+        PER_UNUSE(pbucket);
     }
+    /* High-end search:  if it's possible to go left, do so. */
+    else if (deepest_smaller)
+    {
+        if (deepest_smaller_is_btree)
+        {
+            UNLESS(PER_USE(deepest_smaller))
+                goto Done;
+            /* We own the reference this returns. */
+            pbucket = BTree_lastBucket(BTREE(deepest_smaller));
+            PER_UNUSE(deepest_smaller);
+            if (pbucket == NULL)
+                    goto Done;   /* error */
+        }
+        else
+        {
+            pbucket = BUCKET(deepest_smaller);
+            Py_INCREF(pbucket);
+        }
+        UNLESS(PER_USE(pbucket))
+            goto Done;
+        result = 1;
+        *bucket = pbucket;  /* transfer ownership to caller */
+        *offset = pbucket->len - 1;
+        PER_UNUSE(pbucket);
+    }
     else
-      result = 0;
-    PER_UNUSE(pbucket);
-  }
-  /* High-end search:  if it's possible to go left, do so. */
-  else if (deepest_smaller) {
-    if (deepest_smaller_is_btree) {
-      UNLESS(PER_USE(deepest_smaller)) goto Done;
-      /* We own the reference this returns. */
-      pbucket = BTree_lastBucket(BTREE(deepest_smaller));
-      PER_UNUSE(deepest_smaller);
-      if (pbucket == NULL) goto Done;   /* error */
+        result = 0;     /* simply not found */
+
+Done:
+    if (self_got_rebound)
+    {
+        PER_UNUSE(self);
     }
-    else {
-      pbucket = BUCKET(deepest_smaller);
-      Py_INCREF(pbucket);
-    }
-    UNLESS(PER_USE(pbucket)) goto Done;
-    result = 1;
-    *bucket = pbucket;  /* transfer ownership to caller */
-    *offset = pbucket->len - 1;
-    PER_UNUSE(pbucket);
-  }
-  else
-    result = 0;     /* simply not found */
-
- Done:
-  if (self_got_rebound) {
-    PER_UNUSE(self);
-  }
-  return result;
+    return result;
 }
 
 static PyObject *
 BTree_maxminKey(BTree *self, PyObject *args, int min)
 {
-  PyObject *key=0;
-  Bucket *bucket = NULL;
-  int offset, rc;
-  int empty_tree = 1;
+    PyObject *key=0;
+    Bucket *bucket = NULL;
+    int offset, rc;
+    int empty_tree = 1;
 
-  UNLESS (PyArg_ParseTuple(args, "|O", &key)) return NULL;
+    UNLESS (PyArg_ParseTuple(args, "|O", &key))
+        return NULL;
 
-  UNLESS (PER_USE(self)) return NULL;
+    UNLESS (PER_USE(self))
+        return NULL;
 
-  UNLESS (self->data && self->len) goto empty;
+    UNLESS (self->data && self->len)
+        goto empty;
 
-  /* Find the  range */
+    /* Find the  range */
 
-  if (key)
+    if (key)
     {
-      if ((rc = BTree_findRangeEnd(self, key, min, 0, &bucket, &offset)) <= 0)
+        if ((rc = BTree_findRangeEnd(self, key, min, 0, &bucket, &offset)) <= 0)
         {
-          if (rc < 0) goto err;
-          empty_tree = 0;
-          goto empty;
+            if (rc < 0)
+                goto err;
+            empty_tree = 0;
+            goto empty;
         }
-      PER_UNUSE(self);
-      UNLESS (PER_USE(bucket))
+        PER_UNUSE(self);
+        UNLESS (PER_USE(bucket))
         {
-          Py_DECREF(bucket);
-          return NULL;
+            Py_DECREF(bucket);
+            return NULL;
         }
     }
-  else if (min)
+    else if (min)
     {
-      bucket = self->firstbucket;
-      PER_UNUSE(self);
-      PER_USE_OR_RETURN(bucket, NULL);
-      Py_INCREF(bucket);
-      offset = 0;
+        bucket = self->firstbucket;
+        PER_UNUSE(self);
+        PER_USE_OR_RETURN(bucket, NULL);
+        Py_INCREF(bucket);
+        offset = 0;
     }
-  else
+    else
     {
-      bucket = BTree_lastBucket(self);
-      PER_UNUSE(self);
-      UNLESS (PER_USE(bucket))
+        bucket = BTree_lastBucket(self);
+        PER_UNUSE(self);
+        UNLESS (PER_USE(bucket))
         {
-          Py_DECREF(bucket);
-          return NULL;
+            Py_DECREF(bucket);
+            return NULL;
         }
-      assert(bucket->len);
-      offset = bucket->len - 1;
+        assert(bucket->len);
+        offset = bucket->len - 1;
     }
 
-  COPY_KEY_TO_OBJECT(key, bucket->keys[offset]);
-  PER_UNUSE(bucket);
-  Py_DECREF(bucket);
+    COPY_KEY_TO_OBJECT(key, bucket->keys[offset]);
+    PER_UNUSE(bucket);
+    Py_DECREF(bucket);
 
-  return key;
+    return key;
 
- empty:
-  PyErr_SetString(PyExc_ValueError,
-                  empty_tree ? "empty tree" :
-                  "no key satisfies the conditions");
- err:
-  PER_UNUSE(self);
-  if (bucket)
+empty:
+    PyErr_SetString(PyExc_ValueError,
+                    empty_tree ? "empty tree" :
+                    "no key satisfies the conditions");
+err:
+    PER_UNUSE(self);
+    if (bucket)
     {
-      PER_UNUSE(bucket);
-      Py_DECREF(bucket);
+        PER_UNUSE(bucket);
+        Py_DECREF(bucket);
     }
   return NULL;
 }
@@ -1453,13 +1566,13 @@
 static PyObject *
 BTree_minKey(BTree *self, PyObject *args)
 {
-  return BTree_maxminKey(self, args, 1);
+    return BTree_maxminKey(self, args, 1);
 }
 
 static PyObject *
 BTree_maxKey(BTree *self, PyObject *args)
 {
-  return BTree_maxminKey(self, args, 0);
+    return BTree_maxminKey(self, args, 0);
 }
 
 /*
@@ -1472,159 +1585,184 @@
 static PyObject *
 BTree_rangeSearch(BTree *self, PyObject *args, PyObject *kw, char type)
 {
-  PyObject *min = Py_None;
-  PyObject *max = Py_None;
-  int excludemin = 0;
-  int excludemax = 0;
-  int rc;
-  Bucket *lowbucket = NULL;
-  Bucket *highbucket = NULL;
-  int lowoffset;
-  int highoffset;
-  PyObject *result;
+    PyObject *min = Py_None;
+    PyObject *max = Py_None;
+    int excludemin = 0;
+    int excludemax = 0;
+    int rc;
+    Bucket *lowbucket = NULL;
+    Bucket *highbucket = NULL;
+    int lowoffset;
+    int highoffset;
+    PyObject *result;
 
-  if (args) {
-    if (! PyArg_ParseTupleAndKeywords(args, kw, "|OOii", search_keywords,
-                                      &min,
-                                      &max,
-                                      &excludemin,
-                                      &excludemax))
-      return NULL;
-  }
+    if (args)
+    {
+        if (! PyArg_ParseTupleAndKeywords(args, kw, "|OOii", search_keywords,
+                                        &min,
+                                        &max,
+                                        &excludemin,
+                                        &excludemax))
+        return NULL;
+    }
 
-  UNLESS (PER_USE(self)) return NULL;
+    UNLESS (PER_USE(self))
+        return NULL;
 
-  UNLESS (self->data && self->len) goto empty;
+    UNLESS (self->data && self->len)
+        goto empty;
 
-  /* Find the low range */
-  if (min != Py_None) {
-    if ((rc = BTree_findRangeEnd(self, min, 1, excludemin,
-                                 &lowbucket, &lowoffset)) <= 0) {
-      if (rc < 0) goto err;
-      goto empty;
+    /* Find the low range */
+    if (min != Py_None)
+    {
+        if ((rc = BTree_findRangeEnd(self, min, 1, excludemin,
+                                    &lowbucket, &lowoffset)) <= 0)
+        {
+            if (rc < 0)
+                goto err;
+            goto empty;
+        }
     }
-  }
-  else {
-    lowbucket = self->firstbucket;
-    lowoffset = 0;
-    if (excludemin) {
-      int bucketlen;
-      UNLESS (PER_USE(lowbucket)) goto err;
-      bucketlen = lowbucket->len;
-      PER_UNUSE(lowbucket);
-      if (bucketlen > 1)
-        lowoffset = 1;
-      else if (self->len < 2)
-        goto empty;
-      else {	/* move to first item in next bucket */
-        Bucket *next;
-        UNLESS (PER_USE(lowbucket)) goto err;
-        next = lowbucket->next;
-        PER_UNUSE(lowbucket);
-        assert(next != NULL);
-        lowbucket = next;
-        /* and lowoffset is still 0 */
-        assert(lowoffset == 0);
-      }
+    else
+    {
+        lowbucket = self->firstbucket;
+        lowoffset = 0;
+        if (excludemin)
+        {
+            int bucketlen;
+            UNLESS (PER_USE(lowbucket))
+                goto err;
+            bucketlen = lowbucket->len;
+            PER_UNUSE(lowbucket);
+            if (bucketlen > 1)
+                lowoffset = 1;
+            else if (self->len < 2)
+                goto empty;
+            else
+            {    /* move to first item in next bucket */
+                Bucket *next;
+                UNLESS (PER_USE(lowbucket))
+                    goto err;
+                next = lowbucket->next;
+                PER_UNUSE(lowbucket);
+                assert(next != NULL);
+                lowbucket = next;
+                /* and lowoffset is still 0 */
+                assert(lowoffset == 0);
+            }
+        }
+        Py_INCREF(lowbucket);
     }
-    Py_INCREF(lowbucket);
-  }
 
-  /* Find the high range */
-  if (max != Py_None) {
-    if ((rc = BTree_findRangeEnd(self, max, 0, excludemax,
-                                 &highbucket, &highoffset)) <= 0) {
-      Py_DECREF(lowbucket);
-      if (rc < 0) goto err;
-      goto empty;
+    /* Find the high range */
+    if (max != Py_None)
+    {
+        if ((rc = BTree_findRangeEnd(self, max, 0, excludemax,
+                                    &highbucket, &highoffset)) <= 0)
+        {
+            Py_DECREF(lowbucket);
+            if (rc < 0)
+                goto err;
+            goto empty;
+        }
     }
-  }
-  else {
-    int bucketlen;
-    highbucket = BTree_lastBucket(self);
-    assert(highbucket != NULL);  /* we know self isn't empty */
-    UNLESS (PER_USE(highbucket)) goto err_and_decref_buckets;
-    bucketlen = highbucket->len;
-    PER_UNUSE(highbucket);
-    highoffset = bucketlen - 1;
-    if (excludemax) {
-      if (highoffset > 0)
-        --highoffset;
-      else if (self->len < 2)
-        goto empty_and_decref_buckets;
-      else {	/* move to last item of preceding bucket */
-        int status;
-        assert(highbucket != self->firstbucket);
-        Py_DECREF(highbucket);
-        status = PreviousBucket(&highbucket, self->firstbucket);
-        if (status < 0) {
-          Py_DECREF(lowbucket);
-          goto err;
+    else
+    {
+        int bucketlen;
+        highbucket = BTree_lastBucket(self);
+        assert(highbucket != NULL);  /* we know self isn't empty */
+        UNLESS (PER_USE(highbucket))
+            goto err_and_decref_buckets;
+        bucketlen = highbucket->len;
+        PER_UNUSE(highbucket);
+        highoffset = bucketlen - 1;
+        if (excludemax)
+        {
+            if (highoffset > 0)
+                --highoffset;
+            else if (self->len < 2)
+                goto empty_and_decref_buckets;
+            else /* move to last item of preceding bucket */
+            {
+                int status;
+                assert(highbucket != self->firstbucket);
+                Py_DECREF(highbucket);
+                status = PreviousBucket(&highbucket, self->firstbucket);
+                if (status < 0)
+                {
+                    Py_DECREF(lowbucket);
+                    goto err;
+                }
+                assert(status > 0);
+                Py_INCREF(highbucket);
+                UNLESS (PER_USE(highbucket))
+                    goto err_and_decref_buckets;
+                highoffset = highbucket->len - 1;
+                PER_UNUSE(highbucket);
+            }
         }
-        assert(status > 0);
-        Py_INCREF(highbucket);
-        UNLESS (PER_USE(highbucket)) goto err_and_decref_buckets;
-        highoffset = highbucket->len - 1;
-        PER_UNUSE(highbucket);
-      }
+        assert(highoffset >= 0);
     }
-    assert(highoffset >= 0);
-  }
 
-  /* It's still possible that the range is empty, even if min < max.  For
-   * example, if min=3 and max=4, and 3 and 4 aren't in the BTree, but 2 and
-   * 5 are, then the low position points to the 5 now and the high position
-   * points to the 2 now.  They're not necessarily even in the same bucket,
-   * so there's no trick we can play with pointer compares to get out
-   * cheap in general.
-   */
-  if (lowbucket == highbucket && lowoffset > highoffset)
-    goto empty_and_decref_buckets;      /* definitely empty */
+    /* It's still possible that the range is empty, even if min < max.  For
+    * example, if min=3 and max=4, and 3 and 4 aren't in the BTree, but 2 and
+    * 5 are, then the low position points to the 5 now and the high position
+    * points to the 2 now.  They're not necessarily even in the same bucket,
+    * so there's no trick we can play with pointer compares to get out
+    * cheap in general.
+    */
+    if (lowbucket == highbucket && lowoffset > highoffset)
+        goto empty_and_decref_buckets;      /* definitely empty */
 
-  /* The buckets differ, or they're the same and the offsets show a non-
-   * empty range.
-   */
-  if (min != Py_None && max != Py_None && /* both args user-supplied */
-      lowbucket != highbucket)   /* and different buckets */ {
-    KEY_TYPE first;
-    KEY_TYPE last;
-    int cmp;
+    /* The buckets differ, or they're the same and the offsets show a non-
+    * empty range.
+    */
+    if (min != Py_None && max != Py_None && /* both args user-supplied */
+        lowbucket != highbucket)   /* and different buckets */
+    {
+        KEY_TYPE first;
+        KEY_TYPE last;
+        int cmp;
 
-    /* Have to check the hard way:  see how the endpoints compare. */
-    UNLESS (PER_USE(lowbucket)) goto err_and_decref_buckets;
-    COPY_KEY(first, lowbucket->keys[lowoffset]);
-    PER_UNUSE(lowbucket);
+        /* Have to check the hard way:  see how the endpoints compare. */
+        UNLESS (PER_USE(lowbucket))
+            goto err_and_decref_buckets;
+        COPY_KEY(first, lowbucket->keys[lowoffset]);
+        PER_UNUSE(lowbucket);
 
-    UNLESS (PER_USE(highbucket)) goto err_and_decref_buckets;
-    COPY_KEY(last, highbucket->keys[highoffset]);
-    PER_UNUSE(highbucket);
+        UNLESS (PER_USE(highbucket))
+            goto err_and_decref_buckets;
+        COPY_KEY(last, highbucket->keys[highoffset]);
+        PER_UNUSE(highbucket);
 
-    TEST_KEY_SET_OR(cmp, first, last) goto err_and_decref_buckets;
-    if (cmp > 0) goto empty_and_decref_buckets;
-  }
+        TEST_KEY_SET_OR(cmp, first, last)
+            goto err_and_decref_buckets;
+        if (cmp > 0)
+                goto empty_and_decref_buckets;
+    }
 
-  PER_UNUSE(self);
+    PER_UNUSE(self);
 
-  result = newBTreeItems(type, lowbucket, lowoffset, highbucket, highoffset);
-  Py_DECREF(lowbucket);
-  Py_DECREF(highbucket);
-  return result;
+    result = newBTreeItems(type, lowbucket, lowoffset, highbucket, highoffset);
+    Py_DECREF(lowbucket);
+    Py_DECREF(highbucket);
+    return result;
 
- err_and_decref_buckets:
-  Py_DECREF(lowbucket);
-  Py_DECREF(highbucket);
+err_and_decref_buckets:
+    Py_DECREF(lowbucket);
+    Py_DECREF(highbucket);
 
- err:
-  PER_UNUSE(self);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    return NULL;
 
- empty_and_decref_buckets:
-  Py_DECREF(lowbucket);
-  Py_DECREF(highbucket);
+empty_and_decref_buckets:
+    Py_DECREF(lowbucket);
+    Py_DECREF(highbucket);
 
- empty:
-  PER_UNUSE(self);
-  return newBTreeItems(type, 0, 0, 0, 0);
+empty:
+    PER_UNUSE(self);
+    return newBTreeItems(type, 0, 0, 0, 0);
 }
 
 /*
@@ -1633,7 +1771,7 @@
 static PyObject *
 BTree_keys(BTree *self, PyObject *args, PyObject *kw)
 {
-  return BTree_rangeSearch(self, args, kw, 'k');
+    return BTree_rangeSearch(self, args, kw, 'k');
 }
 
 /*
@@ -1642,7 +1780,7 @@
 static PyObject *
 BTree_values(BTree *self, PyObject *args, PyObject *kw)
 {
-  return BTree_rangeSearch(self, args, kw, 'v');
+    return BTree_rangeSearch(self, args, kw, 'v');
 }
 
 /*
@@ -1651,74 +1789,88 @@
 static PyObject *
 BTree_items(BTree *self, PyObject *args, PyObject *kw)
 {
-  return BTree_rangeSearch(self, args, kw, 'i');
+    return BTree_rangeSearch(self, args, kw, 'i');
 }
 
 static PyObject *
 BTree_byValue(BTree *self, PyObject *omin)
 {
-  PyObject *r=0, *o=0, *item=0;
-  VALUE_TYPE min;
-  VALUE_TYPE v;
-  int copied=1;
-  SetIteration it = {0, 0, 1};
+    PyObject *r=0, *o=0, *item=0;
+    VALUE_TYPE min;
+    VALUE_TYPE v;
+    int copied=1;
+    SetIteration it = {0, 0, 1};
 
-  UNLESS (PER_USE(self)) return NULL;
+    UNLESS (PER_USE(self))
+        return NULL;
 
-  COPY_VALUE_FROM_ARG(min, omin, copied);
-  UNLESS(copied) return NULL;
+    COPY_VALUE_FROM_ARG(min, omin, copied);
+    UNLESS(copied)
+        return NULL;
 
-  UNLESS (r=PyList_New(0)) goto err;
+    UNLESS (r=PyList_New(0))
+        goto err;
 
-  it.set=BTree_rangeSearch(self, NULL, NULL, 'i');
-  UNLESS(it.set) goto err;
+    it.set=BTree_rangeSearch(self, NULL, NULL, 'i');
+    UNLESS(it.set)
+        goto err;
 
-  if (nextBTreeItems(&it) < 0) goto err;
+    if (nextBTreeItems(&it) < 0)
+        goto err;
 
-  while (it.position >= 0)
+    while (it.position >= 0)
     {
-      if (TEST_VALUE(it.value, min) >= 0)
+        if (TEST_VALUE(it.value, min) >= 0)
         {
-          UNLESS (item = PyTuple_New(2)) goto err;
+            UNLESS (item = PyTuple_New(2))
+                goto err;
 
-          COPY_KEY_TO_OBJECT(o, it.key);
-          UNLESS (o) goto err;
-          PyTuple_SET_ITEM(item, 1, o);
+            COPY_KEY_TO_OBJECT(o, it.key);
+            UNLESS (o)
+                goto err;
+            PyTuple_SET_ITEM(item, 1, o);
 
-          COPY_VALUE(v, it.value);
-          NORMALIZE_VALUE(v, min);
-          COPY_VALUE_TO_OBJECT(o, v);
-          DECREF_VALUE(v);
-          UNLESS (o) goto err;
-          PyTuple_SET_ITEM(item, 0, o);
+            COPY_VALUE(v, it.value);
+            NORMALIZE_VALUE(v, min);
+            COPY_VALUE_TO_OBJECT(o, v);
+            DECREF_VALUE(v);
+            UNLESS (o)
+                goto err;
+            PyTuple_SET_ITEM(item, 0, o);
 
-          if (PyList_Append(r, item) < 0) goto err;
-          Py_DECREF(item);
-          item = 0;
+            if (PyList_Append(r, item) < 0)
+                goto err;
+            Py_DECREF(item);
+            item = 0;
         }
-      if (nextBTreeItems(&it) < 0) goto err;
+        if (nextBTreeItems(&it) < 0)
+            goto err;
     }
 
-  item=PyObject_GetAttr(r,sort_str);
-  UNLESS (item) goto err;
-  ASSIGN(item, PyObject_CallObject(item, NULL));
-  UNLESS (item) goto err;
-  ASSIGN(item, PyObject_GetAttr(r, reverse_str));
-  UNLESS (item) goto err;
-  ASSIGN(item, PyObject_CallObject(item, NULL));
-  UNLESS (item) goto err;
-  Py_DECREF(item);
+    item=PyObject_GetAttr(r,sort_str);
+    UNLESS (item)
+        goto err;
+    ASSIGN(item, PyObject_CallObject(item, NULL));
+    UNLESS (item)
+        goto err;
+    ASSIGN(item, PyObject_GetAttr(r, reverse_str));
+    UNLESS (item)
+        goto err;
+    ASSIGN(item, PyObject_CallObject(item, NULL));
+    UNLESS (item)
+        goto err;
+    Py_DECREF(item);
 
-  finiSetIteration(&it);
-  PER_UNUSE(self);
-  return r;
+    finiSetIteration(&it);
+    PER_UNUSE(self);
+    return r;
 
- err:
-  PER_UNUSE(self);
-  Py_XDECREF(r);
-  finiSetIteration(&it);
-  Py_XDECREF(item);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    Py_XDECREF(r);
+    finiSetIteration(&it);
+    Py_XDECREF(item);
+    return NULL;
 }
 
 /*
@@ -1727,49 +1879,52 @@
 static PyObject *
 BTree_getm(BTree *self, PyObject *args)
 {
-  PyObject *key, *d=Py_None, *r;
+    PyObject *key, *d=Py_None, *r;
 
-  UNLESS (PyArg_ParseTuple(args, "O|O", &key, &d)) return NULL;
-  if ((r=_BTree_get(self, key, 0))) return r;
-  UNLESS (PyErr_ExceptionMatches(PyExc_KeyError)) return NULL;
-  PyErr_Clear();
-  Py_INCREF(d);
-  return d;
+    UNLESS (PyArg_ParseTuple(args, "O|O", &key, &d))
+        return NULL;
+    if ((r=_BTree_get(self, key, 0)))
+        return r;
+    UNLESS (PyErr_ExceptionMatches(PyExc_KeyError))
+        return NULL;
+    PyErr_Clear();
+    Py_INCREF(d);
+    return d;
 }
 
 static PyObject *
 BTree_has_key(BTree *self, PyObject *key)
 {
-  return _BTree_get(self, key, 1);
+    return _BTree_get(self, key, 1);
 }
 
 static PyObject *
 BTree_setdefault(BTree *self, PyObject *args)
 {
-  PyObject *key;
-  PyObject *failobj; /* default */
-  PyObject *value;   /* return value */
+    PyObject *key;
+    PyObject *failobj; /* default */
+    PyObject *value;   /* return value */
 
-  if (! PyArg_UnpackTuple(args, "setdefault", 2, 2, &key, &failobj))
-    return NULL;
+    if (! PyArg_UnpackTuple(args, "setdefault", 2, 2, &key, &failobj))
+        return NULL;
 
-  value = _BTree_get(self, key, 0);
-  if (value != NULL)
-    return value;
+    value = _BTree_get(self, key, 0);
+    if (value != NULL)
+        return value;
 
-  /* The key isn't in the tree.  If that's not due to a KeyError exception,
-   * pass back the unexpected exception.
-   */
-  if (! PyErr_ExceptionMatches(PyExc_KeyError))
-    return NULL;
-  PyErr_Clear();
+    /* The key isn't in the tree.  If that's not due to a KeyError exception,
+    * pass back the unexpected exception.
+    */
+    if (! PyErr_ExceptionMatches(PyExc_KeyError))
+        return NULL;
+    PyErr_Clear();
 
-  /* Associate `key` with `failobj` in the tree, and return `failobj`. */
-  value = failobj;
-  if (_BTree_set(self, key, failobj, 0, 0) < 0)
-    value = NULL;
-  Py_XINCREF(value);
-  return value;
+    /* Associate `key` with `failobj` in the tree, and return `failobj`. */
+    value = failobj;
+    if (_BTree_set(self, key, failobj, 0, 0) < 0)
+        value = NULL;
+    Py_XINCREF(value);
+    return value;
 }
 
 /* forward declaration */
@@ -1779,42 +1934,45 @@
 static PyObject *
 BTree_pop(BTree *self, PyObject *args)
 {
-  PyObject *key;
-  PyObject *failobj = NULL; /* default */
-  PyObject *value;          /* return value */
+    PyObject *key;
+    PyObject *failobj = NULL; /* default */
+    PyObject *value;          /* return value */
 
-  if (! PyArg_UnpackTuple(args, "pop", 1, 2, &key, &failobj))
-    return NULL;
+    if (! PyArg_UnpackTuple(args, "pop", 1, 2, &key, &failobj))
+        return NULL;
 
-  value = _BTree_get(self, key, 0);
-  if (value != NULL) {
-    /* Delete key and associated value. */
-    if (_BTree_set(self, key, NULL, 0, 0) < 0) {
-      Py_DECREF(value);
-      return NULL;;
+    value = _BTree_get(self, key, 0);
+    if (value != NULL)
+    {
+        /* Delete key and associated value. */
+        if (_BTree_set(self, key, NULL, 0, 0) < 0)
+        {
+            Py_DECREF(value);
+            return NULL;;
+        }
+        return value;
     }
-    return value;
-  }
 
-  /* The key isn't in the tree.  If that's not due to a KeyError exception,
-   * pass back the unexpected exception.
-   */
-  if (! PyErr_ExceptionMatches(PyExc_KeyError))
-    return NULL;
+    /* The key isn't in the tree.  If that's not due to a KeyError exception,
+    * pass back the unexpected exception.
+    */
+    if (! PyErr_ExceptionMatches(PyExc_KeyError))
+        return NULL;
 
-  if (failobj != NULL) {
-    /* Clear the KeyError and return the explicit default. */
-    PyErr_Clear();
-    Py_INCREF(failobj);
-    return failobj;
-  }
+    if (failobj != NULL)
+    {
+        /* Clear the KeyError and return the explicit default. */
+        PyErr_Clear();
+        Py_INCREF(failobj);
+        return failobj;
+    }
 
-  /* No default given.  The only difference in this case is the error
-   * message, which depends on whether the tree is empty.
-   */
-  if (BTree_length_or_nonzero(self, 1) == 0) /* tree is empty */
-    PyErr_SetString(PyExc_KeyError, "pop(): BTree is empty");
-  return NULL;
+    /* No default given.  The only difference in this case is the error
+    * message, which depends on whether the tree is empty.
+    */
+    if (BTree_length_or_nonzero(self, 1) == 0) /* tree is empty */
+        PyErr_SetString(PyExc_KeyError, "pop(): BTree is empty");
+    return NULL;
 }
 
 /* Search BTree self for key.  This is the sq_contains slot of the
@@ -1828,26 +1986,29 @@
 static int
 BTree_contains(BTree *self, PyObject *key)
 {
-  PyObject *asobj = _BTree_get(self, key, 1);
-  int result = -1;
+    PyObject *asobj = _BTree_get(self, key, 1);
+    int result = -1;
 
-  if (asobj != NULL) {
-    result = PyInt_AsLong(asobj) ? 1 : 0;
-    Py_DECREF(asobj);
-  }
-  return result;
+    if (asobj != NULL)
+    {
+        result = INT_AS_LONG(asobj) ? 1 : 0;
+        Py_DECREF(asobj);
+    }
+    return result;
 }
 
 static PyObject *
 BTree_addUnique(BTree *self, PyObject *args)
 {
-  int grew;
-  PyObject *key, *v;
+    int grew;
+    PyObject *key, *v;
 
-  UNLESS (PyArg_ParseTuple(args, "OO", &key, &v)) return NULL;
+    UNLESS (PyArg_ParseTuple(args, "OO", &key, &v))
+        return NULL;
 
-  if ((grew=_BTree_set(self, key, v, 1, 0)) < 0) return NULL;
-  return PyInt_FromLong(grew);
+    if ((grew=_BTree_set(self, key, v, 1, 0)) < 0)
+        return NULL;
+    return INT_FROM_LONG(grew);
 }
 
 /**************************************************************************/
@@ -1862,42 +2023,43 @@
 static PyObject *
 buildBTreeIter(BTree *self, PyObject *args, PyObject *kw, char kind)
 {
-  BTreeIter *result = NULL;
-  BTreeItems *items = (BTreeItems *)BTree_rangeSearch(self, args, kw, kind);
+    BTreeIter *result = NULL;
+    BTreeItems *items = (BTreeItems *)BTree_rangeSearch(self, args, kw, kind);
 
-  if (items) {
-    result = BTreeIter_new(items);
-    Py_DECREF(items);
-  }
-  return (PyObject *)result;
+    if (items)
+    {
+        result = BTreeIter_new(items);
+        Py_DECREF(items);
+    }
+    return (PyObject *)result;
 }
 
 /* The implementation of iter(BTree_or_TreeSet); the BTree tp_iter slot. */
 static PyObject *
 BTree_getiter(BTree *self)
 {
-  return buildBTreeIter(self, NULL, NULL, 'k');
+    return buildBTreeIter(self, NULL, NULL, 'k');
 }
 
 /* The implementation of BTree.iterkeys(). */
 static PyObject *
 BTree_iterkeys(BTree *self, PyObject *args, PyObject *kw)
 {
-  return buildBTreeIter(self, args, kw, 'k');
+    return buildBTreeIter(self, args, kw, 'k');
 }
 
 /* The implementation of BTree.itervalues(). */
 static PyObject *
 BTree_itervalues(BTree *self, PyObject *args, PyObject *kw)
 {
-  return buildBTreeIter(self, args, kw, 'v');
+    return buildBTreeIter(self, args, kw, 'v');
 }
 
 /* The implementation of BTree.iteritems(). */
 static PyObject *
 BTree_iteritems(BTree *self, PyObject *args, PyObject *kw)
 {
-  return buildBTreeIter(self, args, kw, 'i');
+    return buildBTreeIter(self, args, kw, 'i');
 }
 
 /* End of iterator support. */
@@ -1912,130 +2074,132 @@
 */
 
 static struct PyMemberDef BTree_members[] = {
-  {"_firstbucket", T_OBJECT, offsetof(BTree, firstbucket), RO},
-  {NULL}
+    {"_firstbucket", T_OBJECT, offsetof(BTree, firstbucket), READONLY},
+    {NULL}
 };
 
 static struct PyMethodDef BTree_methods[] = {
-  {"__getstate__", (PyCFunction) BTree_getstate,	METH_NOARGS,
-   "__getstate__() -> state\n\n"
-   "Return the picklable state of the BTree."},
+    {"__getstate__", (PyCFunction) BTree_getstate, METH_NOARGS,
+     "__getstate__() -> state\n\n"
+     "Return the picklable state of the BTree."},
 
-  {"__setstate__", (PyCFunction) BTree_setstate,	METH_O,
-   "__setstate__(state)\n\n"
-   "Set the state of the BTree."},
+    {"__setstate__", (PyCFunction) BTree_setstate, METH_O,
+     "__setstate__(state)\n\n"
+     "Set the state of the BTree."},
 
-  {"has_key",	(PyCFunction) BTree_has_key,	METH_O,
-   "has_key(key)\n\n"
-   "Return true if the BTree contains the given key."},
+    {"has_key", (PyCFunction) BTree_has_key, METH_O,
+     "has_key(key)\n\n"
+     "Return true if the BTree contains the given key."},
 
-  {"keys",	(PyCFunction) BTree_keys,	METH_KEYWORDS,
-   "keys([min, max]) -> list of keys\n\n"
-   "Returns the keys of the BTree.  If min and max are supplied, only\n"
-   "keys greater than min and less than max are returned."},
+    {"keys", (PyCFunction) BTree_keys, METH_VARARGS | METH_KEYWORDS,
+     "keys([min, max]) -> list of keys\n\n"
+     "Returns the keys of the BTree.  If min and max are supplied, only\n"
+     "keys greater than min and less than max are returned."},
 
-  {"values",	(PyCFunction) BTree_values,	METH_KEYWORDS,
-   "values([min, max]) -> list of values\n\n"
-   "Returns the values of the BTree.  If min and max are supplied, only\n"
-   "values corresponding to keys greater than min and less than max are\n"
-   "returned."},
+    {"values", (PyCFunction) BTree_values, METH_VARARGS | METH_KEYWORDS,
+     "values([min, max]) -> list of values\n\n"
+     "Returns the values of the BTree.  If min and max are supplied, only\n"
+     "values corresponding to keys greater than min and less than max are\n"
+     "returned."},
 
-  {"items",	(PyCFunction) BTree_items,	METH_KEYWORDS,
-   "items([min, max]) -> -- list of key, value pairs\n\n"
-   "Returns the items of the BTree.  If min and max are supplied, only\n"
-   "items with keys greater than min and less than max are returned."},
+    {"items", (PyCFunction) BTree_items, METH_VARARGS | METH_KEYWORDS,
+     "items([min, max]) -> -- list of key, value pairs\n\n"
+     "Returns the items of the BTree.  If min and max are supplied, only\n"
+     "items with keys greater than min and less than max are returned."},
 
-  {"byValue",	(PyCFunction) BTree_byValue,	METH_O,
-   "byValue(min) ->  list of value, key pairs\n\n"
-   "Returns list of value, key pairs where the value is >= min.  The\n"
-   "list is sorted by value.  Note that items() returns keys in the\n"
-   "opposite order."},
+    {"byValue", (PyCFunction) BTree_byValue, METH_O,
+     "byValue(min) ->  list of value, key pairs\n\n"
+     "Returns list of value, key pairs where the value is >= min.  The\n"
+     "list is sorted by value.  Note that items() returns keys in the\n"
+     "opposite order."},
 
-  {"get",	(PyCFunction) BTree_getm,	METH_VARARGS,
-   "get(key[, default=None]) -> Value for key or default\n\n"
-   "Return the value or the default if the key is not found."},
+    {"get", (PyCFunction) BTree_getm, METH_VARARGS,
+     "get(key[, default=None]) -> Value for key or default\n\n"
+     "Return the value or the default if the key is not found."},
 
-  {"setdefault", (PyCFunction) BTree_setdefault, METH_VARARGS,
-   "D.setdefault(k, d) -> D.get(k, d), also set D[k]=d if k not in D.\n\n"
-   "Return the value like get() except that if key is missing, d is both\n"
-   "returned and inserted into the BTree as the value of k."},
+    {"setdefault", (PyCFunction) BTree_setdefault, METH_VARARGS,
+     "D.setdefault(k, d) -> D.get(k, d), also set D[k]=d if k not in D.\n\n"
+     "Return the value like get() except that if key is missing, d is both\n"
+     "returned and inserted into the BTree as the value of k."},
 
-  {"pop", (PyCFunction) BTree_pop, METH_VARARGS,
-   "D.pop(k[, d]) -> v, remove key and return the corresponding value.\n\n"
-   "If key is not found, d is returned if given, otherwise KeyError\n"
-   "is raised."},
+    {"pop", (PyCFunction) BTree_pop, METH_VARARGS,
+     "D.pop(k[, d]) -> v, remove key and return the corresponding value.\n\n"
+     "If key is not found, d is returned if given, otherwise KeyError\n"
+     "is raised."},
 
-  {"maxKey", (PyCFunction) BTree_maxKey,	METH_VARARGS,
-   "maxKey([max]) -> key\n\n"
-   "Return the largest key in the BTree.  If max is specified, return\n"
-   "the largest key <= max."},
+    {"maxKey", (PyCFunction) BTree_maxKey, METH_VARARGS,
+     "maxKey([max]) -> key\n\n"
+     "Return the largest key in the BTree.  If max is specified, return\n"
+     "the largest key <= max."},
 
-  {"minKey", (PyCFunction) BTree_minKey,	METH_VARARGS,
-   "minKey([mi]) -> key\n\n"
-   "Return the smallest key in the BTree.  If min is specified, return\n"
-   "the smallest key >= min."},
+    {"minKey", (PyCFunction) BTree_minKey, METH_VARARGS,
+     "minKey([mi]) -> key\n\n"
+     "Return the smallest key in the BTree.  If min is specified, return\n"
+     "the smallest key >= min."},
 
-  {"clear",	(PyCFunction) BTree_clear,	METH_NOARGS,
-   "clear()\n\nRemove all of the items from the BTree."},
+    {"clear", (PyCFunction) BTree_clear, METH_NOARGS,
+     "clear()\n\nRemove all of the items from the BTree."},
 
-  {"insert", (PyCFunction)BTree_addUnique, METH_VARARGS,
-   "insert(key, value) -> 0 or 1\n\n"
-   "Add an item if the key is not already used. Return 1 if the item was\n"
-   "added, or 0 otherwise."},
+    {"insert", (PyCFunction)BTree_addUnique, METH_VARARGS,
+     "insert(key, value) -> 0 or 1\n\n"
+     "Add an item if the key is not already used. Return 1 if the item was\n"
+     "added, or 0 otherwise."},
 
-  {"update",	(PyCFunction) Mapping_update,	METH_O,
-   "update(collection)\n\n Add the items from the given collection."},
+    {"update", (PyCFunction) Mapping_update, METH_O,
+     "update(collection)\n\n Add the items from the given collection."},
 
-  {"iterkeys", (PyCFunction) BTree_iterkeys,  METH_KEYWORDS,
-   "B.iterkeys([min[,max]]) -> an iterator over the keys of B"},
+    {"iterkeys", (PyCFunction) BTree_iterkeys, METH_VARARGS | METH_KEYWORDS,
+     "B.iterkeys([min[,max]]) -> an iterator over the keys of B"},
 
-  {"itervalues", (PyCFunction) BTree_itervalues,  METH_KEYWORDS,
-   "B.itervalues([min[,max]]) -> an iterator over the values of B"},
+    {"itervalues", (PyCFunction) BTree_itervalues, METH_VARARGS | METH_KEYWORDS,
+     "B.itervalues([min[,max]]) -> an iterator over the values of B"},
 
-  {"iteritems", (PyCFunction) BTree_iteritems,    METH_KEYWORDS,
-   "B.iteritems([min[,max]]) -> an iterator over the (key, value) items of B"},
+    {"iteritems", (PyCFunction) BTree_iteritems, METH_VARARGS | METH_KEYWORDS,
+     "B.iteritems([min[,max]]) -> an iterator over the (key, value) "
+     "items of B"},
 
-  {"_check", (PyCFunction) BTree_check,       METH_NOARGS,
-   "Perform sanity check on BTree, and raise exception if flawed."},
+    {"_check", (PyCFunction) BTree_check, METH_NOARGS,
+     "Perform sanity check on BTree, and raise exception if flawed."},
 
 #ifdef PERSISTENT
-  {"_p_resolveConflict", (PyCFunction) BTree__p_resolveConflict,
-   METH_VARARGS,
-   "_p_resolveConflict() -- Reinitialize from a newly created copy"},
+    {"_p_resolveConflict",
+     (PyCFunction) BTree__p_resolveConflict, METH_VARARGS,
+     "_p_resolveConflict() -- Reinitialize from a newly created copy"},
 
-  {"_p_deactivate", (PyCFunction) BTree__p_deactivate,	METH_KEYWORDS,
-   "_p_deactivate()\n\nReinitialize from a newly created copy."},
+    {"_p_deactivate",
+     (PyCFunction) BTree__p_deactivate, METH_VARARGS | METH_KEYWORDS,
+     "_p_deactivate()\n\nReinitialize from a newly created copy."},
 #endif
-  {NULL, NULL}
+    {NULL, NULL}
 };
 
 static int
 BTree_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
-  PyObject *v = NULL;
+    PyObject *v = NULL;
 
-  if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "BTree", &v))
-    return -1;
+    if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "BTree", &v))
+        return -1;
 
-  if (v)
-    return update_from_seq(self, v);
-  else
-    return 0;
+    if (v)
+        return update_from_seq(self, v);
+    else
+        return 0;
 }
 
 static void
 BTree_dealloc(BTree *self)
 {
-  if (self->state != cPersistent_GHOST_STATE)
-    _BTree_clear(self);
-  cPersistenceCAPI->pertype->tp_dealloc((PyObject *)self);
+    if (self->state != cPersistent_GHOST_STATE)
+        _BTree_clear(self);
+    cPersistenceCAPI->pertype->tp_dealloc((PyObject *)self);
 }
 
 static int
 BTree_traverse(BTree *self, visitproc visit, void *arg)
 {
-  int err = 0;
-  int i, len;
+    int err = 0;
+    int i, len;
 
 #define VISIT(SLOT)                             \
   if (SLOT) {                                   \
@@ -2044,40 +2208,40 @@
       goto Done;                                \
   }
 
-  if (self->ob_type == &BTreeType)
-    assert(self->ob_type->tp_dictoffset == 0);
+    if (Py_TYPE(self) == &BTreeType)
+        assert(Py_TYPE(self)->tp_dictoffset == 0);
 
-  /* Call our base type's traverse function.  Because BTrees are
-   * subclasses of Peristent, there must be one.
-   */
-  err = cPersistenceCAPI->pertype->tp_traverse((PyObject *)self, visit, arg);
-  if (err)
-    goto Done;
+    /* Call our base type's traverse function.  Because BTrees are
+    * subclasses of Peristent, there must be one.
+    */
+    err = cPersistenceCAPI->pertype->tp_traverse((PyObject *)self, visit, arg);
+    if (err)
+        goto Done;
 
-  /* If this is registered with the persistence system, cleaning up cycles
-   * is the database's problem.  It would be horrid to unghostify BTree
-   * nodes here just to chase pointers every time gc runs.
-   */
-  if (self->state == cPersistent_GHOST_STATE)
-    goto Done;
+    /* If this is registered with the persistence system, cleaning up cycles
+    * is the database's problem.  It would be horrid to unghostify BTree
+    * nodes here just to chase pointers every time gc runs.
+    */
+    if (self->state == cPersistent_GHOST_STATE)
+        goto Done;
 
-  len = self->len;
+    len = self->len;
 #ifdef KEY_TYPE_IS_PYOBJECT
-  /* Keys are Python objects so need to be traversed.  Note that the
-   * key 0 slot is unused and should not be traversed.
-   */
-  for (i = 1; i < len; i++)
-    VISIT(self->data[i].key);
+    /* Keys are Python objects so need to be traversed.  Note that the
+    * key 0 slot is unused and should not be traversed.
+    */
+    for (i = 1; i < len; i++)
+        VISIT(self->data[i].key);
 #endif
 
-  /* Children are always pointers, and child 0 is legit. */
-  for (i = 0; i < len; i++)
-    VISIT(self->data[i].child);
+    /* Children are always pointers, and child 0 is legit. */
+    for (i = 0; i < len; i++)
+        VISIT(self->data[i].child);
 
-  VISIT(self->firstbucket);
+    VISIT(self->firstbucket);
 
- Done:
-  return err;
+Done:
+    return err;
 
 #undef VISIT
 }
@@ -2085,9 +2249,9 @@
 static int
 BTree_tp_clear(BTree *self)
 {
-  if (self->state != cPersistent_GHOST_STATE)
-    _BTree_clear(self);
-  return 0;
+    if (self->state != cPersistent_GHOST_STATE)
+        _BTree_clear(self);
+    return 0;
 }
 
 /*
@@ -2108,50 +2272,51 @@
 static Py_ssize_t
 BTree_length_or_nonzero(BTree *self, int nonzero)
 {
-  int result;
-  Bucket *b;
-  Bucket *next;
+    int result;
+    Bucket *b;
+    Bucket *next;
 
-  PER_USE_OR_RETURN(self, -1);
-  b = self->firstbucket;
-  PER_UNUSE(self);
-  if (nonzero)
-    return b != NULL;
+    PER_USE_OR_RETURN(self, -1);
+    b = self->firstbucket;
+    PER_UNUSE(self);
+    if (nonzero)
+        return b != NULL;
 
-  result = 0;
-  while (b) {
-    PER_USE_OR_RETURN(b, -1);
-    result += b->len;
-    next = b->next;
-    PER_UNUSE(b);
-    b = next;
-  }
-  return result;
+    result = 0;
+    while (b)
+    {
+        PER_USE_OR_RETURN(b, -1);
+        result += b->len;
+        next = b->next;
+        PER_UNUSE(b);
+        b = next;
+    }
+    return result;
 }
 
 static Py_ssize_t
 BTree_length(BTree *self)
 {
-  return BTree_length_or_nonzero(self, 0);
+    return BTree_length_or_nonzero(self, 0);
 }
 
 static PyMappingMethods BTree_as_mapping = {
-  (lenfunc)BTree_length,		/*mp_length*/
-  (binaryfunc)BTree_get,		/*mp_subscript*/
-  (objobjargproc)BTree_setitem,	        /*mp_ass_subscript*/
+    (lenfunc)BTree_length,                  /* mp_length */
+    (binaryfunc)BTree_get,                  /* mp_subscript */
+    (objobjargproc)BTree_setitem,           /* mp_ass_subscript */
 };
 
 static PySequenceMethods BTree_as_sequence = {
-  (lenfunc)0,                     /* sq_length */
-  (binaryfunc)0,                  /* sq_concat */
-  (ssizeargfunc)0,                /* sq_repeat */
-  (ssizeargfunc)0,                /* sq_item */
-  (ssizessizeargfunc)0,           /* sq_slice */
-  (ssizeobjargproc)0,             /* sq_ass_item */
-  (ssizessizeobjargproc)0,        /* sq_ass_slice */
-  (objobjproc)BTree_contains,     /* sq_contains */
-  0,                              /* sq_inplace_concat */
-  0,                              /* sq_inplace_repeat */
+    (lenfunc)0,                             /* sq_length */
+    (binaryfunc)0,                          /* sq_concat */
+    (ssizeargfunc)0,                        /* sq_repeat */
+    (ssizeargfunc)0,                        /* sq_item */
+    (ssizessizeargfunc)0,                   /* sq_slice */
+    (ssizeobjargproc)0,                     /* sq_ass_item */
+    (ssizessizeobjargproc)0,                /* sq_ass_slice */
+    (objobjproc)BTree_contains,             /* sq_contains */
+    0,                                      /* sq_inplace_concat */
+    0,                                      /* sq_inplace_repeat */
 };
 
 static Py_ssize_t
@@ -2161,48 +2326,60 @@
 }
 
 static PyNumberMethods BTree_as_number_for_nonzero = {
-  0,0,0,0,0,0,0,0,0,0,
-  (inquiry)BTree_nonzero};
+    0,                                      /* nb_add */
+    0,                                      /* nb_subtract */
+    0,                                      /* nb_multiply */
+#ifndef PY3K
+    0,                                      /* nb_divide */
+#endif
+    0,                                      /* nb_remainder */
+    0,                                      /* nb_divmod */
+    0,                                      /* nb_power */
+    0,                                      /* nb_negative */
+    0,                                      /* nb_positive */
+    0,                                      /* nb_absolute */
+    (inquiry)BTree_nonzero                  /* nb_nonzero */
+};
 
 static PyTypeObject BTreeType = {
-  PyObject_HEAD_INIT(NULL) /* PyPersist_Type */
-  0,					/* ob_size */
-  MODULE_NAME MOD_NAME_PREFIX "BTree",/* tp_name */
-  sizeof(BTree),			/* tp_basicsize */
-  0,					/* tp_itemsize */
-  (destructor)BTree_dealloc,		/* tp_dealloc */
-  0,					/* tp_print */
-  0,					/* tp_getattr */
-  0,					/* tp_setattr */
-  0,					/* tp_compare */
-  0,					/* tp_repr */
-  &BTree_as_number_for_nonzero,	/* tp_as_number */
-  &BTree_as_sequence,			/* tp_as_sequence */
-  &BTree_as_mapping,			/* tp_as_mapping */
-  0,					/* tp_hash */
-  0,					/* tp_call */
-  0,					/* tp_str */
-  0,					/* tp_getattro */
-  0,					/* tp_setattro */
-  0,					/* tp_as_buffer */
-  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
-  Py_TPFLAGS_BASETYPE, 	/* tp_flags */
-  0,					/* tp_doc */
-  (traverseproc)BTree_traverse,	/* tp_traverse */
-  (inquiry)BTree_tp_clear,		/* tp_clear */
-  0,					/* tp_richcompare */
-  0,					/* tp_weaklistoffset */
-  (getiterfunc)BTree_getiter,		/* tp_iter */
-  0,					/* tp_iternext */
-  BTree_methods,			/* tp_methods */
-  BTree_members,			/* tp_members */
-  0,					/* tp_getset */
-  0,					/* tp_base */
-  0,					/* tp_dict */
-  0,					/* tp_descr_get */
-  0,					/* tp_descr_set */
-  0,					/* tp_dictoffset */
-  BTree_init,				/* tp_init */
-  0,					/* tp_alloc */
-  0, /*PyType_GenericNew,*/		/* tp_new */
+    PyVarObject_HEAD_INIT(NULL, 0)
+    MODULE_NAME MOD_NAME_PREFIX "BTree",    /* tp_name */
+    sizeof(BTree),                          /* tp_basicsize */
+    0,                                      /* tp_itemsize */
+    (destructor)BTree_dealloc,              /* tp_dealloc */
+    0,                                      /* tp_print */
+    0,                                      /* tp_getattr */
+    0,                                      /* tp_setattr */
+    0,                                      /* tp_compare */
+    0,                                      /* tp_repr */
+    &BTree_as_number_for_nonzero,           /* tp_as_number */
+    &BTree_as_sequence,                     /* tp_as_sequence */
+    &BTree_as_mapping,                      /* tp_as_mapping */
+    0,                                      /* tp_hash */
+    0,                                      /* tp_call */
+    0,                                      /* tp_str */
+    0,                                      /* tp_getattro */
+    0,                                      /* tp_setattro */
+    0,                                      /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+    Py_TPFLAGS_HAVE_GC |
+    Py_TPFLAGS_BASETYPE,                    /* tp_flags */
+    0,                                      /* tp_doc */
+    (traverseproc)BTree_traverse,           /* tp_traverse */
+    (inquiry)BTree_tp_clear,                /* tp_clear */
+    0,                                      /* tp_richcompare */
+    0,                                      /* tp_weaklistoffset */
+    (getiterfunc)BTree_getiter,             /* tp_iter */
+    0,                                      /* tp_iternext */
+    BTree_methods,                          /* tp_methods */
+    BTree_members,                          /* tp_members */
+    0,                                      /* tp_getset */
+    0,                                      /* tp_base */
+    0,                                      /* tp_dict */
+    0,                                      /* tp_descr_get */
+    0,                                      /* tp_descr_set */
+    0,                                      /* tp_dictoffset */
+    BTree_init,                             /* tp_init */
+    0,                                      /* tp_alloc */
+    0, /*PyType_GenericNew,*/               /* tp_new */
 };

Modified: BTrees/trunk/BTrees/BucketTemplate.c
===================================================================
--- BTrees/trunk/BTrees/BucketTemplate.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/BucketTemplate.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -54,9 +54,9 @@
 ** Search a bucket for a given key.
 **
 ** Arguments
-**     self	The bucket
-**     keyarg	The key to look for
-**     has_key	Boolean; if true, return a true/false result; else return
+**     self    The bucket
+**     keyarg    The key to look for
+**     has_key    Boolean; if true, return a true/false result; else return
 **              the value associated with the key.
 **
 ** Return
@@ -75,37 +75,38 @@
 static PyObject *
 _bucket_get(Bucket *self, PyObject *keyarg, int has_key)
 {
-  int i, cmp;
-  KEY_TYPE key;
-  PyObject *r = NULL;
-  int copied = 1;
+    int i, cmp;
+    KEY_TYPE key;
+    PyObject *r = NULL;
+    int copied = 1;
 
-  COPY_KEY_FROM_ARG(key, keyarg, copied);
-  UNLESS (copied) return NULL;
+    COPY_KEY_FROM_ARG(key, keyarg, copied);
+    UNLESS (copied) return NULL;
 
-  UNLESS (PER_USE(self)) return NULL;
+    UNLESS (PER_USE(self)) return NULL;
 
-  BUCKET_SEARCH(i, cmp, self, key, goto Done);
-  if (has_key)
-    r = PyInt_FromLong(cmp ? 0 : has_key);
-  else {
-    if (cmp == 0) {
-      COPY_VALUE_TO_OBJECT(r, self->values[i]);
+    BUCKET_SEARCH(i, cmp, self, key, goto Done);
+    if (has_key)
+        r = INT_FROM_LONG(cmp ? 0 : has_key);
+    else
+    {
+        if (cmp == 0)
+        {
+            COPY_VALUE_TO_OBJECT(r, self->values[i]);
+        }
+        else
+            PyErr_SetObject(PyExc_KeyError, keyarg);
     }
-    else
-      PyErr_SetObject(PyExc_KeyError, keyarg);
-  }
 
- Done:
-  PER_UNUSE(self);
-  return r;
-
+Done:
+    PER_UNUSE(self);
+    return r;
 }
 
 static PyObject *
 bucket_getitem(Bucket *self, PyObject *key)
 {
-  return _bucket_get(self, key, 0);
+    return _bucket_get(self, key, 0);
 }
 
 /*
@@ -126,47 +127,53 @@
 static int
 Bucket_grow(Bucket *self, int newsize, int noval)
 {
-  KEY_TYPE *keys;
-  VALUE_TYPE *values;
+    KEY_TYPE *keys;
+    VALUE_TYPE *values;
 
-  if (self->size) {
-    if (newsize < 0)
-      newsize = self->size * 2;
-    if (newsize < 0)    /* int overflow */
-      goto Overflow;
-    UNLESS (keys = BTree_Realloc(self->keys, sizeof(KEY_TYPE) * newsize))
-      return -1;
+    if (self->size)
+    {
+        if (newsize < 0)
+            newsize = self->size * 2;
+        if (newsize < 0)    /* int overflow */
+            goto Overflow;
+        UNLESS (keys = BTree_Realloc(self->keys, sizeof(KEY_TYPE) * newsize))
+            return -1;
 
-    UNLESS (noval) {
-      values = BTree_Realloc(self->values, sizeof(VALUE_TYPE) * newsize);
-      if (values == NULL) {
-        free(keys);
-        return -1;
-      }
-      self->values = values;
+        UNLESS (noval)
+        {
+            values = BTree_Realloc(self->values, sizeof(VALUE_TYPE) * newsize);
+            if (values == NULL)
+            {
+                free(keys);
+                return -1;
+            }
+            self->values = values;
+        }
+        self->keys = keys;
     }
-    self->keys = keys;
-  }
-  else {
-    if (newsize < 0)
-      newsize = MIN_BUCKET_ALLOC;
-    UNLESS (self->keys = BTree_Malloc(sizeof(KEY_TYPE) * newsize))
-      return -1;
-    UNLESS (noval) {
-      self->values = BTree_Malloc(sizeof(VALUE_TYPE) * newsize);
-      if (self->values == NULL) {
-        free(self->keys);
-        self->keys = NULL;
-        return -1;
-      }
+    else
+    {
+        if (newsize < 0)
+            newsize = MIN_BUCKET_ALLOC;
+        UNLESS (self->keys = BTree_Malloc(sizeof(KEY_TYPE) * newsize))
+            return -1;
+        UNLESS (noval)
+        {
+            self->values = BTree_Malloc(sizeof(VALUE_TYPE) * newsize);
+            if (self->values == NULL)
+            {
+                free(self->keys);
+                self->keys = NULL;
+                return -1;
+            }
+        }
     }
-  }
-  self->size = newsize;
-  return 0;
+    self->size = newsize;
+    return 0;
 
- Overflow:
-  PyErr_NoMemory();
-  return -1;
+Overflow:
+    PyErr_NoMemory();
+    return -1;
 }
 
 /* So far, bucket_append is called only by multiunion_m(), so is called
@@ -213,54 +220,59 @@
 bucket_append(Bucket *self, Bucket *from, int i, int n,
               int copyValues, int overallocate)
 {
-  int newlen;
+    int newlen;
 
-  assert(self && from && self != from);
-  assert(i >= 0);
-  assert(n > 0);
-  assert(i+n <= from->len);
+    assert(self && from && self != from);
+    assert(i >= 0);
+    assert(n > 0);
+    assert(i+n <= from->len);
 
-  /* Make room. */
-  newlen = self->len + n;
-  if (newlen > self->size) {
-    int newsize = newlen;
-    if (overallocate)   /* boost by 25% -- pretty arbitrary */
-      newsize += newsize >> 2;
-    if (Bucket_grow(self, newsize, ! copyValues) < 0)
-      return -1;
-  }
-  assert(newlen <= self->size);
+    /* Make room. */
+    newlen = self->len + n;
+    if (newlen > self->size)
+    {
+        int newsize = newlen;
+        if (overallocate)   /* boost by 25% -- pretty arbitrary */
+        newsize += newsize >> 2;
+        if (Bucket_grow(self, newsize, ! copyValues) < 0)
+        return -1;
+    }
+    assert(newlen <= self->size);
 
-  /* Copy stuff. */
-  memcpy(self->keys + self->len, from->keys + i, n * sizeof(KEY_TYPE));
-  if (copyValues) {
-    assert(self->values);
-    assert(from->values);
-    memcpy(self->values + self->len, from->values + i,
-           n * sizeof(VALUE_TYPE));
-  }
-  self->len = newlen;
+    /* Copy stuff. */
+    memcpy(self->keys + self->len, from->keys + i, n * sizeof(KEY_TYPE));
+    if (copyValues)
+    {
+        assert(self->values);
+        assert(from->values);
+        memcpy(self->values + self->len, from->values + i,
+            n * sizeof(VALUE_TYPE));
+    }
+    self->len = newlen;
 
-  /* Bump refcounts. */
+    /* Bump refcounts. */
 #ifdef KEY_TYPE_IS_PYOBJECT
-  {
-    int j;
-    PyObject **p = from->keys + i;
-    for (j = 0; j < n; ++j, ++p) {
-      Py_INCREF(*p);
+    {
+        int j;
+        PyObject **p = from->keys + i;
+        for (j = 0; j < n; ++j, ++p)
+        {
+            Py_INCREF(*p);
+        }
     }
-  }
 #endif
 #ifdef VALUE_TYPE_IS_PYOBJECT
-  if (copyValues) {
-    int j;
-    PyObject **p = from->values + i;
-    for (j = 0; j < n; ++j, ++p) {
-      Py_INCREF(*p);
+    if (copyValues)
+    {
+        int j;
+        PyObject **p = from->values + i;
+        for (j = 0; j < n; ++j, ++p)
+        {
+            Py_INCREF(*p);
+        }
     }
-  }
 #endif
-  return 0;
+    return 0;
 }
 #endif /* MULTI_INT_UNION */
 
@@ -291,136 +303,149 @@
 _bucket_set(Bucket *self, PyObject *keyarg, PyObject *v,
             int unique, int noval, int *changed)
 {
-  int i, cmp;
-  KEY_TYPE key;
+    int i, cmp;
+    KEY_TYPE key;
 
-  /* Subtle:  there may or may not be a value.  If there is, we need to
-   * check its type early, so that in case of error we can get out before
-   * mutating the bucket.  But because value isn't used on all paths, if
-   * we don't initialize value then gcc gives a nuisance complaint that
-   * value may be used initialized (it can't be, but gcc doesn't know
-   * that).  So we initialize it.  However, VALUE_TYPE can be various types,
-   * including int, PyObject*, and char[6], so it's a puzzle to spell
-   * initialization.  It so happens that {0} is a valid initializer for all
-   * these types.
-   */
-  VALUE_TYPE value = {0};	/* squash nuisance warning */
-  int result = -1;    /* until proven innocent */
-  int copied = 1;
+    /* Subtle:  there may or may not be a value.  If there is, we need to
+     * check its type early, so that in case of error we can get out before
+     * mutating the bucket.  But because value isn't used on all paths, if
+     * we don't initialize value then gcc gives a nuisance complaint that
+     * value may be used initialized (it can't be, but gcc doesn't know
+     * that).  So we initialize it.  However, VALUE_TYPE can be various types,
+     * including int, PyObject*, and char[6], so it's a puzzle to spell
+     * initialization.  It so happens that {0} is a valid initializer for all
+     * these types.
+     */
+    VALUE_TYPE value = {0};    /* squash nuisance warning */
+    int result = -1;    /* until proven innocent */
+    int copied = 1;
 
-  COPY_KEY_FROM_ARG(key, keyarg, copied);
-  UNLESS(copied) return -1;
+    COPY_KEY_FROM_ARG(key, keyarg, copied);
+    UNLESS(copied)
+        return -1;
 
-  /* Copy the value early (if needed), so that in case of error a
-   * pile of bucket mutations don't need to be undone.
-   */
-  if (v && !noval) {
-    COPY_VALUE_FROM_ARG(value, v, copied);
-    UNLESS(copied) return -1;
-  }
+    /* Copy the value early (if needed), so that in case of error a
+     * pile of bucket mutations don't need to be undone.
+     */
+    if (v && !noval) {
+        COPY_VALUE_FROM_ARG(value, v, copied);
+        UNLESS(copied)
+            return -1;
+    }
 
-  UNLESS (PER_USE(self)) return -1;
+    UNLESS (PER_USE(self))
+        return -1;
 
-  BUCKET_SEARCH(i, cmp, self, key, goto Done);
-  if (cmp == 0) {
-    /* The key exists, at index i. */
+    BUCKET_SEARCH(i, cmp, self, key, goto Done);
+    if (cmp == 0)
+    {
+        /* The key exists, at index i. */
+        if (v)
+        {
+            /* The key exists at index i, and there's a new value.
+             * If unique, we're not supposed to replace it.  If noval, or this
+             * is a set bucket (self->values is NULL), there's nothing to do.
+             */
+            if (unique || noval || self->values == NULL)
+            {
+                result = 0;
+                goto Done;
+            }
 
-    if (v) {
-      /* The key exists at index i, and there's a new value.
-       * If unique, we're not supposed to replace it.  If noval, or this
-       * is a set bucket (self->values is NULL), there's nothing to do.
-       */
-      if (unique || noval || self->values == NULL) {
-        result = 0;
-        goto Done;
-      }
-
-      /* The key exists at index i, and we need to replace the value. */
+            /* The key exists at index i, and we need to replace the value. */
 #ifdef VALUE_SAME
-      /* short-circuit if no change */
-      if (VALUE_SAME(self->values[i], value)) {
-        result = 0;
-        goto Done;
-      }
+            /* short-circuit if no change */
+            if (VALUE_SAME(self->values[i], value))
+            {
+                result = 0;
+                goto Done;
+            }
 #endif
-      if (changed)
-        *changed = 1;
-      DECREF_VALUE(self->values[i]);
-      COPY_VALUE(self->values[i], value);
-      INCREF_VALUE(self->values[i]);
-      if (PER_CHANGED(self) >= 0)
-        result = 0;
-      goto Done;
-    }
+            if (changed)
+                *changed = 1;
+            DECREF_VALUE(self->values[i]);
+            COPY_VALUE(self->values[i], value);
+            INCREF_VALUE(self->values[i]);
+            if (PER_CHANGED(self) >= 0)
+                result = 0;
+            goto Done;
+        }
 
-    /* The key exists at index i, and should be deleted. */
-    DECREF_KEY(self->keys[i]);
-    self->len--;
-    if (i < self->len)
-      memmove(self->keys + i, self->keys + i+1,
-              sizeof(KEY_TYPE)*(self->len - i));
+        /* The key exists at index i, and should be deleted. */
+        DECREF_KEY(self->keys[i]);
+        self->len--;
+        if (i < self->len)
+            memmove(self->keys + i, self->keys + i+1,
+                    sizeof(KEY_TYPE)*(self->len - i));
 
-    if (self->values) {
-      DECREF_VALUE(self->values[i]);
-      if (i < self->len)
-        memmove(self->values + i, self->values + i+1,
-                sizeof(VALUE_TYPE)*(self->len - i));
+        if (self->values)
+        {
+            DECREF_VALUE(self->values[i]);
+            if (i < self->len)
+                memmove(self->values + i, self->values + i+1,
+                        sizeof(VALUE_TYPE)*(self->len - i));
+        }
+
+        if (! self->len)
+        {
+            self->size = 0;
+            free(self->keys);
+            self->keys = NULL;
+            if (self->values)
+            {
+                free(self->values);
+                self->values = NULL;
+            }
+        }
+
+        if (changed)
+            *changed = 1;
+        if (PER_CHANGED(self) >= 0)
+            result = 1;
+        goto Done;
     }
 
-    if (! self->len) {
-      self->size = 0;
-      free(self->keys);
-      self->keys = NULL;
-      if (self->values) {
-        free(self->values);
-        self->values = NULL;
-      }
+    /* The key doesn't exist, and belongs at index i. */
+    if (!v)
+    {
+        /* Can't delete a non-existent key. */
+        PyErr_SetObject(PyExc_KeyError, keyarg);
+        goto Done;
     }
 
-    if (changed)
-      *changed = 1;
-    if (PER_CHANGED(self) >= 0)
-      result = 1;
-    goto Done;
-  }
+    /* The key doesn't exist and should be inserted at index i. */
+    if (self->len == self->size && Bucket_grow(self, -1, noval) < 0)
+        goto Done;
 
-  /* The key doesn't exist, and belongs at index i. */
-  if (!v) {
-    /* Can't delete a non-existent key. */
-    PyErr_SetObject(PyExc_KeyError, keyarg);
-    goto Done;
-  }
+    if (self->len > i)
+    {
+        memmove(self->keys + i + 1, self->keys + i,
+                sizeof(KEY_TYPE) * (self->len - i));
+        if (self->values)
+        {
+            memmove(self->values + i + 1, self->values + i,
+                    sizeof(VALUE_TYPE) * (self->len - i));
+        }
+    }
 
-  /* The key doesn't exist and should be inserted at index i. */
-  if (self->len == self->size && Bucket_grow(self, -1, noval) < 0)
-    goto Done;
+    COPY_KEY(self->keys[i], key);
+    INCREF_KEY(self->keys[i]);
 
-  if (self->len > i) {
-    memmove(self->keys + i + 1, self->keys + i,
-            sizeof(KEY_TYPE) * (self->len - i));
-    if (self->values) {
-      memmove(self->values + i + 1, self->values + i,
-              sizeof(VALUE_TYPE) * (self->len - i));
+    if (! noval)
+    {
+        COPY_VALUE(self->values[i], value);
+        INCREF_VALUE(self->values[i]);
     }
-  }
 
-  COPY_KEY(self->keys[i], key);
-  INCREF_KEY(self->keys[i]);
+    self->len++;
+    if (changed)
+        *changed = 1;
+    if (PER_CHANGED(self) >= 0)
+        result = 1;
 
-  if (! noval) {
-    COPY_VALUE(self->values[i], value);
-    INCREF_VALUE(self->values[i]);
-  }
-
-  self->len++;
-  if (changed)
-    *changed = 1;
-  if (PER_CHANGED(self) >= 0)
-    result = 1;
-
- Done:
-  PER_UNUSE(self);
-  return result;
+Done:
+    PER_UNUSE(self);
+    return result;
 }
 
 /*
@@ -428,19 +453,19 @@
 **
 ** wrapper for _bucket_setitem (eliminates +1 return code)
 **
-** Arguments:	self	The bucket
-**		key	The key to insert under
-**		v	The value to insert
+** Arguments:    self    The bucket
+**        key    The key to insert under
+**        v    The value to insert
 **
-** Returns	 0 	on success
-**		-1	on failure
+** Returns     0     on success
+**        -1    on failure
 */
 static int
 bucket_setitem(Bucket *self, PyObject *key, PyObject *v)
 {
-  if (_bucket_set(self, key, v, 0, 0, 0) < 0)
-    return -1;
-  return 0;
+    if (_bucket_set(self, key, v, 0, 0, 0) < 0)
+        return -1;
+    return 0;
 }
 
 /**
@@ -450,71 +475,82 @@
 static int
 update_from_seq(PyObject *map, PyObject *seq)
 {
-  PyObject *iter, *o, *k, *v;
-  int err = -1;
+    PyObject *iter, *o, *k, *v;
+    int err = -1;
 
-  /* One path creates a new seq object.  The other path has an
-     INCREF of the seq argument.  So seq must always be DECREFed on
-     the way out.
-  */
-  /* Use items() if it's not a sequence.  Alas, PySequence_Check()
-   * returns true for a PeristentMapping or PersistentDict, and we
-   * want to use items() in those cases too.
-   */
-  if (!PySequence_Check(seq) || /* or it "looks like a dict" */
-      PyObject_HasAttrString(seq, "iteritems")) {
-    PyObject *items;
-    items = PyObject_GetAttrString(seq, "items");
-    if (items == NULL)
-	    return -1;
-    seq = PyObject_CallObject(items, NULL);
-    Py_DECREF(items);
-    if (seq == NULL)
-	    return -1;
-  }
-  else
-    Py_INCREF(seq);
+    /* One path creates a new seq object.  The other path has an
+        INCREF of the seq argument.  So seq must always be DECREFed on
+        the way out.
+    */
+    /* Use items() if it's not a sequence.  Alas, PySequence_Check()
+     * returns true for a PeristentMapping or PersistentDict, and we
+     * want to use items() in those cases too.
+     */
+#ifdef PY3K
+#define ITERITEMS "items"
+#else
+#define ITERITEMS "iteritems"
+#endif
+    if (!PySequence_Check(seq) || /* or it "looks like a dict" */
+        PyObject_HasAttrString(seq, ITERITEMS))
+#undef ITERITEMS
+    {
+        PyObject *items;
+        items = PyObject_GetAttrString(seq, "items");
+        if (items == NULL)
+            return -1;
+        seq = PyObject_CallObject(items, NULL);
+        Py_DECREF(items);
+        if (seq == NULL)
+            return -1;
+    }
+    else
+        Py_INCREF(seq);
 
-  iter = PyObject_GetIter(seq);
-  if (iter == NULL)
-    goto err;
-  while (1) {
-    o = PyIter_Next(iter);
-    if (o == NULL) {
-	    if (PyErr_Occurred())
+    iter = PyObject_GetIter(seq);
+    if (iter == NULL)
         goto err;
-	    else
-        break;
+    while (1)
+    {
+        o = PyIter_Next(iter);
+        if (o == NULL)
+        {
+            if (PyErr_Occurred())
+                goto err;
+            else
+                break;
+        }
+        if (!PyTuple_Check(o) || PyTuple_GET_SIZE(o) != 2)
+        {
+            Py_DECREF(o);
+            PyErr_SetString(PyExc_TypeError,
+                        "Sequence must contain 2-item tuples");
+            goto err;
+        }
+        k = PyTuple_GET_ITEM(o, 0);
+        v = PyTuple_GET_ITEM(o, 1);
+        if (PyObject_SetItem(map, k, v) < 0)
+        {
+            Py_DECREF(o);
+            goto err;
+        }
+        Py_DECREF(o);
     }
-    if (!PyTuple_Check(o) || PyTuple_GET_SIZE(o) != 2) {
-	    Py_DECREF(o);
-	    PyErr_SetString(PyExc_TypeError,
-                      "Sequence must contain 2-item tuples");
-	    goto err;
-    }
-    k = PyTuple_GET_ITEM(o, 0);
-    v = PyTuple_GET_ITEM(o, 1);
-    if (PyObject_SetItem(map, k, v) < 0) {
-	    Py_DECREF(o);
-	    goto err;
-    }
-    Py_DECREF(o);
-  }
 
-  err = 0;
- err:
-  Py_DECREF(iter);
-  Py_DECREF(seq);
-  return err;
+    err = 0;
+err:
+    Py_DECREF(iter);
+    Py_DECREF(seq);
+    return err;
 }
 
 static PyObject *
 Mapping_update(PyObject *self, PyObject *seq)
 {
-  if (update_from_seq(self, seq) < 0)
-    return NULL;
-  Py_INCREF(Py_None);
-  return Py_None;
+    if (update_from_seq(self, seq) < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 
 /*
@@ -522,52 +558,52 @@
 **
 ** Splits one bucket into two
 **
-** Arguments:	self	The bucket
-**		index	the index of the key to split at (O.O.B use midpoint)
-**		next	the new bucket to split into
+** Arguments:    self    The bucket
+**        index    the index of the key to split at (O.O.B use midpoint)
+**        next    the new bucket to split into
 **
-** Returns:	 0	on success
-**		-1	on failure
+** Returns:     0    on success
+**        -1    on failure
 */
 static int
 bucket_split(Bucket *self, int index, Bucket *next)
 {
-  int next_size;
+    int next_size;
 
-  ASSERT(self->len > 1, "split of empty bucket", -1);
+    ASSERT(self->len > 1, "split of empty bucket", -1);
 
-  if (index < 0 || index >= self->len)
-    index = self->len / 2;
+    if (index < 0 || index >= self->len)
+        index = self->len / 2;
 
-  next_size = self->len - index;
+    next_size = self->len - index;
 
-  next->keys = BTree_Malloc(sizeof(KEY_TYPE) * next_size);
-  if (!next->keys)
-    return -1;
-  memcpy(next->keys, self->keys + index, sizeof(KEY_TYPE) * next_size);
-  if (self->values) {
-    next->values = BTree_Malloc(sizeof(VALUE_TYPE) * next_size);
-    if (!next->values) {
-      free(next->keys);
-      next->keys = NULL;
-      return -1;
+    next->keys = BTree_Malloc(sizeof(KEY_TYPE) * next_size);
+    if (!next->keys)
+        return -1;
+    memcpy(next->keys, self->keys + index, sizeof(KEY_TYPE) * next_size);
+    if (self->values) {
+        next->values = BTree_Malloc(sizeof(VALUE_TYPE) * next_size);
+        if (!next->values) {
+        free(next->keys);
+        next->keys = NULL;
+        return -1;
+        }
+        memcpy(next->values, self->values + index,
+            sizeof(VALUE_TYPE) * next_size);
     }
-    memcpy(next->values, self->values + index,
-           sizeof(VALUE_TYPE) * next_size);
-  }
-  next->size = next_size;
-  next->len = next_size;
-  self->len = index;
+    next->size = next_size;
+    next->len = next_size;
+    self->len = index;
 
-  next->next = self->next;
+    next->next = self->next;
 
-  Py_INCREF(next);
-  self->next = next;
+    Py_INCREF(next);
+    self->next = next;
 
-  if (PER_CHANGED(self) < 0)
-    return -1;
+    if (PER_CHANGED(self) < 0)
+        return -1;
 
-  return 0;
+    return 0;
 }
 
 /* Set self->next to self->next->next, i.e. unlink self's successor from
@@ -580,31 +616,33 @@
 static int
 Bucket_deleteNextBucket(Bucket *self)
 {
-  int result = -1;    /* until proven innocent */
-  Bucket *successor;
+    int result = -1;    /* until proven innocent */
+    Bucket *successor;
 
-  PER_USE_OR_RETURN(self, -1);
-  successor = self->next;
-  if (successor) {
-    Bucket *next;
-    /* Before:  self -> successor -> next
-     * After:   self --------------> next
-     */
-    UNLESS (PER_USE(successor)) goto Done;
-    next = successor->next;
-    PER_UNUSE(successor);
+    PER_USE_OR_RETURN(self, -1);
+    successor = self->next;
+    if (successor)
+    {
+        Bucket *next;
+        /* Before:  self -> successor -> next
+        * After:   self --------------> next
+        */
+        UNLESS (PER_USE(successor))
+            goto Done;
+        next = successor->next;
+        PER_UNUSE(successor);
 
-    Py_XINCREF(next);       /* it may be NULL, of course */
-    self->next = next;
-    Py_DECREF(successor);
-    if (PER_CHANGED(self) < 0)
-	    goto Done;
-  }
-  result = 0;
+        Py_XINCREF(next);       /* it may be NULL, of course */
+        self->next = next;
+        Py_DECREF(successor);
+        if (PER_CHANGED(self) < 0)
+            goto Done;
+    }
+    result = 0;
 
- Done:
-  PER_UNUSE(self);
-  return result;
+Done:
+    PER_UNUSE(self);
+    return result;
 }
 
 /*
@@ -647,157 +685,173 @@
 Bucket_findRangeEnd(Bucket *self, PyObject *keyarg, int low, int exclude_equal,
                     int *offset)
 {
-  int i, cmp;
-  int result = -1;    /* until proven innocent */
-  KEY_TYPE key;
-  int copied = 1;
+    int i, cmp;
+    int result = -1;    /* until proven innocent */
+    KEY_TYPE key;
+    int copied = 1;
 
-  COPY_KEY_FROM_ARG(key, keyarg, copied);
-  UNLESS (copied) return -1;
+    COPY_KEY_FROM_ARG(key, keyarg, copied);
+    UNLESS (copied)
+        return -1;
 
-  UNLESS (PER_USE(self)) return -1;
+    UNLESS (PER_USE(self))
+        return -1;
 
-  BUCKET_SEARCH(i, cmp, self, key, goto Done);
-  if (cmp == 0) {
-    /* exact match at index i */
-    if (exclude_equal) {
-	    /* but we don't want an exact match */
-      if (low)
-        ++i;
-      else
+    BUCKET_SEARCH(i, cmp, self, key, goto Done);
+    if (cmp == 0) {
+        /* exact match at index i */
+        if (exclude_equal)
+        {
+            /* but we don't want an exact match */
+            if (low)
+                ++i;
+            else
+                --i;
+        }
+    }
+    /* Else keys[i-1] < key < keys[i], picturing infinities at OOB indices,
+    * and i has the smallest item > key, which is correct for low.
+    */
+    else if (! low)
+        /* i-1 has the largest item < key (unless i-1 is 0OB) */
         --i;
-    }
-  }
-  /* Else keys[i-1] < key < keys[i], picturing infinities at OOB indices,
-   * and i has the smallest item > key, which is correct for low.
-   */
-  else if (! low)
-    /* i-1 has the largest item < key (unless i-1 is 0OB) */
-    --i;
 
-  result = 0 <= i && i < self->len;
-  if (result)
-    *offset = i;
+    result = 0 <= i && i < self->len;
+    if (result)
+        *offset = i;
 
- Done:
-  PER_UNUSE(self);
-  return result;
+Done:
+    PER_UNUSE(self);
+    return result;
 }
 
 static PyObject *
 Bucket_maxminKey(Bucket *self, PyObject *args, int min)
 {
-  PyObject *key=0;
-  int rc, offset = 0;
-  int empty_bucket = 1;
+    PyObject *key=0;
+    int rc, offset = 0;
+    int empty_bucket = 1;
 
-  if (args && ! PyArg_ParseTuple(args, "|O", &key)) return NULL;
+    if (args && ! PyArg_ParseTuple(args, "|O", &key))
+        return NULL;
 
-  PER_USE_OR_RETURN(self, NULL);
+    PER_USE_OR_RETURN(self, NULL);
 
-  UNLESS (self->len) goto empty;
+    UNLESS (self->len)
+        goto empty;
 
-  /* Find the low range */
-  if (key)
+    /* Find the low range */
+    if (key)
     {
-      if ((rc = Bucket_findRangeEnd(self, key, min, 0, &offset)) <= 0)
+        if ((rc = Bucket_findRangeEnd(self, key, min, 0, &offset)) <= 0)
         {
-          if (rc < 0) return NULL;
-          empty_bucket = 0;
-          goto empty;
+            if (rc < 0)
+                return NULL;
+            empty_bucket = 0;
+            goto empty;
         }
     }
-  else if (min) offset = 0;
-  else offset = self->len -1;
+    else if (min)
+        offset = 0;
+    else
+        offset = self->len -1;
 
-  COPY_KEY_TO_OBJECT(key, self->keys[offset]);
-  PER_UNUSE(self);
+    COPY_KEY_TO_OBJECT(key, self->keys[offset]);
+    PER_UNUSE(self);
 
-  return key;
+    return key;
 
- empty:
-  PyErr_SetString(PyExc_ValueError,
-                  empty_bucket ? "empty bucket" :
-                  "no key satisfies the conditions");
-  PER_UNUSE(self);
-  return NULL;
+empty:
+    PyErr_SetString(PyExc_ValueError,
+                    empty_bucket ? "empty bucket" :
+                    "no key satisfies the conditions");
+    PER_UNUSE(self);
+    return NULL;
 }
 
 static PyObject *
 Bucket_minKey(Bucket *self, PyObject *args)
 {
-  return Bucket_maxminKey(self, args, 1);
+    return Bucket_maxminKey(self, args, 1);
 }
 
 static PyObject *
 Bucket_maxKey(Bucket *self, PyObject *args)
 {
-  return Bucket_maxminKey(self, args, 0);
+    return Bucket_maxminKey(self, args, 0);
 }
 
 static int
 Bucket_rangeSearch(Bucket *self, PyObject *args, PyObject *kw,
                    int *low, int *high)
 {
-  PyObject *min = Py_None;
-  PyObject *max = Py_None;
-  int excludemin = 0;
-  int excludemax = 0;
-  int rc;
+    PyObject *min = Py_None;
+    PyObject *max = Py_None;
+    int excludemin = 0;
+    int excludemax = 0;
+    int rc;
 
-  if (args) {
-    if (! PyArg_ParseTupleAndKeywords(args, kw, "|OOii", search_keywords,
-                                      &min,
-                                      &max,
-                                      &excludemin,
-                                      &excludemax))
-	    return -1;
-  }
+    if (args)
+    {
+        if (! PyArg_ParseTupleAndKeywords(args, kw, "|OOii", search_keywords,
+                                          &min,
+                                          &max,
+                                          &excludemin,
+                                          &excludemax))
+            return -1;
+    }
 
-  UNLESS (self->len) goto empty;
+    UNLESS (self->len)
+        goto empty;
 
-  /* Find the low range */
-  if (min != Py_None) {
-    rc = Bucket_findRangeEnd(self, min, 1, excludemin, low);
-    if (rc < 0)
-      return -1;
-    if (rc == 0)
-      goto empty;
-  }
-  else {
-    *low = 0;
-    if (excludemin) {
-      if (self->len < 2)
-        goto empty;
-      ++*low;
+    /* Find the low range */
+    if (min != Py_None)
+    {
+        rc = Bucket_findRangeEnd(self, min, 1, excludemin, low);
+        if (rc < 0)
+            return -1;
+        if (rc == 0)
+            goto empty;
     }
-  }
+    else
+    {
+        *low = 0;
+        if (excludemin)
+        {
+            if (self->len < 2)
+                goto empty;
+            ++*low;
+        }
+    }
 
-  /* Find the high range */
-  if (max != Py_None) {
-    rc = Bucket_findRangeEnd(self, max, 0, excludemax, high);
-    if (rc < 0)
-      return -1;
-    if (rc == 0)
-      goto empty;
-  }
-  else {
-    *high = self->len - 1;
-    if (excludemax) {
-	    if (self->len < 2)
-	    	goto empty;
-	    --*high;
+    /* Find the high range */
+    if (max != Py_None)
+    {
+        rc = Bucket_findRangeEnd(self, max, 0, excludemax, high);
+        if (rc < 0)
+            return -1;
+        if (rc == 0)
+            goto empty;
     }
-  }
+    else
+    {
+        *high = self->len - 1;
+        if (excludemax)
+        {
+            if (self->len < 2)
+                goto empty;
+            --*high;
+        }
+    }
 
-  /* If min < max to begin with, it's quite possible that low > high now. */
-  if (*low <= *high)
+    /* If min < max to begin with, it's quite possible that low > high now. */
+    if (*low <= *high)
+        return 0;
+
+empty:
+    *low = 0;
+    *high = -1;
     return 0;
-
- empty:
-  *low = 0;
-  *high = -1;
-  return 0;
 }
 
 /*
@@ -805,39 +859,40 @@
 **
 ** Generate a list of all keys in the bucket
 **
-** Arguments:	self	The Bucket
-**		args	(unused)
+** Arguments:    self    The Bucket
+**        args    (unused)
 **
-** Returns:	list of bucket keys
+** Returns:    list of bucket keys
 */
 static PyObject *
 bucket_keys(Bucket *self, PyObject *args, PyObject *kw)
 {
-  PyObject *r = NULL, *key;
-  int i, low, high;
+    PyObject *r = NULL, *key;
+    int i, low, high;
 
-  PER_USE_OR_RETURN(self, NULL);
+    PER_USE_OR_RETURN(self, NULL);
 
-  if (Bucket_rangeSearch(self, args, kw, &low, &high) < 0)
-    goto err;
+    if (Bucket_rangeSearch(self, args, kw, &low, &high) < 0)
+        goto err;
 
-  r = PyList_New(high-low+1);
-  if (r == NULL)
-    goto err;
+    r = PyList_New(high-low+1);
+    if (r == NULL)
+        goto err;
 
-  for (i=low; i <= high; i++) {
-    COPY_KEY_TO_OBJECT(key, self->keys[i]);
-    if (PyList_SetItem(r, i-low , key) < 0)
-      goto err;
-  }
+    for (i=low; i <= high; i++)
+    {
+        COPY_KEY_TO_OBJECT(key, self->keys[i]);
+        if (PyList_SetItem(r, i-low , key) < 0)
+            goto err;
+    }
 
-  PER_UNUSE(self);
-  return r;
+    PER_UNUSE(self);
+    return r;
 
- err:
-  PER_UNUSE(self);
-  Py_XDECREF(r);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    Py_XDECREF(r);
+    return NULL;
 }
 
 /*
@@ -845,37 +900,41 @@
 **
 ** Generate a list of all values in the bucket
 **
-** Arguments:	self	The Bucket
-**		args	(unused)
+** Arguments:    self    The Bucket
+**        args    (unused)
 **
-** Returns	list of values
+** Returns    list of values
 */
 static PyObject *
 bucket_values(Bucket *self, PyObject *args, PyObject *kw)
 {
-  PyObject *r=0, *v;
-  int i, low, high;
+    PyObject *r=0, *v;
+    int i, low, high;
 
-  PER_USE_OR_RETURN(self, NULL);
+    PER_USE_OR_RETURN(self, NULL);
 
-  if (Bucket_rangeSearch(self, args, kw, &low, &high) < 0) goto err;
+    if (Bucket_rangeSearch(self, args, kw, &low, &high) < 0)
+        goto err;
 
-  UNLESS (r=PyList_New(high-low+1)) goto err;
+    UNLESS (r=PyList_New(high-low+1))
+        goto err;
 
-  for (i=low; i <= high; i++)
+    for (i=low; i <= high; i++)
     {
-      COPY_VALUE_TO_OBJECT(v, self->values[i]);
-      UNLESS (v) goto err;
-      if (PyList_SetItem(r, i-low, v) < 0) goto err;
+        COPY_VALUE_TO_OBJECT(v, self->values[i]);
+        UNLESS (v)
+            goto err;
+        if (PyList_SetItem(r, i-low, v) < 0)
+            goto err;
     }
 
-  PER_UNUSE(self);
-  return r;
+    PER_UNUSE(self);
+    return r;
 
- err:
-  PER_UNUSE(self);
-  Py_XDECREF(r);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    Py_XDECREF(r);
+    return NULL;
 }
 
 /*
@@ -883,214 +942,238 @@
 **
 ** Returns a list of all items in a bucket
 **
-** Arguments:	self	The Bucket
-**		args	(unused)
+** Arguments:    self    The Bucket
+**        args    (unused)
 **
-** Returns:	list of all items in the bucket
+** Returns:    list of all items in the bucket
 */
 static PyObject *
 bucket_items(Bucket *self, PyObject *args, PyObject *kw)
 {
-  PyObject *r=0, *o=0, *item=0;
-  int i, low, high;
+    PyObject *r=0, *o=0, *item=0;
+    int i, low, high;
 
-  PER_USE_OR_RETURN(self, NULL);
+    PER_USE_OR_RETURN(self, NULL);
 
-  if (Bucket_rangeSearch(self, args, kw, &low, &high) < 0) goto err;
+    if (Bucket_rangeSearch(self, args, kw, &low, &high) < 0)
+        goto err;
 
-  UNLESS (r=PyList_New(high-low+1)) goto err;
+    UNLESS (r=PyList_New(high-low+1))
+        goto err;
 
-  for (i=low; i <= high; i++)
+    for (i=low; i <= high; i++)
     {
-      UNLESS (item = PyTuple_New(2)) goto err;
+        UNLESS (item = PyTuple_New(2))
+            goto err;
 
-      COPY_KEY_TO_OBJECT(o, self->keys[i]);
-      UNLESS (o) goto err;
-      PyTuple_SET_ITEM(item, 0, o);
+        COPY_KEY_TO_OBJECT(o, self->keys[i]);
+        UNLESS (o)
+            goto err;
+        PyTuple_SET_ITEM(item, 0, o);
 
-      COPY_VALUE_TO_OBJECT(o, self->values[i]);
-      UNLESS (o) goto err;
-      PyTuple_SET_ITEM(item, 1, o);
+        COPY_VALUE_TO_OBJECT(o, self->values[i]);
+        UNLESS (o)
+            goto err;
+        PyTuple_SET_ITEM(item, 1, o);
 
-      if (PyList_SetItem(r, i-low, item) < 0) goto err;
+        if (PyList_SetItem(r, i-low, item) < 0)
+            goto err;
 
-      item = 0;
+        item = 0;
     }
 
-  PER_UNUSE(self);
-  return r;
+    PER_UNUSE(self);
+    return r;
 
- err:
-  PER_UNUSE(self);
-  Py_XDECREF(r);
-  Py_XDECREF(item);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    Py_XDECREF(r);
+    Py_XDECREF(item);
+    return NULL;
 }
 
 static PyObject *
 bucket_byValue(Bucket *self, PyObject *omin)
 {
-  PyObject *r=0, *o=0, *item=0;
-  VALUE_TYPE min;
-  VALUE_TYPE v;
-  int i, l, copied=1;
+    PyObject *r=0, *o=0, *item=0;
+    VALUE_TYPE min;
+    VALUE_TYPE v;
+    int i, l, copied=1;
 
-  PER_USE_OR_RETURN(self, NULL);
+    PER_USE_OR_RETURN(self, NULL);
 
-  COPY_VALUE_FROM_ARG(min, omin, copied);
-  UNLESS(copied) return NULL;
+    COPY_VALUE_FROM_ARG(min, omin, copied);
+    UNLESS(copied)
+        return NULL;
 
-  for (i=0, l=0; i < self->len; i++)
-    if (TEST_VALUE(self->values[i], min) >= 0)
-      l++;
+    for (i=0, l=0; i < self->len; i++)
+        if (TEST_VALUE(self->values[i], min) >= 0)
+        l++;
 
-  UNLESS (r=PyList_New(l)) goto err;
+    UNLESS (r=PyList_New(l))
+        goto err;
 
-  for (i=0, l=0; i < self->len; i++)
+    for (i=0, l=0; i < self->len; i++)
     {
-      if (TEST_VALUE(self->values[i], min) < 0) continue;
+        if (TEST_VALUE(self->values[i], min) < 0)
+            continue;
 
-      UNLESS (item = PyTuple_New(2)) goto err;
+        UNLESS (item = PyTuple_New(2))
+            goto err;
 
-      COPY_KEY_TO_OBJECT(o, self->keys[i]);
-      UNLESS (o) goto err;
-      PyTuple_SET_ITEM(item, 1, o);
+        COPY_KEY_TO_OBJECT(o, self->keys[i]);
+        UNLESS (o)
+            goto err;
+        PyTuple_SET_ITEM(item, 1, o);
 
-      COPY_VALUE(v, self->values[i]);
-      NORMALIZE_VALUE(v, min);
-      COPY_VALUE_TO_OBJECT(o, v);
-      DECREF_VALUE(v);
-      UNLESS (o) goto err;
-      PyTuple_SET_ITEM(item, 0, o);
+        COPY_VALUE(v, self->values[i]);
+        NORMALIZE_VALUE(v, min);
+        COPY_VALUE_TO_OBJECT(o, v);
+        DECREF_VALUE(v);
+        UNLESS (o)
+            goto err;
+        PyTuple_SET_ITEM(item, 0, o);
 
-      if (PyList_SetItem(r, l, item) < 0) goto err;
-      l++;
+        if (PyList_SetItem(r, l, item) < 0)
+            goto err;
+        l++;
 
-      item = 0;
+        item = 0;
     }
 
-  item=PyObject_GetAttr(r,sort_str);
-  UNLESS (item) goto err;
-  ASSIGN(item, PyObject_CallObject(item, NULL));
-  UNLESS (item) goto err;
-  ASSIGN(item, PyObject_GetAttr(r, reverse_str));
-  UNLESS (item) goto err;
-  ASSIGN(item, PyObject_CallObject(item, NULL));
-  UNLESS (item) goto err;
-  Py_DECREF(item);
+    item=PyObject_GetAttr(r,sort_str);
+    UNLESS (item)
+        goto err;
+    ASSIGN(item, PyObject_CallObject(item, NULL));
+    UNLESS (item)
+        goto err;
+    ASSIGN(item, PyObject_GetAttr(r, reverse_str));
+    UNLESS (item)
+        goto err;
+    ASSIGN(item, PyObject_CallObject(item, NULL));
+    UNLESS (item)
+        goto err;
+    Py_DECREF(item);
 
-  PER_UNUSE(self);
-  return r;
+    PER_UNUSE(self);
+    return r;
 
- err:
-  PER_UNUSE(self);
-  Py_XDECREF(r);
-  Py_XDECREF(item);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    Py_XDECREF(r);
+    Py_XDECREF(item);
+    return NULL;
 }
 
 static int
 _bucket_clear(Bucket *self)
 {
-  const int len = self->len;
-  /* Don't declare i at this level.  If neither keys nor values are
-   * PyObject*, i won't be referenced, and you'll get a nuisance compiler
-   * wng for declaring it here.
-   */
-  self->len = self->size = 0;
+    const int len = self->len;
+    /* Don't declare i at this level.  If neither keys nor values are
+     * PyObject*, i won't be referenced, and you'll get a nuisance compiler
+     * wng for declaring it here.
+     */
+    self->len = self->size = 0;
 
-  if (self->next) {
-    Py_DECREF(self->next);
-    self->next = NULL;
-  }
+    if (self->next)
+    {
+        Py_DECREF(self->next);
+        self->next = NULL;
+    }
 
-  /* Silence compiler warning about unused variable len for the case
-     when neither key nor value is an object, i.e. II. */
-  (void)len;
+    /* Silence compiler warning about unused variable len for the case
+        when neither key nor value is an object, i.e. II. */
+    (void)len;
 
-  if (self->keys) {
+    if (self->keys)
+    {
 #ifdef KEY_TYPE_IS_PYOBJECT
-    int i;
-    for (i = 0; i < len; ++i)
-      DECREF_KEY(self->keys[i]);
+        int i;
+        for (i = 0; i < len; ++i)
+            DECREF_KEY(self->keys[i]);
 #endif
-    free(self->keys);
-    self->keys = NULL;
-  }
+        free(self->keys);
+        self->keys = NULL;
+    }
 
-  if (self->values) {
+    if (self->values)
+    {
 #ifdef VALUE_TYPE_IS_PYOBJECT
-    int i;
-    for (i = 0; i < len; ++i)
-      DECREF_VALUE(self->values[i]);
+        int i;
+        for (i = 0; i < len; ++i)
+            DECREF_VALUE(self->values[i]);
 #endif
-    free(self->values);
-    self->values = NULL;
-  }
-  return 0;
+        free(self->values);
+        self->values = NULL;
+    }
+    return 0;
 }
 
 #ifdef PERSISTENT
 static PyObject *
 bucket__p_deactivate(Bucket *self, PyObject *args, PyObject *keywords)
 {
-  int ghostify = 1;
-  PyObject *force = NULL;
+    int ghostify = 1;
+    PyObject *force = NULL;
 
-  if (args && PyTuple_GET_SIZE(args) > 0) {
-    PyErr_SetString(PyExc_TypeError,
-                    "_p_deactivate takes no positional arguments");
-    return NULL;
-  }
-  if (keywords) {
-    int size = PyDict_Size(keywords);
-    force = PyDict_GetItemString(keywords, "force");
-    if (force)
-	    size--;
-    if (size) {
-	    PyErr_SetString(PyExc_TypeError,
-                      "_p_deactivate only accepts keyword arg force");
-	    return NULL;
+    if (args && PyTuple_GET_SIZE(args) > 0)
+    {
+        PyErr_SetString(PyExc_TypeError,
+                        "_p_deactivate takes no positional arguments");
+        return NULL;
     }
-  }
+    if (keywords)
+    {
+        int size = PyDict_Size(keywords);
+        force = PyDict_GetItemString(keywords, "force");
+        if (force)
+            size--;
+        if (size) {
+            PyErr_SetString(PyExc_TypeError,
+                        "_p_deactivate only accepts keyword arg force");
+            return NULL;
+        }
+    }
 
-  if (self->jar && self->oid) {
-    ghostify = self->state == cPersistent_UPTODATE_STATE;
-    if (!ghostify && force) {
-	    if (PyObject_IsTrue(force))
-        ghostify = 1;
-	    if (PyErr_Occurred())
-        return NULL;
+    if (self->jar && self->oid)
+    {
+        ghostify = self->state == cPersistent_UPTODATE_STATE;
+        if (!ghostify && force) {
+            if (PyObject_IsTrue(force))
+            ghostify = 1;
+            if (PyErr_Occurred())
+            return NULL;
+        }
+        if (ghostify) {
+            if (_bucket_clear(self) < 0)
+            return NULL;
+            PER_GHOSTIFY(self);
+        }
     }
-    if (ghostify) {
-	    if (_bucket_clear(self) < 0)
-        return NULL;
-	    PER_GHOSTIFY(self);
-    }
-  }
-  Py_INCREF(Py_None);
-  return Py_None;
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 #endif
 
 static PyObject *
 bucket_clear(Bucket *self, PyObject *args)
 {
-  PER_USE_OR_RETURN(self, NULL);
+    PER_USE_OR_RETURN(self, NULL);
 
-  if (self->len) {
-    if (_bucket_clear(self) < 0)
-      return NULL;
-    if (PER_CHANGED(self) < 0)
-      goto err;
-  }
-  PER_UNUSE(self);
-  Py_INCREF(Py_None);
-  return Py_None;
+    if (self->len)
+    {
+        if (_bucket_clear(self) < 0)
+        return NULL;
+        if (PER_CHANGED(self) < 0)
+        goto err;
+    }
+    PER_UNUSE(self);
+    Py_INCREF(Py_None);
+    return Py_None;
 
- err:
-  PER_UNUSE(self);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    return NULL;
 }
 
 /*
@@ -1119,178 +1202,181 @@
 static PyObject *
 bucket_getstate(Bucket *self)
 {
-  PyObject *o = NULL, *items = NULL, *state;
-  int i, len, l;
+    PyObject *o = NULL, *items = NULL, *state;
+    int i, len, l;
 
-  PER_USE_OR_RETURN(self, NULL);
+    PER_USE_OR_RETURN(self, NULL);
 
-  len = self->len;
+    len = self->len;
 
-  if (self->values) { /* Bucket */
-    items = PyTuple_New(len * 2);
-    if (items == NULL)
-	    goto err;
-    for (i = 0, l = 0; i < len; i++) {
-	    COPY_KEY_TO_OBJECT(o, self->keys[i]);
-	    if (o == NULL)
-        goto err;
-	    PyTuple_SET_ITEM(items, l, o);
-	    l++;
+    if (self->values) /* Bucket */
+    {
+        items = PyTuple_New(len * 2);
+        if (items == NULL)
+            goto err;
+        for (i = 0, l = 0; i < len; i++) {
+            COPY_KEY_TO_OBJECT(o, self->keys[i]);
+            if (o == NULL)
+            goto err;
+            PyTuple_SET_ITEM(items, l, o);
+            l++;
 
-	    COPY_VALUE_TO_OBJECT(o, self->values[i]);
-	    if (o == NULL)
-        goto err;
-	    PyTuple_SET_ITEM(items, l, o);
-	    l++;
+            COPY_VALUE_TO_OBJECT(o, self->values[i]);
+            if (o == NULL)
+            goto err;
+            PyTuple_SET_ITEM(items, l, o);
+            l++;
+        }
     }
-  } else { /* Set */
-    items = PyTuple_New(len);
-    if (items == NULL)
-	    goto err;
-    for (i = 0; i < len; i++) {
-	    COPY_KEY_TO_OBJECT(o, self->keys[i]);
-	    if (o == NULL)
-        goto err;
-	    PyTuple_SET_ITEM(items, i, o);
+    else /* Set */
+    {
+        items = PyTuple_New(len);
+        if (items == NULL)
+            goto err;
+        for (i = 0; i < len; i++) {
+            COPY_KEY_TO_OBJECT(o, self->keys[i]);
+            if (o == NULL)
+            goto err;
+            PyTuple_SET_ITEM(items, i, o);
+        }
     }
-  }
 
-  if (self->next)
-    state = Py_BuildValue("OO", items, self->next);
-  else
-    state = Py_BuildValue("(O)", items);
-  Py_DECREF(items);
+    if (self->next)
+        state = Py_BuildValue("OO", items, self->next);
+    else
+        state = Py_BuildValue("(O)", items);
+    Py_DECREF(items);
 
-  PER_UNUSE(self);
-  return state;
+    PER_UNUSE(self);
+    return state;
 
- err:
-  PER_UNUSE(self);
-  Py_XDECREF(items);
-  return NULL;
+err:
+    PER_UNUSE(self);
+    Py_XDECREF(items);
+    return NULL;
 }
 
 static int
 _bucket_setstate(Bucket *self, PyObject *state)
 {
-  PyObject *k, *v, *items;
-  Bucket *next = NULL;
-  int i, l, len, copied=1;
-  KEY_TYPE *keys;
-  VALUE_TYPE *values;
+    PyObject *k, *v, *items;
+    Bucket *next = NULL;
+    int i, l, len, copied=1;
+    KEY_TYPE *keys;
+    VALUE_TYPE *values;
 
-  if (!PyArg_ParseTuple(state, "O|O:__setstate__", &items, &next))
-    return -1;
+    if (!PyArg_ParseTuple(state, "O|O:__setstate__", &items, &next))
+        return -1;
 
-  if (!PyTuple_Check(items)) {
-    PyErr_SetString(PyExc_TypeError,
-                    "tuple required for first state element");
-    return -1;
-  }
+    if (!PyTuple_Check(items)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "tuple required for first state element");
+        return -1;
+    }
 
-  len = PyTuple_Size(items);
-  if (len < 0)
-    return -1;
-  len /= 2;
+    len = PyTuple_Size(items);
+    if (len < 0)
+        return -1;
+    len /= 2;
 
-  for (i = self->len; --i >= 0; ) {
-    DECREF_KEY(self->keys[i]);
-    DECREF_VALUE(self->values[i]);
-  }
-  self->len = 0;
+    for (i = self->len; --i >= 0; ) {
+        DECREF_KEY(self->keys[i]);
+        DECREF_VALUE(self->values[i]);
+    }
+    self->len = 0;
 
-  if (self->next) {
-    Py_DECREF(self->next);
-    self->next = NULL;
-  }
+    if (self->next) {
+        Py_DECREF(self->next);
+        self->next = NULL;
+    }
 
-  if (len > self->size) {
-    keys = BTree_Realloc(self->keys, sizeof(KEY_TYPE)*len);
-    if (keys == NULL)
-	    return -1;
-    values = BTree_Realloc(self->values, sizeof(VALUE_TYPE)*len);
-    if (values == NULL)
-	    return -1;
-    self->keys = keys;
-    self->values = values;
-    self->size = len;
-  }
+    if (len > self->size) {
+        keys = BTree_Realloc(self->keys, sizeof(KEY_TYPE)*len);
+        if (keys == NULL)
+            return -1;
+        values = BTree_Realloc(self->values, sizeof(VALUE_TYPE)*len);
+        if (values == NULL)
+            return -1;
+        self->keys = keys;
+        self->values = values;
+        self->size = len;
+    }
 
-  for (i=0, l=0; i < len; i++) {
-    k = PyTuple_GET_ITEM(items, l);
-    l++;
-    v = PyTuple_GET_ITEM(items, l);
-    l++;
+    for (i=0, l=0; i < len; i++) {
+        k = PyTuple_GET_ITEM(items, l);
+        l++;
+        v = PyTuple_GET_ITEM(items, l);
+        l++;
 
-    COPY_KEY_FROM_ARG(self->keys[i], k, copied);
-    if (!copied)
-	    return -1;
-    COPY_VALUE_FROM_ARG(self->values[i], v, copied);
-    if (!copied)
-	    return -1;
-    INCREF_KEY(self->keys[i]);
-    INCREF_VALUE(self->values[i]);
-  }
+        COPY_KEY_FROM_ARG(self->keys[i], k, copied);
+        if (!copied)
+            return -1;
+        COPY_VALUE_FROM_ARG(self->values[i], v, copied);
+        if (!copied)
+            return -1;
+        INCREF_KEY(self->keys[i]);
+        INCREF_VALUE(self->values[i]);
+    }
 
-  self->len = len;
+    self->len = len;
 
-  if (next) {
-    self->next = next;
-    Py_INCREF(next);
-  }
+    if (next) {
+        self->next = next;
+        Py_INCREF(next);
+    }
 
-  return 0;
+    return 0;
 }
 
 static PyObject *
 bucket_setstate(Bucket *self, PyObject *state)
 {
-  int r;
+    int r;
 
-  PER_PREVENT_DEACTIVATION(self);
-  r = _bucket_setstate(self, state);
-  PER_UNUSE(self);
+    PER_PREVENT_DEACTIVATION(self);
+    r = _bucket_setstate(self, state);
+    PER_UNUSE(self);
 
-  if (r < 0)
-    return NULL;
-  Py_INCREF(Py_None);
-  return Py_None;
+    if (r < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 
 static PyObject *
 bucket_has_key(Bucket *self, PyObject *key)
 {
-  return _bucket_get(self, key, 1);
+    return _bucket_get(self, key, 1);
 }
 
 static PyObject *
 bucket_setdefault(Bucket *self, PyObject *args)
 {
-  PyObject *key;
-  PyObject *failobj; /* default */
-  PyObject *value;   /* return value */
-  int dummy_changed; /* in order to call _bucket_set */
+    PyObject *key;
+    PyObject *failobj; /* default */
+    PyObject *value;   /* return value */
+    int dummy_changed; /* in order to call _bucket_set */
 
-  if (! PyArg_UnpackTuple(args, "setdefault", 2, 2, &key, &failobj))
-    return NULL;
+    if (! PyArg_UnpackTuple(args, "setdefault", 2, 2, &key, &failobj))
+        return NULL;
 
-  value = _bucket_get(self, key, 0);
-  if (value != NULL)
-    return value;
+    value = _bucket_get(self, key, 0);
+    if (value != NULL)
+        return value;
 
-  /* The key isn't in the bucket.  If that's not due to a KeyError exception,
-   * pass back the unexpected exception.
-   */
-  if (! PyErr_ExceptionMatches(PyExc_KeyError))
-    return NULL;
-  PyErr_Clear();
+    /* The key isn't in the bucket.  If that's not due to a KeyError exception,
+     * pass back the unexpected exception.
+     */
+    if (! PyErr_ExceptionMatches(PyExc_KeyError))
+        return NULL;
+    PyErr_Clear();
 
-  /* Associate `key` with `failobj` in the bucket, and return `failobj`. */
-  value = failobj;
-  if (_bucket_set(self, key, failobj, 0, 0, &dummy_changed) < 0)
-    value = NULL;
-  Py_XINCREF(value);
-  return value;
+    /* Associate `key` with `failobj` in the bucket, and return `failobj`. */
+    value = failobj;
+    if (_bucket_set(self, key, failobj, 0, 0, &dummy_changed) < 0)
+        value = NULL;
+    Py_XINCREF(value);
+    return value;
 }
 
 
@@ -1301,43 +1387,43 @@
 static PyObject *
 bucket_pop(Bucket *self, PyObject *args)
 {
-  PyObject *key;
-  PyObject *failobj = NULL; /* default */
-  PyObject *value;          /* return value */
-  int dummy_changed;        /* in order to call _bucket_set */
+    PyObject *key;
+    PyObject *failobj = NULL; /* default */
+    PyObject *value;          /* return value */
+    int dummy_changed;        /* in order to call _bucket_set */
 
-  if (! PyArg_UnpackTuple(args, "pop", 1, 2, &key, &failobj))
-    return NULL;
+    if (! PyArg_UnpackTuple(args, "pop", 1, 2, &key, &failobj))
+        return NULL;
 
-  value = _bucket_get(self, key, 0);
-  if (value != NULL) {
-    /* Delete key and associated value. */
-    if (_bucket_set(self, key, NULL, 0, 0, &dummy_changed) < 0) {
-      Py_DECREF(value);
-      return NULL;
+    value = _bucket_get(self, key, 0);
+    if (value != NULL) {
+        /* Delete key and associated value. */
+        if (_bucket_set(self, key, NULL, 0, 0, &dummy_changed) < 0) {
+        Py_DECREF(value);
+        return NULL;
+        }
+        return value;
     }
-    return value;
-  }
 
-  /* The key isn't in the bucket.  If that's not due to a KeyError exception,
-   * pass back the unexpected exception.
-   */
-  if (! PyErr_ExceptionMatches(PyExc_KeyError))
-    return NULL;
+    /* The key isn't in the bucket.  If that's not due to a KeyError exception,
+     * pass back the unexpected exception.
+     */
+    if (! PyErr_ExceptionMatches(PyExc_KeyError))
+        return NULL;
 
-  if (failobj != NULL) {
-    /* Clear the KeyError and return the explicit default. */
-    PyErr_Clear();
-    Py_INCREF(failobj);
-    return failobj;
-  }
+    if (failobj != NULL) {
+        /* Clear the KeyError and return the explicit default. */
+        PyErr_Clear();
+        Py_INCREF(failobj);
+        return failobj;
+    }
 
-  /* No default given.  The only difference in this case is the error
-   * message, which depends on whether the bucket is empty.
-   */
-  if (Bucket_length(self) == 0)
-    PyErr_SetString(PyExc_KeyError, "pop(): Bucket is empty");
-  return NULL;
+    /* No default given.  The only difference in this case is the error
+     * message, which depends on whether the bucket is empty.
+     */
+    if (Bucket_length(self) == 0)
+        PyErr_SetString(PyExc_KeyError, "pop(): Bucket is empty");
+    return NULL;
 }
 
 /* Search bucket self for key.  This is the sq_contains slot of the
@@ -1351,14 +1437,14 @@
 static int
 bucket_contains(Bucket *self, PyObject *key)
 {
-  PyObject *asobj = _bucket_get(self, key, 1);
-  int result = -1;
+    PyObject *asobj = _bucket_get(self, key, 1);
+    int result = -1;
 
-  if (asobj != NULL) {
-    result = PyInt_AsLong(asobj) ? 1 : 0;
-    Py_DECREF(asobj);
-  }
-  return result;
+    if (asobj != NULL) {
+        result = INT_AS_LONG(asobj) ? 1 : 0;
+        Py_DECREF(asobj);
+    }
+    return result;
 }
 
 /*
@@ -1368,18 +1454,18 @@
 static PyObject *
 bucket_getm(Bucket *self, PyObject *args)
 {
-  PyObject *key, *d=Py_None, *r;
+    PyObject *key, *d=Py_None, *r;
 
-  if (!PyArg_ParseTuple(args, "O|O:get", &key, &d))
-    return NULL;
-  r = _bucket_get(self, key, 0);
-  if (r)
-    return r;
-  if (!PyErr_ExceptionMatches(PyExc_KeyError))
-    return NULL;
-  PyErr_Clear();
-  Py_INCREF(d);
-  return d;
+    if (!PyArg_ParseTuple(args, "O|O:get", &key, &d))
+        return NULL;
+    r = _bucket_get(self, key, 0);
+    if (r)
+        return r;
+    if (!PyErr_ExceptionMatches(PyExc_KeyError))
+        return NULL;
+    PyErr_Clear();
+    Py_INCREF(d);
+    return d;
 }
 
 /**************************************************************************/
@@ -1394,52 +1480,53 @@
 static PyObject *
 buildBucketIter(Bucket *self, PyObject *args, PyObject *kw, char kind)
 {
-  BTreeItems *items;
-  int lowoffset, highoffset;
-  BTreeIter *result = NULL;
+    BTreeItems *items;
+    int lowoffset, highoffset;
+    BTreeIter *result = NULL;
 
-  PER_USE_OR_RETURN(self, NULL);
-  if (Bucket_rangeSearch(self, args, kw, &lowoffset, &highoffset) < 0)
-    goto Done;
+    PER_USE_OR_RETURN(self, NULL);
+    if (Bucket_rangeSearch(self, args, kw, &lowoffset, &highoffset) < 0)
+        goto Done;
 
-  items = (BTreeItems *)newBTreeItems(kind, self, lowoffset,
-                                      self, highoffset);
-  if (items == NULL) goto Done;
+    items = (BTreeItems *)newBTreeItems(kind, self, lowoffset,
+                                        self, highoffset);
+    if (items == NULL)
+        goto Done;
 
-  result = BTreeIter_new(items);      /* win or lose, we're done */
-  Py_DECREF(items);
+    result = BTreeIter_new(items);      /* win or lose, we're done */
+    Py_DECREF(items);
 
- Done:
-  PER_UNUSE(self);
-  return (PyObject *)result;
+Done:
+    PER_UNUSE(self);
+    return (PyObject *)result;
 }
 
 /* The implementation of iter(Bucket_or_Set); the Bucket tp_iter slot. */
 static PyObject *
 Bucket_getiter(Bucket *self)
 {
-  return buildBucketIter(self, NULL, NULL, 'k');
+    return buildBucketIter(self, NULL, NULL, 'k');
 }
 
 /* The implementation of Bucket.iterkeys(). */
 static PyObject *
 Bucket_iterkeys(Bucket *self, PyObject *args, PyObject *kw)
 {
-  return buildBucketIter(self, args, kw, 'k');
+    return buildBucketIter(self, args, kw, 'k');
 }
 
 /* The implementation of Bucket.itervalues(). */
 static PyObject *
 Bucket_itervalues(Bucket *self, PyObject *args, PyObject *kw)
 {
-  return buildBucketIter(self, args, kw, 'v');
+    return buildBucketIter(self, args, kw, 'v');
 }
 
 /* The implementation of Bucket.iteritems(). */
 static PyObject *
 Bucket_iteritems(Bucket *self, PyObject *args, PyObject *kw)
 {
-  return buildBucketIter(self, args, kw, 'i');
+    return buildBucketIter(self, args, kw, 'i');
 }
 
 /* End of iterator support. */
@@ -1451,61 +1538,61 @@
 static PyObject *
 _bucket__p_resolveConflict(PyObject *ob_type, PyObject *s[3])
 {
-  PyObject *result = NULL;	/* guilty until proved innocent */
-  Bucket *b[3] = {NULL, NULL, NULL};
-  PyObject *meth = NULL;
-  PyObject *a = NULL;
-  int i;
+    PyObject *result = NULL;    /* guilty until proved innocent */
+    Bucket *b[3] = {NULL, NULL, NULL};
+    PyObject *meth = NULL;
+    PyObject *a = NULL;
+    int i;
 
-  for (i = 0; i < 3; i++) {
-    PyObject *r;
+    for (i = 0; i < 3; i++) {
+        PyObject *r;
 
-    b[i] = (Bucket*)PyObject_CallObject((PyObject *)ob_type, NULL);
-    if (b[i] == NULL)
-	    goto Done;
-    if (s[i] == Py_None) /* None is equivalent to empty, for BTrees */
-	    continue;
-    meth = PyObject_GetAttr((PyObject *)b[i], __setstate___str);
-    if (meth == NULL)
-	    goto Done;
-    a = PyTuple_New(1);
-    if (a == NULL)
-	    goto Done;
-    PyTuple_SET_ITEM(a, 0, s[i]);
-    Py_INCREF(s[i]);
-    r = PyObject_CallObject(meth, a);  /* b[i].__setstate__(s[i]) */
-    if (r == NULL)
-	    goto Done;
-    Py_DECREF(r);
-    Py_DECREF(a);
-    Py_DECREF(meth);
-    a = meth = NULL;
-  }
+        b[i] = (Bucket*)PyObject_CallObject((PyObject *)ob_type, NULL);
+        if (b[i] == NULL)
+            goto Done;
+        if (s[i] == Py_None) /* None is equivalent to empty, for BTrees */
+            continue;
+        meth = PyObject_GetAttr((PyObject *)b[i], __setstate___str);
+        if (meth == NULL)
+            goto Done;
+        a = PyTuple_New(1);
+        if (a == NULL)
+            goto Done;
+        PyTuple_SET_ITEM(a, 0, s[i]);
+        Py_INCREF(s[i]);
+        r = PyObject_CallObject(meth, a);  /* b[i].__setstate__(s[i]) */
+        if (r == NULL)
+            goto Done;
+        Py_DECREF(r);
+        Py_DECREF(a);
+        Py_DECREF(meth);
+        a = meth = NULL;
+    }
 
-  if (b[0]->next != b[1]->next || b[0]->next != b[2]->next)
-    merge_error(-1, -1, -1, 0);
-  else
-    result = bucket_merge(b[0], b[1], b[2]);
+    if (b[0]->next != b[1]->next || b[0]->next != b[2]->next)
+        merge_error(-1, -1, -1, 0);
+    else
+        result = bucket_merge(b[0], b[1], b[2]);
 
- Done:
-  Py_XDECREF(meth);
-  Py_XDECREF(a);
-  Py_XDECREF(b[0]);
-  Py_XDECREF(b[1]);
-  Py_XDECREF(b[2]);
+Done:
+    Py_XDECREF(meth);
+    Py_XDECREF(a);
+    Py_XDECREF(b[0]);
+    Py_XDECREF(b[1]);
+    Py_XDECREF(b[2]);
 
-  return result;
+    return result;
 }
 
 static PyObject *
 bucket__p_resolveConflict(Bucket *self, PyObject *args)
 {
-  PyObject *s[3];
+    PyObject *s[3];
 
-  if (!PyArg_ParseTuple(args, "OOO", &s[0], &s[1], &s[2]))
-    return NULL;
+    if (!PyArg_ParseTuple(args, "OOO", &s[0], &s[1], &s[2]))
+        return NULL;
 
-  return _bucket__p_resolveConflict((PyObject *)self->ob_type, s);
+    return _bucket__p_resolveConflict((PyObject *)Py_TYPE(self), s);
 }
 #endif
 
@@ -1518,113 +1605,116 @@
 */
 
 static struct PyMemberDef Bucket_members[] = {
-  {"_next", T_OBJECT, offsetof(Bucket, next)},
-  {NULL}
+    {"_next", T_OBJECT, offsetof(Bucket, next)},
+    {NULL}
 };
 
 static struct PyMethodDef Bucket_methods[] = {
-  {"__getstate__", (PyCFunction) bucket_getstate,	METH_NOARGS,
-   "__getstate__() -- Return the picklable state of the object"},
+    {"__getstate__", (PyCFunction) bucket_getstate, METH_NOARGS,
+     "__getstate__() -- Return the picklable state of the object"},
 
-  {"__setstate__", (PyCFunction) bucket_setstate,	METH_O,
-   "__setstate__() -- Set the state of the object"},
+    {"__setstate__", (PyCFunction) bucket_setstate, METH_O,
+     "__setstate__() -- Set the state of the object"},
 
-  {"keys",	(PyCFunction) bucket_keys,	METH_KEYWORDS,
-   "keys([min, max]) -- Return the keys"},
+    {"keys", (PyCFunction) bucket_keys, METH_VARARGS | METH_KEYWORDS,
+     "keys([min, max]) -- Return the keys"},
 
-  {"has_key",	(PyCFunction) bucket_has_key,	METH_O,
-   "has_key(key) -- Test whether the bucket contains the given key"},
+    {"has_key", (PyCFunction) bucket_has_key, METH_O,
+     "has_key(key) -- Test whether the bucket contains the given key"},
 
-  {"clear",	(PyCFunction) bucket_clear,	METH_VARARGS,
-   "clear() -- Remove all of the items from the bucket"},
+    {"clear", (PyCFunction) bucket_clear, METH_VARARGS,
+     "clear() -- Remove all of the items from the bucket"},
 
-  {"update",	(PyCFunction) Mapping_update,	METH_O,
-   "update(collection) -- Add the items from the given collection"},
+    {"update", (PyCFunction) Mapping_update, METH_O,
+     "update(collection) -- Add the items from the given collection"},
 
-  {"maxKey", (PyCFunction) Bucket_maxKey,	METH_VARARGS,
-   "maxKey([key]) -- Find the maximum key\n\n"
-   "If an argument is given, find the maximum <= the argument"},
+    {"maxKey", (PyCFunction) Bucket_maxKey, METH_VARARGS,
+     "maxKey([key]) -- Find the maximum key\n\n"
+     "If an argument is given, find the maximum <= the argument"},
 
-  {"minKey", (PyCFunction) Bucket_minKey,	METH_VARARGS,
-   "minKey([key]) -- Find the minimum key\n\n"
-   "If an argument is given, find the minimum >= the argument"},
+    {"minKey", (PyCFunction) Bucket_minKey, METH_VARARGS,
+     "minKey([key]) -- Find the minimum key\n\n"
+     "If an argument is given, find the minimum >= the argument"},
 
-  {"values",	(PyCFunction) bucket_values,	METH_KEYWORDS,
-   "values([min, max]) -- Return the values"},
+    {"values", (PyCFunction) bucket_values, METH_VARARGS | METH_KEYWORDS,
+     "values([min, max]) -- Return the values"},
 
-  {"items",	(PyCFunction) bucket_items,	METH_KEYWORDS,
-   "items([min, max])) -- Return the items"},
+    {"items", (PyCFunction) bucket_items, METH_VARARGS | METH_KEYWORDS,
+     "items([min, max])) -- Return the items"},
 
-  {"byValue",	(PyCFunction) bucket_byValue,	METH_O,
-   "byValue(min) -- "
-   "Return value-keys with values >= min and reverse sorted by values"},
+    {"byValue", (PyCFunction) bucket_byValue, METH_O,
+     "byValue(min) -- "
+     "Return value-keys with values >= min and reverse sorted by values"},
 
-  {"get",	(PyCFunction) bucket_getm,	METH_VARARGS,
-   "get(key[,default]) -- Look up a value\n\n"
-   "Return the default (or None) if the key is not found."},
+    {"get", (PyCFunction) bucket_getm, METH_VARARGS,
+     "get(key[,default]) -- Look up a value\n\n"
+     "Return the default (or None) if the key is not found."},
 
-  {"setdefault", (PyCFunction) bucket_setdefault, METH_VARARGS,
-   "D.setdefault(k, d) -> D.get(k, d), also set D[k]=d if k not in D.\n\n"
-   "Return the value like get() except that if key is missing, d is both\n"
-   "returned and inserted into the bucket as the value of k."},
+    {"setdefault", (PyCFunction) bucket_setdefault, METH_VARARGS,
+     "D.setdefault(k, d) -> D.get(k, d), also set D[k]=d if k not in D.\n\n"
+     "Return the value like get() except that if key is missing, d is both\n"
+     "returned and inserted into the bucket as the value of k."},
 
-  {"pop", (PyCFunction) bucket_pop, METH_VARARGS,
-   "D.pop(k[, d]) -> v, remove key and return the corresponding value.\n\n"
-   "If key is not found, d is returned if given, otherwise KeyError\n"
-   "is raised."},
+    {"pop", (PyCFunction) bucket_pop, METH_VARARGS,
+     "D.pop(k[, d]) -> v, remove key and return the corresponding value.\n\n"
+     "If key is not found, d is returned if given, otherwise KeyError\n"
+     "is raised."},
 
-  {"iterkeys", (PyCFunction) Bucket_iterkeys,  METH_KEYWORDS,
-   "B.iterkeys([min[,max]]) -> an iterator over the keys of B"},
+    {"iterkeys", (PyCFunction) Bucket_iterkeys, METH_VARARGS | METH_KEYWORDS,
+     "B.iterkeys([min[,max]]) -> an iterator over the keys of B"},
+ 
+    {"itervalues",
+     (PyCFunction) Bucket_itervalues, METH_VARARGS | METH_KEYWORDS,
+     "B.itervalues([min[,max]]) -> an iterator over the values of B"},
 
-  {"itervalues", (PyCFunction) Bucket_itervalues,  METH_KEYWORDS,
-   "B.itervalues([min[,max]]) -> an iterator over the values of B"},
+    {"iteritems", (PyCFunction) Bucket_iteritems, METH_VARARGS | METH_KEYWORDS,
+     "B.iteritems([min[,max]]) -> an iterator over the (key, value) "
+     "items of B"},
 
-  {"iteritems", (PyCFunction) Bucket_iteritems,    METH_KEYWORDS,
-   "B.iteritems([min[,max]]) -> an iterator over the (key, value) items of B"},
-
 #ifdef EXTRA_BUCKET_METHODS
-  EXTRA_BUCKET_METHODS
+    EXTRA_BUCKET_METHODS
 #endif
 
 #ifdef PERSISTENT
-  {"_p_resolveConflict", (PyCFunction) bucket__p_resolveConflict,
-   METH_VARARGS,
-   "_p_resolveConflict() -- Reinitialize from a newly created copy"},
+    {"_p_resolveConflict",
+     (PyCFunction) bucket__p_resolveConflict, METH_VARARGS,
+     "_p_resolveConflict() -- Reinitialize from a newly created copy"},
 
-  {"_p_deactivate", (PyCFunction) bucket__p_deactivate, METH_KEYWORDS,
-   "_p_deactivate() -- Reinitialize from a newly created copy"},
+    {"_p_deactivate",
+     (PyCFunction) bucket__p_deactivate, METH_VARARGS | METH_KEYWORDS,
+     "_p_deactivate() -- Reinitialize from a newly created copy"},
 #endif
-  {NULL, NULL}
+    {NULL, NULL}
 };
 
 static int
 Bucket_init(PyObject *self, PyObject *args, PyObject *kwds)
 {
-  PyObject *v = NULL;
+    PyObject *v = NULL;
 
-  if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "Bucket", &v))
-    return -1;
+    if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "Bucket", &v))
+        return -1;
 
-  if (v)
-    return update_from_seq(self, v);
-  else
-    return 0;
+    if (v)
+        return update_from_seq(self, v);
+    else
+        return 0;
 }
 
 static void
 bucket_dealloc(Bucket *self)
 {
-  if (self->state != cPersistent_GHOST_STATE)
-    _bucket_clear(self);
+    if (self->state != cPersistent_GHOST_STATE)
+        _bucket_clear(self);
 
-  cPersistenceCAPI->pertype->tp_dealloc((PyObject *)self);
+    cPersistenceCAPI->pertype->tp_dealloc((PyObject *)self);
 }
 
 static int
 bucket_traverse(Bucket *self, visitproc visit, void *arg)
 {
-  int err = 0;
-  int i, len;
+    int err = 0;
+    int i, len;
 
 #define VISIT(SLOT)                             \
   if (SLOT) {                                   \
@@ -1633,42 +1723,44 @@
       goto Done;                                \
   }
 
-  /* Call our base type's traverse function.  Because buckets are
-   * subclasses of Peristent, there must be one.
-   */
-  err = cPersistenceCAPI->pertype->tp_traverse((PyObject *)self, visit, arg);
-  if (err)
-    goto Done;
+    /* Call our base type's traverse function.  Because buckets are
+     * subclasses of Peristent, there must be one.
+     */
+    err = cPersistenceCAPI->pertype->tp_traverse((PyObject *)self, visit, arg);
+    if (err)
+        goto Done;
 
-  /* If this is registered with the persistence system, cleaning up cycles
-   * is the database's problem.  It would be horrid to unghostify buckets
-   * here just to chase pointers every time gc runs.
-   */
-  if (self->state == cPersistent_GHOST_STATE)
-    goto Done;
+    /* If this is registered with the persistence system, cleaning up cycles
+     * is the database's problem.  It would be horrid to unghostify buckets
+     * here just to chase pointers every time gc runs.
+     */
+    if (self->state == cPersistent_GHOST_STATE)
+        goto Done;
 
-  len = self->len;
-  (void)i;    /* if neither keys nor values are PyObject*, "i" is otherwise
-                 unreferenced and we get a nuisance compiler wng */
+    len = self->len;
+    /* if neither keys nor values are PyObject*, "i" is otherwise
+       unreferenced and we get a nuisance compiler wng */
+    (void)i;
+    (void)len;
 #ifdef KEY_TYPE_IS_PYOBJECT
-  /* Keys are Python objects so need to be traversed. */
-  for (i = 0; i < len; i++)
-    VISIT(self->keys[i]);
+    /* Keys are Python objects so need to be traversed. */
+    for (i = 0; i < len; i++)
+        VISIT(self->keys[i]);
 #endif
 
 #ifdef VALUE_TYPE_IS_PYOBJECT
-  if (self->values != NULL) {
-    /* self->values exists (this is a mapping bucket, not a set bucket),
-     * and are Python objects, so need to be traversed. */
-    for (i = 0; i < len; i++)
-      VISIT(self->values[i]);
-  }
+    if (self->values != NULL) {
+        /* self->values exists (this is a mapping bucket, not a set bucket),
+        * and are Python objects, so need to be traversed. */
+        for (i = 0; i < len; i++)
+            VISIT(self->values[i]);
+    }
 #endif
 
-  VISIT(self->next);
+    VISIT(self->next);
 
- Done:
-  return err;
+Done:
+    return err;
 
 #undef VISIT
 }
@@ -1676,139 +1768,169 @@
 static int
 bucket_tp_clear(Bucket *self)
 {
-  if (self->state != cPersistent_GHOST_STATE)
-    _bucket_clear(self);
-  return 0;
+    if (self->state != cPersistent_GHOST_STATE)
+        _bucket_clear(self);
+    return 0;
 }
 
 /* Code to access Bucket objects as mappings */
 static int
 Bucket_length( Bucket *self)
 {
-  int r;
-  UNLESS (PER_USE(self)) return -1;
-  r = self->len;
-  PER_UNUSE(self);
-  return r;
+    int r;
+    UNLESS (PER_USE(self))
+        return -1;
+    r = self->len;
+    PER_UNUSE(self);
+    return r;
 }
 
 static PyMappingMethods Bucket_as_mapping = {
-  (lenfunc)Bucket_length,		/*mp_length*/
-  (binaryfunc)bucket_getitem,		/*mp_subscript*/
-  (objobjargproc)bucket_setitem,	/*mp_ass_subscript*/
+    (lenfunc)Bucket_length,             /*mp_length*/
+    (binaryfunc)bucket_getitem,         /*mp_subscript*/
+    (objobjargproc)bucket_setitem,      /*mp_ass_subscript*/
 };
 
 static PySequenceMethods Bucket_as_sequence = {
-  (lenfunc)0,                     /* sq_length */
-  (binaryfunc)0,                  /* sq_concat */
-  (ssizeargfunc)0,                /* sq_repeat */
-  (ssizeargfunc)0,                /* sq_item */
-  (ssizessizeargfunc)0,           /* sq_slice */
-  (ssizeobjargproc)0,             /* sq_ass_item */
-  (ssizessizeobjargproc)0,        /* sq_ass_slice */
-  (objobjproc)bucket_contains,    /* sq_contains */
-  0,                              /* sq_inplace_concat */
-  0,                              /* sq_inplace_repeat */
+    (lenfunc)0,                         /* sq_length */
+    (binaryfunc)0,                      /* sq_concat */
+    (ssizeargfunc)0,                    /* sq_repeat */
+    (ssizeargfunc)0,                    /* sq_item */
+    (ssizessizeargfunc)0,               /* sq_slice */
+    (ssizeobjargproc)0,                 /* sq_ass_item */
+    (ssizessizeobjargproc)0,            /* sq_ass_slice */
+    (objobjproc)bucket_contains,        /* sq_contains */
+    0,                                  /* sq_inplace_concat */
+    0,                                  /* sq_inplace_repeat */
 };
 
 static PyObject *
 bucket_repr(Bucket *self)
 {
-  PyObject *i, *r;
-  char repr[10000];
-  int rv;
+    PyObject *i, *r;
+#ifdef PY3K
+    PyObject *rb;
+#endif
+    char repr[10000];
+    int rv;
 
-  i = bucket_items(self, NULL, NULL);
-  if (!i)
-    return NULL;
-  r = PyObject_Repr(i);
-  Py_DECREF(i);
-  if (!r) {
-    return NULL;
-  }
-  rv = PyOS_snprintf(repr, sizeof(repr),
-                     "%s(%s)", self->ob_type->tp_name,
-                     PyString_AS_STRING(r));
-  if (rv > 0 && rv < sizeof(repr)) {
-    Py_DECREF(r);
-    return PyString_FromStringAndSize(repr, strlen(repr));
-  }
-  else {
-    /* The static buffer wasn't big enough */
-    int size;
-    PyObject *s;
-
-    /* 3 for the parens and the null byte */
-    size = strlen(self->ob_type->tp_name) + PyString_GET_SIZE(r) + 3;
-    s = PyString_FromStringAndSize(NULL, size);
-    if (!s) {
-	    Py_DECREF(r);
-	    return r;
+    i = bucket_items(self, NULL, NULL);
+    if (!i)
+    {
+        return NULL;
     }
-    PyOS_snprintf(PyString_AS_STRING(s), size,
-                  "%s(%s)", self->ob_type->tp_name, PyString_AS_STRING(r));
-    Py_DECREF(r);
-    return s;
-  }
+    r = PyObject_Repr(i);
+    Py_DECREF(i);
+    if (!r)
+    {
+        return NULL;
+    }
+#ifdef PY3K
+    rb = PyUnicode_AsLatin1String(r);
+    rv = PyOS_snprintf(repr, sizeof(repr),
+                       "%s(%s)", Py_TYPE(self)->tp_name,
+                       PyBytes_AsString(rb));
+    Py_DECREF(rb);
+#else
+    rv = PyOS_snprintf(repr, sizeof(repr),
+                       "%s(%s)", Py_TYPE(self)->tp_name,
+                       PyBytes_AS_STRING(r));
+#endif
+    if (rv > 0 && rv < sizeof(repr))
+    {
+        Py_DECREF(r);
+#ifdef PY3K
+        return PyUnicode_DecodeLatin1(repr, sizeof(repr), "surrogateescape");
+#else
+        return PyBytes_FromStringAndSize(repr, sizeof(repr));
+#endif
+    }
+    else
+    {
+        /* The static buffer wasn't big enough */
+        int size;
+        PyObject *s;
+#ifdef PY3K
+        PyObject *result;
+#endif
+        /* 3 for the parens and the null byte */
+        size = strlen(Py_TYPE(self)->tp_name) + PyBytes_GET_SIZE(r) + 3;
+        s = PyBytes_FromStringAndSize(NULL, size);
+        if (!s) {
+            Py_DECREF(r);
+            return r;
+        }
+        PyOS_snprintf(PyBytes_AS_STRING(s), size,
+                    "%s(%s)", Py_TYPE(self)->tp_name, PyBytes_AS_STRING(r));
+        Py_DECREF(r);
+#ifdef PY3K
+        result = PyUnicode_FromEncodedObject(s, "latin1", "surrogateescape");
+        Py_DECREF(s);
+        return result;
+#else
+        return s;
+#endif
+    }
 }
 
 static PyTypeObject BucketType = {
-  PyObject_HEAD_INIT(NULL) /* PyPersist_Type */
-  0,					/* ob_size */
-  MODULE_NAME MOD_NAME_PREFIX "Bucket",/* tp_name */
-  sizeof(Bucket),			/* tp_basicsize */
-  0,					/* tp_itemsize */
-  (destructor)bucket_dealloc,		/* tp_dealloc */
-  0,					/* tp_print */
-  0,					/* tp_getattr */
-  0,					/* tp_setattr */
-  0,					/* tp_compare */
-  (reprfunc)bucket_repr,		/* tp_repr */
-  0,					/* tp_as_number */
-  &Bucket_as_sequence,		/* tp_as_sequence */
-  &Bucket_as_mapping,			/* tp_as_mapping */
-  0,					/* tp_hash */
-  0,					/* tp_call */
-  0,					/* tp_str */
-  0,					/* tp_getattro */
-  0,					/* tp_setattro */
-  0,					/* tp_as_buffer */
-  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
-  Py_TPFLAGS_BASETYPE, 	/* tp_flags */
-  0,					/* tp_doc */
-  (traverseproc)bucket_traverse,	/* tp_traverse */
-  (inquiry)bucket_tp_clear,		/* tp_clear */
-  0,					/* tp_richcompare */
-  0,					/* tp_weaklistoffset */
-  (getiterfunc)Bucket_getiter,	/* tp_iter */
-  0,					/* tp_iternext */
-  Bucket_methods,			/* tp_methods */
-  Bucket_members,			/* tp_members */
-  0,					/* tp_getset */
-  0,					/* tp_base */
-  0,					/* tp_dict */
-  0,					/* tp_descr_get */
-  0,					/* tp_descr_set */
-  0,					/* tp_dictoffset */
-  Bucket_init,			/* tp_init */
-  0,					/* tp_alloc */
-  0, /*PyType_GenericNew,*/		/* tp_new */
+    PyVarObject_HEAD_INIT(NULL, 0)
+    MODULE_NAME MOD_NAME_PREFIX "Bucket",   /* tp_name */
+    sizeof(Bucket),                         /* tp_basicsize */
+    0,                                      /* tp_itemsize */
+    (destructor)bucket_dealloc,             /* tp_dealloc */
+    0,                                      /* tp_print */
+    0,                                      /* tp_getattr */
+    0,                                      /* tp_setattr */
+    0,                                      /* tp_compare */
+    (reprfunc)bucket_repr,                  /* tp_repr */
+    0,                                      /* tp_as_number */
+    &Bucket_as_sequence,                    /* tp_as_sequence */
+    &Bucket_as_mapping,                     /* tp_as_mapping */
+    0,                                      /* tp_hash */
+    0,                                      /* tp_call */
+    0,                                      /* tp_str */
+    0,                                      /* tp_getattro */
+    0,                                      /* tp_setattro */
+    0,                                      /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+    Py_TPFLAGS_HAVE_GC |
+    Py_TPFLAGS_BASETYPE,                    /* tp_flags */
+    0,                                      /* tp_doc */
+    (traverseproc)bucket_traverse,          /* tp_traverse */
+    (inquiry)bucket_tp_clear,               /* tp_clear */
+    0,                                      /* tp_richcompare */
+    0,                                      /* tp_weaklistoffset */
+    (getiterfunc)Bucket_getiter,            /* tp_iter */
+    0,                                      /* tp_iternext */
+    Bucket_methods,                         /* tp_methods */
+    Bucket_members,                         /* tp_members */
+    0,                                      /* tp_getset */
+    0,                                      /* tp_base */
+    0,                                      /* tp_dict */
+    0,                                      /* tp_descr_get */
+    0,                                      /* tp_descr_set */
+    0,                                      /* tp_dictoffset */
+    Bucket_init,                            /* tp_init */
+    0,                                      /* tp_alloc */
+    0, /*PyType_GenericNew,*/               /* tp_new */
 };
 
 static int
 nextBucket(SetIteration *i)
 {
-  if (i->position >= 0)
+    if (i->position >= 0)
     {
-      UNLESS(PER_USE(BUCKET(i->set))) return -1;
+        UNLESS(PER_USE(BUCKET(i->set)))
+            return -1;
 
-      if (i->position)
+        if (i->position)
         {
           DECREF_KEY(i->key);
           DECREF_VALUE(i->value);
         }
 
-      if (i->position < BUCKET(i->set)->len)
+        if (i->position < BUCKET(i->set)->len)
         {
           COPY_KEY(i->key, BUCKET(i->set)->keys[i->position]);
           INCREF_KEY(i->key);
@@ -1816,15 +1938,14 @@
           INCREF_VALUE(i->value);
           i->position ++;
         }
-      else
+        else
         {
           i->position = -1;
           PER_ACCESSED(BUCKET(i->set));
         }
 
-      PER_ALLOW_DEACTIVATION(BUCKET(i->set));
+        PER_ALLOW_DEACTIVATION(BUCKET(i->set));
     }
 
-
-  return 0;
+    return 0;
 }

Modified: BTrees/trunk/BTrees/IFBTree.py
===================================================================
--- BTrees/trunk/BTrees/IFBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/IFBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -99,17 +99,8 @@
 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
+    from ._IFBTree import IFBucket
+except ImportError: #pragma NO COVER w/ C extensions
     IFBucket = IFBucketPy
     IFSet = IFSetPy
     IFBTree = IFBTreePy
@@ -120,6 +111,16 @@
     multiunion = multiunionPy
     weightedUnion = weightedUnionPy
     weightedIntersection = weightedIntersectionPy
+else: #pragma NO COVER w/o C extensions
+    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 ._IFBTree import weightedUnion
+    from ._IFBTree import weightedIntersection
 
 Bucket = IFBucket
 Set = IFSet

Modified: BTrees/trunk/BTrees/IIBTree.py
===================================================================
--- BTrees/trunk/BTrees/IIBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/IIBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -100,17 +100,8 @@
 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
+    from ._IIBTree import IIBucket
+except ImportError: #pragma NO COVER w/ C extensions
     IIBucket = IIBucketPy
     IISet = IISetPy
     IIBTree = IIBTreePy
@@ -121,6 +112,16 @@
     multiunion = multiunionPy
     weightedUnion = weightedUnionPy
     weightedIntersection = weightedIntersectionPy
+else: #pragma NO COVER w/o C extensions
+    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
 
 Bucket = IIBucket
 Set = IISet

Modified: BTrees/trunk/BTrees/IOBTree.py
===================================================================
--- BTrees/trunk/BTrees/IOBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/IOBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -83,15 +83,8 @@
 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
+    from ._IOBTree import IOBucket
+except ImportError: #pragma NO COVER w/ C extensions
     IOBucket = IOBucketPy
     IOSet = IOSetPy
     IOBTree = IOBTreePy
@@ -100,6 +93,14 @@
     union = unionPy
     intersection = intersectionPy
     multiunion = multiunionPy
+else: #pragma NO COVER w/o C extensions
+    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
 
 Bucket = IOBucket
 Set = IOSet

Modified: BTrees/trunk/BTrees/LFBTree.py
===================================================================
--- BTrees/trunk/BTrees/LFBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/LFBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -100,17 +100,8 @@
 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
+    from ._LFBTree import LFBucket
+except ImportError: #pragma NO COVER w/ C extensions
     LFBucket = LFBucketPy
     LFSet = LFSetPy
     LFBTree = LFBTreePy
@@ -121,6 +112,16 @@
     multiunion = multiunionPy
     weightedUnion = weightedUnionPy
     weightedIntersection = weightedIntersectionPy
+else: #pragma NO COVER w/o C extensions
+    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 ._LFBTree import weightedUnion
+    from ._LFBTree import weightedIntersection
 
 Bucket = LFBucket
 Set = LFSet

Modified: BTrees/trunk/BTrees/LLBTree.py
===================================================================
--- BTrees/trunk/BTrees/LLBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/LLBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -100,17 +100,8 @@
 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
+    from ._LLBTree import LLBucket
+except ImportError: #pragma NO COVER w/ C extensions
     LLBucket = LLBucketPy
     LLSet = LLSetPy
     LLBTree = LLBTreePy
@@ -121,6 +112,16 @@
     multiunion = multiunionPy
     weightedUnion = weightedUnionPy
     weightedIntersection = weightedIntersectionPy
+else: #pragma NO COVER w/o C extensions
+    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
 
 Bucket = LLBucket
 Set = LLSet

Modified: BTrees/trunk/BTrees/LOBTree.py
===================================================================
--- BTrees/trunk/BTrees/LOBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/LOBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -83,15 +83,8 @@
 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
+    from ._LOBTree import LOBucket
+except ImportError: #pragma NO COVER w/ C extensions
     LOBucket = LOBucketPy
     LOSet = LOSetPy
     LOBTree = LOBTreePy
@@ -100,6 +93,14 @@
     union = unionPy
     intersection = intersectionPy
     multiunion = multiunionPy
+else: #pragma NO COVER w/o C extensions
+    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
 
 Bucket = LOBucket
 Set = LOSet

Modified: BTrees/trunk/BTrees/OIBTree.py
===================================================================
--- BTrees/trunk/BTrees/OIBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/OIBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -97,16 +97,8 @@
 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
+    from ._OIBTree import OIBucket
+except ImportError: #pragma NO COVER w/ C extensions
     OIBucket = OIBucketPy
     OISet = OISetPy
     OIBTree = OIBTreePy
@@ -116,6 +108,15 @@
     intersection = intersectionPy
     weightedUnion = weightedUnionPy
     weightedIntersection = weightedIntersectionPy
+else: #pragma NO COVER w/o C extensions
+    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
 
 
 Bucket = OIBucket

Modified: BTrees/trunk/BTrees/OLBTree.py
===================================================================
--- BTrees/trunk/BTrees/OLBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/OLBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -98,16 +98,8 @@
 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
+    from ._OLBTree import OLBucket
+except ImportError: #pragma NO COVER w/ C extensions
     OLBucket = OLBucketPy
     OLSet = OLSetPy
     OLBTree = OLBTreePy
@@ -117,6 +109,15 @@
     intersection = intersectionPy
     weightedUnion = weightedUnionPy
     weightedIntersection = weightedIntersectionPy
+else: #pragma NO COVER w/o C extensions
+    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
 
 Bucket = OLBucket
 Set = OLSet

Modified: BTrees/trunk/BTrees/OOBTree.py
===================================================================
--- BTrees/trunk/BTrees/OOBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/OOBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -78,14 +78,8 @@
 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
+    from ._OOBTree import OOBucket
+except ImportError as e: #pragma NO COVER w/ C extensions
     OOBucket = OOBucketPy
     OOSet = OOSetPy
     OOBTree = OOBTreePy
@@ -93,6 +87,13 @@
     difference = differencePy
     union = unionPy
     intersection = intersectionPy
+else: #pragma NO COVER w/o C extensions
+    from ._OOBTree import OOSet
+    from ._OOBTree import OOBTree
+    from ._OOBTree import OOTreeSet
+    from ._OOBTree import difference
+    from ._OOBTree import union
+    from ._OOBTree import intersection
 
 Bucket = OOBucket
 Set = OOSet

Modified: BTrees/trunk/BTrees/SetTemplate.c
===================================================================
--- BTrees/trunk/BTrees/SetTemplate.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/SetTemplate.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -11,18 +11,21 @@
   FOR A PARTICULAR PURPOSE
 
  ****************************************************************************/
+#include "_compat.h"
 
 #define SETTEMPLATE_C "$Id$\n"
 
 static PyObject *
 Set_insert(Bucket *self, PyObject *args)
 {
-  PyObject *key;
-  int i;
+    PyObject *key;
+    int i;
 
-  UNLESS (PyArg_ParseTuple(args, "O", &key)) return NULL;
-  if ( (i=_bucket_set(self, key, Py_None, 1, 1, 0)) < 0) return NULL;
-  return PyInt_FromLong(i);
+    UNLESS (PyArg_ParseTuple(args, "O", &key))
+        return NULL;
+    if ( (i=_bucket_set(self, key, Py_None, 1, 1, 0)) < 0)
+        return NULL;
+    return INT_FROM_LONG(i);
 }
 
 /* _Set_update and _TreeSet_update are identical except for the
@@ -37,28 +40,28 @@
  
     iter = PyObject_GetIter(seq);
     if (iter == NULL)
-	return -1;
+        return -1;
 
     while (1) {
-	v = PyIter_Next(iter);
-	if (v == NULL) {
-	    if (PyErr_Occurred())
-		goto err;
-	    else
-		break;
-	}
-	ind = _bucket_set(self, v, Py_None, 1, 1, 0);
-	Py_DECREF(v);
-	if (ind < 0)
-	    goto err;
-	else
-	    n += ind;
+        v = PyIter_Next(iter);
+        if (v == NULL) {
+            if (PyErr_Occurred())
+                goto err;
+            else
+                break;
+        }
+        ind = _bucket_set(self, v, Py_None, 1, 1, 0);
+        Py_DECREF(v);
+        if (ind < 0)
+            goto err;
+        else
+            n += ind;
     }
 
- err:
+err:
     Py_DECREF(iter);
     if (ind < 0)
-      return -1;
+        return -1;
     return n;
 }
 
@@ -69,147 +72,156 @@
     int n = 0;
 
     if (!PyArg_ParseTuple(args, "|O:update", &seq))
-	return NULL;
+        return NULL;
 
     if (seq) {
-	n = _Set_update(self, seq);
-	if (n < 0)
-	    return NULL;
+        n = _Set_update(self, seq);
+        if (n < 0)
+            return NULL;
     }
 
-    return PyInt_FromLong(n);
+    return INT_FROM_LONG(n);
 }
 
 static PyObject *
 Set_remove(Bucket *self, PyObject *args)
 {
-  PyObject *key;
+    PyObject *key;
 
-  UNLESS (PyArg_ParseTuple(args, "O", &key)) return NULL;
-  if (_bucket_set(self, key, NULL, 0, 1, 0) < 0) return NULL;
+    UNLESS (PyArg_ParseTuple(args, "O", &key))
+        return NULL;
+    if (_bucket_set(self, key, NULL, 0, 1, 0) < 0)
+        return NULL;
 
-  Py_INCREF(Py_None);
-  return Py_None;
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 
 static int
 _set_setstate(Bucket *self, PyObject *args)
 {
-  PyObject *k, *items;
-  Bucket *next=0;
-  int i, l, copied=1;
-  KEY_TYPE *keys;
+    PyObject *k, *items;
+    Bucket *next=0;
+    int i, l, copied=1;
+    KEY_TYPE *keys;
 
-  UNLESS (PyArg_ParseTuple(args, "O|O", &items, &next))
-    return -1;
+    UNLESS (PyArg_ParseTuple(args, "O|O", &items, &next))
+        return -1;
 
-  if (!PyTuple_Check(items)) {
-    PyErr_SetString(PyExc_TypeError,
-                    "tuple required for first state element");
-    return -1;
-  }
+    if (!PyTuple_Check(items)) {
+        PyErr_SetString(PyExc_TypeError,
+                        "tuple required for first state element");
+        return -1;
+    }
 
-  if ((l=PyTuple_Size(items)) < 0) return -1;
+    if ((l=PyTuple_Size(items)) < 0)
+        return -1;
 
-  for (i=self->len; --i >= 0; )
+    for (i=self->len; --i >= 0; )
     {
-      DECREF_KEY(self->keys[i]);
+        DECREF_KEY(self->keys[i]);
     }
-  self->len=0;
+    self->len=0;
 
-  if (self->next)
+    if (self->next)
     {
-      Py_DECREF(self->next);
-      self->next=0;
+        Py_DECREF(self->next);
+        self->next=0;
     }
 
-  if (l > self->size)
+    if (l > self->size)
     {
-      UNLESS (keys=BTree_Realloc(self->keys, sizeof(KEY_TYPE)*l)) return -1;
-      self->keys=keys;
-      self->size=l;
+        UNLESS (keys=BTree_Realloc(self->keys, sizeof(KEY_TYPE)*l))
+            return -1;
+        self->keys=keys;
+        self->size=l;
     }
 
-  for (i=0; i<l; i++)
+    for (i=0; i<l; i++)
     {
-      k=PyTuple_GET_ITEM(items, i);
-      COPY_KEY_FROM_ARG(self->keys[i], k, copied);
-      UNLESS (copied) return -1;
-      INCREF_KEY(self->keys[i]);
+        k=PyTuple_GET_ITEM(items, i);
+        COPY_KEY_FROM_ARG(self->keys[i], k, copied);
+        UNLESS (copied)
+            return -1;
+        INCREF_KEY(self->keys[i]);
     }
 
-  self->len=l;
+    self->len=l;
 
-  if (next)
+    if (next)
     {
-      self->next=next;
-      Py_INCREF(next);
+        self->next=next;
+        Py_INCREF(next);
     }
 
-  return 0;
+    return 0;
 }
 
 static PyObject *
 set_setstate(Bucket *self, PyObject *args)
 {
-  int r;
+    int r;
 
-  UNLESS (PyArg_ParseTuple(args, "O", &args)) return NULL;
+    UNLESS (PyArg_ParseTuple(args, "O", &args))
+        return NULL;
 
-  PER_PREVENT_DEACTIVATION(self);
-  r=_set_setstate(self, args);
-  PER_UNUSE(self);
+    PER_PREVENT_DEACTIVATION(self);
+    r=_set_setstate(self, args);
+    PER_UNUSE(self);
 
-  if (r < 0) return NULL;
-  Py_INCREF(Py_None);
-  return Py_None;
+    if (r < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 
 static struct PyMethodDef Set_methods[] = {
-  {"__getstate__", (PyCFunction) bucket_getstate,	METH_VARARGS,
-   "__getstate__() -- Return the picklable state of the object"},
+    {"__getstate__", (PyCFunction) bucket_getstate, METH_VARARGS,
+     "__getstate__() -- Return the picklable state of the object"},
 
-  {"__setstate__", (PyCFunction) set_setstate,	METH_VARARGS,
-   "__setstate__() -- Set the state of the object"},
+    {"__setstate__", (PyCFunction) set_setstate, METH_VARARGS,
+     "__setstate__() -- Set the state of the object"},
 
-  {"keys",	(PyCFunction) bucket_keys,	METH_KEYWORDS,
+    {"keys", (PyCFunction) bucket_keys, METH_VARARGS | METH_KEYWORDS,
      "keys() -- Return the keys"},
 
-  {"has_key",	(PyCFunction) bucket_has_key,	METH_O,
+    {"has_key", (PyCFunction) bucket_has_key, METH_O,
      "has_key(key) -- Test whether the bucket contains the given key"},
 
-  {"clear",	(PyCFunction) bucket_clear,	METH_VARARGS,
-   "clear() -- Remove all of the items from the bucket"},
+    {"clear", (PyCFunction) bucket_clear, METH_VARARGS,
+     "clear() -- Remove all of the items from the bucket"},
 
-  {"maxKey", (PyCFunction) Bucket_maxKey,	METH_VARARGS,
-   "maxKey([key]) -- Find the maximum key\n\n"
-   "If an argument is given, find the maximum <= the argument"},
+    {"maxKey", (PyCFunction) Bucket_maxKey, METH_VARARGS,
+     "maxKey([key]) -- Find the maximum key\n\n"
+     "If an argument is given, find the maximum <= the argument"},
 
-  {"minKey", (PyCFunction) Bucket_minKey,	METH_VARARGS,
-   "minKey([key]) -- Find the minimum key\n\n"
-   "If an argument is given, find the minimum >= the argument"},
+    {"minKey", (PyCFunction) Bucket_minKey, METH_VARARGS,
+     "minKey([key]) -- Find the minimum key\n\n"
+     "If an argument is given, find the minimum >= the argument"},
 
 #ifdef PERSISTENT
-  {"_p_resolveConflict", (PyCFunction) bucket__p_resolveConflict, METH_VARARGS,
-   "_p_resolveConflict() -- Reinitialize from a newly created copy"},
+    {"_p_resolveConflict",
+     (PyCFunction) bucket__p_resolveConflict, METH_VARARGS,
+     "_p_resolveConflict() -- Reinitialize from a newly created copy"},
 
-  {"_p_deactivate", (PyCFunction) bucket__p_deactivate, METH_KEYWORDS,
-   "_p_deactivate() -- Reinitialize from a newly created copy"},
+    {"_p_deactivate",
+     (PyCFunction) bucket__p_deactivate, METH_VARARGS | METH_KEYWORDS,
+     "_p_deactivate() -- Reinitialize from a newly created copy"},
 #endif
 
-  {"add",	(PyCFunction)Set_insert,	METH_VARARGS,
-   "add(id) -- Add a key to the set"},
+    {"add", (PyCFunction)Set_insert, METH_VARARGS,
+     "add(id) -- Add a key to the set"},
 
-  {"insert",	(PyCFunction)Set_insert,	METH_VARARGS,
-   "insert(id) -- Add a key to the set"},
+    {"insert", (PyCFunction)Set_insert, METH_VARARGS,
+     "insert(id) -- Add a key to the set"},
 
-  {"update",	(PyCFunction)Set_update,	METH_VARARGS,
-   "update(seq) -- Add the items from the given sequence to the set"},
+    {"update", (PyCFunction)Set_update,    METH_VARARGS,
+     "update(seq) -- Add the items from the given sequence to the set"},
 
-  {"remove",	(PyCFunction)Set_remove,	METH_VARARGS,
-   "remove(id) -- Remove an id from the set"},
+    {"remove",    (PyCFunction)Set_remove,    METH_VARARGS,
+     "remove(id) -- Remove an id from the set"},
 
-  {NULL,		NULL}		/* sentinel */
+    {NULL, NULL}        /* sentinel */
 };
 
 static int
@@ -218,12 +230,12 @@
     PyObject *v = NULL;
 
     if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "Set", &v))
-	return -1;
+        return -1;
 
     if (v)
-	return _Set_update((Bucket *)self, v);
+        return _Set_update((Bucket *)self, v);
     else
-	return 0;
+        return 0;
 }
 
 
@@ -231,128 +243,131 @@
 static PyObject *
 set_repr(Bucket *self)
 {
-  static PyObject *format;
-  PyObject *r, *t;
+    static PyObject *format;
+    PyObject *r, *t;
 
-  if (!format)
-      format = PyString_FromString(MOD_NAME_PREFIX "Set(%s)");
-  UNLESS (t = PyTuple_New(1)) return NULL;
-  UNLESS (r = bucket_keys(self, NULL, NULL)) goto err;
-  PyTuple_SET_ITEM(t, 0, r);
-  r = t;
-  ASSIGN(r, PyString_Format(format, r));
-  return r;
+    if (!format)
+        format = TEXT_FROM_STRING(MOD_NAME_PREFIX "Set(%s)");
+    UNLESS (t = PyTuple_New(1))
+        return NULL;
+    UNLESS (r = bucket_keys(self, NULL, NULL))
+        goto err;
+    PyTuple_SET_ITEM(t, 0, r);
+    r = t;
+    ASSIGN(r, TEXT_FORMAT(format, r));
+    return r;
 err:
-  Py_DECREF(t);
-  return NULL;
+    Py_DECREF(t);
+    return NULL;
 }
 
 static Py_ssize_t
 set_length(Bucket *self)
 {
-  int r;
+    int r;
 
-  PER_USE_OR_RETURN(self, -1);
-  r = self->len;
-  PER_UNUSE(self);
+    PER_USE_OR_RETURN(self, -1);
+    r = self->len;
+    PER_UNUSE(self);
 
-  return r;
+    return r;
 }
 
 static PyObject *
 set_item(Bucket *self, Py_ssize_t index)
 {
-  PyObject *r=0;
+    PyObject *r=0;
 
-  PER_USE_OR_RETURN(self, NULL);
-  if (index >= 0 && index < self->len)
+    PER_USE_OR_RETURN(self, NULL);
+    if (index >= 0 && index < self->len)
     {
-      COPY_KEY_TO_OBJECT(r, self->keys[index]);
+        COPY_KEY_TO_OBJECT(r, self->keys[index]);
     }
-  else
-    IndexError(index);
+    else
+        IndexError(index);
 
-  PER_UNUSE(self);
+    PER_UNUSE(self);
 
-  return r;
+    return r;
 }
 
 static PySequenceMethods set_as_sequence = {
-  (lenfunc)set_length,            /* sq_length */
-  (binaryfunc)0,                  /* sq_concat */
-  (ssizeargfunc)0,                /* sq_repeat */
-  (ssizeargfunc)set_item,         /* sq_item */
-  (ssizessizeargfunc)0,           /* sq_slice */
-  (ssizeobjargproc)0,             /* sq_ass_item */
-  (ssizessizeobjargproc)0,        /* sq_ass_slice */
-  (objobjproc)bucket_contains,    /* sq_contains */
-  0,                              /* sq_inplace_concat */
-  0,                              /* sq_inplace_repeat */
+    (lenfunc)set_length,                /* sq_length */
+    (binaryfunc)0,                      /* sq_concat */
+    (ssizeargfunc)0,                    /* sq_repeat */
+    (ssizeargfunc)set_item,             /* sq_item */
+    (ssizessizeargfunc)0,               /* sq_slice */
+    (ssizeobjargproc)0,                 /* sq_ass_item */
+    (ssizessizeobjargproc)0,            /* sq_ass_slice */
+    (objobjproc)bucket_contains,        /* sq_contains */
+    0,                                  /* sq_inplace_concat */
+    0,                                  /* sq_inplace_repeat */
 };
 
 static PyTypeObject SetType = {
-    PyObject_HEAD_INIT(NULL) /* PyPersist_Type */
-    0,					/* ob_size */
-    MODULE_NAME MOD_NAME_PREFIX "Set",	/* tp_name */
-    sizeof(Bucket),			/* tp_basicsize */
-    0,					/* tp_itemsize */
-    (destructor)bucket_dealloc,		/* tp_dealloc */
-    0,					/* tp_print */
-    0,					/* tp_getattr */
-    0,					/* tp_setattr */
-    0,					/* tp_compare */
-    (reprfunc)set_repr,			/* tp_repr */
-    0,					/* tp_as_number */
-    &set_as_sequence,			/* tp_as_sequence */
-    0,					/* tp_as_mapping */
-    0,					/* tp_hash */
-    0,					/* tp_call */
-    0,					/* tp_str */
-    0,					/* tp_getattro */
-    0,					/* tp_setattro */
-    0,					/* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
-	    Py_TPFLAGS_BASETYPE, 	/* tp_flags */
-    0,					/* tp_doc */
-    (traverseproc)bucket_traverse,	/* tp_traverse */
-    (inquiry)bucket_tp_clear,		/* tp_clear */
-    0,					/* tp_richcompare */
-    0,					/* tp_weaklistoffset */
-    (getiterfunc)Bucket_getiter,	/* tp_iter */
-    0,					/* tp_iternext */
-    Set_methods,			/* tp_methods */
-    Bucket_members,			/* tp_members */
-    0,					/* tp_getset */
-    0,					/* tp_base */
-    0,					/* tp_dict */
-    0,					/* tp_descr_get */
-    0,					/* tp_descr_set */
-    0,					/* tp_dictoffset */
-    Set_init,				/* tp_init */
-    0,					/* tp_alloc */
-    0, /*PyType_GenericNew,*/		/* tp_new */
+    PyVarObject_HEAD_INIT(NULL, 0)      /* PyPersist_Type */
+    MODULE_NAME MOD_NAME_PREFIX "Set",  /* tp_name */
+    sizeof(Bucket),                     /* tp_basicsize */
+    0,                                  /* tp_itemsize */
+    (destructor)bucket_dealloc,         /* tp_dealloc */
+    0,                                  /* tp_print */
+    0,                                  /* tp_getattr */
+    0,                                  /* tp_setattr */
+    0,                                  /* tp_compare */
+    (reprfunc)set_repr,                 /* tp_repr */
+    0,                                  /* tp_as_number */
+    &set_as_sequence,                   /* tp_as_sequence */
+    0,                                  /* tp_as_mapping */
+    0,                                  /* tp_hash */
+    0,                                  /* tp_call */
+    0,                                  /* tp_str */
+    0,                                  /* tp_getattro */
+    0,                                  /* tp_setattro */
+    0,                                  /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+    Py_TPFLAGS_HAVE_GC |
+    Py_TPFLAGS_BASETYPE,                /* tp_flags */
+    0,                                  /* tp_doc */
+    (traverseproc)bucket_traverse,      /* tp_traverse */
+    (inquiry)bucket_tp_clear,           /* tp_clear */
+    0,                                  /* tp_richcompare */
+    0,                                  /* tp_weaklistoffset */
+    (getiterfunc)Bucket_getiter,        /* tp_iter */
+    0,                                  /* tp_iternext */
+    Set_methods,                        /* tp_methods */
+    Bucket_members,                     /* tp_members */
+    0,                                  /* tp_getset */
+    0,                                  /* tp_base */
+    0,                                  /* tp_dict */
+    0,                                  /* tp_descr_get */
+    0,                                  /* tp_descr_set */
+    0,                                  /* tp_dictoffset */
+    Set_init,                           /* tp_init */
+    0,                                  /* tp_alloc */
+    0, /*PyType_GenericNew,*/           /* tp_new */
 };
 
 static int
 nextSet(SetIteration *i)
 {
 
-  if (i->position >= 0)
+    if (i->position >= 0)
     {
-      UNLESS(PER_USE(BUCKET(i->set))) return -1;
+        UNLESS(PER_USE(BUCKET(i->set)))
+            return -1;
 
-      if (i->position)
+        if (i->position)
         {
           DECREF_KEY(i->key);
         }
 
-      if (i->position < BUCKET(i->set)->len)
+        if (i->position < BUCKET(i->set)->len)
         {
           COPY_KEY(i->key, BUCKET(i->set)->keys[i->position]);
           INCREF_KEY(i->key);
           i->position ++;
         }
-      else
+        else
         {
           i->position = -1;
           PER_ACCESSED(BUCKET(i->set));

Modified: BTrees/trunk/BTrees/TreeSetTemplate.c
===================================================================
--- BTrees/trunk/BTrees/TreeSetTemplate.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/TreeSetTemplate.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -11,6 +11,7 @@
   FOR A PARTICULAR PURPOSE
 
  ****************************************************************************/
+#include "_compat.h"
 
 #define TREESETTEMPLATE_C "$Id$\n"
 
@@ -21,11 +22,11 @@
     int i;
 
     if (!PyArg_ParseTuple(args, "O:insert", &key)) 
-	return NULL;
+        return NULL;
     i = _BTree_set(self, key, Py_None, 1, 1);
     if (i < 0) 
-	return NULL;
-    return PyInt_FromLong(i);
+        return NULL;
+    return INT_FROM_LONG(i);
 }
 
 /* _Set_update and _TreeSet_update are identical except for the
@@ -40,28 +41,30 @@
 
     iter = PyObject_GetIter(seq);
     if (iter == NULL)
-	return -1;
+        return -1;
 
-    while (1) {
-	v = PyIter_Next(iter);
-	if (v == NULL) {
-	    if (PyErr_Occurred())
-		goto err;
-	    else
-		break;
-	}
-	ind = _BTree_set(self, v, Py_None, 1, 1);
-	Py_DECREF(v);
-	if (ind < 0)
-	    goto err;
-	else
-	    n += ind;
+    while (1)
+    {
+        v = PyIter_Next(iter);
+        if (v == NULL)
+        {
+            if (PyErr_Occurred())
+                goto err;
+            else
+                break;
+        }
+        ind = _BTree_set(self, v, Py_None, 1, 1);
+        Py_DECREF(v);
+        if (ind < 0)
+            goto err;
+        else
+            n += ind;
     }
 
- err:
+err:
     Py_DECREF(iter);
     if (ind < 0)
-      return -1;
+        return -1;
     return n;
 }
 
@@ -72,116 +75,124 @@
     int n = 0;
 
     if (!PyArg_ParseTuple(args, "|O:update", &seq))
-	return NULL;
+        return NULL;
 
-    if (seq) {
-	n = _TreeSet_update(self, seq);
-	if (n < 0)
-	    return NULL;
+    if (seq)
+    {
+        n = _TreeSet_update(self, seq);
+        if (n < 0)
+            return NULL;
     }
 
-    return PyInt_FromLong(n);
+    return INT_FROM_LONG(n);
 }
 
 
 static PyObject *
 TreeSet_remove(BTree *self, PyObject *args)
 {
-  PyObject *key;
+    PyObject *key;
 
-  UNLESS (PyArg_ParseTuple(args, "O", &key)) return NULL;
-  if (_BTree_set(self, key, NULL, 0, 1) < 0) return NULL;
-  Py_INCREF(Py_None);
-  return Py_None;
+    UNLESS (PyArg_ParseTuple(args, "O", &key))
+        return NULL;
+    if (_BTree_set(self, key, NULL, 0, 1) < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 
 static PyObject *
 TreeSet_setstate(BTree *self, PyObject *args)
 {
-  int r;
+    int r;
 
-  if (!PyArg_ParseTuple(args,"O",&args)) return NULL;
+    if (!PyArg_ParseTuple(args,"O",&args))
+        return NULL;
 
-  PER_PREVENT_DEACTIVATION(self);
-  r=_BTree_setstate(self, args, 1);
-  PER_UNUSE(self);
+    PER_PREVENT_DEACTIVATION(self);
+    r=_BTree_setstate(self, args, 1);
+    PER_UNUSE(self);
 
-  if (r < 0) return NULL;
-  Py_INCREF(Py_None);
-  return Py_None;
+    if (r < 0)
+        return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
 }
 
-static struct PyMethodDef TreeSet_methods[] = {
-  {"__getstate__", (PyCFunction) BTree_getstate,	METH_NOARGS,
-   "__getstate__() -> state\n\n"
-   "Return the picklable state of the TreeSet."},
+static struct PyMethodDef TreeSet_methods[] =
+{
+    {"__getstate__", (PyCFunction) BTree_getstate, METH_NOARGS,
+     "__getstate__() -> state\n\n"
+     "Return the picklable state of the TreeSet."},
 
-  {"__setstate__", (PyCFunction) TreeSet_setstate,	METH_VARARGS,
-   "__setstate__(state)\n\n"
-   "Set the state of the TreeSet."},
+    {"__setstate__", (PyCFunction) TreeSet_setstate, METH_VARARGS,
+     "__setstate__(state)\n\n"
+     "Set the state of the TreeSet."},
 
-  {"has_key",	(PyCFunction) BTree_has_key,	METH_O,
-   "has_key(key)\n\n"
-   "Return true if the TreeSet contains the given key."},
+    {"has_key", (PyCFunction) BTree_has_key, METH_O,
+     "has_key(key)\n\n"
+     "Return true if the TreeSet contains the given key."},
 
-  {"keys",	(PyCFunction) BTree_keys,	METH_KEYWORDS,
-   "keys([min, max]) -> list of keys\n\n"
-   "Returns the keys of the TreeSet.  If min and max are supplied, only\n"
-   "keys greater than min and less than max are returned."},
+    {"keys", (PyCFunction) BTree_keys, METH_VARARGS | METH_KEYWORDS,
+     "keys([min, max]) -> list of keys\n\n"
+     "Returns the keys of the TreeSet.  If min and max are supplied, only\n"
+     "keys greater than min and less than max are returned."},
 
-  {"maxKey", (PyCFunction) BTree_maxKey,	METH_VARARGS,
-   "maxKey([max]) -> key\n\n"
-   "Return the largest key in the BTree.  If max is specified, return\n"
-   "the largest key <= max."},
+    {"maxKey", (PyCFunction) BTree_maxKey, METH_VARARGS,
+     "maxKey([max]) -> key\n\n"
+     "Return the largest key in the BTree.  If max is specified, return\n"
+     "the largest key <= max."},
 
-  {"minKey", (PyCFunction) BTree_minKey,	METH_VARARGS,
-   "minKey([mi]) -> key\n\n"
-   "Return the smallest key in the BTree.  If min is specified, return\n"
-   "the smallest key >= min."},
+    {"minKey", (PyCFunction) BTree_minKey, METH_VARARGS,
+     "minKey([mi]) -> key\n\n"
+     "Return the smallest key in the BTree.  If min is specified, return\n"
+     "the smallest key >= min."},
 
-  {"clear",	(PyCFunction) BTree_clear,	METH_NOARGS,
-   "clear()\n\nRemove all of the items from the BTree."},
+    {"clear", (PyCFunction) BTree_clear, METH_NOARGS,
+     "clear()\n\nRemove all of the items from the BTree."},
 
-  {"add",	(PyCFunction)TreeSet_insert,	METH_VARARGS,
-   "add(id) -- Add an item to the set"},
+    {"add", (PyCFunction)TreeSet_insert, METH_VARARGS,
+     "add(id) -- Add an item to the set"},
 
-  {"insert",	(PyCFunction)TreeSet_insert,	METH_VARARGS,
-   "insert(id) -- Add an item to the set"},
+    {"insert", (PyCFunction)TreeSet_insert, METH_VARARGS,
+     "insert(id) -- Add an item to the set"},
 
-  {"update",	(PyCFunction)TreeSet_update,	METH_VARARGS,
-   "update(collection)\n\n Add the items from the given collection."},
+    {"update", (PyCFunction)TreeSet_update, METH_VARARGS,
+     "update(collection)\n\n Add the items from the given collection."},
 
-  {"remove",	(PyCFunction)TreeSet_remove,	METH_VARARGS,
-   "remove(id) -- Remove a key from the set"},
+    {"remove", (PyCFunction)TreeSet_remove, METH_VARARGS,
+     "remove(id) -- Remove a key from the set"},
 
-  {"_check", (PyCFunction) BTree_check,       METH_NOARGS,
-   "Perform sanity check on TreeSet, and raise exception if flawed."},
+    {"_check", (PyCFunction) BTree_check, METH_NOARGS,
+     "Perform sanity check on TreeSet, and raise exception if flawed."},
 
 #ifdef PERSISTENT
-  {"_p_resolveConflict", (PyCFunction) BTree__p_resolveConflict, METH_VARARGS,
-   "_p_resolveConflict() -- Reinitialize from a newly created copy"},
+    {"_p_resolveConflict",
+     (PyCFunction) BTree__p_resolveConflict, METH_VARARGS,
+     "_p_resolveConflict() -- Reinitialize from a newly created copy"},
 
-  {"_p_deactivate", (PyCFunction) BTree__p_deactivate,	METH_KEYWORDS,
-   "_p_deactivate()\n\nReinitialize from a newly created copy."},
+    {"_p_deactivate",
+     (PyCFunction) BTree__p_deactivate, METH_VARARGS | METH_KEYWORDS,
+     "_p_deactivate()\n\nReinitialize from a newly created copy."},
 #endif
-  {NULL,		NULL}		/* sentinel */
+    {NULL,        NULL}        /* sentinel */
 };
 
 static PyMappingMethods TreeSet_as_mapping = {
-  (lenfunc)BTree_length,	/*mp_length*/
+  (lenfunc)BTree_length,                        /*mp_length*/
 };
 
 static PySequenceMethods TreeSet_as_sequence = {
-    (lenfunc)0,                     /* sq_length */
-    (binaryfunc)0,                  /* sq_concat */
-    (ssizeargfunc)0,                /* sq_repeat */
-    (ssizeargfunc)0,                /* sq_item */
-    (ssizessizeargfunc)0,           /* sq_slice */
-    (ssizeobjargproc)0,             /* sq_ass_item */
-    (ssizessizeobjargproc)0,        /* sq_ass_slice */
-    (objobjproc)BTree_contains,     /* sq_contains */
-    0,                              /* sq_inplace_concat */
-    0,                              /* sq_inplace_repeat */
+    (lenfunc)0,                                 /* sq_length */
+    (binaryfunc)0,                              /* sq_concat */
+    (ssizeargfunc)0,                            /* sq_repeat */
+    (ssizeargfunc)0,                            /* sq_item */
+    (ssizessizeargfunc)0,                       /* sq_slice */
+    (ssizeobjargproc)0,                         /* sq_ass_item */
+    (ssizessizeobjargproc)0,                    /* sq_ass_slice */
+    (objobjproc)BTree_contains,                 /* sq_contains */
+    0,                                          /* sq_inplace_concat */
+    0,                                          /* sq_inplace_repeat */
 };
 
 static int
@@ -190,53 +201,54 @@
     PyObject *v = NULL;
 
     if (!PyArg_ParseTuple(args, "|O:" MOD_NAME_PREFIX "TreeSet", &v))
-	return -1;
+        return -1;
 
     if (v)
-	return _TreeSet_update((BTree *)self, v);
+        return _TreeSet_update((BTree *)self, v);
     else
-	return 0;
+        return 0;
 }
 
-static PyTypeObject TreeSetType = {
-    PyObject_HEAD_INIT(NULL) /* PyPersist_Type */
-    0,					/* ob_size */
-    MODULE_NAME MOD_NAME_PREFIX "TreeSet",/* tp_name */
-    sizeof(BTree),			/* tp_basicsize */
-    0,					/* tp_itemsize */
-    (destructor)BTree_dealloc,		/* tp_dealloc */
-    0,					/* tp_print */
-    0,					/* tp_getattr */
-    0,					/* tp_setattr */
-    0,					/* tp_compare */
-    0,					/* tp_repr */
-    &BTree_as_number_for_nonzero,	/* tp_as_number */
-    &TreeSet_as_sequence,		/* tp_as_sequence */
-    &TreeSet_as_mapping,		/* tp_as_mapping */
-    0,					/* tp_hash */
-    0,					/* tp_call */
-    0,					/* tp_str */
-    0,					/* tp_getattro */
-    0,					/* tp_setattro */
-    0,					/* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
-	    Py_TPFLAGS_BASETYPE, 	/* tp_flags */
-    0,					/* tp_doc */
-    (traverseproc)BTree_traverse,	/* tp_traverse */
-    (inquiry)BTree_tp_clear,		/* tp_clear */
-    0,					/* tp_richcompare */
-    0,					/* tp_weaklistoffset */
-    (getiterfunc)BTree_getiter,		/* tp_iter */
-    0,					/* tp_iternext */
-    TreeSet_methods,			/* tp_methods */
-    BTree_members,			/* tp_members */
-    0,					/* tp_getset */
-    0,					/* tp_base */
-    0,					/* tp_dict */
-    0,					/* tp_descr_get */
-    0,					/* tp_descr_set */
-    0,					/* tp_dictoffset */
-    TreeSet_init,			/* tp_init */
-    0,					/* tp_alloc */
-    0, /*PyType_GenericNew,*/		/* tp_new */
+static PyTypeObject TreeSetType =
+{
+    PyVarObject_HEAD_INIT(NULL, 0)
+    MODULE_NAME MOD_NAME_PREFIX "TreeSet",      /* tp_name */
+    sizeof(BTree),                              /* tp_basicsize */
+    0,                                          /* tp_itemsize */
+    (destructor)BTree_dealloc,                  /* tp_dealloc */
+    0,                                          /* tp_print */
+    0,                                          /* tp_getattr */
+    0,                                          /* tp_setattr */
+    0,                                          /* tp_compare */
+    0,                                          /* tp_repr */
+    &BTree_as_number_for_nonzero,               /* tp_as_number */
+    &TreeSet_as_sequence,                       /* tp_as_sequence */
+    &TreeSet_as_mapping,                        /* tp_as_mapping */
+    0,                                          /* tp_hash */
+    0,                                          /* tp_call */
+    0,                                          /* tp_str */
+    0,                                          /* tp_getattro */
+    0,                                          /* tp_setattro */
+    0,                                          /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT |
+    Py_TPFLAGS_HAVE_GC |
+    Py_TPFLAGS_BASETYPE,                        /* tp_flags */
+    0,                                          /* tp_doc */
+    (traverseproc)BTree_traverse,               /* tp_traverse */
+    (inquiry)BTree_tp_clear,                    /* tp_clear */
+    0,                                          /* tp_richcompare */
+    0,                                          /* tp_weaklistoffset */
+    (getiterfunc)BTree_getiter,                 /* tp_iter */
+    0,                                          /* tp_iternext */
+    TreeSet_methods,                            /* tp_methods */
+    BTree_members,                              /* tp_members */
+    0,                                          /* tp_getset */
+    0,                                          /* tp_base */
+    0,                                          /* tp_dict */
+    0,                                          /* tp_descr_get */
+    0,                                          /* tp_descr_set */
+    0,                                          /* tp_dictoffset */
+    TreeSet_init,                               /* tp_init */
+    0,                                          /* tp_alloc */
+    0, /*PyType_GenericNew,*/                   /* tp_new */
 };

Modified: BTrees/trunk/BTrees/_IFBTree.c
===================================================================
--- BTrees/trunk/BTrees/_IFBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_IFBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -25,10 +25,17 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "IF"
-#define INITMODULE init_IFBTree
+
 #define DEFAULT_MAX_BUCKET_SIZE 120
 #define DEFAULT_MAX_BTREE_SIZE 500
 
+#include "_compat.h"
 #include "intkeymacros.h"
 #include "floatvaluemacros.h"
+
+#ifdef PY3K
+#define INITMODULE PyInit__IFBTree
+#else
+#define INITMODULE init_IFBTree
+#endif
 #include "BTreeModuleTemplate.c"

Modified: BTrees/trunk/BTrees/_IIBTree.c
===================================================================
--- BTrees/trunk/BTrees/_IIBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_IIBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -25,10 +25,17 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "II"
-#define INITMODULE init_IIBTree
+
 #define DEFAULT_MAX_BUCKET_SIZE 120
 #define DEFAULT_MAX_BTREE_SIZE 500
 
+#include "_compat.h"
 #include "intkeymacros.h"
 #include "intvaluemacros.h"
+
+#ifdef PY3K
+#define INITMODULE PyInit__IIBTree
+#else
+#define INITMODULE init_IIBTree
+#endif
 #include "BTreeModuleTemplate.c"

Modified: BTrees/trunk/BTrees/_IOBTree.c
===================================================================
--- BTrees/trunk/BTrees/_IOBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_IOBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -23,10 +23,17 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "IO"
+
 #define DEFAULT_MAX_BUCKET_SIZE 60
 #define DEFAULT_MAX_BTREE_SIZE 500
-#define INITMODULE init_IOBTree
                                 
+#include "_compat.h"
 #include "intkeymacros.h"
 #include "objectvaluemacros.h"
+
+#ifdef PY3K
+#define INITMODULE PyInit__IOBTree
+#else
+#define INITMODULE init_IOBTree
+#endif
 #include "BTreeModuleTemplate.c"

Modified: BTrees/trunk/BTrees/_LFBTree.c
===================================================================
--- BTrees/trunk/BTrees/_LFBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_LFBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -25,12 +25,19 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "LF"
-#define INITMODULE init_LFBTree
+
 #define DEFAULT_MAX_BUCKET_SIZE 120
 #define DEFAULT_MAX_BTREE_SIZE 500
 
 #define ZODB_64BIT_INTS
 
+#include "_compat.h"
 #include "intkeymacros.h"
 #include "floatvaluemacros.h"
+
+#ifdef PY3K
+#define INITMODULE PyInit__LFBTree
+#else
+#define INITMODULE init_LFBTree
+#endif
 #include "BTreeModuleTemplate.c"

Modified: BTrees/trunk/BTrees/_LLBTree.c
===================================================================
--- BTrees/trunk/BTrees/_LLBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_LLBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -25,12 +25,19 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "LL"
-#define INITMODULE init_LLBTree
+
 #define DEFAULT_MAX_BUCKET_SIZE 120
 #define DEFAULT_MAX_BTREE_SIZE 500
 
 #define ZODB_64BIT_INTS
 
+#include "_compat.h"
 #include "intkeymacros.h"
 #include "intvaluemacros.h"
+
+#ifdef PY3K
+#define INITMODULE PyInit__LLBTree
+#else
+#define INITMODULE init_LLBTree
+#endif
 #include "BTreeModuleTemplate.c"

Modified: BTrees/trunk/BTrees/_LOBTree.c
===================================================================
--- BTrees/trunk/BTrees/_LOBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_LOBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -23,12 +23,19 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "LO"
+
 #define DEFAULT_MAX_BUCKET_SIZE 60
 #define DEFAULT_MAX_BTREE_SIZE 500
-#define INITMODULE init_LOBTree
 
 #define ZODB_64BIT_INTS
 
+#include "_compat.h"
 #include "intkeymacros.h"
 #include "objectvaluemacros.h"
+
+#ifdef PY3K
+#define INITMODULE PyInit__LOBTree
+#else
+#define INITMODULE init_LOBTree
+#endif
 #include "BTreeModuleTemplate.c"

Modified: BTrees/trunk/BTrees/_OIBTree.c
===================================================================
--- BTrees/trunk/BTrees/_OIBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_OIBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -23,10 +23,17 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "OI"
-#define INITMODULE init_OIBTree
+
 #define DEFAULT_MAX_BUCKET_SIZE 60
 #define DEFAULT_MAX_BTREE_SIZE 250
                                 
+#include "_compat.h"
 #include "objectkeymacros.h"
 #include "intvaluemacros.h"
+
+#ifdef PY3K
+#define INITMODULE PyInit__OIBTree
+#else
+#define INITMODULE init_OIBTree
+#endif
 #include "BTreeModuleTemplate.c"

Modified: BTrees/trunk/BTrees/_OLBTree.c
===================================================================
--- BTrees/trunk/BTrees/_OLBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_OLBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -23,12 +23,19 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "OL"
-#define INITMODULE init_OLBTree
+
 #define DEFAULT_MAX_BUCKET_SIZE 60
 #define DEFAULT_MAX_BTREE_SIZE 250
 
 #define ZODB_64BIT_INTS
 
+#include "_compat.h"
 #include "objectkeymacros.h"
 #include "intvaluemacros.h"
+
+#ifdef PY3K
+#define INITMODULE PyInit__OLBTree
+#else
+#define INITMODULE init_OLBTree
+#endif
 #include "BTreeModuleTemplate.c"

Modified: BTrees/trunk/BTrees/_OOBTree.c
===================================================================
--- BTrees/trunk/BTrees/_OOBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_OOBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -23,10 +23,17 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "OO"
-#define INITMODULE init_OOBTree
+
 #define DEFAULT_MAX_BUCKET_SIZE 30
 #define DEFAULT_MAX_BTREE_SIZE 250
                                 
+#include "_compat.h"
 #include "objectkeymacros.h"
 #include "objectvaluemacros.h"
+
+#ifdef PY3K
+#define INITMODULE PyInit__OOBTree
+#else
+#define INITMODULE init_OOBTree
+#endif
 #include "BTreeModuleTemplate.c"

Modified: BTrees/trunk/BTrees/_base.py
===================================================================
--- BTrees/trunk/BTrees/_base.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_base.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -21,6 +21,10 @@
 from persistent import Persistent
 
 from .Interfaces import BTreesConflictError
+from ._compat import PY3
+from ._compat import cmp
+from ._compat import int_types
+from ._compat import xrange
 
 
 _marker = object()
@@ -156,7 +160,7 @@
 
     __slots__ = ('to_iterate',
                  'useValues',
-                 '_next',
+                 '_iter',
                  'active',
                  'position',
                  'key',
@@ -172,15 +176,18 @@
             try:
                 itmeth = to_iterate.iteritems
             except AttributeError:
-                itmeth = to_iterate.__iter__
-                useValues = False
+                if PY3 and isinstance(to_iterate, dict): #pragma NO COVER Py3k
+                    itmeth = to_iterate.items().__iter__
+                else:
+                    itmeth = to_iterate.__iter__
+                    useValues = False
             else:
                 self.value = None
         else:
             itmeth = to_iterate.__iter__
 
         self.useValues = useValues
-        self._next = itmeth().next
+        self._iter = itmeth()
         self.active = True
         self.position = 0
         self.key = _marker
@@ -190,9 +197,9 @@
     def advance(self):
         try:
             if self.useValues:
-                self.key, self.value = self._next()
+                self.key, self.value = next(self._iter)
             else:
-                self.key = self._next()
+                self.key = next(self._iter)
             self.position += 1
         except StopIteration:
             self.active = False
@@ -200,6 +207,15 @@
 
         return self
 
+def _no_default_comparison(key):
+    # Enforce test that key has non-default comparison.
+    lt = getattr(key, '__lt__', None)
+    if lt is not None:
+        if getattr(lt, '__objclass__', None) is object: #pragma NO COVER Py3k
+            lt = None
+    if (lt is None and
+        getattr(key, '__cmp__', None) is None):
+        raise TypeError("Can't use default __cmp__")
 
 class Bucket(_BucketBase):
 
@@ -237,10 +253,7 @@
             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__")
+        _no_default_comparison(key)
         self._set(self._to_key(key), self._to_value(value))
 
     def __delitem__(self, key):
@@ -298,7 +311,7 @@
 
     def _split(self, index=-1):
         if index < 0 or index >= len(self._keys):
-            index = len(self._keys) / 2
+            index = len(self._keys) // 2
         new_instance = self.__class__()
         new_instance._keys = self._keys[index:]
         new_instance._values = self._values[index:]
@@ -553,7 +566,7 @@
 
     def _split(self, index=-1):
         if index < 0 or index >= len(self._keys):
-            index = len(self._keys) / 2
+            index = len(self._keys) // 2
         new_instance = self.__class__()
         new_instance._keys = self._keys[index:]
         del self._keys[index:]
@@ -727,10 +740,7 @@
             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__")
+        _no_default_comparison(key)
         self._set(self._to_key(key), self._to_value(value))
 
     def __delitem__(self, key):
@@ -742,6 +752,7 @@
 
     def __nonzero__(self):
         return bool(self._data)
+    __bool__ = __nonzero__ #Py3k rename
 
     def __len__(self):
         l = 0
@@ -760,7 +771,7 @@
         if data:
             lo = 0
             hi = len(data)
-            i = hi//2
+            i = hi // 2
             while i > lo:
                 cmp_ = cmp(data[i].key, key)
                 if cmp_ < 0:
@@ -769,7 +780,7 @@
                     hi = i
                 else:
                     break
-                i = (lo+hi)//2
+                i = (lo + hi) // 2
             return i
         return -1
 
@@ -882,7 +893,7 @@
     def _split(self, index=None):
         data = self._data
         if index is None:
-            index = len(data)//2
+            index = len(data) // 2
 
         next = self.__class__()
         next._data = data[index:]
@@ -1083,7 +1094,7 @@
 
         while i > self.index:
             try:
-                self.v = self.it.next()
+                self.v = next(self.it)
             except StopIteration:
                 raise IndexError(i)
             else:
@@ -1158,7 +1169,6 @@
 
     __slots__ = ()
 
-    #_next = None
     def add(self, key):
         return self._set(self._to_key(key))[0]
 
@@ -1270,6 +1280,14 @@
             i2.advance()
     return result
 
+def _prepMergeIterators(o1, o2):
+    MERGE_DEFAULT = getattr(o1, 'MERGE_DEFAULT', None)
+    if MERGE_DEFAULT is None:
+        raise TypeError("invalid set operation")
+    i1 = _SetIteration(o1, True, MERGE_DEFAULT)
+    i2 = _SetIteration(o2, True, MERGE_DEFAULT)
+    return i1, i2
+
 def weightedUnion(set_type, o1, o2, w1=1, w2=1):
     if o1 is None:
         if o2 is None:
@@ -1277,9 +1295,7 @@
         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)
+    i1, i2 = _prepMergeIterators(o1, o2)
     MERGE = getattr(o1, 'MERGE', None)
     if MERGE is None and i1.useValues and i2.useValues:
         raise TypeError("invalid set operation")
@@ -1287,12 +1303,6 @@
     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()
@@ -1333,22 +1343,13 @@
         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)
+    i1, i2 = _prepMergeIterators(o1, o2)
     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()
@@ -1384,7 +1385,6 @@
 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.
@@ -1420,10 +1420,10 @@
 
     return int(v)
 
-def to_str(l):
+def to_bytes(l):
     def to(self, v):
-        if not (isinstance(v, str) and len(v) == l):
-            raise TypeError("%s-character string expected" % l)
+        if not (isinstance(v, bytes) and len(v) == l):
+            raise TypeError("%s-byte array expected" % l)
         return v
     return to
 

Copied: BTrees/trunk/BTrees/_compat.h (from rev 128563, BTrees/trunk/BTrees/py24compat.h)
===================================================================
--- BTrees/trunk/BTrees/_compat.h	                        (rev 0)
+++ BTrees/trunk/BTrees/_compat.h	2012-12-17 17:08:58 UTC (rev 128692)
@@ -0,0 +1,50 @@
+/* Straddle Python 2 / 3 */
+#ifndef BTREES__COMPAT_H
+#define BTREES__COMPAT_H
+
+#include "Python.h"
+
+#ifdef INTERN
+#undef INTERN
+#endif
+
+#ifdef INT_FROM_LONG
+#undef INT_FROM_LONG
+#endif
+
+#ifdef INT_CHECK
+#undef INT_CHECK
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+
+#define PY3K
+
+#define INTERN PyUnicode_InternFromString
+#define INT_FROM_LONG(x) PyLong_FromLong(x)
+#define INT_CHECK(x) PyLong_Check(x)
+#define INT_AS_LONG(x) PyLong_AS_LONG(x)
+#define INT_GETMAX(x) 2<<31
+#define TEXT_FROM_STRING PyUnicode_FromString
+#define TEXT_FORMAT PyUnicode_Format
+
+#define COMPARE(lhs, rhs) \
+    PyObject_RichCompareBool((lhs), (rhs), Py_LT) > 0 ? -1 : \
+    (PyObject_RichCompareBool((lhs), (rhs), Py_EQ) > 0 ? 0 : 1)
+
+
+#else
+
+#define INTERN PyString_InternFromString
+#define INT_FROM_LONG(x) PyInt_FromLong(x)
+#define INT_CHECK(x) PyInt_Check(x)
+#define INT_AS_LONG(x) PyInt_AS_LONG(x)
+#define INT_GETMAX(x) PyInt_GetMax(x)
+#define TEXT_FROM_STRING PyString_FromString
+#define TEXT_FORMAT PyString_Format
+
+#define COMPARE(lhs, rhs) PyObject_Compare((lhs), (rhs))
+
+#endif
+
+#endif /* BTREES__COMPAT_H */

Copied: BTrees/trunk/BTrees/_compat.py (from rev 128688, BTrees/branches/py3k/BTrees/_compat.py)
===================================================================
--- BTrees/trunk/BTrees/_compat.py	                        (rev 0)
+++ BTrees/trunk/BTrees/_compat.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -0,0 +1,56 @@
+##############################################################################
+#
+# 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 sys
+
+if sys.version_info[0] < 3: #pragma NO COVER Python2
+
+    PY2 = True
+    PY3 = False
+
+    from StringIO import StringIO
+    BytesIO = StringIO
+
+    int_types = int, long
+    xrange = xrange
+    cmp = cmp
+
+    _bytes = str
+    def _ascii(x):
+        return bytes(x)
+
+    def _u(s, encoding='unicode_escape'):
+        return unicode(s, encoding)
+
+else: #pragma NO COVER Python3
+
+    PY2 = False
+    PY3 = True
+
+    from io import StringIO
+    from io import BytesIO
+
+    int_types = int,
+    xrange = range
+
+    def cmp(x, y):
+        return (x > y) - (y > x)
+
+    _bytes = bytes
+    def _ascii(x):
+        return bytes(x, 'ascii')
+
+    def _u(s, encoding=None):
+        if encoding is None:
+            return s
+        return str(s, encoding)

Modified: BTrees/trunk/BTrees/_fsBTree.c
===================================================================
--- BTrees/trunk/BTrees/_fsBTree.c	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/_fsBTree.c	2012-12-17 17:08:58 UTC (rev 128692)
@@ -31,23 +31,24 @@
 #define PERSISTENT
 
 #define MOD_NAME_PREFIX "fs"
-#define INITMODULE init_fsBTree
+
 #define DEFAULT_MAX_BUCKET_SIZE 500
 #define DEFAULT_MAX_BTREE_SIZE 500
 
+#include "_compat.h"
 /*#include "intkeymacros.h"*/
 
 #define KEYMACROS_H "$Id$\n"
 #define KEY_TYPE char2
 #undef KEY_TYPE_IS_PYOBJECT
-#define KEY_CHECK(K) (PyString_Check(K) && PyString_GET_SIZE(K)==2)
+#define KEY_CHECK(K) (PyBytes_Check(K) && PyBytes_GET_SIZE(K)==2)
 #define TEST_KEY_SET_OR(V, K, T) if ( ( (V) = ((*(K) < *(T) || (*(K) == *(T) && (K)[1] < (T)[1])) ? -1 : ((*(K) == *(T) && (K)[1] == (T)[1]) ? 0 : 1)) ), 0 )
 #define DECREF_KEY(KEY)
 #define INCREF_KEY(k)
 #define COPY_KEY(KEY, E) (*(KEY)=*(E), (KEY)[1]=(E)[1])
-#define COPY_KEY_TO_OBJECT(O, K) O=PyString_FromStringAndSize((const char*)K,2)
+#define COPY_KEY_TO_OBJECT(O, K) O=PyBytes_FromStringAndSize((const char*)K,2)
 #define COPY_KEY_FROM_ARG(TARGET, ARG, STATUS) \
-  if (KEY_CHECK(ARG)) memcpy(TARGET, PyString_AS_STRING(ARG), 2); else { \
+  if (KEY_CHECK(ARG)) memcpy(TARGET, PyBytes_AS_STRING(ARG), 2); else { \
       PyErr_SetString(PyExc_TypeError, "expected two-character string key"); \
       (STATUS)=0; }
 
@@ -59,10 +60,10 @@
 #define DECREF_VALUE(k)
 #define INCREF_VALUE(k)
 #define COPY_VALUE(V, E) (memcpy(V, E, 6))
-#define COPY_VALUE_TO_OBJECT(O, K) O=PyString_FromStringAndSize((const char*)K,6)
+#define COPY_VALUE_TO_OBJECT(O, K) O=PyBytes_FromStringAndSize((const char*)K,6)
 #define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
-  if ((PyString_Check(ARG) && PyString_GET_SIZE(ARG)==6)) \
-      memcpy(TARGET, PyString_AS_STRING(ARG), 6); else { \
+  if ((PyBytes_Check(ARG) && PyBytes_GET_SIZE(ARG)==6)) \
+      memcpy(TARGET, PyBytes_AS_STRING(ARG), 6); else { \
       PyErr_SetString(PyExc_TypeError, "expected six-character string key"); \
       (STATUS)=0; }
 
@@ -70,20 +71,29 @@
 
 #include "Python.h"
 
-static PyObject *bucket_toString(PyObject *self);
+static PyObject *bucket_toBytes(PyObject *self);
 
-static PyObject *bucket_fromString(PyObject *self, PyObject *state);
+static PyObject *bucket_fromBytes(PyObject *self, PyObject *state);
 
 #define EXTRA_BUCKET_METHODS \
-    {"toString", (PyCFunction) bucket_toString,	METH_NOARGS, \
-     "toString() -- Return the state as a string"}, \
-    {"fromString", (PyCFunction) bucket_fromString,	METH_O, \
-     "fromString(s) -- Set the state of the object from a string"}, \
+    {"toBytes", (PyCFunction) bucket_toBytes,	METH_NOARGS, \
+     "toBytes() -- Return the state as a bytes array"}, \
+    {"fromBytes", (PyCFunction) bucket_fromBytes,	METH_O, \
+     "fromSBytes(s) -- Set the state of the object from a bytes array"}, \
+    {"toString", (PyCFunction) bucket_toBytes,	METH_NOARGS, \
+     "toString() -- Deprecated alias for 'toBytes'"}, \
+    {"fromString", (PyCFunction) bucket_fromBytes,	METH_O, \
+     "fromString(s) -- Deprecated alias for 'fromBytes'"}, \
 
+#ifdef PY3K
+#define INITMODULE PyInit__fsBTree
+#else
+#define INITMODULE init_fsBTree
+#endif
 #include "BTreeModuleTemplate.c"
 
 static PyObject *
-bucket_toString(PyObject *oself)
+bucket_toBytes(PyObject *oself)
 {
   Bucket *self = (Bucket *)oself;
   PyObject *items = NULL;
@@ -93,11 +103,11 @@
 
   len = self->len;
 
-  items = PyString_FromStringAndSize(NULL, len*8);
+  items = PyBytes_FromStringAndSize(NULL, len*8);
   if (items == NULL)
     goto err;
-  memcpy(PyString_AS_STRING(items),       self->keys,   len*2);
-  memcpy(PyString_AS_STRING(items)+len*2, self->values, len*6);
+  memcpy(PyBytes_AS_STRING(items),       self->keys,   len*2);
+  memcpy(PyBytes_AS_STRING(items)+len*2, self->values, len*6);
   
   PER_UNUSE(self);
   return items;
@@ -109,14 +119,14 @@
 }
 
 static PyObject *
-bucket_fromString(PyObject *oself, PyObject *state)
+bucket_fromBytes(PyObject *oself, PyObject *state)
 {
   Bucket *self = (Bucket *)oself;
   int len;
   KEY_TYPE *keys;
   VALUE_TYPE *values;
 
-  len = PyString_Size(state);
+  len = PyBytes_Size(state);
   if (len < 0)
     return NULL;
   
@@ -144,8 +154,8 @@
     self->size = len;
   }
 
-  memcpy(self->keys,   PyString_AS_STRING(state),       len*2);
-  memcpy(self->values, PyString_AS_STRING(state)+len*2, len*6);
+  memcpy(self->keys,   PyBytes_AS_STRING(state),       len*2);
+  memcpy(self->values, PyBytes_AS_STRING(state)+len*2, len*6);
 
   self->len = len;
 

Modified: BTrees/trunk/BTrees/check.py
===================================================================
--- BTrees/trunk/BTrees/check.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/check.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -378,30 +378,30 @@
     def visit_btree(self, obj, path, parent, is_mapping,
                     keys, kids, lo, hi):
         indent = "    " * len(path)
-        print "%s%s %s with %d children" % (
+        print("%s%s %s with %d children" % (
                   indent,
                   ".".join(map(str, path)),
                   type_and_adr(obj),
-                  len(kids))
+                  len(kids)))
         indent += "    "
         n = len(keys)
         for i in range(n):
-            print "%skey %d: %r" % (indent, i, keys[i])
+            print("%skey %d: %r" % (indent, i, keys[i]))
 
     def visit_bucket(self, obj, path, parent, is_mapping,
                      keys, values, lo, hi):
         indent = "    " * len(path)
-        print "%s%s %s with %d keys" % (
+        print("%s%s %s with %d keys" % (
                   indent,
                   ".".join(map(str, path)),
                   type_and_adr(obj),
-                  len(keys))
+                  len(keys)))
         indent += "    "
         n = len(keys)
         for i in range(n):
-            print "%skey %d: %r" % (indent, i, keys[i]),
+            print("%skey %d: %r" % (indent, i, keys[i]),)
             if is_mapping:
-                print "value %r" % (values[i],)
+                print("value %r" % (values[i],))
 
 def check(btree):
     """Check internal value-based invariants in a BTree or TreeSet.

Modified: BTrees/trunk/BTrees/floatvaluemacros.h
===================================================================
--- BTrees/trunk/BTrees/floatvaluemacros.h	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/floatvaluemacros.h	2012-12-17 17:08:58 UTC (rev 128692)
@@ -13,7 +13,7 @@
 #define COPY_VALUE_TO_OBJECT(O, K) O=PyFloat_FromDouble(K)
 #define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
   if (PyFloat_Check(ARG)) TARGET = (float)PyFloat_AsDouble(ARG); \
-  else if (PyInt_Check(ARG)) TARGET = (float)PyInt_AsLong(ARG); \
+  else if (INT_CHECK(ARG)) TARGET = (float)INT_AS_LONG(ARG); \
   else { \
       PyErr_SetString(PyExc_TypeError, "expected float or int value"); \
       (STATUS)=0; (TARGET)=0; }

Modified: BTrees/trunk/BTrees/fsBTree.py
===================================================================
--- BTrees/trunk/BTrees/fsBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/fsBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -14,10 +14,11 @@
 
 # fsBTrees are data structures used for ZODB FileStorage.  They are not
 # expected to be "public" excpect to FileStorage.
+# Each item in an fsBTree maps a two-byte key to a six-byte value.
 
 __all__ = ('Bucket', 'Set', 'BTree', 'TreeSet',
            'fsBucket', 'fsSet', 'fsBTree', 'fsTreeSet',
-           'union', 'intersection', 'difference', 'multiunion',
+           'union', 'intersection', 'difference',
           )
 
 
@@ -30,16 +31,15 @@
 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 to_bytes as _to_bytes
 from ._base import union as _union
 
 _BUCKET_SIZE = 500
 _TREE_SIZE = 500
 using64bits = False
-_to_key = _to_str(2)
-_to_value = _to_str(6)
+_to_key = _to_bytes(2)
+_to_value = _to_bytes(6)
 
 
 class fsBucketPy(Bucket):
@@ -47,11 +47,8 @@
     _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)
+        return b''.join(self._keys) + b''.join(self._values)
 
     def fromString(self, v):
         length = len(v)
@@ -77,8 +74,6 @@
     MAX_SIZE = _TREE_SIZE
     _to_key = _to_key
     _to_value = _to_value
-    def MERGE_WEIGHT(self, value, weight):
-        return value
 
 
 class fsTreeSetPy(TreeSet):
@@ -104,18 +99,10 @@
 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
+    from ._fsBTree import fsBucket
+except ImportError: #pragma NO COVER w/ C extensions
     fsBucket = fsBucketPy
     fsSet = fsSetPy
     fsBTree = fsBTreePy
@@ -123,7 +110,13 @@
     difference = differencePy
     union = unionPy
     intersection = intersectionPy
-    multiunion = multiunionPy
+else: #pragma NO COVER w/o C extensions
+    from ._fsBTree import fsSet
+    from ._fsBTree import fsBTree
+    from ._fsBTree import fsTreeSet
+    from ._fsBTree import difference
+    from ._fsBTree import union
+    from ._fsBTree import intersection
 
 Bucket = fsBucket
 Set = fsSet

Modified: BTrees/trunk/BTrees/intkeymacros.h
===================================================================
--- BTrees/trunk/BTrees/intkeymacros.h	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/intkeymacros.h	2012-12-17 17:08:58 UTC (rev 128692)
@@ -4,26 +4,23 @@
 #ifdef ZODB_64BIT_INTS
 /* PY_LONG_LONG as key */
 #define NEED_LONG_LONG_SUPPORT
+#define NEED_LONG_LONG_KEYS
 #define KEY_TYPE PY_LONG_LONG
 #define KEY_CHECK longlong_check
 #define COPY_KEY_TO_OBJECT(O, K) O=longlong_as_object(K)
 #define COPY_KEY_FROM_ARG(TARGET, ARG, STATUS) \
-    if (PyInt_Check(ARG)) TARGET=PyInt_AS_LONG(ARG); else \
-        if (longlong_check(ARG)) TARGET=PyLong_AsLongLong(ARG); else \
-            if (PyLong_Check(ARG)) { \
-                PyErr_SetString(PyExc_ValueError, "long integer out of range"); \
-                (STATUS)=0; (TARGET)=0; } \
-            else { \
-            PyErr_SetString(PyExc_TypeError, "expected integer key");   \
-            (STATUS)=0; (TARGET)=0; }
+    if (!longlong_convert((ARG), &TARGET)) \
+    { \
+        (STATUS)=0; (TARGET)=0; \
+    } 
 #else
 /* C int as key */
 #define KEY_TYPE int
-#define KEY_CHECK PyInt_Check
-#define COPY_KEY_TO_OBJECT(O, K) O=PyInt_FromLong(K)
+#define KEY_CHECK INT_CHECK
+#define COPY_KEY_TO_OBJECT(O, K) O=INT_FROM_LONG(K)
 #define COPY_KEY_FROM_ARG(TARGET, ARG, STATUS)                    \
-  if (PyInt_Check(ARG)) {                                         \
-      long vcopy = PyInt_AS_LONG(ARG);                            \
+  if (INT_CHECK(ARG)) {                                         \
+      long vcopy = INT_AS_LONG(ARG);                            \
       if ((int)vcopy != vcopy) {                                  \
         PyErr_SetString(PyExc_TypeError, "integer out of range"); \
         (STATUS)=0; (TARGET)=0;                                   \

Modified: BTrees/trunk/BTrees/intvaluemacros.h
===================================================================
--- BTrees/trunk/BTrees/intvaluemacros.h	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/intvaluemacros.h	2012-12-17 17:08:58 UTC (rev 128692)
@@ -7,7 +7,7 @@
 #define VALUE_PARSE "L"
 #define COPY_VALUE_TO_OBJECT(O, K) O=longlong_as_object(K)
 #define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS) \
-    if (PyInt_Check(ARG)) TARGET=PyInt_AS_LONG(ARG); else \
+    if (INT_CHECK(ARG)) TARGET=INT_AS_LONG(ARG); else \
         if (longlong_check(ARG)) TARGET=PyLong_AsLongLong(ARG); else \
             if (PyLong_Check(ARG)) { \
                 PyErr_SetString(PyExc_ValueError, "long integer out of range"); \
@@ -18,11 +18,11 @@
 #else
 #define VALUE_TYPE int
 #define VALUE_PARSE "i"
-#define COPY_VALUE_TO_OBJECT(O, K) O=PyInt_FromLong(K)
+#define COPY_VALUE_TO_OBJECT(O, K) O=INT_FROM_LONG(K)
 
 #define COPY_VALUE_FROM_ARG(TARGET, ARG, STATUS)                  \
-  if (PyInt_Check(ARG)) {                                         \
-      long vcopy = PyInt_AS_LONG(ARG);                            \
+  if (INT_CHECK(ARG)) {                                         \
+      long vcopy = INT_AS_LONG(ARG);                            \
       if ((int)vcopy != vcopy) {                                  \
         PyErr_SetString(PyExc_TypeError, "integer out of range"); \
         (STATUS)=0; (TARGET)=0;                                   \

Modified: BTrees/trunk/BTrees/objectkeymacros.h
===================================================================
--- BTrees/trunk/BTrees/objectkeymacros.h	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/objectkeymacros.h	2012-12-17 17:08:58 UTC (rev 128692)
@@ -3,35 +3,34 @@
 #define KEY_TYPE_IS_PYOBJECT
 
 #include "Python.h"
+#include "_compat.h"
 
-static PyObject *object_;
+static PyObject *object_; /* initialized in BTreeModuleTemplate init */
 
 static int
 check_argument_cmp(PyObject *arg)
 {
-  /* printf("check cmp %p %p %p %p\n",  */
-  /*        arg->ob_type->tp_richcompare, */
-  /*        ((PyTypeObject *)object_)->ob_type->tp_richcompare, */
-  /*        arg->ob_type->tp_compare, */
-  /*        ((PyTypeObject *)object_)->ob_type->tp_compare); */
+    /* printf("check cmp %p %p %p %p\n",  */
+    /*        arg->ob_type->tp_richcompare, */
+    /*        ((PyTypeObject *)object_)->ob_type->tp_richcompare, */
+    /*        arg->ob_type->tp_compare, */
+    /*        ((PyTypeObject *)object_)->ob_type->tp_compare); */
 
-  if (arg->ob_type->tp_richcompare == NULL
-      &&
-#if PY_MAJOR_VERSION==2 && PY_MINOR_VERSION < 6
-       arg->ob_type->tp_compare == NULL
+#ifdef PY3K
+    if (Py_TYPE(arg)->tp_richcompare == Py_TYPE(object_)->tp_richcompare)
 #else
-       arg->ob_type->tp_compare ==
-       ((PyTypeObject *)object_)->ob_type->tp_compare
+    if (Py_TYPE(arg)->tp_richcompare == NULL
+        && Py_TYPE(arg)->tp_compare == Py_TYPE(object_)->tp_compare)
 #endif
-      )
     {
-      PyErr_SetString(PyExc_TypeError, "Object has default comparison");
-      return 0;
+        PyErr_SetString(PyExc_TypeError, "Object has default comparison");
+        return 0;
     }
-  return 1;
+    return 1;
 }
 
-#define TEST_KEY_SET_OR(V, KEY, TARGET) if ( ( (V) = PyObject_Compare((KEY),(TARGET)) ), PyErr_Occurred() )
+#define TEST_KEY_SET_OR(V, KEY, TARGET) \
+if ( ( (V) = COMPARE((KEY),(TARGET)) ), PyErr_Occurred() )
 #define INCREF_KEY(k) Py_INCREF(k)
 #define DECREF_KEY(KEY) Py_DECREF(KEY)
 #define COPY_KEY(KEY, E) KEY=(E)

Modified: BTrees/trunk/BTrees/objectvaluemacros.h
===================================================================
--- BTrees/trunk/BTrees/objectvaluemacros.h	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/objectvaluemacros.h	2012-12-17 17:08:58 UTC (rev 128692)
@@ -1,9 +1,8 @@
-
 #define VALUEMACROS_H "$Id$\n"
 
 #define VALUE_TYPE PyObject *
 #define VALUE_TYPE_IS_PYOBJECT
-#define TEST_VALUE(VALUE, TARGET) PyObject_Compare((VALUE),(TARGET))
+#define TEST_VALUE(VALUE, TARGET) COMPARE((VALUE),(TARGET))
 #define DECLARE_VALUE(NAME) VALUE_TYPE NAME
 #define INCREF_VALUE(k) Py_INCREF(k)
 #define DECREF_VALUE(k) Py_DECREF(k)

Deleted: BTrees/trunk/BTrees/py24compat.h
===================================================================
--- BTrees/trunk/BTrees/py24compat.h	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/py24compat.h	2012-12-17 17:08:58 UTC (rev 128692)
@@ -1,11 +0,0 @@
-/* Backport type definitions from Python 2.5's object.h */
-#ifndef BTREE_PY24COMPATH_H
-#define BTREE_PY24COMPAT_H
-#if PY_VERSION_HEX < 0x02050000
-typedef Py_ssize_t (*lenfunc)(PyObject *);
-typedef PyObject *(*ssizeargfunc)(PyObject *, Py_ssize_t);
-typedef PyObject *(*ssizessizeargfunc)(PyObject *, Py_ssize_t, Py_ssize_t);
-typedef int(*ssizeobjargproc)(PyObject *, Py_ssize_t, PyObject *);
-typedef int(*ssizessizeobjargproc)(PyObject *, Py_ssize_t, Py_ssize_t, PyObject *);
-#endif /* PY_VERSION_HEX */
-#endif /* BTREE_PY24COMPAT_H */

Modified: BTrees/trunk/BTrees/tests/common.py
===================================================================
--- BTrees/trunk/BTrees/tests/common.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/common.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -22,7 +22,17 @@
     else:
         return test_method
 
+def _skip_under_Py3k(test_method): #pragma NO COVER
+    try:
+        unicode
+    except NameError: # skip this test
+        def _dummy(*args):
+            pass
+        return _dummy
+    else:
+        return test_method
 
+
 class Base(object):
     # Tests common to all types: sets, buckets, and BTrees 
 
@@ -75,7 +85,7 @@
     def testSetstateArgumentChecking(self):
         try:
             self._makeOne().__setstate__(('',))
-        except TypeError, v:
+        except TypeError as v:
             self.assertEqual(str(v), 'tuple required for first state element')
         else:
             raise AssertionError("Expected exception")
@@ -171,17 +181,17 @@
 
         # Modifying a thing
         remove(100)
-        self.assert_(t in read)
+        self.assertTrue(t in read)
         del read[:]
         add(100)
-        self.assert_(t in read)
+        self.assertTrue(t in read)
         del read[:]
 
         transaction.abort()
         conn.cacheMinimize()
         list(t)
-        self.assert_(100 in t)
-        self.assert_(not read)
+        self.assertTrue(100 in t)
+        self.assertTrue(not read)
 
 
 class MappingBase(Base):
@@ -189,7 +199,8 @@
 
     def _populate(self, t, l):
         # Make some data
-        for i in range(l): t[i]=i
+        for i in range(l):
+            t[i]=i
 
     def testRepr(self):
         # test the repr because buckets have a complex repr implementation
@@ -203,7 +214,7 @@
         # 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)
+            self.assertTrue(len(r) > 10000)
 
     def testGetItemFails(self):
         self.assertRaises(KeyError, self._getitemfail)
@@ -219,7 +230,7 @@
         t = self._makeOne()
         t[1] = 1
         a = t[1]
-        self.assertEqual(a , 1, `a`)
+        self.assertEqual(a , 1, repr(a))
 
     def testReplaceWorks(self):
         t = self._makeOne()
@@ -232,7 +243,7 @@
         import random
         t = self._makeOne()
         added = {}
-        r = range(1000)
+        r = list(range(1000))
         for x in r:
             k = random.choice(r)
             t[k] = x
@@ -241,12 +252,14 @@
         self.assertEqual(len(t) , len(addl), len(t))
 
     def testHasKeyWorks(self):
+        from .._compat import PY2
         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)
+        if PY2:
+            self.assertTrue(t.has_key(1))
+        self.assertTrue(1 in t)
+        self.assertTrue(0 not in t)
+        self.assertTrue(2 not in t)
 
     def testValuesWorks(self):
         t = self._makeOne()
@@ -267,20 +280,18 @@
             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 = sorted(t.values(0+x,99-x))
+            self.assertEqual(lst, list(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))
+            lst = sorted(t.values(max=99-x, min=0+x))
+            self.assertEqual(lst, list(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()
+        L = sorted(L)
         vals = t.values()
         for i in range(-1, -5, -1):
             self.assertEqual(vals[i], L[i])
@@ -299,10 +310,10 @@
 
         for x in range(40):
             lst = t.keys(0+x,99-x)
-            self.assertEqual(list(lst), range(0+x, 99-x+1))
+            self.assertEqual(list(lst), list(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(list(lst), list(range(0+x, 99-x+1)))
 
         self.assertEqual(len(v), 100)
 
@@ -311,7 +322,7 @@
         L = [-3, 6, -11, 4]
         for i in L:
             t[i] = i
-        L.sort()
+        L = sorted(L)
         keys = t.keys()
         for i in range(-1, -5, -1):
             self.assertEqual(keys[i], L[i])
@@ -335,17 +346,17 @@
             i += 1
 
         items = list(t.items(min=12, max=20))
-        self.assertEqual(items, zip(range(12, 21), range(24, 43, 2)))
+        self.assertEqual(items, list(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)))
+        self.assertEqual(items, list(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()
+        L = sorted(L)
         items = t.items()
         for i in range(-1, -5, -1):
             self.assertEqual(items[i], (L[i], L[i]))
@@ -378,14 +389,14 @@
 
         try:
             t.maxKey(t.minKey() - 1)
-        except ValueError, err:
+        except ValueError as err:
             self.assertEqual(str(err), "no key satisfies the conditions")
         else:
             self.fail("expected ValueError")
 
         try:
             t.minKey(t.maxKey() + 1)
-        except ValueError, err:
+        except ValueError as err:
             self.assertEqual(str(err), "no key satisfies the conditions")
         else:
             self.fail("expected ValueError")
@@ -393,7 +404,7 @@
     def testClear(self):
         import random
         t = self._makeOne()
-        r = range(100)
+        r = list(range(100))
         for x in r:
             rnd = random.choice(r)
             t[rnd] = 0
@@ -411,8 +422,7 @@
             d[k]=i
             l.append((k, i))
 
-        items=d.items()
-        items.sort()
+        items= sorted(d.items())
 
         t.update(d)
         self.assertEqual(list(t.items()), items)
@@ -447,7 +457,7 @@
         # 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)))
+        t.update(list(zip(range(300), range(300))))
         keys = t.keys(200, 50)
         self.assertEqual(len(keys), 0)
         self.assertEqual(list(keys), [])
@@ -464,6 +474,7 @@
         # This tests fixes to several bugs in this area, starting with
         # http://collector.zope.org/Zope/419,
         # "BTreeItems slice contains 1 too many elements".
+        from .._compat import xrange
         t = self._makeOne()
         for n in range(10):
             t.clear()
@@ -531,12 +542,12 @@
             t[i] = 1
         tslice = t.items()[20:80]
         self.assertEqual(len(tslice), 60)
-        self.assertEqual(list(tslice), zip(range(20, 80), [1]*60))
+        self.assertEqual(list(tslice), list(zip(range(20, 80), [1]*60)))
 
     def testIterators(self):
         t = self._makeOne()
 
-        for keys in [], [-2], [1, 4], range(-170, 2000, 6):
+        for keys in [], [-2], [1, 4], list(range(-170, 2000, 6)):
             t.clear()
             for k in keys:
                 t[k] = -3 * k
@@ -549,11 +560,11 @@
             self.assertEqual(x, keys)
 
             it = iter(t)
-            self.assert_(it is iter(it))
+            self.assertTrue(it is iter(it))
             x = []
             try:
                 while 1:
-                    x.append(it.next())
+                    x.append(next(it))
             except StopIteration:
                 pass
             self.assertEqual(x, keys)
@@ -565,14 +576,14 @@
     def testRangedIterators(self):
         t = self._makeOne()
 
-        for keys in [], [-2], [1, 4], range(-170, 2000, 13):
+        for keys in [], [-2], [1, 4], list(range(-170, 2000, 13)):
             t.clear()
             values = []
             for k in keys:
                 value = -3 * k
                 t[k] = value
                 values.append(value)
-            items = zip(keys, values)
+            items = list(zip(keys, values))
 
             self.assertEqual(list(t.iterkeys()), keys)
             self.assertEqual(list(t.itervalues()), values)
@@ -593,7 +604,7 @@
                     got = t.itervalues(lo)
                     self.assertEqual(goodvalues, list(got))
 
-                    gooditems = zip(goodkeys, goodvalues)
+                    gooditems = list(zip(goodkeys, goodvalues))
                     got = t.iteritems(lo)
                     self.assertEqual(gooditems, list(got))
 
@@ -607,7 +618,7 @@
                             got = t.itervalues(lo, max=hi)
                             self.assertEqual(goodvalues, list(got))
 
-                            gooditems = zip(goodkeys, goodvalues)
+                            gooditems = list(zip(goodkeys, goodvalues))
                             got = t.iteritems(max=hi, min=lo)
                             self.assertEqual(gooditems, list(got))
 
@@ -684,7 +695,7 @@
 
         self.assertEqual(t.setdefault(1, 2), 2)
         # That should also have associated 1 with 2 in the tree.
-        self.assert_(1 in t)
+        self.assertTrue(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)
@@ -820,14 +831,13 @@
         import random
         t = self._makeOne()
         added = {}
-        r = range(100)
+        r = list(range(100))
         for x in r:
             k = random.choice(r)
-            if not added.has_key(k):
+            if k not in added:
                 t[k] = x
                 added[k] = 1
-        addl = added.keys()
-        addl.sort()
+        addl = sorted(added.keys())
         diff = lsubtract(list(t.keys()), addl)
         self.assertEqual(diff , [], (diff, addl, list(t.keys())))
         self._checkIt(t)
@@ -836,13 +846,12 @@
         import random
         t = self._makeOne()
         added = {}
-        r = range(100)
+        r = list(range(100))
         for x in r:
             k = random.choice(r)
             t[k] = x
             added[k] = 1
-        addl = added.keys()
-        addl.sort()
+        addl = sorted(added.keys())
         diff = lsubtract(t.keys(), addl)
         self.assertEqual(diff , [], diff)
         self._checkIt(t)
@@ -850,7 +859,7 @@
     def testRandomDeletes(self):
         import random
         t = self._makeOne()
-        r = range(1000)
+        r = list(range(1000))
         added = []
         for x in r:
             k = random.choice(r)
@@ -859,15 +868,15 @@
         deleted = []
         for x in r:
             k = random.choice(r)
-            if t.has_key(k):
-                self.assert_(k in t)
+            if k in t:
+                self.assertTrue(k in t)
                 del t[k]
                 deleted.append(k)
-                if t.has_key(k):
+                if k in t:
                     self.fail( "had problems deleting %s" % k )
         badones = []
         for x in deleted:
-            if t.has_key(x):
+            if x in t:
                 badones.append(x)
         self.assertEqual(badones , [], (badones, added, deleted))
         self._checkIt(t)
@@ -875,7 +884,7 @@
     def testTargetedDeletes(self):
         import random
         t = self._makeOne()
-        r = range(1000)
+        r = list(range(1000))
         for x in r:
             k = random.choice(r)
             t[k] = x
@@ -889,7 +898,7 @@
 
     def testPathologicalRightBranching(self):
         t = self._makeOne()
-        r = range(1000)
+        r = list(range(1000))
         for x in r:
             t[x] = 1
         self.assertEqual(realseq(t.keys()) , r, realseq(t.keys()))
@@ -900,9 +909,8 @@
 
     def testPathologicalLeftBranching(self):
         t = self._makeOne()
-        r = range(1000)
-        revr = r[:]
-        revr.reverse()
+        r = list(range(1000))
+        revr = list(reversed(r[:]))
         for x in revr:
             t[x] = 1
         self.assertEqual(realseq(t.keys()) , r, realseq(t.keys()))
@@ -955,9 +963,10 @@
         for x in add_order:
             t[x] = 1
         for x in delete_order:
-            try: del t[x]
+            try:
+                del t[x]
             except KeyError:
-                if t.has_key(x):
+                if x in t:
                     self.assertEqual(1,2,"failed to delete %s" % x)
         self._checkIt(t)
 
@@ -989,14 +998,14 @@
         for i in range(200):
             t[i] = i
         items, dummy = t.__getstate__()
-        self.assert_(len(items) > 2)   # at least two buckets and a key
+        self.assertTrue(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))
+        self.assertEqual(list(therange), list(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
@@ -1008,7 +1017,7 @@
         del t[firstkey]
         therange = t.keys(min=-1, max=firstkey)
         self.assertEqual(len(therange), firstkey)
-        self.assertEqual(list(therange), range(firstkey))
+        self.assertEqual(list(therange), list(range(firstkey)))
         self._checkIt(t)
 
     def testInsertMethod(self):
@@ -1037,11 +1046,11 @@
         for dummy in range(20):
             try:
                 del t[k[0]]
-            except RuntimeError, detail:
+            except RuntimeError as detail:
                 self.assertEqual(str(detail), "the bucket being iterated "
                                               "changed size")
                 break
-            except KeyError, v:
+            except KeyError as 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
@@ -1069,22 +1078,28 @@
         self.assertEqual(t.add(5) , 0)
 
     def testInsert(self):
+        from .._compat import PY2
         t = self._makeOne()
         t.insert(1)
-        self.assert_(t.has_key(1))
-        self.assert_(1 in t)
-        self.assert_(2 not in t)
+        if PY2:
+            self.assertTrue(t.has_key(1))
+        self.assertTrue(1 in t)
+        self.assertTrue(2 not in t)
 
     def testBigInsert(self):
+        from .._compat import PY2
+        from .._compat import xrange
         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)
+            if PY2:
+                self.assertTrue(t.has_key(x))
+            self.assertTrue(x in t)
 
     def testRemoveSucceeds(self):
+        from .._compat import xrange
         t = self._makeOne()
         r = xrange(10000)
         for x in r: t.insert(x)
@@ -1097,11 +1112,14 @@
         self._makeOne().remove(1)
 
     def testHasKeyFails(self):
+        from .._compat import PY2
         t = self._makeOne()
-        self.assert_(not t.has_key(1))
-        self.assert_(1 not in t)
+        if PY2:
+            self.assertTrue(not t.has_key(1))
+        self.assertTrue(1 not in t)
 
     def testKeys(self):
+        from .._compat import xrange
         t = self._makeOne()
         r = xrange(1000)
         for x in r:
@@ -1111,6 +1129,7 @@
 
 
     def testClear(self):
+        from .._compat import xrange
         t = self._makeOne()
         r = xrange(1000)
         for x in r: t.insert(x)
@@ -1134,21 +1153,21 @@
         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)
+        self.assertTrue(t.minKey() in t)
+        self.assertTrue(t.minKey()-1 not in t)
+        self.assertTrue(t.maxKey() in t)
+        self.assertTrue(t.maxKey()+1 not in t)
 
         try:
             t.maxKey(t.minKey() - 1)
-        except ValueError, err:
+        except ValueError as err:
             self.assertEqual(str(err), "no key satisfies the conditions")
         else:
             self.fail("expected ValueError")
 
         try:
             t.minKey(t.maxKey() + 1)
-        except ValueError, err:
+        except ValueError as err:
             self.assertEqual(str(err), "no key satisfies the conditions")
         else:
             self.fail("expected ValueError")
@@ -1163,8 +1182,7 @@
             d[k]=i
             l.append(k)
 
-        items = d.keys()
-        items.sort()
+        items = sorted(d.keys())
 
         t.update(l)
         self.assertEqual(list(t.keys()), items)
@@ -1203,28 +1221,28 @@
             self.assertEqual(len(t), n)
 
             kslice = t.keys()
-            self.assertEqual(len(kslice), n)
+            self.assertEqual(len(list(kslice)), n)
 
             # Test whole-structure slices.
             x = kslice[:]
-            self.assertEqual(list(x), keys[:])
+            self.assertEqual(list(x), list(keys[:]))
 
             for lo in range(-2*n, 2*n+1):
                 # Test one-sided slices.
                 x = kslice[:lo]
-                self.assertEqual(list(x), keys[:lo])
+                self.assertEqual(list(x), list(keys[:lo]))
                 x = kslice[lo:]
-                self.assertEqual(list(x), keys[lo:])
+                self.assertEqual(list(x), list(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])
+                    self.assertEqual(list(x), list(keys[lo:hi]))
 
     def testIterator(self):
         t = self._makeOne()
 
-        for keys in [], [-2], [1, 4], range(-170, 2000, 6):
+        for keys in [], [-2], [1, 4], list(range(-170, 2000, 6)):
             t.clear()
             t.update(keys)
 
@@ -1236,11 +1254,11 @@
             self.assertEqual(x, keys)
 
             it = iter(t)
-            self.assert_(it is iter(it))
+            self.assertTrue(it is iter(it))
             x = []
             try:
                 while 1:
-                    x.append(it.next())
+                    x.append(next(it))
             except StopIteration:
                 pass
             self.assertEqual(x, keys)
@@ -1248,12 +1266,14 @@
 class ExtendedSetTests(NormalSetTests):
 
     def testLen(self):
+        from .._compat import xrange
         t = self._makeOne()
         r = xrange(10000)
         for x in r: t.insert(x)
         self.assertEqual(len(t) , 10000, len(t))
 
     def testGetItem(self):
+        from .._compat import xrange
         t = self._makeOne()
         r = xrange(10000)
         for x in r: t.insert(x)
@@ -1300,10 +1320,10 @@
         key = data[1]
         del tree[key]
         data = tree.__getstate__()[0]
-        self.assert_(data[1] != key)
+        self.assertTrue(data[1] != key)
 
         # The tree should have changed:
-        self.assert_(tree._p_changed)
+        self.assertTrue(tree._p_changed)
 
         # Grow the btree until we have multiple levels
         while 1:
@@ -1318,7 +1338,7 @@
         key = data[1]
         del tree[key]
         data = tree.__getstate__()[0]
-        self.assert_(data[1] != key)
+        self.assertTrue(data[1] != key)
 
         transaction.abort()
         db.close()
@@ -1340,7 +1360,7 @@
         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.assertTrue(klass is getattr(self._getModule(),
                                           self.prefix + name))
 
     def testModuleProvides(self):
@@ -1350,12 +1370,12 @@
     def testFamily(self):
         import BTrees
         if self.prefix == 'OO':
-            self.assert_(
+            self.assertTrue(
                 getattr(self._getModule(), 'family', self) is self)
         elif 'L' in self.prefix:
-            self.assert_(self._getModule().family is BTrees.family64)
+            self.assertTrue(self._getModule().family is BTrees.family64)
         elif 'I' in self.prefix:
-            self.assert_(self._getModule().family is BTrees.family32)
+            self.assertTrue(self._getModule().family is BTrees.family32)
 
 
 class TypeTest(object):
@@ -1423,6 +1443,12 @@
 
 class TestLongIntKeys(TestLongIntSupport):
 
+    def _makeLong(self, v):
+        try:
+            return long(v)
+        except NameError: #pragma NO COVER Py3k
+            return int(v)
+
     def testLongIntKeysWork(self):
         from BTrees.IIBTree import using64bits
         if not using64bits:
@@ -1432,10 +1458,11 @@
         assert o1 != o2
 
         # Test some small key values first:
-        t[0L] = o1
+        zero_long = self._makeLong(0)
+        t[zero_long] = o1
         self.assertEqual(t[0], o1)
         t[0] = o2
-        self.assertEqual(t[0L], o2)
+        self.assertEqual(t[zero_long], o2)
         self.assertEqual(list(t.keys()), [0])
 
         # Test some large key values too:
@@ -1469,8 +1496,7 @@
         if not using64bits:
             return
         t = self._makeOne()
-        keys = list(self.getTwoKeys())
-        keys.sort()
+        keys = sorted(self.getTwoKeys())
         k1, k2 = keys
         assert k1 != k2
 
@@ -1500,7 +1526,7 @@
 # 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 mapbuilder(list(zip(keys, keys)))
     return result
 
 # Subclasses have to set up:
@@ -1521,8 +1547,7 @@
         for e in y:
             if e not in result:
                 result.append(e)
-        result.sort()
-        return result
+        return sorted(result)
 
     def _intersection(self, x, y):
         result = []
@@ -1544,39 +1569,39 @@
     def testNone(self):
         for op in self.union, self.intersection, self.difference:
             C = op(None, None)
-            self.assert_(C is None)
+            self.assertTrue(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)
+                self.assertTrue(C is A)
 
                 C = op(None, A)
                 if op == self.difference:
-                    self.assert_(C is None)
+                    self.assertTrue(C is None)
                 else:
-                    self.assert_(C is A)
+                    self.assertTrue(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.assertTrue(not hasattr(C, "values"))
                 self.assertEqual(list(C), self.Akeys)
 
                 C = self.union(E, A)
-                self.assert_(not hasattr(C, "values"))
+                self.assertTrue(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.assertTrue(not hasattr(C, "values"))
                 self.assertEqual(list(C), [])
 
                 C = self.intersection(E, A)
-                self.assert_(not hasattr(C, "values"))
+                self.assertTrue(not hasattr(C, "values"))
                 self.assertEqual(list(C), [])
 
     def testEmptyDifference(self):
@@ -1599,7 +1624,7 @@
         for A in inputs:
             for B in inputs:
                 C = self.union(A, B)
-                self.assert_(not hasattr(C, "values"))
+                self.assertTrue(not hasattr(C, "values"))
                 self.assertEqual(list(C), self._union(A, B))
 
     def testIntersection(self):
@@ -1607,7 +1632,7 @@
         for A in inputs:
             for B in inputs:
                 C = self.intersection(A, B)
-                self.assert_(not hasattr(C, "values"))
+                self.assertTrue(not hasattr(C, "values"))
                 self.assertEqual(list(C), self._intersection(A, B))
 
     def testDifference(self):
@@ -1673,39 +1698,39 @@
     def testBothNone(self):
         for op in self.weightedUnion(), self.weightedIntersection():
             w, C = op(None, None)
-            self.assert_(C is None)
+            self.assertTrue(C is None)
             self.assertEqual(w, 0)
 
             w, C = op(None, None, 42, 666)
-            self.assert_(C is None)
+            self.assertTrue(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.assertTrue(C is A)
                 self.assertEqual(w, 1)
 
                 w, C = op(None, A, 42, 666)
-                self.assert_(C is A)
+                self.assertTrue(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.assertTrue(C is A)
                 self.assertEqual(w, 1)
 
                 w, C = op(A, None, 42, 666)
-                self.assert_(C is A)
+                self.assertTrue(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)))
+            obj = self.mkbucket(list(zip(obj, [1] * len(obj))))
         return obj
 
     # Python simulation of weightedUnion.
@@ -1796,12 +1821,13 @@
         self.assertEqual(len(self.multiunion([])), 0)
 
     def testOne(self):
-        for sequence in [3], range(20), range(-10, 0, 2) + range(1, 10, 2):
+        for sequence in ([3],
+                         list(range(20)),
+                         list(range(-10, 0, 2)) + list(range(1, 10, 2)),
+                        ):
             seq1 = sequence[:]
-            seq2 = sequence[:]
-            seq2.reverse()
-            seqsorted = sequence[:]
-            seqsorted.sort()
+            seq2 = list(reversed(sequence[:]))
+            seqsorted = sorted(sequence[:])
             for seq in seq1, seq2, seqsorted:
                 for builder in self.mkset, self.mktreeset:
                     input = builder(seq)
@@ -1817,12 +1843,12 @@
 
     def testBigInput(self):
         N = 100000
-        input = self.mkset(range(N))
+        input = self.mkset(list(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))
+        self.assertEqual(list(output), list(range(N)))
 
     def testLotsOfLittleOnes(self):
         from random import shuffle
@@ -1836,7 +1862,7 @@
         shuffle(inputs)
         output = self.multiunion(inputs)
         self.assertEqual(len(output), N*4)
-        self.assertEqual(list(output), range(-N, 3*N))
+        self.assertEqual(list(output), list(range(-N, 3*N)))
 
     def testFunkyKeyIteration(self):
         # The internal set iteration protocol allows "iterating over" a
@@ -1846,11 +1872,11 @@
         slow = mkset()
         for i in range(N):
             slow = union(slow, mkset([i]))
-        fast = self.multiunion(range(N)) # acts like N distinct singleton sets
+        fast = self.multiunion(list(range(N))) # 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))
+        self.assertEqual(list(fast), list(range(N)))
 
 
 class ConflictTestBase(object):
@@ -1890,7 +1916,7 @@
     if should_fail:
         try:
             merged = o1._p_resolveConflict(s1, s2, s3)
-        except BTreesConflictError, err:
+        except BTreesConflictError as err:
             pass
         else:
             assert 0, message
@@ -2143,9 +2169,8 @@
 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
+    return (list(filter(lambda x, l1=l1: x not in l1, l2)) +
+            list(filter(lambda x, l2=l2: x not in l2, l1)))
 
 def realseq(itemsob):
     return [x for x in itemsob]

Modified: BTrees/trunk/BTrees/tests/testBTrees.py
===================================================================
--- BTrees/trunk/BTrees/tests/testBTrees.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/testBTrees.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -121,7 +121,7 @@
         self.assertEqual(t.has_key(7), 5)
         self.assertEqual(t.has_key(11), 5)
         for i in 0, 2, 4, 6, 8, 9, 10, 12:
-            self.assert_(i not in t)
+            self.assertTrue(i not in t)
 
     def _checkRanges(self, tree, keys):
         self.assertEqual(len(tree), len(keys))
@@ -129,7 +129,7 @@
         sorted_keys.sort()
         self.assertEqual(list(tree.keys()), sorted_keys)
         for k in keys:
-            self.assert_(k in tree)
+            self.assertTrue(k in tree)
         if keys:
             lokey = sorted_keys[0]
             hikey = sorted_keys[-1]
@@ -206,6 +206,24 @@
     def __cmp__(self, other):
         return cmp(self.id, other.id)
 
+    def __le__(self, other):
+        return self.id <= other.id
+
+    def __lt__(self, other):
+        return self.id < other.id
+
+    def __eq__(self, other):
+        return self.id == other.id
+
+    def __ne__(self, other):
+        return self.id != other.id
+
+    def __gt__(self, other):
+        return self.id > other.id
+
+    def __ge__(self, other):
+        return self.id >= other.id
+
     def __hash__(self):
         return hash(self.id)
 
@@ -236,6 +254,8 @@
         import gc
         import random
         from BTrees.OOBTree import OOBTree
+        from .._compat import _u
+        from .._compat import xrange
 
         t = OOBTree()
 
@@ -257,12 +277,12 @@
                 t[id] = ToBeDeleted(id)
             else:
                 #del
-                id = trandom.choice(ids.keys())
+                id = trandom.choice(list(ids.keys()))
                 del t[id]
                 del ids[id]
 
         ids = ids.keys()
-        trandom.shuffle(ids)
+        trandom.shuffle(list(ids))
         for id in ids:
             del t[id]
         ids = None
@@ -287,15 +307,15 @@
                     id = trandom.randint(0,1000000)
 
                 ids[id] = 1
-                t[id] = (id, ToBeDeleted(id), u'somename')
+                t[id] = (id, ToBeDeleted(id), _u('somename'))
             else:
                 #del
-                id = trandom.choice(ids.keys())
+                id = trandom.choice(list(ids.keys()))
                 del t[id]
                 del ids[id]
 
         ids = ids.keys()
-        trandom.shuffle(ids)
+        trandom.shuffle(list(ids))
         for id in ids:
             del t[id]
         ids = None
@@ -325,12 +345,12 @@
                 t[id] = 1
             else:
                 #del
-                id = trandom.choice(ids.keys())
+                id = trandom.choice(list(ids.keys()))
                 del ids[id]
                 del t[id]
 
         ids = ids.keys()
-        trandom.shuffle(ids)
+        trandom.shuffle(list(ids))
         for id in ids:
             del t[id]
         #release all refs
@@ -354,18 +374,18 @@
                 id = None
                 while id is None or id in ids:
                     id = trandom.randint(0,1000000)
-                    id = (id, ToBeDeleted(id), u'somename')
+                    id = (id, ToBeDeleted(id), _u('somename'))
 
                 ids[id] = 1
                 t[id] = 1
             else:
                 #del
-                id = trandom.choice(ids.keys())
+                id = trandom.choice(list(ids.keys()))
                 del ids[id]
                 del t[id]
 
         ids = ids.keys()
-        trandom.shuffle(ids)
+        trandom.shuffle(list(ids))
         for id in ids:
             del t[id]
         #release all refs
@@ -387,8 +407,8 @@
 
     def __cmp__(self,other):
         raise ValueError('incomparable')
+    __lt__ = __le__ = __eq__ = __ne__ = __ge__ = __gt__ = __cmp__
 
-
 class TestCmpError(unittest.TestCase):
 
     def testFoo(self):
@@ -397,7 +417,7 @@
         t['hello world'] = None
         try:
             t[DoesntLikeBeingCompared()] = None
-        except ValueError,e:
+        except ValueError as e:
             self.assertEqual(str(e), 'incomparable')
         else:
             self.fail('incomarable objects should not be allowed into '
@@ -410,22 +430,22 @@
         import BTrees
         from BTrees.IOBTree import IOTreeSet
         verifyObject(BTrees.Interfaces.IBTreeFamily, BTrees.family32)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family32.IO, BTrees.IOBTree)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family32.OI, BTrees.OIBTree)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family32.II, BTrees.IIBTree)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family32.IF, BTrees.IFBTree)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family32.OO, BTrees.OOBTree)
         s = IOTreeSet()
         s.insert(BTrees.family32.maxint)
-        self.assert_(BTrees.family32.maxint in s)
+        self.assertTrue(BTrees.family32.maxint in s)
         s = IOTreeSet()
         s.insert(BTrees.family32.minint)
-        self.assert_(BTrees.family32.minint in s)
+        self.assertTrue(BTrees.family32.minint in s)
         s = IOTreeSet()
         # this next bit illustrates an, um, "interesting feature".  If
         # the characteristics change to match the 64 bit version, please
@@ -440,22 +460,22 @@
         import BTrees
         from BTrees.LOBTree import LOTreeSet
         verifyObject(BTrees.Interfaces.IBTreeFamily, BTrees.family64)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family64.IO, BTrees.LOBTree)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family64.OI, BTrees.OLBTree)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family64.II, BTrees.LLBTree)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family64.IF, BTrees.LFBTree)
-        self.assertEquals(
+        self.assertEqual(
             BTrees.family64.OO, BTrees.OOBTree)
         s = LOTreeSet()
         s.insert(BTrees.family64.maxint)
-        self.assert_(BTrees.family64.maxint in s)
+        self.assertTrue(BTrees.family64.maxint in s)
         s = LOTreeSet()
         s.insert(BTrees.family64.minint)
-        self.assert_(BTrees.family64.minint in s)
+        self.assertTrue(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)
@@ -468,35 +488,35 @@
         # unpickling, whether from the same unpickler or different
         # unpicklers.
         import pickle
-        import StringIO
+        from .._compat import BytesIO
 
         s = pickle.dumps((family, family))
         (f1, f2) = pickle.loads(s)
-        self.failUnless(f1 is family)
-        self.failUnless(f2 is family)
+        self.assertTrue(f1 is family)
+        self.assertTrue(f2 is family)
 
         # Using a single memo across multiple pickles:
-        sio = StringIO.StringIO()
+        sio = BytesIO()
         p = pickle.Pickler(sio)
         p.dump(family)
         p.dump([family])
-        u = pickle.Unpickler(StringIO.StringIO(sio.getvalue()))
+        u = pickle.Unpickler(BytesIO(sio.getvalue()))
         f1 = u.load()
         f2, = u.load()
-        self.failUnless(f1 is family)
-        self.failUnless(f2 is family)
+        self.assertTrue(f1 is family)
+        self.assertTrue(f2 is family)
 
         # Using separate memos for each pickle:
-        sio = StringIO.StringIO()
+        sio = BytesIO()
         p = pickle.Pickler(sio)
         p.dump(family)
         p.clear_memo()
         p.dump([family])
-        u = pickle.Unpickler(StringIO.StringIO(sio.getvalue()))
+        u = pickle.Unpickler(BytesIO(sio.getvalue()))
         f1 = u.load()
         f2, = u.load()
-        self.failUnless(f1 is family)
-        self.failUnless(f2 is family)
+        self.assertTrue(f1 is family)
+        self.assertTrue(f2 is family)
 
 
 def test_suite():

Modified: BTrees/trunk/BTrees/tests/testBTreesUnicode.py
===================================================================
--- BTrees/trunk/BTrees/tests/testBTreesUnicode.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/testBTreesUnicode.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -13,7 +13,7 @@
 ##############################################################################
 
 import unittest
-from BTrees.OOBTree import OOBTree
+from .common import _skip_under_Py3k
 
 # When an OOBtree contains unicode strings as keys,
 # it is neccessary accessing non-unicode strings are
@@ -26,33 +26,40 @@
     """ test unicode"""
 
     def setUp(self):
-        """setup an OOBTree with some unicode strings"""
+        #setup an OOBTree with some unicode strings
+        from BTrees.OOBTree import OOBTree
+        from BTrees._compat import _bytes
+        from BTrees._compat import _u
 
-        self.s = unicode('dreit\xe4gigen', 'latin1')
+        self.s = _u(b'dreit\xe4gigen', 'latin1')
 
-        self.data = [('alien', 1),
-                     ('k\xf6nnten', 2),
-                     ('fox', 3),
-                     ('future', 4),
-                     ('quick', 5),
-                     ('zerst\xf6rt', 6),
-                     (unicode('dreit\xe4gigen','latin1'), 7),
+        self.data = [(b'alien', 1),
+                     (b'k\xf6nnten', 2),
+                     (b'fox', 3),
+                     (b'future', 4),
+                     (b'quick', 5),
+                     (b'zerst\xf6rt', 6),
+                     (_u(b'dreit\xe4gigen','latin1'), 7),
                     ]
 
         self.tree = OOBTree()
         for k, v in self.data:
-            if isinstance(k, str):
-                k = unicode(k, 'latin1')
+            if isinstance(k, _bytes):
+                k = _u(k, 'latin1')
             self.tree[k] = v
 
+    @_skip_under_Py3k
     def testAllKeys(self):
         # check every item of the tree
+        from BTrees._compat import _u
+        from BTrees._compat import _bytes
         for k, v in self.data:
-            if isinstance(k, str):
-                k = unicode(k, encoding)
-            self.assert_(self.tree.has_key(k))
+            if isinstance(k, _bytes):
+                k = _u(k, encoding)
+            self.assertTrue(k in self.tree)
             self.assertEqual(self.tree[k], v)
 
+    @_skip_under_Py3k
     def testUnicodeKeys(self):
         # try to access unicode keys in tree
         k, v = self.data[-1]
@@ -60,10 +67,11 @@
         self.assertEqual(self.tree[k], v)
         self.assertEqual(self.tree[self.s], v)
 
+    @_skip_under_Py3k
     def testAsciiKeys(self):
         # try to access some "plain ASCII" keys in the tree
         for k, v in self.data[0], self.data[2]:
-            self.assert_(isinstance(k, str))
+            self.assertTrue(isinstance(k, str))
             self.assertEqual(self.tree[k], v)
 
 def test_suite():

Modified: BTrees/trunk/BTrees/tests/testConflict.py
===================================================================
--- BTrees/trunk/BTrees/tests/testConflict.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/testConflict.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -136,7 +136,7 @@
         numtoadd = 16
         candidate = 60
         while numtoadd:
-            if not b.has_key(candidate):
+            if candidate not in b:
                 b[candidate] = candidate
                 numtoadd -= 1
             candidate += 1
@@ -332,11 +332,11 @@
         state1 = bucket.__getstate__()
         state2 = bucket.__getstate__()
         state3 = bucket.__getstate__()
-        self.assert_(state2 is not state1 and
-                     state2 is not state3 and
-                     state3 is not state1)
-        self.assert_(state2 == state1 and
-                     state3 == state1)
+        self.assertTrue(state2 is not state1 and
+                        state2 is not state3 and
+                        state3 is not state1)
+        self.assertTrue(state2 == state1 and
+                        state3 == state1)
         self.assertRaises(BTreesConflictError, bucket._p_resolveConflict,
                           state1, state2, state3)
         # When an empty BTree resolves conflicts, it computes the

Modified: BTrees/trunk/BTrees/tests/test_Length.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_Length.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/test_Length.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -53,24 +53,42 @@
         length = self._makeOne()
         self.assertEqual(length._p_resolveConflict(5, 7, 9), 11)
 
+    def test_change_w_positive_delta(self):
+        length = self._makeOne()
+        length.change(3)
+        self.assertEqual(length.value, 3)
+
+    def test_change_w_negative_delta(self):
+        length = self._makeOne()
+        length.change(-3)
+        self.assertEqual(length.value, -3)
+
     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)
+        try:
+            length = self._makeOne(sys.maxint)
+        except AttributeError: #pragma NO COVER Py3k
+            return
+        else: #pragma NO COVER Py2
+            self.assertEqual(length(), sys.maxint)
+            self.assertTrue(type(length()) is int)
+            length.change(+1)
+            self.assertEqual(length(), sys.maxint + 1)
+            self.assertTrue(type(length()) is long)
 
     def test_change_underflows_to_long(self):
         import sys
-        minint = (-sys.maxint) - 1
-        length = self._makeOne(minint)
-        self.assertEqual(length(), minint)
-        self.assert_(type(length()) is int)
-        length.change(-1)
-        self.assertEqual(length(), minint - 1)
-        self.assert_(type(length()) is long)
+        try:
+            minint = (-sys.maxint) - 1
+        except AttributeError: #pragma NO COVER Py3k
+            return
+        else: #pragma NO COVER Py2
+            length = self._makeOne(minint)
+            self.assertEqual(length(), minint)
+            self.assertTrue(type(length()) is int)
+            length.change(-1)
+            self.assertEqual(length(), minint - 1)
+            self.assertTrue(type(length()) is long)
 
     def test___call___no_args(self):
         length = self._makeOne(42)

Modified: BTrees/trunk/BTrees/tests/test_OIBTree.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_OIBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/test_OIBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -143,6 +143,7 @@
         self._makeOne()[1] = None
 
     def testEmptyFirstBucketReportedByGuido(self):
+        from .._compat import xrange
         b = self._makeOne()
         for i in xrange(29972): # reduce to 29971 and it works
             b[i] = i

Modified: BTrees/trunk/BTrees/tests/test_OOBTree.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_OOBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/test_OOBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -112,6 +112,7 @@
         # used in a function that's used in lots of places.
         # Otherwise, there are many permutations that would have to be
         # checked.
+        from .._compat import PY2
         t = self._makeOne()
 
         class C(object):
@@ -119,30 +120,31 @@
 
         self.assertRaises(TypeError, lambda : t.__setitem__(C(), 1))
 
-        class C(object):
-            def __cmp__(*args):
-                return 1
+        if PY2: # we only check for __cmp__ on Python2
 
-        c = C()
-        t[c] = 1
+            class With___cmp__(object):
+                def __cmp__(*args):
+                    return 1
+            c = With___cmp__()
+            t[c] = 1
 
-        t.clear()
+            t.clear()
 
-        class C(object):
+        class With___lt__(object):
             def __lt__(*args):
                 return 1
 
-        c = C()
+        c = With___lt__()
         t[c] = 1
 
         t.clear()
 
 
-#class OOBTreePyTest(OOBTreeTest):
+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):
+#class OOBTreePyTest(BTreeTests, unittest.TestCase):
 
     def _makeOne(self):
         from BTrees.OOBTree import OOBTreePy

Modified: BTrees/trunk/BTrees/tests/test__base.py
===================================================================
--- BTrees/trunk/BTrees/tests/test__base.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/test__base.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -640,7 +640,7 @@
         bucket = self._makeOne()
         for i, c in enumerate('abcdef'):
             bucket[c] = i
-        self.assertEqual(bucket.values(), range(6))
+        self.assertEqual(bucket.values(), list(range(6)))
 
     def test_values_filled_w_args(self):
         bucket = self._makeOne()
@@ -657,7 +657,7 @@
         bucket = self._makeOne()
         for i, c in enumerate('abcdef'):
             bucket[c] = i
-        self.assertEqual(list(bucket.itervalues()), range(6))
+        self.assertEqual(list(bucket.itervalues()), list(range(6)))
 
     def test_itervalues_filled_w_args(self):
         bucket = self._makeOne()
@@ -1783,8 +1783,8 @@
 
     def test__set_calls_readCurrent_on_jar(self):
         tree = self._makeOne()
-        tree._p_oid = 'OID'
-        tree._p_serial = '01234567'
+        tree._p_oid = b'OID'
+        tree._p_serial = b'01234567'
         tree._p_jar = jar = _Jar()
         tree._set('a', 'b')
         self.assertTrue(tree in jar._current)
@@ -1839,8 +1839,8 @@
 
     def test__del_calls_readCurrent_on_jar(self):
         tree = self._makeOne({'a': 'b'})
-        tree._p_oid = 'OID'
-        tree._p_serial = '01234567'
+        tree._p_oid = b'OID'
+        tree._p_serial = b'01234567'
         tree._p_jar = jar = _Jar()
         tree._del('a')
         self.assertTrue(tree in jar._current)
@@ -1898,7 +1898,7 @@
         bucket = tree._firstbucket
         jar = _Jar()
         bucket._p_jar = jar
-        bucket._p_oid = 'OID'
+        bucket._p_oid = b'OID'
         self.assertEqual(tree.__getstate__(), ((bucket,), bucket))
 
     def test___getstate___multiple_buckets(self):
@@ -2273,7 +2273,7 @@
     def test_values_filled_no_args(self):
         ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
         tree = self._makeOne(ITEMS)
-        self.assertEqual(list(tree.values()), range(26))
+        self.assertEqual(list(tree.values()), list(range(26)))
 
     def test_values_filled_w_args(self):
         ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
@@ -2289,7 +2289,7 @@
     def test_itervalues_filled_no_args(self):
         ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
         tree = self._makeOne(ITEMS)
-        self.assertEqual(list(tree.itervalues()), range(26))
+        self.assertEqual(list(tree.itervalues()), list(range(26)))
 
     def test_itervalues_filled_w_args(self):
         ITEMS = [(y, x) for x, y in enumerate('abcdefghijklmnopqrstuvwxyz')]
@@ -2634,6 +2634,28 @@
         rhs = self._makeSet('a', 'b', 'c')
         self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
 
+    def test_lhs_mapping_wo_MERGE_DEFAULT_rhs_set(self):
+        class _MappingWoDefault(dict):
+            def MERGE(self, v1, w1, v2, w2):
+                return (v1 * w1) + (v2 * w2)
+            def MERGE_WEIGHT(self, v, w):
+                return v
+        lhs = _MappingWoDefault({'a': 13, 'b': 12, 'c': 11})
+        lhs._mapping_type = _MappingWoDefault
+        rhs = self._makeSet('a', 'b', 'c')
+        self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
+
+    def test_lhs_mapping_wo_MERGE_rhs_mapping(self):
+        class _MappingWoMerge(dict):
+            def MERGE_DEFAULT(self):
+                return 1
+            def MERGE_WEIGHT(self, v, w):
+                return v
+        lhs = _MappingWoMerge({'a': 13, 'b': 12, 'c': 11})
+        lhs._mapping_type = _MappingWoMerge
+        rhs = self._makeMapping({'a': 1, 'b': 2, 'c': 3})
+        self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
+
     def test_lhs_set_wo_MERGE_DEFAULT_rhs_mapping(self):
         lhs = self._makeSet('a', 'd')
         lhs.MERGE = lambda v1, w1, v2, w2: (v1 * w1) + (v2 * w2)
@@ -2725,6 +2747,17 @@
         rhs = {'b': 22, 'd': 14}
         self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
 
+    def test_lhs_mapping_wo_MERGE_rhs_mapping(self):
+        class _MappingWoMerge(dict):
+            def MERGE_DEFAULT(self):
+                return 1
+            def MERGE_WEIGHT(self, v, w):
+                return v
+        lhs = _MappingWoMerge({'a': 13, 'b': 12, 'c': 11})
+        lhs._mapping_type = _MappingWoMerge
+        rhs = self._makeMapping({'a': 1, 'b': 2, 'c': 3})
+        self.assertRaises(TypeError, self._callFUT, lhs.__class__, lhs, rhs)
+
     def test_lhs_set_wo_MERGE_DEFAULT_rhs_set(self):
         lhs = self._makeSet('a', 'd')
         lhs.MERGE = lambda v1, w1, v2, w2: (v1 * w1) + (v2 * w2)
@@ -2824,7 +2857,10 @@
         import sys
         from BTrees._base import to_int
         faux_self = object()
-        self.assertRaises(TypeError, to_int, faux_self, sys.maxint + 1)
+        try:
+            self.assertRaises(TypeError, to_int, faux_self, sys.maxint + 1)
+        except AttributeError: #pragma NO COVER Py3k
+            pass
 
     def test_to_int_w_invalid(self):
         from BTrees._base import to_int
@@ -2863,25 +2899,28 @@
         import sys
         from BTrees._base import to_long
         faux_self = object()
-        self.assertRaises(ValueError, to_long, faux_self, sys.maxint + 1)
+        try:
+            self.assertRaises(ValueError, to_long, faux_self, sys.maxint + 1)
+        except AttributeError: #pragma NO COVER Py3k
+            pass
 
     def test_to_long_w_invalid(self):
         from BTrees._base import to_long
         faux_self = object()
         self.assertRaises(TypeError, to_long, faux_self, ())
 
-    def test_to_str_w_ok(self):
-        from BTrees._base import to_str
+    def test_to_bytes_w_ok(self):
+        from BTrees._base import to_bytes
         faux_self = object()
-        conv = to_str(3)
-        self.assertEqual(conv(faux_self, 'abc'), 'abc')
+        conv = to_bytes(3)
+        self.assertEqual(conv(faux_self, b'abc'), b'abc')
 
-    def test_to_str_w_invalid_length(self):
-        from BTrees._base import to_str
+    def test_to_bytes_w_invalid_length(self):
+        from BTrees._base import to_bytes
         faux_self = object()
-        conv = to_str(3)
-        self.assertRaises(TypeError, conv, faux_self, 'ab')
-        self.assertRaises(TypeError, conv, faux_self, 'abcd')
+        conv = to_bytes(3)
+        self.assertRaises(TypeError, conv, faux_self, b'ab')
+        self.assertRaises(TypeError, conv, faux_self, b'abcd')
 
     def test_MERGE(self):
         from BTrees._base import MERGE

Modified: BTrees/trunk/BTrees/tests/test_btreesubclass.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_btreesubclass.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/test_btreesubclass.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -38,7 +38,7 @@
             t[i] = i
 
         state = t.__getstate__()
-        self.assert_(state[0][0].__class__ is B)
+        self.assertTrue(state[0][0].__class__ is B)
 
 def test_suite():
     return unittest.makeSuite(SubclassTest)

Modified: BTrees/trunk/BTrees/tests/test_check.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_check.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/test_check.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -149,10 +149,10 @@
     def test_type_and_adr_w_oid(self):
         from BTrees.utils import oid_repr
         class WithOid(object):
-            _p_oid = 'DEADBEEF'
+            _p_oid = b'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')))
+        self.assertTrue(t_and_a.endswith('oid=%s)' % oid_repr(b'DEADBEEF')))
 
     def test_type_and_adr_wo_oid(self):
         class WithoutOid(object):

Deleted: BTrees/trunk/BTrees/tests/test_compare.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_compare.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/test_compare.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -1,75 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2002 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Test errors during comparison of BTree keys."""
-
-import unittest
-
-
-STR = "A string with hi-bit-set characters: \700\701"
-UNICODE = u"A unicode string"
-
-
-class CompareTest(unittest.TestCase):
-
-    def setUp(self):
-        # These defaults only make sense if the default encoding
-        # prevents STR from being promoted to Unicode.
-        self.assertRaises(UnicodeError, unicode, STR)
-
-    def _makeBucket(self):
-        from BTrees.OOBTree import OOBucket
-        return OOBucket()
-
-    def _makeSet(self):
-        from BTrees.OOBTree import OOSet
-        return OOSet()
-
-    def assertUE(self, callable, *args):
-        self.assertRaises(UnicodeError, callable, *args)
-
-    def testBucketGet(self):
-        import warnings
-        b = self._makeBucket()
-        with warnings.catch_warnings(True) as _warnlog:
-            b[STR] = 1
-            self.assertUE(b.get, UNICODE)
-        self.assertEqual(len(_warnlog), 1)
-
-    def testSetGet(self):
-        s = self._makeSet()
-        s.insert(STR)
-        self.assertUE(s.remove, UNICODE)
-
-    def testBucketSet(self):
-        b = self._makeBucket()
-        b[STR] = 1
-        self.assertUE(b.__setitem__, UNICODE, 1)
-
-    def testSetSet(self):
-        s = self._makeSet()
-        s.insert(STR)
-        self.assertUE(s.insert, UNICODE)
-
-    def testBucketMinKey(self):
-        b = self._makeBucket()
-        b[STR] = 1
-        self.assertUE(b.minKey, UNICODE)
-
-    def testSetMinKey(self):
-        s = self._makeSet()
-        s.insert(STR)
-        self.assertUE(s.minKey, UNICODE)
-
-def test_suite():
-    return unittest.makeSuite(CompareTest)

Modified: BTrees/trunk/BTrees/tests/test_fsBTree.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_fsBTree.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/test_fsBTree.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -14,54 +14,51 @@
 import unittest
 
 
-class fsBucketTests(unittest.TestCase):
+class fsBucketBase(object):
 
-    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 _makeBytesItems(self):
+        from .._compat import _ascii
+        return[(_ascii(c*2), _ascii(c*6)) for c in 'abcdef']
 
     def test_toString(self):
-        bucket = self._makeOne([(c*2, c*6) for c in 'abcdef'])
+        bucket = self._makeOne(self._makeBytesItems())
         self.assertEqual(bucket.toString(),
-                         'aabbccddeeffaaaaaabbbbbbccccccddddddeeeeeeffffff')
+                         b'aabbccddeeffaaaaaabbbbbbccccccddddddeeeeeeffffff')
 
     def test_fromString(self):
-        before = self._makeOne([(c*2, c*6) for c in 'abcdef'])
+        before = self._makeOne(self._makeBytesItems())
         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('')
+        before = self._makeOne(self._makeBytesItems())
+        after = before.fromString(b'')
         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_fromString_invalid_length(self):
+        bucket = self._makeOne(self._makeBytesItems())
+        self.assertRaises(ValueError, bucket.fromString, b'xxx')
 
 
-class fsBTreeTests(unittest.TestCase):
+class fsBucketTests(unittest.TestCase, fsBucketBase):
 
     def _getTargetClass(self):
-        from BTrees.fsBTree import fsBTree
-        return fsBTree
+        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)
+class fsBucketPyTests(unittest.TestCase, fsBucketBase):
 
+    def _getTargetClass(self):
+        from BTrees.fsBTree import fsBucketPy
+        return fsBucketPy
 
+
 def test_suite():
     return unittest.TestSuite((
         unittest.makeSuite(fsBucketTests),
+        unittest.makeSuite(fsBucketPyTests),
     ))

Modified: BTrees/trunk/BTrees/tests/test_utils.py
===================================================================
--- BTrees/trunk/BTrees/tests/test_utils.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/tests/test_utils.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -22,11 +22,17 @@
 
     def test_w_big_negative(self):
         import sys
-        self.assertEqual(self._callFUT(-sys.maxint), 1)
+        try:
+            self.assertEqual(self._callFUT(-sys.maxint), 1)
+        except AttributeError: #pragma NO COVER Py3k
+            pass
 
     def test_w_negative(self):
         import sys
-        self.assertEqual(self._callFUT(-1), sys.maxint)
+        try:
+            self.assertEqual(self._callFUT(-1), sys.maxint)
+        except AttributeError: #pragma NO COVER Py3k
+            pass
 
     def test_w_zero(self):
         self.assertEqual(self._callFUT(0), 0)
@@ -36,7 +42,10 @@
 
     def test_w_big_positive(self):
         import sys
-        self.assertEqual(self._callFUT(sys.maxint), sys.maxint)
+        try:
+            self.assertEqual(self._callFUT(sys.maxint), sys.maxint)
+        except AttributeError: #pragma NO COVER Py3k
+            pass
 
 
 class Test_oid_repr(unittest.TestCase):
@@ -63,16 +72,16 @@
             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')
+        self.assertEqual(self._callFUT(b'\0\0\0\0\0\0\0\0'), b'0x00')
 
     def test_w_one(self):
-        self.assertEqual(self._callFUT('\0\0\0\0\0\0\0\1'), '0x01')
+        self.assertEqual(self._callFUT(b'\0\0\0\0\0\0\0\1'), b'0x01')
 
     def test_w_even_length(self):
-        self.assertEqual(self._callFUT('\0\0\0\0\0\0\xAB\xC4'), '0xabc4')
+        self.assertEqual(self._callFUT(b'\0\0\0\0\0\0\xAB\xC4'), b'0xabc4')
 
     def test_w_odd_length(self):
-        self.assertEqual(self._callFUT('\0\0\0\0\0\0\x0D\xEF'), '0x0def')
+        self.assertEqual(self._callFUT(b'\0\0\0\0\0\0\x0D\xEF'), b'0x0def')
 
 
 def test_suite():

Modified: BTrees/trunk/BTrees/utils.py
===================================================================
--- BTrees/trunk/BTrees/utils.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/BTrees/utils.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -15,6 +15,8 @@
 
 from binascii import hexlify
 
+from ._compat import _bytes
+
 def non_negative(int_val):
     if int_val < 0:
         # Coerce to non-negative.
@@ -28,14 +30,16 @@
 
 
 def oid_repr(oid):
-    if isinstance(oid, str) and len(oid) == 8:
+    if isinstance(oid, _bytes) and len(oid) == 8:
         # Convert to hex and strip leading zeroes.
-        as_hex = hexlify(oid).lstrip('0')
+        as_hex = hexlify(oid).lstrip(b'0')
         # Ensure two characters per input byte.
+        chunks = [b'0x']
         if len(as_hex) & 1:
-            as_hex = '0' + as_hex
-        elif as_hex == '':
-            as_hex = '00'
-        return '0x' + as_hex
+            chunks.append(b'0')
+        elif as_hex == b'':
+            as_hex = b'00'
+        chunks.append(as_hex)
+        return b''.join(chunks)
     else:
         return repr(oid)

Modified: BTrees/trunk/CHANGES.txt
===================================================================
--- BTrees/trunk/CHANGES.txt	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/CHANGES.txt	2012-12-17 17:08:58 UTC (rev 128692)
@@ -5,6 +5,9 @@
 4.0.2 (unreleased)
 ------------------
 
+- Added explicit support for Python 3.2, Python 3.3, and PyPy.
+  Note that the C extensions are not (yet) available on PyPy.
+
 - Python reference implementations now tested separately from the C
   verions on all platforms.
 

Modified: BTrees/trunk/setup.py
===================================================================
--- BTrees/trunk/setup.py	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/setup.py	2012-12-17 17:08:58 UTC (rev 128692)
@@ -100,16 +100,22 @@
 # 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 pure_python or is_pypy or is_jython or sys.version_info[0] > 2:
+if pure_python or is_pypy or is_jython:
     ext_modules = []
 else:
 
     ext_modules = [BTreeExtension(family) for family in FAMILIES]
 
-REQUIRES = [
-    'persistent',
-    'zope.interface',
-]
+if sys.version_info[0] > 3:
+    REQUIRES = [
+        'persistent>=4.0.4',
+        'zope.interface',
+    ]
+else:
+    REQUIRES = [
+        'persistent',
+        'zope.interface',
+    ]
 TESTS_REQUIRE = REQUIRES + ['transaction']
 
 setup(name='BTrees',
@@ -123,8 +129,9 @@
         'Programming Language :: Python :: 2',
         'Programming Language :: Python :: 2.6',
         'Programming Language :: Python :: 2.7',
-        #'Programming Language :: Python :: 3',
-        #'Programming Language :: Python :: 3.2',
+        'Programming Language :: Python :: 3',
+        'Programming Language :: Python :: 3.2',
+        'Programming Language :: Python :: 3.3',
         "Programming Language :: Python :: Implementation :: CPython",
         "Programming Language :: Python :: Implementation :: PyPy",
         "Topic :: Database",

Modified: BTrees/trunk/tox.ini
===================================================================
--- BTrees/trunk/tox.ini	2012-12-17 16:48:34 UTC (rev 128691)
+++ BTrees/trunk/tox.ini	2012-12-17 17:08:58 UTC (rev 128692)
@@ -3,7 +3,7 @@
 # Jython support pending 2.7 support, due 2012-07-15 or so.  See:
 # http://fwierzbicki.blogspot.com/2012/03/adconion-to-fund-jython-27.html
 #   py26,py27,py32,jython,pypy,coverage,docs
-    py26,py27,pypy,w_zodb,coverage,docs
+    py26,py27,pypy,py32,py33,w_zodb,coverage,docs
 
 [testenv]
 deps =



More information about the checkins mailing list