Commit 5f4f6d4f authored by Tres Seaver's avatar Tres Seaver

Begin Py3k compatiility.

parent 90fc145a
......@@ -6,3 +6,4 @@ nosetests.xml
coverage.xml
*.egg
docs/_build
__pycache__
......@@ -21,6 +21,9 @@ from struct import error as struct_error
from persistent import Persistent
from .Interfaces import BTreesConflictError
from ._compat import cmp
from ._compat import int_types
from ._compat import xrange
_marker = object()
......@@ -298,7 +301,7 @@ class Bucket(_BucketBase):
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 +556,7 @@ class Set(_BucketBase):
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:]
......@@ -760,7 +763,7 @@ class _Tree(_Base):
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 +772,7 @@ class _Tree(_Base):
hi = i
else:
break
i = (lo+hi)//2
i = (lo + hi) // 2
return i
return -1
......@@ -882,7 +885,7 @@ class _Tree(_Base):
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:]
......@@ -1384,7 +1387,6 @@ def multiunion(set_type, seqs):
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.
......
##############################################################################
#
# 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
from StringIO import StringIO
BytesIO = StringIO
int_types = int, long
xrange = xrange
cmp = cmp
_bytes = str
def _u(s, encoding='unicode_escape'):
return unicode(s, encoding)
else: #pragma NO COVER Python3
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 _u(s, encoding=None):
if encoding is None:
return s
return str(s, encoding)
......@@ -378,30 +378,30 @@ class Printer(Walker): #pragma NO COVER
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.
......
......@@ -22,6 +22,16 @@ def _skip_wo_ZODB(test_method): #pragma NO COVER
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 @@ class Base(object):
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")
......@@ -219,7 +229,7 @@ class MappingBase(Base):
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()
......@@ -378,14 +388,14 @@ class MappingBase(Base):
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")
......@@ -1037,11 +1047,11 @@ class BTreeTests(MappingBase):
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
......@@ -1141,14 +1151,14 @@ class NormalSetTests(Base):
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")
......@@ -1423,6 +1433,12 @@ class TestLongIntSupport:
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 +1448,11 @@ class TestLongIntKeys(TestLongIntSupport):
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:
......@@ -1890,7 +1907,7 @@ def _test_merge(o1, o2, o3, expect, message='failed to merge', should_fail=0):
if should_fail:
try:
merged = o1._p_resolveConflict(s1, s2, s3)
except BTreesConflictError, err:
except BTreesConflictError as err:
pass
else:
assert 0, message
......
......@@ -206,6 +206,24 @@ class ToBeDeleted(object):
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 @@ class BugFixes(unittest.TestCase):
import gc
import random
from BTrees.OOBTree import OOBTree
from .._compat import _u
from .._compat import xrange
t = OOBTree()
......@@ -257,12 +277,12 @@ class BugFixes(unittest.TestCase):
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 @@ class BugFixes(unittest.TestCase):
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 @@ class BugFixes(unittest.TestCase):
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 @@ class BugFixes(unittest.TestCase):
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,7 +407,7 @@ class DoesntLikeBeingCompared:
def __cmp__(self,other):
raise ValueError('incomparable')
__lt__ = __le__ = __eq__ = __ne__ = __ge__ = __gt__ = __cmp__
class TestCmpError(unittest.TestCase):
......@@ -397,7 +417,7 @@ class TestCmpError(unittest.TestCase):
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 '
......@@ -468,7 +488,7 @@ class FamilyTest(unittest.TestCase):
# 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)
......@@ -476,23 +496,23 @@ class FamilyTest(unittest.TestCase):
self.failUnless(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)
# 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)
......
......@@ -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,7 +26,8 @@ class TestBTreesUnicode(unittest.TestCase):
""" test unicode"""
def setUp(self):
"""setup an OOBTree with some unicode strings"""
#setup an OOBTree with some unicode strings
from BTrees.OOBTree import OOBTree
self.s = unicode('dreit\xe4gigen', 'latin1')
......@@ -45,6 +46,7 @@ class TestBTreesUnicode(unittest.TestCase):
k = unicode(k, 'latin1')
self.tree[k] = v
@_skip_under_Py3k
def testAllKeys(self):
# check every item of the tree
for k, v in self.data:
......@@ -53,6 +55,7 @@ class TestBTreesUnicode(unittest.TestCase):
self.assert_(self.tree.has_key(k))
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,6 +63,7 @@ class TestBTreesUnicode(unittest.TestCase):
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]:
......
......@@ -15,9 +15,10 @@
import unittest
from .._compat import _u
STR = "A string with hi-bit-set characters: \700\701"
UNICODE = u"A unicode string"
UNICODE = _u("A unicode string")
class CompareTest(unittest.TestCase):
......
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