diff --git a/.travis.yml b/.travis.yml index f89b95c..85620d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: python python: - 2.6 - 2.7 +- 3.3 - pypy services: - redis-server diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index ee5ff24..0000000 --- a/pytest.ini +++ /dev/null @@ -1,2 +0,0 @@ -[pytest] -addopts = --doctest-modules sider/ sidertests/ diff --git a/sider/hash.py b/sider/hash.py index b91767d..9975d6a 100644 --- a/sider/hash.py +++ b/sider/hash.py @@ -10,7 +10,7 @@ """ import collections from .session import Session -from .types import Bulk, ByteString +from .types import Bulk, String from .transaction import query, manipulative from . import utils @@ -54,7 +54,7 @@ class Hash(collections.MutableMapping): value_type = None def __init__(self, session, key, - key_type=ByteString, value_type=ByteString): + key_type=String, value_type=String): if not isinstance(session, Session): raise TypeError('session must be a sider.session.Session ' 'instance, not ' + repr(session)) @@ -238,8 +238,8 @@ def items(self): items = self.session.client.hgetall(self.key) decode_key = self.key_type.decode decode_value = self.value_type.decode - return frozenset((decode_key(k), decode_value(v)) - for k, v in items.iteritems()) + return frozenset((decode_key(k), decode_value(items[k])) + for k in items) @manipulative def clear(self): @@ -373,8 +373,8 @@ def _raw_update(self, value, pipe, encoded=False): def __repr__(self): cls = type(self) - items = list(self.iteritems()) - items.sort(key=lambda (key, _): key) + items = list(self.items()) + items.sort(key=lambda elem: elem[0]) elements = ', '.join('{0!r}: {1!r}'.format(*pair) for pair in items) return '<{0}.{1} ({2!r}) {{{3}}}>'.format(cls.__module__, cls.__name__, self.key, elements) diff --git a/sider/lazyimport.py b/sider/lazyimport.py index c52001f..74950b0 100644 --- a/sider/lazyimport.py +++ b/sider/lazyimport.py @@ -7,6 +7,7 @@ """ from __future__ import absolute_import import types +import functools class DeferredModule(types.ModuleType): @@ -23,7 +24,7 @@ def __getattr__(self, name): mod = self.__actual_module__ if mod is None: mod = __import__(self.__name__) - mod = reduce(getattr, self.__name__.split('.')[1:], mod) + mod = functools.reduce(getattr, self.__name__.split('.')[1:], mod) self.__actual_module__ = mod return getattr(mod, name) @@ -65,6 +66,6 @@ def __repr__(self): version = DeferredModule('sider.version') -__all__ = tuple(name for name, value in globals().iteritems() +__all__ = tuple(name for name, value in globals().items() if isinstance(value, DeferredModule)) diff --git a/sider/list.py b/sider/list.py index 5baee7a..ba2a411 100644 --- a/sider/list.py +++ b/sider/list.py @@ -13,7 +13,7 @@ import numbers import warnings from redis.exceptions import ResponseError -from .types import Bulk, ByteString +from .types import Bulk, String from .session import Session from .transaction import manipulative, query from .warnings import PerformanceWarning @@ -62,7 +62,7 @@ class List(collections.MutableSequence): #: (:class:`sider.types.Bulk`) The type of list values. value_type = None - def __init__(self, session, key, value_type=ByteString): + def __init__(self, session, key, value_type=String): if not isinstance(session, Session): raise TypeError('session must be a sider.session.Session ' 'instance, not ' + repr(session)) @@ -132,7 +132,7 @@ def __getitem__(self, index): result = self.session.client.lrange(self.key, start, stop) if index.step is not None: result = result[::index.step] - return map(decode, result) + return list(map(decode, result)) raise TypeError('indices must be integers, not ' + repr(index)) def __setitem__(self, index, value): @@ -157,7 +157,7 @@ def __setitem__(self, index, value): raise ValueError('slice with step is not supported for ' 'assignment') elif index.start in (0, None) and index.stop == 1: - seq = map(encode, value) + seq = list(map(encode, value)) seq.reverse() self.session.mark_manipulative([self.key]) if self.session.server_version_info < (2, 4, 0): diff --git a/sider/set.py b/sider/set.py index eeaf4b4..b4d5074 100644 --- a/sider/set.py +++ b/sider/set.py @@ -11,7 +11,7 @@ from __future__ import absolute_import import collections from .session import Session -from .types import Bulk, ByteString +from .types import Bulk, String from .transaction import manipulative, query from . import utils @@ -62,7 +62,7 @@ class Set(collections.MutableSet): """ - def __init__(self, session, key, value_type=ByteString): + def __init__(self, session, key, value_type=String): if not isinstance(session, Session): raise TypeError('session must be a sider.session.Session ' 'instance, not ' + repr(session)) @@ -602,7 +602,8 @@ def union(self, *sets): else: offline_sets.append(operand) union = set() - for value_type, group in online_sets.iteritems(): + for value_type in online_sets: + group = online_sets[value_type] keys = (s.key for s in group) self.session.mark_query([self.key]) subset = self.session.client.sunion(*keys) diff --git a/sider/sortedset.py b/sider/sortedset.py index 2101484..26a9688 100644 --- a/sider/sortedset.py +++ b/sider/sortedset.py @@ -12,7 +12,7 @@ import collections import itertools from .session import Session -from .types import Bulk, ByteString +from .types import Bulk, String from .transaction import query, manipulative @@ -71,7 +71,7 @@ class SortedSet(collections.MutableMapping, collections.MutableSet): #: (:class:`sider.types.Bulk`) The type of set elements. value_type = None - def __init__(self, session, key, value_type=ByteString): + def __init__(self, session, key, value_type=String): if not isinstance(session, Session): raise TypeError('session must be a sider.session.Session ' 'instance, not ' + repr(session)) @@ -98,7 +98,8 @@ def __len__(self): @query def __iter__(self): result = self.session.client.zrange(self.key, 0, -1) - return itertools.imap(self.value_type.decode, result) + for i in result: + yield self.value_type.decode(i) @query def __contains__(self, member): @@ -713,7 +714,7 @@ def block(trial, transaction): zincrby(key, value=el, amount=1) else: raise TypeError('expected iterable, not ' + repr(set_)) - for el, score in keywords.iteritems(): + for el, score in getattr(keywords, 'iteritems', keywords.items)(): if not isinstance(score, numbers.Real): raise TypeError('score must be a float, not ' + repr(score)) @@ -728,7 +729,7 @@ def block(trial, transaction): def __repr__(self): cls = type(self) pairs= list(self.items()) - pairs.sort(key=lambda (element, score): (score, element)) + pairs.sort(key=lambda pair: (pair[1], pair[0])) elements = ', '.join(repr(v) if s == 1 else '{0!r}: {1!r}'.format(v, s) for v, s in pairs) return '<{0}.{1} ({2!r}) {{{3}}}>'.format(cls.__module__, cls.__name__, diff --git a/sider/threadlocal.py b/sider/threadlocal.py index 6b36eac..60c91d9 100644 --- a/sider/threadlocal.py +++ b/sider/threadlocal.py @@ -115,13 +115,22 @@ def items(self): return self.current.items() def iteritems(self): - return self.current.iteritems() + try: + return self.current.iteritems() + except AttributeError: + return self.items() def iterkeys(self): - return self.current.keys() + try: + return self.current.iterkeys() + except AttributeError: + return self.keys() def itervalues(self): - return self.current.itervalues() + try: + return self.current.itervalues() + except AttributeError: + return self.values() def keys(self): return self.current.keys() diff --git a/sider/transaction.py b/sider/transaction.py index ed4831c..e8756a8 100644 --- a/sider/transaction.py +++ b/sider/transaction.py @@ -72,6 +72,12 @@ def block(trial, transaction): from . import lazyimport +try: + _string_type = basestring +except NameError: + _string_type = str + + class Transaction(object): """Transaction block. @@ -222,7 +228,7 @@ def watch(self, keys, initialize=False): :type initialize: :class:`bool` """ - if isinstance(keys, basestring): + if isinstance(keys, _string_type): warnings.warn('you could probably want to watch [{0!r}] instead of ' '{1!r}; do not directly pass a string but a list of ' 'string to be explicit'.format(keys, list(keys)), diff --git a/sider/types.py b/sider/types.py index be454ed..5f3a1e9 100644 --- a/sider/types.py +++ b/sider/types.py @@ -21,10 +21,10 @@ """ from __future__ import absolute_import +import sys import re import collections import numbers -import itertools import datetime import uuid from .lazyimport import list, set, sortedset @@ -223,21 +223,21 @@ class Hash(Value): :class:`collections.Mapping` objects. :param key_type: the type of keys the hash will contain. - default is :class:`ByteString` + default is :class:`String` :type key_type: :class:`Bulk`, :class:`type` :param value_type: the type of values the hash will contain. - default is :class:`ByteString` + default is :class:`String` :type value_type: :class:`Bulk`, :class:`type` """ def __init__(self, key_type=None, value_type=None): if key_type is None: - key_type = ByteString() + key_type = String() else: key_type = Bulk.ensure_value_type(key_type, parameter='key_type') if value_type is None: - value_type = ByteString() + value_type = String() else: value_type = Bulk.ensure_value_type(value_type, parameter='value_type') @@ -271,14 +271,14 @@ class List(Value): (Use :class:`ByteString` or :class:`UnicodeString` for strings.) :param value_type: the type of values the list will contain. - default is :class:`ByteString` + default is :class:`String` :type value_type: :class:`Bulk`, :class:`type` """ def __init__(self, value_type=None): if value_type is None: - self.value_type = ByteString() + self.value_type = String() else: self.value_type = Bulk.ensure_value_type(value_type, parameter='value_type') @@ -311,14 +311,14 @@ class Set(Value): :class:`collections.Set` objects. :param value_type: the type of values the set will contain. - default is :class:`ByteString` + default is :class:`String` :type value_type: :class:`Bulk`, :class:`type` """ def __init__(self, value_type=None): if value_type is None: - self.value_type = ByteString() + self.value_type = String() else: self.value_type = Bulk.ensure_value_type(value_type, parameter='value_type') @@ -350,7 +350,7 @@ class SortedSet(Set): """The type object for :class:`sider.sortedset.SortedSet` objects. :param value_type: the type of values the sorted set will contain. - default is :class:`ByteString` + default is :class:`String` :type value_type: :class:`Bulk`, :class:`type` """ @@ -486,8 +486,8 @@ class Tuple(Bulk): field_types = None def __init__(self, *field_types): - self.field_types = tuple(itertools.imap(Bulk.ensure_value_type, - field_types)) + self.field_types = tuple(Bulk.ensure_value_type(t) + for t in field_types) def encode(self, value): if not isinstance(value, tuple): @@ -503,9 +503,10 @@ def encode(self, value): msg = 'need {0} value to unpack: {1!r}' raise ValueError(msg.format(fields_num, value)) codes = [field.encode(val) - for field, val in itertools.izip(self.field_types, value)] - codes.insert(0, ','.join(str(len(code)) for code in codes)) - return '\n'.join(codes) + for field, val in zip(self.field_types, value)] + codes.insert(0, b','.join(str(len(code)).encode('ascii') + for code in codes)) + return b'\n'.join(codes) def decode(self, bulk): pos = bulk.index('\n') @@ -513,7 +514,7 @@ def decode(self, bulk): sizes = map(int, header.split(',')) pos += 1 values = [] - for field, size in itertools.izip(self.field_types, sizes): + for field, size in zip(self.field_types, sizes): code = bulk[pos:pos + size] value = field.decode(code) values.append(value) @@ -542,7 +543,7 @@ class Integer(Bulk): def encode(self, value): if not isinstance(value, numbers.Integral): raise TypeError('expected an integer, not ' + repr(value)) - return str(value) + return str(value).encode('ascii') def decode(self, bulk): return int(bulk) @@ -562,8 +563,13 @@ class ByteString(Bulk): """ + try: + bytes_type = bytes + except NameError: + bytes_type = str + def encode(self, value): - if not isinstance(value, str): + if not isinstance(value, self.bytes_type): raise TypeError('expected a byte str, not ' + repr(value)) return value @@ -586,8 +592,13 @@ class UnicodeString(Bulk): """ + try: + string_type = unicode + except NameError: + string_type = str + def encode(self, value): - if not isinstance(value, unicode): + if not isinstance(value, self.string_type): raise TypeError('expected a unicode string, not ' + repr(value)) return value.encode('utf-8') @@ -595,6 +606,12 @@ def decode(self, bulk): return bulk.decode('utf-8') +if sys.version_info[0] == 3: # python 3.x + String = UnicodeString +else: + String = ByteString + + class Boolean(Integer): """Stores :class:`bool` values as ``'1'`` or ``'0'``. @@ -633,7 +650,7 @@ class Date(Bulk): #: The :mod:`re` pattern that matches to :rfc:`3339` formatted date #: string e.g. ``'2012-03-28'``. DATE_PATTERN = re.compile( - r'^(?P\d{4})-(?P\d\d)-(?P\d\d)$' + br'^(?P\d{4})-(?P\d\d)-(?P\d\d)$' ) #: (:class:`str`) The :meth:`~datetime.date.strftime()` format string @@ -643,7 +660,7 @@ class Date(Bulk): def encode(self, value): if not isinstance(value, datetime.date): raise TypeError('expected a datetime.date, not ' + repr(value)) - return value.strftime(self.DATE_FORMAT) + return value.strftime(self.DATE_FORMAT).encode('ascii') def decode(self, bulk): match = self.DATE_PATTERN.search(bulk) @@ -689,10 +706,10 @@ class DateTime(Bulk): """ DATETIME_PATTERN = re.compile( - r'^(?P\d{4})-(?P\d\d)-(?P\d\d)T(?P\d\d):' - r'(?P\d\d):(?P\d\d)(?:\.(?P\d{6}))?' - r'(?P(?PZ)|(?P[+-])(?P' - r'\d\d):(?P\d\d))?$' + br'^(?P\d{4})-(?P\d\d)-(?P\d\d)T(?P\d\d):' + br'(?P\d\d):(?P\d\d)(?:\.(?P\d{6}))?' + br'(?P(?PZ)|(?P[+-])(?P' + br'\d\d):(?P\d\d))?$' ) def encode(self, value): @@ -700,7 +717,7 @@ def encode(self, value): raise TypeError('expected a datetime.datetime, not ' + repr(value)) if value.tzinfo is not None: value = value.replace(tzinfo=None) - return value.isoformat() + return value.isoformat().encode('ascii') def decode(self, bulk): parsed = self.parse_datetime(bulk) @@ -800,7 +817,7 @@ def encode(self, value): elif value.tzinfo is None: raise ValueError('datetime.datetime must be aware of tzinfo') encoded = super(TZDateTime, self).encode(value.astimezone(UTC)) - return encoded + 'Z' + return encoded + b'Z' def decode(self, bulk): parsed = self.parse_datetime(bulk) @@ -840,10 +857,10 @@ class Time(Bulk): """ TIME_PATTERN = re.compile( - r'^(?P\d\d):(?P\d\d):(?P\d\d)' - r'(?:\.(?P\d{6}))?' - r'(?P(?PZ)|(?P[+-])(?P' - r'\d\d):(?P\d\d))?$' + br'^(?P\d\d):(?P\d\d):(?P\d\d)' + br'(?:\.(?P\d{6}))?' + br'(?P(?PZ)|(?P[+-])(?P' + br'\d\d):(?P\d\d))?$' ) def encode(self, value): @@ -851,7 +868,7 @@ def encode(self, value): raise TypeError('expected a datetime.time, not ' + repr(value)) if value.tzinfo is not None: value = value.replace(tzinfo=None) - return value.isoformat() + return value.isoformat().encode('ascii') def decode(self, bulk): return self.parse_time(bulk, drop_tzinfo=True) @@ -924,8 +941,9 @@ def encode(self, value): elif value.tzinfo is None: raise ValueError('datetime.time must be aware of tzinfo') if value.tzinfo is UTC: - return value.replace(tzinfo=None).isoformat() + 'Z' - return value.isoformat() + result = value.replace(tzinfo=None).isoformat() + 'Z' + return result.encode('ascii') + return value.isoformat().encode('ascii') def decode(self, bulk): time = self.parse_time(bulk, drop_tzinfo=False) @@ -950,14 +968,14 @@ class TimeDelta(Bulk): """ TIMEDELTA_FORMAT = '{0.days},{0.seconds},{0.microseconds}' - TIMEDELTA_PATTERN = re.compile(r'^(?P\d+),(?P\d+),' - r'(?P\d{1,6})$') + TIMEDELTA_PATTERN = re.compile(br'^(?P\d+),(?P\d+),' + br'(?P\d{1,6})$') def encode(self, value): if not isinstance(value, datetime.timedelta): raise TypeError('expected a datetime.timedelta, not ' + repr(value)) - return self.TIMEDELTA_FORMAT.format(value) + return self.TIMEDELTA_FORMAT.format(value).encode('ascii') def decode(self, bulk): match = self.TIMEDELTA_PATTERN.search(bulk) diff --git a/sider/version.py b/sider/version.py index 2e094d8..4d89ef8 100644 --- a/sider/version.py +++ b/sider/version.py @@ -11,5 +11,5 @@ if __name__ == '__main__': - print VERSION + print(VERSION) diff --git a/sidertests/env.py b/sidertests/env.py index 4c2a1ee..d41b5ce 100644 --- a/sidertests/env.py +++ b/sidertests/env.py @@ -1,5 +1,6 @@ import os import datetime +import numbers import pytest from redis.client import StrictRedis, ConnectionError from sider.session import Session @@ -61,7 +62,7 @@ class NInt(Integer): """Saves integers as its negative number. Testing purpose.""" def encode(self, value): - if not isinstance(value, (int, long)): + if not isinstance(value, numbers.Integral): raise TypeError('expected an integer, not {0!r}; something went ' 'wrong!'.format(value)) return Integer.encode(self, -value + 6) diff --git a/sidertests/test_hash.py b/sidertests/test_hash.py index d85bc1e..b5fd9a9 100644 --- a/sidertests/test_hash.py +++ b/sidertests/test_hash.py @@ -313,7 +313,7 @@ def test_update(session): def test_massive_update(session): huge_data = dict(('{0}'.format(i), chr(ord('a') + (i % 26)) * i) - for i in xrange(1235)) + for i in range(1235)) hash_ = session.get(key('test_hash_massive_update'), Hash) hash_.update(huge_data) assert dict(hash_) == huge_data diff --git a/sidertests/test_list.py b/sidertests/test_list.py index 538f3c7..f4583da 100644 --- a/sidertests/test_list.py +++ b/sidertests/test_list.py @@ -180,9 +180,9 @@ def test_delete(session): del list_[0] listx = session.set(key('test_listx_delete'), range(1, 8), List(NInt)) del listx[0] - assert range(2, 8) == list(listx) + assert list(range(2, 8)) == list(listx) del listx[-1] - assert range(2, 7) == list(listx) + assert list(range(2, 7)) == list(listx) with warnings.catch_warnings(record=True) as w: warnings.simplefilter('always') del listx[2] @@ -255,7 +255,7 @@ def test_delete_slice(session): listx = session.set(key('test_listx_delete_slice'), range(1, 8), value_type=List(NInt)) del listx[:2] - assert range(3, 8) == list(listx) + assert list(range(3, 8)) == list(listx) del listx[3:] assert [3, 4, 5] == list(listx) del listx[:] @@ -330,9 +330,9 @@ def test_append(session): list_.append(123) listx = session.set(key('test_listx_append'), range(1, 5), List(NInt)) listx.append(5) - assert range(1, 6) == list(listx) + assert list(range(1, 6)) == list(listx) listx.append(6) - assert range(1, 7) == list(listx) + assert list(range(1, 7)) == list(listx) with raises(TypeError): listx.append('abc') @@ -349,7 +349,7 @@ def test_extend(session): list_.extend([object(), object()]) listx = session.set(key('test_listx_extend'), [1, 2], List(NInt)) listx.extend([3, 4, 5]) - assert range(1, 6) == list(listx) + assert list(range(1, 6)) == list(listx) listx.extend([67, 89]) assert [1, 2, 3, 4, 5, 67, 89] == list(listx) with raises(TypeError): @@ -465,10 +465,10 @@ def test_pop(session): listx = session.set(key('test_listx_pop'), range(1, 8), List(NInt)) popped = listx.pop(0) assert 1 == popped - assert range(2, 8) == list(listx) + assert list(range(2, 8)) == list(listx) popped = listx.pop(-1) assert 7 == popped - assert range(2, 7) == list(listx) + assert list(range(2, 7)) == list(listx) popped = listx.pop(2) assert 4 == popped assert [2, 3, 5, 6] == list(listx) @@ -542,9 +542,10 @@ def test_repr(session): assert '' == r list_ = session.set(keyid, range(20), List(NInt)) r = repr(list_) - assert ''.format(keyid, range(20)) == r + assert ''.format(keyid, + list(range(20))) == r list_.append(50) r = repr(list_) expected = ''.format(keyid, - repr(range(20))[:-1]) + repr(list(range(20)))[:-1]) assert expected == r diff --git a/sidertests/test_session.py b/sidertests/test_session.py index c54d868..7e61455 100644 --- a/sidertests/test_session.py +++ b/sidertests/test_session.py @@ -25,7 +25,7 @@ def ensure_encoding_error(excinfo): .. seealso:: """ - assert 'argument after * must be a sequence' not in excinfo.value.message,\ + assert 'argument after * must be a sequence' not in str(excinfo.value), \ 'Ensure to not use an iterable object as a variadic arugments' assert excinfo.traceback[-1].name == 'encode' diff --git a/sidertests/test_set.py b/sidertests/test_set.py index 3d70f79..d64c3ee 100644 --- a/sidertests/test_set.py +++ b/sidertests/test_set.py @@ -87,7 +87,7 @@ def test_isdisjoint(session): def test_issubset(session): test_sets = {Set(): 'abcdefg', Set(NInt): range(1, 8)} fixtures = {} - for value_type, members in test_sets.iteritems(): + for value_type, members in test_sets.items(): typeid = str(hash(value_type)) d = list(members) e = d[1:-1] @@ -146,7 +146,7 @@ def test_issubset(session): def test_issuperset(session): test_sets = {Set(): 'abcdefg', Set(NInt): range(1, 8)} fixtures = {} - for value_type, members in test_sets.iteritems(): + for value_type, members in test_sets.items(): typeid = str(hash(value_type)) f = list(members) e = f[1:-1] diff --git a/sidertests/test_sortedset.py b/sidertests/test_sortedset.py index 102be7e..7cb67a8 100644 --- a/sidertests/test_sortedset.py +++ b/sidertests/test_sortedset.py @@ -144,10 +144,10 @@ def test_keys(session): set_ = session.set(key('test_sortedset_keys'), {'a': 3, 'b': 1, 'c': 2}, SortedSet) - assert set_.keys() == ['b', 'c', 'a'] - assert set_.keys(reverse=True) == ['a', 'c', 'b'] + assert list(set_.keys()) == ['b', 'c', 'a'] + assert list(set_.keys(reverse=True)) == ['a', 'c', 'b'] setx = session.set(key('test_sortedsetx_keys'), {1: 3, 2: 1, 3: 2}, IntSet) - assert setx.keys(reverse=True) == [1, 3, 2] + assert list(setx.keys(reverse=True)) == [1, 3, 2] def test_items(session): @@ -710,8 +710,8 @@ def reset2(): def test_massive_update(session): huge_data = dict((chr(a) * i, (a - ord('a') + 1) * i) - for a in xrange(ord('a'), ord('z') + 1) - for i in xrange(1, 101)) + for a in range(ord('a'), ord('z') + 1) + for i in range(1, 101)) set_ = session.get(key('test_sortedset_massive_update'), SortedSet) set_.update(huge_data) assert dict(set_) == huge_data @@ -720,7 +720,7 @@ def test_massive_update(session): for i in a_to_z: huge_data[i] += 1 assert dict(set_) == huge_data - data = dict((chr(a), a) for a in xrange(ord('a'), ord('z') + 1)) + data = dict((chr(a), a) for a in range(ord('a'), ord('z') + 1)) setx = session.set(key('test_sortedsetx_massive_update'), data, SortedSet) set_.update(setx) for e, score in setx.items(): diff --git a/sidertests/test_threadlocal.py b/sidertests/test_threadlocal.py index 2579862..0c90bc5 100644 --- a/sidertests/test_threadlocal.py +++ b/sidertests/test_threadlocal.py @@ -8,7 +8,7 @@ def thread_test(generator, args1=(), args2=()): def test(g, *args): - g.next() + next(g) for arg in args: try: g.send(arg) @@ -24,8 +24,9 @@ def test(g, *args): if greenlet: def coro_test(generator, args1=(), args2=()): - def test(g, (cc, next_args), *args): - g.next() + def test(g, v, *args): + cc, next_args = v + next(g) for arg in args: try: g.send(arg) @@ -70,9 +71,9 @@ def run(): result[result_idx] = ( len(local), list(iter(local)), 'a' in local, 'b' in local, local['a'], local.copy(), local.get('a', 1), local.get('b', 2), - 'a' in local, 'b' in local, local.items(), + 'a' in local, 'b' in local, list(local.items()), list(local.iteritems()), list(local.iterkeys()), - list(local.itervalues()), local.keys(), local.values() + list(local.itervalues()), list(local.keys()), list(local.values()), ) def assert_expects(result, value): assert result[0] == 1 diff --git a/sidertests/test_types.py b/sidertests/test_types.py index a20d7b2..0cd141f 100644 --- a/sidertests/test_types.py +++ b/sidertests/test_types.py @@ -1,64 +1,102 @@ +# -*- coding: utf-8 -*- import datetime import uuid from pytest import raises from .env import key from .env import session +from sider import types from sider.types import Boolean, ByteString, Date, DateTime, TZDateTime, UUID from sider.datetime import FixedOffset +try: + bytes_t = bytes +except NameError: + bytes_t = str + + +def test_encoding(): + integer_type = types.Integer() + bytestring_type = types.ByteString() + unicode_type = types.UnicodeString() + boolean_type = types.Boolean() + tuple_type = types.Tuple(types.Integer, types.UnicodeString) + date_type = types.Date() + datetime_type = types.DateTime() + tz_datetime_type = types.TZDateTime() + time_type = types.Time() + tz_time_type = types.TZTime() + timedelta_type = types.TimeDelta() + assert type(integer_type.encode(42)) == bytes_t + assert type(bytestring_type.encode(b'annyeong')) == bytes_t + assert type(unicode_type.encode(u'안녕')) == bytes_t + assert type(boolean_type.encode(True)) == bytes_t + assert type(tuple_type.encode((1, u'2'))) == bytes_t + assert type(date_type.encode(datetime.date(1988, 5, 28))) == bytes_t + assert type(datetime_type.encode(datetime.datetime.now())) == bytes_t + tzdt = datetime.datetime(2013, 3, 8, 17, 2, 9, + tzinfo=FixedOffset(540)) + assert type(tz_datetime_type.encode(tzdt)) == bytes_t + assert type(time_type.encode(datetime.time(7, 21, 39))) == bytes_t + tzt = datetime.time(13, 0, 42, tzinfo=FixedOffset(360)) + assert type(tz_time_type.encode(tzt)) == bytes_t + assert type(timedelta_type.encode(datetime.timedelta(days=1))) == bytes_t + + def test_boolean(session): - session.set(key('test_types_boolean_t'), True, Boolean) - assert session.get(key('test_types_boolean_t'), Boolean) is True - session.set(key('test_types_boolean_t2'), 2, Boolean) - assert session.get(key('test_types_boolean_t2'), Boolean) is True - session.set(key('test_types_boolean_f'), False, Boolean) - assert session.get(key('test_types_boolean_f'), Boolean) is False + session.set(key(u'test_types_boolean_t'), True, Boolean) + assert session.get(key(u'test_types_boolean_t'), Boolean) is True + session.set(key(u'test_types_boolean_t2'), 2, Boolean) + assert session.get(key(u'test_types_boolean_t2'), Boolean) is True + session.set(key(u'test_types_boolean_f'), False, Boolean) + assert session.get(key(u'test_types_boolean_f'), Boolean) is False def test_date(session): - date = session.set(key('test_types_date'), datetime.date(1988, 8, 4), Date) + date = session.set(key(u'test_types_date'), + datetime.date(1988, 8, 4), + Date) assert date == datetime.date(1988, 8, 4) with raises(TypeError): - session.set(key('test_types_date'), 1234, Date) - session.set(key('test_types_date'), '19880804', ByteString) + session.set(key(u'test_types_date'), 1234, Date) + session.set(key(u'test_types_date'), b'19880804', ByteString) with raises(ValueError): - session.get(key('test_types_date'), Date) + session.get(key(u'test_types_date'), Date) def test_datetime(session): naive = datetime.datetime(2012, 3, 28, 9, 21, 34, 638972) aware = datetime.datetime(2012, 3, 28, 18, 21, 34, 638972, tzinfo=FixedOffset(540)) - session.set(key('test_types_datetime'), naive, DateTime) - dt = session.get(key('test_types_datetime'), DateTime) + session.set(key(u'test_types_datetime'), naive, DateTime) + dt = session.get(key(u'test_types_datetime'), DateTime) assert dt == naive - session.set(key('test_types_datetime'), aware, DateTime) - dt = session.get(key('test_types_datetime'), DateTime) + session.set(key(u'test_types_datetime'), aware, DateTime) + dt = session.get(key(u'test_types_datetime'), DateTime) assert dt.tzinfo is None assert dt == aware.replace(tzinfo=None) with raises(TypeError): - session.set(key('test_types_datetime'), 1234, DateTime) - session.set(key('test_types_datetime'), '1988-08-04', ByteString) + session.set(key(u'test_types_datetime'), 1234, DateTime) + session.set(key(u'test_types_datetime'), b'1988-08-04', ByteString) with raises(ValueError): - session.get(key('test_types_datetime'), DateTime) + session.get(key(u'test_types_datetime'), DateTime) def test_tzdatetime(session): aware = datetime.datetime(2012, 3, 28, 18, 21, 34, 638972, tzinfo=FixedOffset(540)) - session.set(key('test_types_tzdatetime'), aware, TZDateTime) - dt = session.get(key('test_types_tzdatetime'), TZDateTime) + session.set(key(u'test_types_tzdatetime'), aware, TZDateTime) + dt = session.get(key(u'test_types_tzdatetime'), TZDateTime) assert dt.tzinfo is not None assert dt == aware with raises(TypeError): - session.set(key('test_types_tzdatetime'), 1234, TZDateTime) + session.set(key(u'test_types_tzdatetime'), 1234, TZDateTime) naive = datetime.datetime(2012, 3, 28, 9, 21, 34, 638972) with raises(ValueError): - session.set(key('test_types_tzdatetime'), naive, TZDateTime) - session.set(key('test_types_tzdatetime'), '1988-08-04', ByteString) + session.set(key(u'test_types_tzdatetime'), naive, TZDateTime) + session.set(key(u'test_types_tzdatetime'), b'1988-08-04', ByteString) with raises(ValueError): - session.get(key('test_types_tzdatetime'), TZDateTime) + session.get(key(u'test_types_tzdatetime'), TZDateTime) def test_uuid(session): diff --git a/sidertests/test_utils.py b/sidertests/test_utils.py index e0b6294..c99ca9c 100644 --- a/sidertests/test_utils.py +++ b/sidertests/test_utils.py @@ -5,7 +5,7 @@ def test_chunk(): data_length = 1000 chunk_length = 7 - data = range(data_length) + data = list(range(data_length)) chunks = utils.chunk(data, chunk_length) assert isinstance(chunks, collections.Iterable) chunks = list(chunks) diff --git a/tox.ini b/tox.ini index f191e2e..2528b69 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] -envlist = py26, py27, pypy +envlist = py26, py27, py33, pypy [testenv] deps = pytest -commands = py.test +commands = py.test []