Commit 7b48768a authored by Jason Madden's avatar Jason Madden

Make the Python trees and sets accept an explicit None argument to indicate an...

Make the Python trees and sets accept an explicit None argument to indicate an open range in keys(), values() and min/maxKey(), as per the interface documentation and the C implementation. Except actually, the C implementation didn't accept a None for mim/maxKey, so make it actually do that.
parent db8c553b
......@@ -1506,7 +1506,7 @@ BTree_maxminKey(BTree *self, PyObject *args, int min)
/* Find the range */
if (key)
if (key && key != Py_None)
{
if ((rc = BTree_findRangeEnd(self, key, min, 0, &bucket, &offset)) <= 0)
{
......
......@@ -741,7 +741,7 @@ Bucket_maxminKey(Bucket *self, PyObject *args, int min)
goto empty;
/* Find the low range */
if (key)
if (key && key != Py_None)
{
if ((rc = Bucket_findRangeEnd(self, key, min, 0, &offset)) <= 0)
{
......@@ -1662,7 +1662,7 @@ static struct PyMethodDef Bucket_methods[] = {
{"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"},
......
......@@ -82,7 +82,7 @@ class _BucketBase(_Base):
return -1 - low
def minKey(self, key=_marker):
if key is _marker:
if key is _marker or key is None:
return self._keys[0]
key = self._to_key(key)
index = self._search(key)
......@@ -95,7 +95,7 @@ class _BucketBase(_Base):
raise ValueError("no key satisfies the conditions")
def maxKey(self, key=_marker):
if key is _marker:
if key is _marker or key is None:
return self._keys[-1]
key = self._to_key(key)
index = self._search(key)
......@@ -110,7 +110,7 @@ class _BucketBase(_Base):
def _range(self, min=_marker, max=_marker,
excludemin=False, excludemax=False):
if min is _marker:
if min is _marker or min is None:
start = 0
if excludemin:
start = 1
......@@ -122,7 +122,7 @@ class _BucketBase(_Base):
start += 1
else:
start = -start - 1
if max is _marker:
if max is _marker or max is None:
end = len(self._keys)
if excludemax:
end -= 1
......@@ -808,7 +808,7 @@ class _Tree(_Base):
if not self._data:
return ()
if min != _marker:
if min is not _marker and min is not None:
min = self._to_key(min)
bucket = self._findbucket(min)
else:
......@@ -826,7 +826,7 @@ class _Tree(_Base):
return iter(self.keys())
def minKey(self, min=_marker):
if min is _marker:
if min is _marker or min is None:
bucket = self._firstbucket
else:
min = self._to_key(min)
......@@ -839,7 +839,7 @@ class _Tree(_Base):
data = self._data
if not data:
raise ValueError('empty tree')
if max is _marker:
if max is _marker or max is None:
return data[-1].child.maxKey()
max = self._to_key(max)
......
......@@ -34,7 +34,7 @@ def _skip_under_Py3k(test_method): #pragma NO COVER
class Base(object):
# Tests common to all types: sets, buckets, and BTrees
# Tests common to all types: sets, buckets, and BTrees
db = None
......@@ -195,7 +195,7 @@ class Base(object):
class MappingBase(Base):
# Tests common to mappings (buckets, btrees)
# Tests common to mappings (buckets, btrees)
def _populate(self, t, l):
# Make some data
......@@ -393,9 +393,11 @@ class MappingBase(Base):
t[4] = 150
del t[7]
self.assertEqual(t.maxKey(), 10)
self.assertEqual(t.maxKey(None), 10)
self.assertEqual(t.maxKey(6), 6)
self.assertEqual(t.maxKey(9), 8)
self.assertEqual(t.minKey(), 1)
self.assertEqual(t.minKey(None), 1)
self.assertEqual(t.minKey(3), 3)
self.assertEqual(t.minKey(9), 10)
......@@ -758,7 +760,7 @@ class MappingBase(Base):
class BTreeTests(MappingBase):
# Tests common to all BTrees
# Tests common to all BTrees
def _checkIt(self, t):
from BTrees.check import check
......@@ -989,6 +991,15 @@ class BTreeTests(MappingBase):
t[x] = 0
diff = lsubtract(list(t.keys(0, 100)), r)
self.assertEqual(diff , [], diff)
# The same thing with no bounds
diff = lsubtract(list(t.keys(0, 100)), r)
self.assertEqual(diff , [], diff)
# The same thing with each bound set and the other
# explicitly None
diff = lsubtract(list(t.keys(0, None)), r)
self.assertEqual(diff , [], diff)
diff = lsubtract(list(t.keys(None,100)), r)
self.assertEqual(diff , [], diff)
self._checkIt(t)
def testRangeSearchAfterRandomInsert(self):
......@@ -1072,7 +1083,7 @@ class BTreeTests(MappingBase):
class NormalSetTests(Base):
# Test common to all set types
# Test common to all set types
def _populate(self, t, l):
# Make some data
......@@ -1160,9 +1171,11 @@ class NormalSetTests(Base):
t.insert(6)
t.insert(4)
self.assertEqual(t.maxKey() , 10)
self.assertEqual(t.maxKey(None) , 10)
self.assertEqual(t.maxKey(6) , 6)
self.assertEqual(t.maxKey(9) , 8)
self.assertEqual(t.minKey() , 1)
self.assertEqual(t.minKey(None) , 1)
self.assertEqual(t.minKey(3) , 3)
self.assertEqual(t.minKey(9) , 10)
self.assertTrue(t.minKey() in t)
......@@ -1481,6 +1494,7 @@ class TestLongIntKeys(TestLongIntSupport):
t[0] = o2
self.assertEqual(t[zero_long], o2)
self.assertEqual(list(t.keys()), [0])
self.assertEqual(list(t.keys(None,None)), [0])
# Test some large key values too:
k1 = SMALLEST_POSITIVE_33_BITS
......@@ -1493,6 +1507,8 @@ class TestLongIntKeys(TestLongIntSupport):
self.assertEqual(t[k2], o2)
self.assertEqual(t[k3], o1)
self.assertEqual(list(t.keys()), [k3, 0, k1, k2])
self.assertEqual(list(t.keys(k3,None)), [k3, 0, k1, k2])
self.assertEqual(list(t.keys(None,k2)), [k3, 0, k1, k2])
def testLongIntKeysOutOfRange(self):
from BTrees.IIBTree import using64bits
......@@ -1526,6 +1542,7 @@ class TestLongIntValues(TestLongIntSupport):
self.assertEqual(t[k1], v1)
self.assertEqual(t[k2], v2)
self.assertEqual(list(t.values()), [v1, v2])
self.assertEqual(list(t.values(None,None)), [v1, v2])
def testLongIntValuesOutOfRange(self):
from BTrees.IIBTree import using64bits
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment