summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Bishop <stuart@stuartbishop.net>2014-01-03 09:21:28 +0000
committerStuart Bishop <stuart@stuartbishop.net>2014-01-03 09:21:28 +0000
commit265cc332f1de0bd43a7cfe79d9edeee0859fbc47 (patch)
treee1a7e9adbc589799083c12b3104ec86a1033afc2
parent3b9780489b6bddc85fb66f64f5ef7f3e46402706 (diff)
downloadpytz-265cc332f1de0bd43a7cfe79d9edeee0859fbc47.tar.gz
LazySet tests and fixes
-rw-r--r--src/pytz/lazy.py40
-rw-r--r--src/pytz/tests/test_lazy.py141
2 files changed, 158 insertions, 23 deletions
diff --git a/src/pytz/lazy.py b/src/pytz/lazy.py
index 2d59335..f7fc597 100644
--- a/src/pytz/lazy.py
+++ b/src/pytz/lazy.py
@@ -116,6 +116,22 @@ LazyList._props = [prop for prop in LazyList._props if hasattr(list, prop)]
class LazySet(set):
"""Set populated on first use."""
+
+ _props = (
+ '__str__', '__repr__', '__unicode__',
+ '__hash__', '__sizeof__', '__cmp__',
+ '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
+ '__contains__', '__len__', '__nonzero__',
+ '__getitem__', '__setitem__', '__delitem__', '__iter__',
+ '__sub__', '__and__', '__xor__', '__or__',
+ '__rsub__', '__rand__', '__rxor__', '__ror__',
+ '__isub__', '__iand__', '__ixor__', '__ior__',
+ 'add', 'clear', 'copy', 'difference', 'difference_update',
+ 'discard', 'intersection', 'intersection_update', 'isdisjoint',
+ 'issubset', 'issuperset', 'pop', 'remove',
+ 'symmetric_difference', 'symmetric_difference_update',
+ 'union', 'update')
+
def __new__(cls, fill_iter=None):
if fill_iter is None:
@@ -124,21 +140,6 @@ class LazySet(set):
class LazySet(set):
pass
- _props = (
- '__str__', '__repr__', '__unicode__',
- '__hash__', '__sizeof__', '__cmp__',
- '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
- '__contains__', '__len__', '__nonzero__',
- '__getitem__', '__setitem__', '__delitem__', '__iter__',
- '__sub__', '__and__', '__xor__', '__or__',
- '__rsub__', '__rand__', '__rxor__', '__ror__',
- '__isub__', '__iand__', '__ixor__', '__ior__',
- 'add', 'clear', 'copy', 'difference', 'difference_update',
- 'discard', 'intersection', 'intersection_update', 'isdisjoint',
- 'issubset', 'issuperset', 'pop', 'remove',
- 'symmetric_difference', 'symmetric_difference_update',
- 'union', 'update')
-
fill_iter = [fill_iter]
def lazy(name):
@@ -148,15 +149,20 @@ class LazySet(set):
if len(fill_iter) > 0:
for i in fill_iter.pop():
set.add(self, i)
- for method_name in _props:
+ for method_name in cls._props:
delattr(LazySet, method_name)
finally:
_fill_lock.release()
return getattr(set, name)(self, *args, **kw)
return _lazy
- for name in _props:
+ for name in cls._props:
setattr(LazySet, name, lazy(name))
new_set = LazySet()
return new_set
+
+# Not all versions of Python declare the same magic methods.
+# Filter out properties that don't exist in this version of Python
+# from the list.
+LazySet._props = [prop for prop in LazySet._props if hasattr(set, prop)]
diff --git a/src/pytz/tests/test_lazy.py b/src/pytz/tests/test_lazy.py
index 2641bd9..3a4afa6 100644
--- a/src/pytz/tests/test_lazy.py
+++ b/src/pytz/tests/test_lazy.py
@@ -11,7 +11,7 @@ if __name__ == '__main__':
sys.path.insert(0, os.path.abspath(os.path.join(os.pardir, os.pardir)))
-import pytz.lazy as lazy
+from pytz.lazy import LazyList, LazySet
class LazyListTestCase(unittest.TestCase):
@@ -22,10 +22,10 @@ class LazyListTestCase(unittest.TestCase):
self.lesser = [2, 1, 0]
self.greater = [4, 3, 2]
- self.lazy = lazy.LazyList(iter(list(self.base)))
+ self.lazy = LazyList(iter(list(self.base)))
def test_unary_ops(self):
- unary_ops = [str, repr, len]
+ unary_ops = [str, repr, len, bool, not_]
try:
unary_ops.append(unicode)
except NameError:
@@ -36,7 +36,7 @@ class LazyListTestCase(unittest.TestCase):
op(self.lazy),
op(self.base), str(op))
- def test_binary_list_ops(self):
+ def test_binary_ops(self):
binary_ops = [eq, ge, gt, le, lt, ne, add, concat]
try:
binary_ops.append(cmp)
@@ -63,10 +63,15 @@ class LazyListTestCase(unittest.TestCase):
self.assertTrue(2 in self.lazy)
self.assertFalse(42 in self.lazy)
+ def test_iadd(self):
+ self.lazy += [1]
+ self.base += [1]
+ self.assertEqual(self.lazy, self.base)
+
def test_bool(self):
self.assertTrue(bool(self.lazy))
- self.assertFalse(bool(lazy.LazyList()))
- self.assertFalse(bool(lazy.LazyList(iter([]))))
+ self.assertFalse(bool(LazyList()))
+ self.assertFalse(bool(LazyList(iter([]))))
def test_hash(self):
self.assertRaises(TypeError, hash, self.lazy)
@@ -179,6 +184,130 @@ class LazyListTestCase(unittest.TestCase):
self.assertEqual(self.lazy, self.base)
+class LazySetTestCase(unittest.TestCase):
+ initial_data = set([3,2,1])
+
+ def setUp(self):
+ self.base = set([3, 2, 1])
+ self.lazy = LazySet(iter(set(self.base)))
+
+ def test_unary_ops(self):
+ # These ops just need to work.
+ unary_ops = [str, repr]
+ try:
+ unary_ops.append(unicode)
+ except NameError:
+ pass # unicode no longer exists in Python 3.
+
+ for op in unary_ops:
+ op(self.lazy) # These ops just need to work.
+
+ # These ops should return identical values as a real set.
+ unary_ops = [len, bool, not_]
+
+ for op in unary_ops:
+ self.assertEqual(
+ op(self.lazy),
+ op(self.base), '%s(lazy) == %r' % (op, op(self.lazy)))
+
+ def test_binary_ops(self):
+ binary_ops = [eq, ge, gt, le, lt, ne, sub, and_, or_, xor]
+ try:
+ binary_ops.append(cmp)
+ except NameError:
+ pass # cmp no longer exists in Python 3.
+
+ for op in binary_ops:
+ self.assertEqual(
+ op(self.lazy, self.lazy),
+ op(self.base, self.base), str(op))
+ self.assertEqual(
+ op(self.lazy, self.base),
+ op(self.base, self.base), str(op))
+ self.assertEqual(
+ op(self.base, self.lazy),
+ op(self.base, self.base), str(op))
+
+ # Contains
+ self.assertTrue(2 in self.lazy)
+ self.assertFalse(42 in self.lazy)
+
+ def test_iops(self):
+ try:
+ iops = [isub, iand, ior, ixor]
+ except NameError:
+ return # Don't exist in older Python versions.
+ for op in iops:
+ # Mutating operators, so make fresh copies.
+ lazy = LazySet(self.base)
+ base = self.base.copy()
+ op(lazy, set([1]))
+ op(base, set([1]))
+ self.assertEqual(lazy, base, str(op))
+
+ def test_bool(self):
+ self.assertTrue(bool(self.lazy))
+ self.assertFalse(bool(LazySet()))
+ self.assertFalse(bool(LazySet(iter([]))))
+
+ def test_hash(self):
+ self.assertRaises(TypeError, hash, self.lazy)
+
+ def test_isinstance(self):
+ self.assertTrue(isinstance(self.lazy, set))
+
+ def test_callable(self):
+ try:
+ callable
+ except NameError:
+ return # No longer exists with Python 3.
+ self.assertFalse(callable(self.lazy))
+
+ def test_add(self):
+ self.base.add('extra')
+ self.lazy.add('extra')
+ self.assertEqual(self.lazy, self.base)
+
+ def test_copy(self):
+ self.assertEqual(self.lazy.copy(), self.base)
+
+ def test_method_ops(self):
+ ops = [
+ 'difference', 'intersection', 'isdisjoint',
+ 'issubset', 'issuperset', 'symmetric_difference', 'union',
+ 'difference_update', 'intersection_update',
+ 'symmetric_difference_update', 'update']
+ for op in ops:
+ if not hasattr(set, op):
+ continue # Not in this version of Python.
+ # Make a copy, as some of the ops are mutating.
+ lazy = LazySet(set(self.base))
+ base = set(self.base)
+ self.assertEqual(
+ getattr(self.lazy, op)(set([1])),
+ getattr(self.base, op)(set([1])), op)
+ self.assertEqual(self.lazy, self.base, op)
+
+ def test_discard(self):
+ self.base.discard(1)
+ self.assertNotEqual(self.lazy, self.base)
+ self.lazy.discard(1)
+ self.assertEqual(self.lazy, self.base)
+
+ def test_pop(self):
+ self.assertEqual(self.lazy.pop(), self.base.pop())
+ self.assertEqual(self.lazy, self.base)
+
+ def test_remove(self):
+ self.base.remove(2)
+ self.lazy.remove(2)
+ self.assertEqual(self.lazy, self.base)
+
+ def test_clear(self):
+ self.lazy.clear()
+ self.assertEqual(self.lazy, set())
+
+
if __name__ == '__main__':
warnings.simplefilter("error") # Warnings should be fatal in tests.
unittest.main()