summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Bishop <stuart@stuartbishop.net>2014-01-03 08:01:53 +0000
committerStuart Bishop <stuart@stuartbishop.net>2014-01-03 08:01:53 +0000
commit3b9780489b6bddc85fb66f64f5ef7f3e46402706 (patch)
tree4c482dd4f205a402a0920e856e2bc28615790a2f
parentd4ac4e52e0da663fe4c0c0c9f1e0a78bf583278b (diff)
downloadpytz-3b9780489b6bddc85fb66f64f5ef7f3e46402706.tar.gz
Tests and fixes for LazyList
-rw-r--r--Makefile12
-rw-r--r--src/pytz/lazy.py30
-rw-r--r--src/pytz/tests/test_lazy.py184
3 files changed, 213 insertions, 13 deletions
diff --git a/Makefile b/Makefile
index 5f970e5..8577073 100644
--- a/Makefile
+++ b/Makefile
@@ -60,7 +60,7 @@ upload: dist build/dist/locales/pytz.pot .stamp-upload
upload --sign
touch $@
-test: test_tzinfo test_docs test_zdump
+test: test_lazy test_tzinfo test_docs test_zdump
clean:
rm -f .stamp-*
@@ -68,6 +68,16 @@ clean:
make -C ${OLSON}/src clean
find . -name \*.pyc | xargs rm -f
+test_lazy: .stamp-tzinfo
+ cd build/dist/pytz/tests \
+ && ${PYTHON24} test_lazy.py ${TESTARGS} \
+ && ${PYTHON25} test_lazy.py ${TESTARGS} \
+ && ${PYTHON26} test_lazy.py ${TESTARGS} \
+ && ${PYTHON27} test_lazy.py ${TESTARGS} \
+ && ${PYTHON31} test_lazy.py ${TESTARGS} \
+ && ${PYTHON32} test_lazy.py ${TESTARGS} \
+ && ${PYTHON33} test_lazy.py ${TESTARGS}
+
test_tzinfo: .stamp-tzinfo
cd build/dist/pytz/tests \
&& ${PYTHON24} test_tzinfo.py ${TESTARGS} \
diff --git a/src/pytz/lazy.py b/src/pytz/lazy.py
index d839ff0..2d59335 100644
--- a/src/pytz/lazy.py
+++ b/src/pytz/lazy.py
@@ -66,6 +66,17 @@ class LazyDict(DictMixin):
class LazyList(list):
"""List populated on first use."""
+
+ _props = [
+ '__str__', '__repr__', '__unicode__',
+ '__hash__', '__sizeof__', '__cmp__',
+ '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
+ 'append', 'count', 'index', 'extend', 'insert', 'pop', 'remove',
+ 'reverse', 'sort', '__add__', '__radd__', '__iadd__', '__mul__',
+ '__rmul__', '__imul__', '__contains__', '__len__', '__nonzero__',
+ '__getitem__', '__setitem__', '__delitem__', '__iter__',
+ '__reversed__', '__getslice__', '__setslice__', '__delslice__']
+
def __new__(cls, fill_iter=None):
if fill_iter is None:
@@ -76,16 +87,6 @@ class LazyList(list):
class LazyList(list):
pass
- _props = (
- '__str__', '__repr__', '__unicode__',
- '__hash__', '__sizeof__', '__cmp__',
- '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
- 'append', 'count', 'index', 'extend', 'insert', 'pop', 'remove',
- 'reverse', 'sort', '__add__', '__radd__', '__iadd__', '__mul__',
- '__rmul__', '__imul__', '__contains__', '__len__', '__nonzero__',
- '__getitem__', '__setitem__', '__delitem__', '__iter__',
- '__reversed__', '__getslice__', '__setslice__', '__delslice__')
-
fill_iter = [fill_iter]
def lazy(name):
@@ -94,19 +95,24 @@ class LazyList(list):
try:
if len(fill_iter) > 0:
list.extend(self, fill_iter.pop())
- for method_name in _props:
+ for method_name in cls._props:
delattr(LazyList, method_name)
finally:
_fill_lock.release()
return getattr(list, name)(self, *args, **kw)
return _lazy
- for name in _props:
+ for name in cls._props:
setattr(LazyList, name, lazy(name))
new_list = LazyList()
return new_list
+# 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.
+LazyList._props = [prop for prop in LazyList._props if hasattr(list, prop)]
+
class LazySet(set):
"""Set populated on first use."""
diff --git a/src/pytz/tests/test_lazy.py b/src/pytz/tests/test_lazy.py
new file mode 100644
index 0000000..2641bd9
--- /dev/null
+++ b/src/pytz/tests/test_lazy.py
@@ -0,0 +1,184 @@
+from operator import *
+import os.path
+import sys
+import unittest
+import warnings
+
+
+if __name__ == '__main__':
+ # Only munge path if invoked as a script. Testrunners should have setup
+ # the paths already
+ sys.path.insert(0, os.path.abspath(os.path.join(os.pardir, os.pardir)))
+
+
+import pytz.lazy as lazy
+
+
+class LazyListTestCase(unittest.TestCase):
+ initial_data = [3,2,1]
+
+ def setUp(self):
+ self.base = [3, 2, 1]
+ self.lesser = [2, 1, 0]
+ self.greater = [4, 3, 2]
+
+ self.lazy = lazy.LazyList(iter(list(self.base)))
+
+ def test_unary_ops(self):
+ unary_ops = [str, repr, len]
+ try:
+ unary_ops.append(unicode)
+ except NameError:
+ pass # unicode no longer exists in Python 3.
+
+ for op in unary_ops:
+ self.assertEqual(
+ op(self.lazy),
+ op(self.base), str(op))
+
+ def test_binary_list_ops(self):
+ binary_ops = [eq, ge, gt, le, lt, ne, add, concat]
+ 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))
+ for other in [self.base, self.lesser, self.greater]:
+ self.assertEqual(
+ op(self.lazy, other),
+ op(self.base, other), '%s %s' % (op, other))
+ self.assertEqual(
+ op(other, self.lazy),
+ op(other, self.base), '%s %s' % (op, other))
+
+ # Multiplication
+ self.assertEqual(self.lazy * 3, self.base * 3)
+ self.assertEqual(3 * self.lazy, 3 * self.base)
+
+ # Contains
+ self.assertTrue(2 in self.lazy)
+ self.assertFalse(42 in self.lazy)
+
+ def test_bool(self):
+ self.assertTrue(bool(self.lazy))
+ self.assertFalse(bool(lazy.LazyList()))
+ self.assertFalse(bool(lazy.LazyList(iter([]))))
+
+ def test_hash(self):
+ self.assertRaises(TypeError, hash, self.lazy)
+
+ def test_isinstance(self):
+ self.assertTrue(isinstance(self.lazy, list))
+ self.assertFalse(isinstance(self.lazy, tuple))
+
+ def test_callable(self):
+ try:
+ callable
+ except NameError:
+ return # No longer exists with Python 3.
+ self.assertFalse(callable(self.lazy))
+
+ def test_append(self):
+ self.base.append('extra')
+ self.lazy.append('extra')
+ self.assertEqual(self.lazy, self.base)
+
+ def test_count(self):
+ self.assertEqual(self.lazy.count(2), 1)
+
+ def test_index(self):
+ self.assertEqual(self.lazy.index(2), 1)
+
+ def test_extend(self):
+ self.base.extend([6, 7])
+ self.lazy.extend([6, 7])
+ self.assertEqual(self.lazy, self.base)
+
+ def test_insert(self):
+ self.base.insert(0, 'ping')
+ self.lazy.insert(0, 'ping')
+ 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_reverse(self):
+ self.base.reverse()
+ self.lazy.reverse()
+ self.assertEqual(self.lazy, self.base)
+
+ def test_reversed(self):
+ self.assertEqual(list(reversed(self.lazy)), list(reversed(self.base)))
+
+ def test_sort(self):
+ self.base.sort()
+ self.assertNotEqual(self.lazy, self.base, 'Test data already sorted')
+ self.lazy.sort()
+ self.assertEqual(self.lazy, self.base)
+
+ def test_sorted(self):
+ self.assertEqual(sorted(self.lazy), sorted(self.base))
+
+ def test_getitem(self):
+ for idx in range(-len(self.base), len(self.base)):
+ self.assertEqual(self.lazy[idx], self.base[idx])
+
+ def test_setitem(self):
+ for idx in range(-len(self.base), len(self.base)):
+ self.base[idx] = idx + 1000
+ self.assertNotEqual(self.lazy, self.base)
+ self.lazy[idx] = idx + 1000
+ self.assertEqual(self.lazy, self.base)
+
+ def test_delitem(self):
+ del self.base[0]
+ self.assertNotEqual(self.lazy, self.base)
+ del self.lazy[0]
+ self.assertEqual(self.lazy, self.base)
+
+ del self.base[-2]
+ self.assertNotEqual(self.lazy, self.base)
+ del self.lazy[-2]
+ self.assertEqual(self.lazy, self.base)
+
+ def test_iter(self):
+ self.assertEqual(list(iter(self.lazy)), list(iter(self.base)))
+
+ def test_getslice(self):
+ for i in range(-len(self.base), len(self.base)):
+ for j in range(-len(self.base), len(self.base)):
+ for step in [-1, 1]:
+ self.assertEqual(self.lazy[i:j:step], self.base[i:j:step])
+
+ def test_setslice(self):
+ for i in range(-len(self.base), len(self.base)):
+ for j in range(-len(self.base), len(self.base)):
+ for step in [-1, 1]:
+ replacement = range(0, len(self.base[i:j:step]))
+ self.base[i:j:step] = replacement
+ self.lazy[i:j:step] = replacement
+ self.assertEqual(self.lazy, self.base)
+
+ def test_delslice(self):
+ del self.base[0:1]
+ del self.lazy[0:1]
+ self.assertEqual(self.lazy, self.base)
+
+ del self.base[-1:1:-1]
+ del self.lazy[-1:1:-1]
+ self.assertEqual(self.lazy, self.base)
+
+
+if __name__ == '__main__':
+ warnings.simplefilter("error") # Warnings should be fatal in tests.
+ unittest.main()